Skip to content

Commit ef4e825

Browse files
committed
Auto merge of #131628 - matthiaskrgr:rollup-imbojxz, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #128784 (Check ABI target compatibility for function pointers) - #130965 (make `Step` doc-comments more clear) - #131239 (Don't assume traits used as type are trait objs in 2021 edition) - #131277 (Handle `clippy` cases of `rustc::potential_query_instability` lint) - #131503 (More clearly document Stdin::read_line) - #131567 (Emit an error for unstable attributes that reference already stable features) - #131599 (Shallowly match opaque key in storage) - #131617 (remove const_cow_is_borrowed feature gate) Failed merges: - #131616 (merge const_ipv4 / const_ipv6 feature gate into 'ip' feature gate) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6b9676b + de72917 commit ef4e825

File tree

102 files changed

+1913
-862
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1913
-862
lines changed

compiler/rustc_data_structures/src/unhash.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::hash::{BuildHasherDefault, Hasher};
33

44
pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>;
55
pub type UnhashSet<V> = HashSet<V, BuildHasherDefault<Unhasher>>;
6+
pub type UnindexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<Unhasher>>;
67

78
/// This no-op hasher expects only a single `write_u64` call. It's intended for
89
/// map keys that already have hash-like quality, like `Fingerprint`.

compiler/rustc_hir_analysis/src/check/check.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use rustc_hir::Node;
88
use rustc_hir::def::{CtorKind, DefKind};
99
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1010
use rustc_infer::traits::Obligation;
11-
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
11+
use rustc_lint_defs::builtin::{
12+
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
13+
};
1214
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
1315
use rustc_middle::middle::stability::EvalResult;
1416
use rustc_middle::span_bug;
@@ -52,16 +54,18 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
5254
});
5355
}
5456
}
57+
}
5558

56-
// This ABI is only allowed on function pointers
57-
if abi == Abi::CCmseNonSecureCall {
58-
struct_span_code_err!(
59-
tcx.dcx(),
60-
span,
61-
E0781,
62-
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
63-
)
64-
.emit();
59+
pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
60+
match tcx.sess.target.is_abi_supported(abi) {
61+
Some(true) => (),
62+
Some(false) | None => {
63+
tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| {
64+
lint.primary_message(
65+
"use of calling convention not supported on this target on function pointer",
66+
);
67+
});
68+
}
6569
}
6670
}
6771

compiler/rustc_hir_analysis/src/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub mod wfcheck;
7373

7474
use std::num::NonZero;
7575

76-
pub use check::check_abi;
76+
pub use check::{check_abi, check_abi_fn_ptr};
7777
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
7878
use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};
7979
use rustc_hir::def_id::{DefId, LocalDefId};

compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use rustc_errors::DiagCtxtHandle;
2-
use rustc_hir as hir;
3-
use rustc_hir::HirId;
1+
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
2+
use rustc_hir::{self as hir, HirId};
43
use rustc_middle::ty::layout::LayoutError;
54
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
65
use rustc_span::Span;
@@ -26,7 +25,19 @@ pub(crate) fn validate_cmse_abi<'tcx>(
2625
..
2726
}) = hir_node
2827
else {
29-
// might happen when this ABI is used incorrectly. That will be handled elsewhere
28+
let span = match tcx.parent_hir_node(hir_id) {
29+
hir::Node::Item(hir::Item {
30+
kind: hir::ItemKind::ForeignMod { .. }, span, ..
31+
}) => *span,
32+
_ => tcx.hir().span(hir_id),
33+
};
34+
struct_span_code_err!(
35+
tcx.dcx(),
36+
span,
37+
E0781,
38+
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
39+
)
40+
.emit();
3041
return;
3142
};
3243

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

+25-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::TraitObjectSyntax;
22
use rustc_errors::codes::*;
3-
use rustc_errors::{Diag, EmissionGuarantee, StashKey};
3+
use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, StashKey, Suggestions};
44
use rustc_hir as hir;
55
use rustc_hir::def::{DefKind, Res};
66
use rustc_lint_defs::Applicability;
@@ -15,13 +15,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1515
///
1616
/// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
1717
/// In edition 2021 and onward we emit a hard error for them.
18-
pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) {
18+
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
19+
&self,
20+
self_ty: &hir::Ty<'_>,
21+
) -> Option<ErrorGuaranteed> {
1922
let tcx = self.tcx();
2023

2124
let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
2225
self_ty.kind
2326
else {
24-
return;
27+
return None;
2528
};
2629

2730
let in_path = match tcx.parent_hir_node(self_ty.hir_id) {
@@ -70,8 +73,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7073
}
7174

7275
if self_ty.span.edition().at_least_rust_2021() {
73-
let msg = "trait objects must include the `dyn` keyword";
74-
let label = "add `dyn` keyword before this trait";
76+
let msg = "expected a type, found a trait";
77+
let label = "you can add the `dyn` keyword if you want a trait object";
7578
let mut diag =
7679
rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg);
7780
if self_ty.span.can_be_used_for_suggestions()
@@ -83,7 +86,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8386
// Check if the impl trait that we are considering is an impl of a local trait.
8487
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
8588
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
86-
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
89+
// In case there is an associate type with the same name
90+
// Add the suggestion to this error
91+
if let Some(mut sugg) =
92+
tcx.dcx().steal_non_err(self_ty.span, StashKey::AssociatedTypeSuggestion)
93+
&& let Suggestions::Enabled(ref mut s1) = diag.suggestions
94+
&& let Suggestions::Enabled(ref mut s2) = sugg.suggestions
95+
{
96+
s1.append(s2);
97+
sugg.cancel();
98+
}
99+
diag.stash(self_ty.span, StashKey::TraitMissingMethod)
87100
} else {
88101
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
89102
lint.primary_message("trait objects without an explicit `dyn` are deprecated");
@@ -96,6 +109,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
96109
}
97110
self.maybe_suggest_blanket_trait_impl(self_ty, lint);
98111
});
112+
None
99113
}
100114
}
101115

