Skip to content

Commit cf073ec

Browse files
committed
Auto merge of rust-lang#109202 - compiler-errors:new-solver-fast-reject-faster-2, r=lcnr
Don't pass `TreatProjections` separately to `fast_reject` Don't pass `TreatProjections` separately to `fast_reject`, and instead use the original approach of switching on two variants of `TreatParams` (undoes this: rust-lang#108830 (review)). Fixes the regression introduced in rust-lang#108830 (comment)
2 parents 1459b31 + fc0cbe8 commit cf073ec

File tree

7 files changed

+53
-80
lines changed

7 files changed

+53
-80
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs

+3-13
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::{DefId, LocalDefId};
14-
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams, TreatProjections};
14+
use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams};
1515
use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt};
1616
use rustc_span::symbol::sym;
1717

@@ -97,12 +97,7 @@ impl<'tcx> InherentCollect<'tcx> {
9797
}
9898
}
9999

100-
if let Some(simp) = simplify_type(
101-
self.tcx,
102-
self_ty,
103-
TreatParams::AsCandidateKey,
104-
TreatProjections::AsCandidateKey,
105-
) {
100+
if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) {
106101
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
107102
} else {
108103
bug!("unexpected self type: {:?}", self_ty);
@@ -162,12 +157,7 @@ impl<'tcx> InherentCollect<'tcx> {
162157
}
163158
}
164159

165-
if let Some(simp) = simplify_type(
166-
self.tcx,
167-
ty,
168-
TreatParams::AsCandidateKey,
169-
TreatProjections::AsCandidateKey,
170-
) {
160+
if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsCandidateKey) {
171161
self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
172162
} else {
173163
bug!("unexpected primitive type: {:?}", ty);

compiler/rustc_hir_typeck/src/method/probe.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
1616
use rustc_infer::infer::DefineOpaqueTypes;
1717
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
1818
use rustc_middle::middle::stability;
19-
use rustc_middle::ty::fast_reject::TreatProjections;
2019
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
2120
use rustc_middle::ty::AssocItem;
2221
use rustc_middle::ty::GenericParamDefKind;
@@ -701,7 +700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
701700
}
702701

