Skip to content

Commit c54af45

Browse files
committed
Auto merge of #109097 - matthiaskrgr:rollup-6ydc4ri, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #108419 (Stabilize `atomic_as_ptr`) - #108507 (use `as_ptr` to determine the address of atomics) - #108607 (Don't use fd-lock on Solaris in bootstrap) - #108830 (Treat projections with infer as placeholder during fast reject in new solver) - #109055 (create `config::tests::detect_src_and_out` test for bootstrap) - #109058 (Document BinOp::is_checkable) - #109081 (simd-wide-sum test: adapt for LLVM 17 codegen change) - #109083 (Update books) - #109088 (Gracefully handle `#[target_feature]` on statics) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 22f247c + 30cd4b3 commit c54af45

File tree

36 files changed

+454
-144
lines changed

36 files changed

+454
-144
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+25-20
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,29 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
6161

6262
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
6363

64-
// In some cases, attribute are only valid on functions, but it's the `check_attr`
65-
// pass that check that they aren't used anywhere else, rather this module.
66-
// In these cases, we bail from performing further checks that are only meaningful for
67-
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
68-
// report a delayed bug, just in case `check_attr` isn't doing its job.
69-
let validate_fn_only_attr = |attr_sp| -> bool {
70-
let def_kind = tcx.def_kind(did);
71-
if let DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..) = def_kind {
72-
true
73-
} else {
74-
tcx.sess.delay_span_bug(attr_sp, "this attribute can only be applied to functions");
75-
false
76-
}
77-
};
78-
7964
let mut inline_span = None;
8065
let mut link_ordinal_span = None;
8166
let mut no_sanitize_span = None;
67+
8268
for attr in attrs.iter() {
69+
// In some cases, attribute are only valid on functions, but it's the `check_attr`
70+
// pass that check that they aren't used anywhere else, rather this module.
71+
// In these cases, we bail from performing further checks that are only meaningful for
72+
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
73+
// report a delayed bug, just in case `check_attr` isn't doing its job.
74+
let fn_sig = || {
75+
use DefKind::*;
76+
77+
let def_kind = tcx.def_kind(did);
78+
if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
79+
Some(tcx.fn_sig(did))
80+
} else {
81+
tcx.sess
82+
.delay_span_bug(attr.span, "this attribute can only be applied to functions");
83+
None
84+
}
85+
};
86+
8387
if attr.has_name(sym::cold) {
8488
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
8589
} else if attr.has_name(sym::rustc_allocator) {
@@ -169,8 +173,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
169173
}
170174
}
171175
} else if attr.has_name(sym::cmse_nonsecure_entry) {
172-
if validate_fn_only_attr(attr.span)
173-
&& !matches!(tcx.fn_sig(did).skip_binder().abi(), abi::Abi::C { .. })
176+
if let Some(fn_sig) = fn_sig()
177+
&& !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. })
174178
{
175179
struct_span_err!(
176180
tcx.sess,
@@ -189,8 +193,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
189193
codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
190194
} else if attr.has_name(sym::track_caller) {
191195
if !tcx.is_closure(did.to_def_id())
192-
&& validate_fn_only_attr(attr.span)
193-
&& tcx.fn_sig(did).skip_binder().abi() != abi::Abi::Rust
196+
&& let Some(fn_sig) = fn_sig()
197+
&& fn_sig.skip_binder().abi() != abi::Abi::Rust
194198
{
195199
struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
196200
.emit();
@@ -222,7 +226,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
222226
}
223227
} else if attr.has_name(sym::target_feature) {
224228
if !tcx.is_closure(did.to_def_id())
225-
&& tcx.fn_sig(did).skip_binder().unsafety() == hir::Unsafety::Normal
229+
&& let Some(fn_sig) = fn_sig()
230+
&& fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal
226231
{
227232
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
228233
// The `#[target_feature]` attribute is allowed on

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_errors::struct_span_err;
1111
use rustc_hir as hir;
1212
use rustc_hir::def::DefKind;
1313
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
14-
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
14+
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams, TreatProjections};
1515
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
1616
use rustc_span::symbol::sym;
1717

@@ -99,7 +99,12 @@ impl<'tcx> InherentCollect<'tcx> {
9999
}
100100
}
101101

102-
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) {
102+
if let Some(simp) = simplify_type(
103+
self.tcx,
104+
self_ty,
105+
TreatParams::AsCandidateKey,
106+
TreatProjections::AsCandidateKey,
107+
) {
103108
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
104109
} else {
105110
bug!("unexpected self type: {:?}", self_ty);
@@ -159,7 +164,12 @@ impl<'tcx> InherentCollect<'tcx> {
159164
}
160165
}
161166

162-
if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsInfer) {
167+
if let Some(simp) = simplify_type(
168+
self.tcx,
169+
ty,
170+
TreatParams::AsCandidateKey,
171+
TreatProjections::AsCandidateKey,
172+
) {
163173
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
164174
} else {
165175
bug!("unexpected primitive type: {:?}", ty);

compiler/rustc_hir_typeck/src/method/probe.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_infer::infer::canonical::OriginalQueryValues;
1515
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
1616
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
1717
use rustc_middle::middle::stability;
18+
use rustc_middle::ty::fast_reject::TreatProjections;
1819
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
1920
use rustc_middle::ty::AssocItem;
2021
use rustc_middle::ty::GenericParamDefKind;
@@ -699,7 +700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
699700
}
700701

701702
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
702-
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) else {
703+
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey) else {
703704
bug!("unexpected incoherent type: {:?}", self_ty)
704705
};
705706
for &impl_def_id in self.tcx.incoherent_impls(simp) {

compiler/rustc_hir_typeck/src/method/suggest.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_infer::infer::{
2525
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
2626
use rustc_middle::traits::util::supertraits;
2727
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
28+
use rustc_middle::ty::fast_reject::TreatProjections;
2829
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
2930
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
3031
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
@@ -1257,7 +1258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12571258
let target_ty = self
12581259
.autoderef(sugg_span, rcvr_ty)
12591260
.find(|(rcvr_ty, _)| {
1260-
DeepRejectCtxt { treat_obligation_params: TreatParams::AsInfer }
1261+
DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey }
12611262
.types_may_unify(*rcvr_ty, impl_ty)
12621263
})
12631264
.map_or(impl_ty, |(ty, _)| ty)
@@ -1516,7 +1517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15161517
.into_iter()
15171518
.any(|info| self.associated_value(info.def_id, item_name).is_some());
15181519
let found_assoc = |ty: Ty<'tcx>| {
1519-
simplify_type(tcx, ty, TreatParams::AsInfer)
1520+
simplify_type(tcx, ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey)
15201521
.and_then(|simp| {
15211522
tcx.incoherent_impls(simp)
15221523
.iter()
@@ -2645,9 +2646,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26452646
// FIXME: Even though negative bounds are not implemented, we could maybe handle
26462647
// cases where a positive bound implies a negative impl.
26472648
(candidates, Vec::new())
2648-
} else if let Some(simp_rcvr_ty) =
2649-
simplify_type(self.tcx, rcvr_ty, TreatParams::AsPlaceholder)
2650-
{
2649+
} else if let Some(simp_rcvr_ty) = simplify_type(
2650+
self.tcx,
2651+
rcvr_ty,
2652+
TreatParams::ForLookup,
2653+
TreatProjections::ForLookup,
2654+
) {
26512655
let mut potential_candidates = Vec::new();
26522656
let mut explicitly_negative = Vec::new();
26532657
for candidate in candidates {
@@ -2660,8 +2664,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26602664
})
26612665
.any(|imp_did| {
26622666
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
2663-
let imp_simp =
2664-
simplify_type(self.tcx, imp.self_ty(), TreatParams::AsPlaceholder);
2667+
let imp_simp = simplify_type(
2668+
self.tcx,
2669+
imp.self_ty(),
2670+
TreatParams::ForLookup,
2671+
TreatProjections::ForLookup,
2672+
);
26652673
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
26662674
})
26672675
{

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_middle::middle::exported_symbols::{
2626
use rustc_middle::mir::interpret;
2727
use rustc_middle::traits::specialization_graph;
2828
use rustc_middle::ty::codec::TyEncoder;
29-
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
29+
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
3030
use rustc_middle::ty::query::Providers;
3131
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
3232
use rustc_middle::util::common::to_readable_str;
@@ -1858,7 +1858,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18581858
let simplified_self_ty = fast_reject::simplify_type(
18591859
self.tcx,
18601860
trait_ref.self_ty(),
1861-
TreatParams::AsInfer,
1861+
TreatParams::AsCandidateKey,
1862+
TreatProjections::AsCandidateKey,
18621863
);
18631864

18641865
fx_hash_map

compiler/rustc_middle/src/mir/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1999,6 +1999,9 @@ impl BorrowKind {
19991999
}
20002000

20012001
impl BinOp {
2002+
/// The checkable operators are those whose overflow checking behavior is controlled by
2003+
/// -Coverflow-checks option. The remaining operators have either no overflow conditions (e.g.,
2004+
/// BitAnd, BitOr, BitXor) or are always checked for overflow (e.g., Div, Rem).
20022005
pub fn is_checkable(self) -> bool {
20032006
use self::BinOp::*;
20042007
matches!(self, Add | Sub | Mul | Shl | Shr)

compiler/rustc_middle/src/ty/fast_reject.rs

+39-24
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,35 @@ pub enum SimplifiedType {
5151
/// generic parameters as if they were inference variables in that case.
5252
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
5353
pub enum TreatParams {
54-
/// Treat parameters as placeholders in the given environment.
54+
/// Treat parameters as infer vars. This is the correct mode for caching
55+
/// an impl's type for lookup.
56+
AsCandidateKey,
57+
/// Treat parameters as placeholders in the given environment. This is the
58+
/// correct mode for *lookup*, as during candidate selection.
59+
ForLookup,
60+
}
61+
62+
/// During fast-rejection, we have the choice of treating projection types
63+
/// as either simplifyable or not, depending on whether we expect the projection
64+
/// to be normalized/rigid.
65+
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
66+
pub enum TreatProjections {
67+
/// In candidates, we may be able to normalize the projection
68+
/// after instantiating the candidate and equating it with a goal.
5569
///
56-
/// Note that this also causes us to treat projections as if they were
57-
/// placeholders. This is only correct if the given projection cannot
58-
/// be normalized in the current context. Even if normalization fails,
59-
/// it may still succeed later if the projection contains any inference
60-
/// variables.
61-
AsPlaceholder,
62-
AsInfer,
70+
/// We must assume that the `impl<T> Trait<T> for <T as Id>::This`
71+
/// can apply to all self types so we don't return a simplified type
72+
/// for `<T as Id>::This`.
73+
AsCandidateKey,
74+
/// In the old solver we don't try to normalize projections
75+
/// when looking up impls and only access them by using the
76+
/// current self type. This means that if the self type is
77+
/// a projection which could later be normalized, we must not
78+
/// treat it as rigid.
79+
ForLookup,
80+
/// We can treat projections in the self type as opaque as
81+
/// we separately look up impls for the normalized self type.
82+
NextSolverLookup,
6383
}
6484

6585
/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
@@ -87,6 +107,7 @@ pub fn simplify_type<'tcx>(
87107
tcx: TyCtxt<'tcx>,
88108
ty: Ty<'tcx>,
89109
treat_params: TreatParams,
110+
treat_projections: TreatProjections,
90111
) -> Option<SimplifiedType> {
91112
match *ty.kind() {
92113
ty::Bool => Some(BoolSimplifiedType),
@@ -115,19 +136,13 @@ pub fn simplify_type<'tcx>(
115136
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
116137
ty::Placeholder(..) => Some(PlaceholderSimplifiedType),
117138
ty::Param(_) => match treat_params {
118-
TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType),
119-
TreatParams::AsInfer => None,
139+
TreatParams::ForLookup => Some(PlaceholderSimplifiedType),
140+
TreatParams::AsCandidateKey => None,
120141
},
121-
ty::Alias(..) => match treat_params {
122-
// When treating `ty::Param` as a placeholder, projections also
123-
// don't unify with anything else as long as they are fully normalized.
124-
//
125-
// We will have to be careful with lazy normalization here.
126-
TreatParams::AsPlaceholder if !ty.has_non_region_infer() => {
127-
debug!("treating `{}` as a placeholder", ty);
128-
Some(PlaceholderSimplifiedType)
129-
}
130-
TreatParams::AsPlaceholder | TreatParams::AsInfer => None,
142+
ty::Alias(..) => match treat_projections {
143+
TreatProjections::ForLookup if !ty.needs_infer() => Some(PlaceholderSimplifiedType),
144+
TreatProjections::NextSolverLookup => Some(PlaceholderSimplifiedType),
145+
TreatProjections::AsCandidateKey | TreatProjections::ForLookup => None,
131146
},
132147
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
133148
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
@@ -295,8 +310,8 @@ impl DeepRejectCtxt {
295310
// Depending on the value of `treat_obligation_params`, we either
296311
// treat generic parameters like placeholders or like inference variables.
297312
ty::Param(_) => match self.treat_obligation_params {
298-
TreatParams::AsPlaceholder => false,
299-
TreatParams::AsInfer => true,
313+
TreatParams::ForLookup => false,
314+
TreatParams::AsCandidateKey => true,
300315
},
301316

302317
ty::Infer(_) => true,
@@ -333,8 +348,8 @@ impl DeepRejectCtxt {
333348
let k = impl_ct.kind();
334349
match obligation_ct.kind() {
335350
ty::ConstKind::Param(_) => match self.treat_obligation_params {
336-
TreatParams::AsPlaceholder => false,
337-
TreatParams::AsInfer => true,
351+
TreatParams::ForLookup => false,
352+
TreatParams::AsCandidateKey => true,
338353
},
339354

340355
// As we don't necessarily eagerly evaluate constants,

0 commit comments

Comments
 (0)