@@ -174,41 +188,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
174188
// 1. Independent functions
175189
// 2. Functions inside trait blocks
176190
// 3. Functions inside impl blocks
177-
let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
191+
let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
178192
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
179-
(sig, generics, None)
193+
(sig, generics)
180194
}
181195
hir::Node::TraitItem(hir::TraitItem {
182196
kind: hir::TraitItemKind::Fn(sig, _),
183197
generics,
184-
owner_id,
185198
..
186-
}) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
199+
}) => (sig, generics),
187200
hir::Node::ImplItem(hir::ImplItem {
188201
kind: hir::ImplItemKind::Fn(sig, _),
189202
generics,
190-
owner_id,
191203
..
192-
}) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
204+
}) => (sig, generics),
193205
_ => return false,
194206
};
195207
let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
196208
return false;
197209
};
198210
let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
199-
let mut is_downgradable = true;
200-
201211
// Check if trait object is safe for suggesting dynamic dispatch.
202212
let is_dyn_compatible = match self_ty.kind {
203213
hir::TyKind::TraitObject(objects, ..) => {
204214
objects.iter().all(|(o, _)| match o.trait_ref.path.res {
205-
Res::Def(DefKind::Trait, id) => {
206-
if Some(id) == owner {
207-
// For recursive traits, don't downgrade the error. (#119652)
208-
is_downgradable = false;
209-
}
210-
tcx.is_dyn_compatible(id)
211-
}
215+
Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
212216
_ => false,
213217
})
214218
}
@@ -255,9 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
255259
suggestion,
256260
Applicability::MachineApplicable,
257261
);
258-
} else if is_downgradable {
259-
// We'll emit the dyn-compatibility error already, with a structured suggestion.
260-
diag.downgrade_to_delayed_bug();
261262
}
262263
return true;
263264
}
@@ -281,10 +282,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
281282
);
282283
if !is_dyn_compatible {
283284
diag.note(format!("`{trait_name}` it is dyn-incompatible, so it can't be `dyn`"));
284-
if is_downgradable {
285-
// We'll emit the dyn-compatibility error already, with a structured suggestion.
286-
diag.downgrade_to_delayed_bug();
287-
}
288285
} else {
289286
// No ampersand in suggestion if it's borrowed already
290287
let (dyn_str, paren_dyn_str) =

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
5353
use tracing::{debug, debug_span, instrument};
5454

5555
use crate::bounds::Bounds;
56+
use crate::check::check_abi_fn_ptr;
5657
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
5758
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
5859
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
@@ -2063,13 +2064,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20632064
)
20642065
}
20652066
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
2066-
self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
2067-
2068-
let repr = match repr {
2069-
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2070-
TraitObjectSyntax::DynStar => ty::DynStar,
2071-
};
2072-
self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2067+
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2068+
// Don't continue with type analysis if the `dyn` keyword is missing
2069+
// It generates confusing errors, especially if the user meant to use another
2070+
// keyword like `impl`
2071+
Ty::new_error(tcx, guar)
2072+
} else {
2073+
let repr = match repr {
2074+
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2075+
TraitObjectSyntax::DynStar => ty::DynStar,
2076+
};
2077+
self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2078+
}
20732079
}
20742080
// If we encounter a fully qualified path with RTN generics, then it must have
20752081
// *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
@@ -2337,6 +2343,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23372343
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
23382344
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
23392345

2346+
if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::BareFn(bare_fn_ty), span, .. }) =
2347+
tcx.hir_node(hir_id)
2348+
{
2349+
check_abi_fn_ptr(tcx, hir_id, *span, bare_fn_ty.abi);
2350+
}
2351+
23402352
// reject function types that violate cmse ABI requirements
23412353
cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, bare_fn_ty);
23422354

compiler/rustc_lint_defs/src/builtin.rs