703702
fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
704-
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey) else {
703+
let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) else {
705704
bug!("unexpected incoherent type: {:?}", self_ty)
706705
};
707706
for &impl_def_id in self.tcx.incoherent_impls(simp) {

compiler/rustc_hir_typeck/src/method/suggest.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ 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;
2928
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
3029
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
3130
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
@@ -1524,7 +1523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15241523
.into_iter()
15251524
.any(|info| self.associated_value(info.def_id, item_name).is_some());
15261525
let found_assoc = |ty: Ty<'tcx>| {
1527-
simplify_type(tcx, ty, TreatParams::AsCandidateKey, TreatProjections::AsCandidateKey)
1526+
simplify_type(tcx, ty, TreatParams::AsCandidateKey)
15281527
.and_then(|simp| {
15291528
tcx.incoherent_impls(simp)
15301529
.iter()
@@ -2653,12 +2652,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26532652
// FIXME: Even though negative bounds are not implemented, we could maybe handle
26542653
// cases where a positive bound implies a negative impl.
26552654
(candidates, Vec::new())
2656-
} else if let Some(simp_rcvr_ty) = simplify_type(
2657-
self.tcx,
2658-
rcvr_ty,
2659-
TreatParams::ForLookup,
2660-
TreatProjections::ForLookup,
2661-
) {
2655+
} else if let Some(simp_rcvr_ty) =
2656+
simplify_type(self.tcx, rcvr_ty, TreatParams::ForLookup)
2657+
{
26622658
let mut potential_candidates = Vec::new();
26632659
let mut explicitly_negative = Vec::new();
26642660
for candidate in candidates {
@@ -2671,12 +2667,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26712667
})
26722668
.any(|imp_did| {
26732669
let imp = self.tcx.impl_trait_ref(imp_did).unwrap().subst_identity();
2674-
let imp_simp = simplify_type(
2675-
self.tcx,
2676-
imp.self_ty(),
2677-
TreatParams::ForLookup,
2678-
TreatProjections::ForLookup,
2679-
);
2670+
let imp_simp =
2671+
simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
26802672
imp_simp.map_or(false, |s| s == simp_rcvr_ty)
26812673
})
26822674
{

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_middle::mir::interpret;
2727
use rustc_middle::query::LocalCrate;
2828
use rustc_middle::traits::specialization_graph;
2929
use rustc_middle::ty::codec::TyEncoder;
30-
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
30+
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
3131
use rustc_middle::ty::query::Providers;
3232
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
3333
use rustc_middle::util::common::to_readable_str;
@@ -1881,7 +1881,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18811881
self.tcx,
18821882
trait_ref.self_ty(),
18831883
TreatParams::AsCandidateKey,
1884-
TreatProjections::AsCandidateKey,
18851884
);
18861885

18871886
fx_hash_map

compiler/rustc_middle/src/ty/fast_reject.rs

+22-15
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,22 @@ pub enum TreatParams {
5656
AsCandidateKey,
5757
/// Treat parameters as placeholders in the given environment. This is the
5858
/// correct mode for *lookup*, as during candidate selection.
59+
///
60+
/// This also treats projections with inference variables as infer vars
61+
/// since they could be further normalized.
5962
ForLookup,
63+
/// Treat parameters as placeholders in the given environment. This is the
64+
/// correct mode for *lookup*, as during candidate selection.
65+
///
66+
/// N.B. during deep rejection, this acts identically to `ForLookup`.
67+
NextSolverLookup,
6068
}
6169

6270
/// During fast-rejection, we have the choice of treating projection types
6371
/// as either simplifyable or not, depending on whether we expect the projection
6472
/// to be normalized/rigid.
6573
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
6674
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.
69-
///
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,
7475
/// In the old solver we don't try to normalize projections
7576
/// when looking up impls and only access them by using the
7677
/// current self type. This means that if the self type is
@@ -107,7 +108,6 @@ pub fn simplify_type<'tcx>(
107108
tcx: TyCtxt<'tcx>,
108109
ty: Ty<'tcx>,
109110
treat_params: TreatParams,
110-
treat_projections: TreatProjections,
111111
) -> Option<SimplifiedType> {
112112
match *ty.kind() {
113113
ty::Bool => Some(BoolSimplifiedType),
@@ -136,13 +136,20 @@ pub fn simplify_type<'tcx>(
136136
ty::FnPtr(f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())),
137137
ty::Placeholder(..) => Some(PlaceholderSimplifiedType),
138138
ty::Param(_) => match treat_params {
139-
TreatParams::ForLookup => Some(PlaceholderSimplifiedType),
139+
TreatParams::ForLookup | TreatParams::NextSolverLookup => {
140+
Some(PlaceholderSimplifiedType)
141+
}
140142
TreatParams::AsCandidateKey => None,
141143
},
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,
144+
ty::Alias(..) => match treat_params {
145+
// When treating `ty::Param` as a placeholder, projections also
146+
// don't unify with anything else as long as they are fully normalized.
147+
//
148+
// We will have to be careful with lazy normalization here.
149+
// FIXME(lazy_normalization): This is probably not right...
150+
TreatParams::ForLookup if !ty.has_non_region_infer() => Some(PlaceholderSimplifiedType),
151+
TreatParams::NextSolverLookup => Some(PlaceholderSimplifiedType),
152+
TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
146153
},
147154
ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)),
148155
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
@@ -310,7 +317,7 @@ impl DeepRejectCtxt {
310317
// Depending on the value of `treat_obligation_params`, we either
311318
// treat generic parameters like placeholders or like inference variables.
312319
ty::Param(_) => match self.treat_obligation_params {
313-
TreatParams::ForLookup => false,
320+
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
314321
TreatParams::AsCandidateKey => true,
315322
},
316323

@@ -348,7 +355,7 @@ impl DeepRejectCtxt {
348355
let k = impl_ct.kind();
349356
match obligation_ct.kind() {
350357
ty::ConstKind::Param(_) => match self.treat_obligation_params {
351-
TreatParams::ForLookup => false,
358+
TreatParams::ForLookup | TreatParams::NextSolverLookup => false,
352359
TreatParams::AsCandidateKey => true,
353360
},
354361

compiler/rustc_middle/src/ty/trait_def.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,7 @@ impl<'tcx> TyCtxt<'tcx> {
153153
self_ty: Ty<'tcx>,
154154
) -> impl Iterator<Item = DefId> + 'tcx {
155155
let impls = self.trait_impls_of(trait_def_id);
156-
if let Some(simp) = fast_reject::simplify_type(
157-
self,
158-
self_ty,
159-
TreatParams::AsCandidateKey,
160-
TreatProjections::AsCandidateKey,
161-
) {
156+
if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) {
162157
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
163158
return impls.iter().copied();
164159
}
@@ -191,13 +186,17 @@ impl<'tcx> TyCtxt<'tcx> {
191186
}
192187
}
193188

189+
// Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
190+
// `TreatParams::AsCandidateKey` while actually adding them.
191+
let treat_params = match treat_projections {
192+
TreatProjections::NextSolverLookup => TreatParams::NextSolverLookup,
193+
TreatProjections::ForLookup => TreatParams::ForLookup,
194+
};
194195
// This way, when searching for some impl for `T: Trait`, we do not look at any impls
195196
// whose outer level is not a parameter or projection. Especially for things like
196197
// `T: Clone` this is incredibly useful as we would otherwise look at all the impls
197198
// of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
198-
if let Some(simp) =
199-
fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup, treat_projections)
200-
{
199+
if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) {
201200
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
202201
for &impl_def_id in impls {
203202
if let result @ Some(_) = f(impl_def_id) {
@@ -258,12 +257,9 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
258257
continue;
259258
}
260259

261-
if let Some(simplified_self_ty) = fast_reject::simplify_type(
262-
tcx,
263-
impl_self_ty,
264-
TreatParams::AsCandidateKey,
265-
TreatProjections::AsCandidateKey,
266-
) {
260+
if let Some(simplified_self_ty) =
261+
fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
262+
{
267263
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
268264
} else {
269265
impls.blanket_impls.push(impl_def_id);

compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs

+9-19
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::OverlapError;
33
use crate::traits;
44
use rustc_errors::ErrorGuaranteed;
55
use rustc_hir::def_id::DefId;
6-
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
6+
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
77
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
88

99
pub use rustc_middle::traits::specialization_graph::*;
@@ -49,12 +49,9 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
4949
/// Insert an impl into this set of children without comparing to any existing impls.
5050
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
5151
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
52-
if let Some(st) = fast_reject::simplify_type(
53-
tcx,
54-
trait_ref.self_ty(),
55-
TreatParams::AsCandidateKey,
56-
TreatProjections::AsCandidateKey,
57-
) {
52+
if let Some(st) =
53+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
54+
{
5855
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
5956
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
6057
} else {
@@ -69,12 +66,9 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
6966
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
7067
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
7168
let vec: &mut Vec<DefId>;
72-
if let Some(st) = fast_reject::simplify_type(
73-
tcx,
74-
trait_ref.self_ty(),
75-
TreatParams::AsCandidateKey,
76-
TreatProjections::AsCandidateKey,
77-
) {
69+
if let Some(st) =
70+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
71+
{
7872
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
7973
vec = self.non_blanket_impls.get_mut(&st).unwrap();
8074
} else {
@@ -310,12 +304,8 @@ impl<'tcx> GraphExt<'tcx> for Graph {
310304

311305
let mut parent = trait_def_id;
312306
let mut last_lint = None;
313-
let simplified = fast_reject::simplify_type(
314-
tcx,
315-
trait_ref.self_ty(),
316-
TreatParams::AsCandidateKey,
317-
TreatProjections::AsCandidateKey,
318-
);
307+
let simplified =
308+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);
319309

320310
// Descend the specialization tree, where `parent` is the current parent node.
321311
loop {

0 commit comments

Comments
 (0)