+45
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ declare_lint_pass! {
124124
UNSTABLE_NAME_COLLISIONS,
125125
UNSTABLE_SYNTAX_PRE_EXPANSION,
126126
UNSUPPORTED_CALLING_CONVENTIONS,
127+
UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
127128
UNUSED_ASSIGNMENTS,
128129
UNUSED_ASSOCIATED_TYPE_BOUNDS,
129130
UNUSED_ATTRIBUTES,
@@ -3839,6 +3840,50 @@ declare_lint! {
38393840
};
38403841
}
38413842

3843+
declare_lint! {
3844+
/// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
3845+
/// a target dependent calling convention on a target that does not support this calling
3846+
/// convention on a function pointer.
3847+
///
3848+
/// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3849+
/// code, because this calling convention was never specified for those targets.
3850+
///
3851+
/// ### Example
3852+
///
3853+
/// ```rust,ignore (needs specific targets)
3854+
/// fn stdcall_ptr(f: extern "stdcall" fn ()) {
3855+
/// f()
3856+
/// }
3857+
/// ```
3858+
///
3859+
/// This will produce:
3860+
///
3861+
/// ```text
3862+
/// warning: use of calling convention not supported on this target on function pointer
3863+
/// --> $DIR/unsupported.rs:34:15
3864+
/// |
3865+
/// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
3866+
/// | ^^^^^^^^^^^^^^^^^^^^^^^^
3867+
/// |
3868+
/// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3869+
/// = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
3870+
/// = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
3871+
/// ```
3872+
///
3873+
/// ### Explanation
3874+
///
3875+
/// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3876+
/// defined at all, but was previously accepted due to a bug in the implementation of the
3877+
/// compiler.
3878+
pub UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
3879+
Warn,
3880+
"use of unsupported calling convention for function pointer",
3881+
@future_incompatible = FutureIncompatibleInfo {
3882+
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
3883+
reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
3884+
};
3885+
}
3886+
38423887
declare_lint! {
38433888
/// The `break_with_label_and_loop` lint detects labeled `break` expressions with
38443889
/// an unlabeled loop as their value expression.

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+17-34
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use derive_where::derive_where;
44
#[cfg(feature = "nightly")]
55
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
66
use rustc_type_ir::data_structures::{HashMap, HashSet, ensure_sufficient_stack};
7+
use rustc_type_ir::fast_reject::DeepRejectCtxt;
78
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
89
use rustc_type_ir::inherent::*;
910
use rustc_type_ir::relate::Relate;
@@ -18,9 +19,9 @@ use crate::delegate::SolverDelegate;
1819
use crate::solve::inspect::{self, ProofTreeBuilder};
1920
use crate::solve::search_graph::SearchGraph;
2021
use crate::solve::{
21-
CanonicalInput, CanonicalResponse, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind,
22-
GoalSource, HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData,
23-
QueryResult, SolverMode,
22+
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind, GoalSource,
23+
HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult,
24+
SolverMode,
2425
};
2526

2627
pub(super) mod canonical;
@@ -987,40 +988,22 @@ where
987988

988989
// Do something for each opaque/hidden pair defined with `def_id` in the
989990
// current inference context.
990-
pub(super) fn unify_existing_opaque_tys(
991+
pub(super) fn probe_existing_opaque_ty(
991992
&mut self,
992-
param_env: I::ParamEnv,
993993
key: ty::OpaqueTypeKey<I>,
994-
ty: I::Ty,
995-
) -> Vec<CanonicalResponse<I>> {
996-
// FIXME: Super inefficient to be cloning this...
997-
let opaques = self.delegate.clone_opaque_types_for_query_response();
998-
999-
let mut values = vec![];
1000-
for (candidate_key, candidate_ty) in opaques {
1001-
if candidate_key.def_id != key.def_id {
1002-
continue;
1003-
}
1004-
values.extend(
1005-
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
1006-
result: *result,
1007-
})
1008-
.enter(|ecx| {
1009-
for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
1010-
ecx.eq(param_env, a, b)?;
1011-
}
1012-
ecx.eq(param_env, candidate_ty, ty)?;
1013-
ecx.add_item_bounds_for_hidden_type(
1014-
candidate_key.def_id.into(),
1015-
candidate_key.args,
1016-
param_env,
1017-
candidate_ty,
1018-
);
1019-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1020-
}),
994+
) -> Option<(ty::OpaqueTypeKey<I>, I::Ty)> {
995+
let mut matching =
996+
self.delegate.clone_opaque_types_for_query_response().into_iter().filter(
997+
|(candidate_key, _)| {
998+
candidate_key.def_id == key.def_id
999+
&& DeepRejectCtxt::relate_rigid_rigid(self.cx())
1000+
.args_may_unify(candidate_key.args, key.args)
1001+
},
10211002
);
1022-
}
1023-
values
1003+
let first = matching.next();
1004+
let second = matching.next();
1005+
assert_eq!(second, None);
1006+
first
10241007
}
10251008

10261009
// Try to evaluate a const, or return `None` if the const is too generic.

0 commit comments

Comments
 (0)