Skip to content

Commit 149edce

Browse files
Auto merge of #133502 - lcnr:rust4, r=<try>
[DO NOT MERGE] bootstrap with `-Znext-solver=globally`
2 parents 42b384e + 028c9a4 commit 149edce

File tree

94 files changed

+969
-584
lines changed

Some content is hidden

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

94 files changed

+969
-584
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_ast as ast;
22
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{NodeId, PatKind, attr, token};
4+
use rustc_errors::E0001;
45
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
56
use rustc_session::Session;
67
use rustc_session::parse::{feature_err, feature_warn};
@@ -654,10 +655,13 @@ fn check_new_solver_banned_features(sess: &Session, features: &Features) {
654655
.map(|feat| feat.attr_sp)
655656
{
656657
#[allow(rustc::symbol_intern_string_literal)]
657-
sess.dcx().emit_err(errors::IncompatibleFeatures {
658-
spans: vec![gce_span],
659-
f1: Symbol::intern("-Znext-solver=globally"),
660-
f2: sym::generic_const_exprs,
661-
});
658+
sess.dcx()
659+
.create_fatal(errors::IncompatibleFeatures {
660+
spans: vec![gce_span],
661+
f1: Symbol::intern("-Znext-solver=globally"),
662+
f2: sym::generic_const_exprs,
663+
})
664+
.with_code(E0001)
665+
.emit();
662666
}
663667
}

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
278278
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>,
279279
) -> Ty<'tcx> {
280280
fold_regions(tcx, self.inner, |r, depth| match r.kind() {
281-
ty::ReBound(debruijn, br) => {
281+
ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => {
282282
debug_assert_eq!(debruijn, depth);
283283
map(ty::RegionVid::from_usize(br.var.index()))
284284
}

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,21 +181,25 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
181181
for (param, var) in std::iter::zip(&generics.own_params, gat_vars) {
182182
let existing = match var.kind() {
183183
ty::GenericArgKind::Lifetime(re) => {
184-
if let ty::RegionKind::ReBound(ty::INNERMOST, bv) = re.kind() {
184+
if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
185+
re.kind()
186+
{
185187
mapping.insert(bv.var, tcx.mk_param_from_def(param))
186188
} else {
187189
return None;
188190
}
189191
}
190192
ty::GenericArgKind::Type(ty) => {
191-
if let ty::Bound(ty::INNERMOST, bv) = *ty.kind() {
193+
if let ty::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) = *ty.kind() {
192194
mapping.insert(bv.var, tcx.mk_param_from_def(param))
193195
} else {
194196
return None;
195197
}
196198
}
197199
ty::GenericArgKind::Const(ct) => {
198-
if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() {
200+
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(ty::INNERMOST), bv) =
201+
ct.kind()
202+
{
199203
mapping.insert(bv.var, tcx.mk_param_from_def(param))
200204
} else {
201205
return None;
@@ -260,7 +264,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
260264
return ty;
261265
}
262266

263-
if let ty::Bound(binder, old_bound) = *ty.kind()
267+
if let ty::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = *ty.kind()
264268
&& self.binder == binder
265269
{
266270
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
@@ -286,7 +290,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
286290
}
287291

288292
fn fold_region(&mut self, re: ty::Region<'tcx>) -> ty::Region<'tcx> {
289-
if let ty::ReBound(binder, old_bound) = re.kind()
293+
if let ty::ReBound(ty::BoundVarIndexKind::Bound(binder), old_bound) = re.kind()
290294
&& self.binder == binder
291295
{
292296
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
@@ -314,7 +318,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
314318
return ct;
315319
}
316320

317-
if let ty::ConstKind::Bound(binder, old_bound) = ct.kind()
321+
if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(binder), old_bound) = ct.kind()
318322
&& self.binder == binder
319323
{
320324
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
921921
ty::Param(param) => {
922922
self.params.insert(param.index);
923923
}
924-
ty::Bound(db, bt) if *db >= self.depth => {
924+
ty::Bound(ty::BoundVarIndexKind::Bound(db), bt) if *db >= self.depth => {
925925
self.vars.insert(match bt.kind {
926926
ty::BoundTyKind::Param(def_id) => def_id,
927927
ty::BoundTyKind::Anon => {
@@ -944,7 +944,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
944944
ty::ReEarlyParam(param) => {
945945
self.params.insert(param.index);
946946
}
947-
ty::ReBound(db, br) if db >= self.depth => {
947+
ty::ReBound(ty::BoundVarIndexKind::Bound(db), br) if db >= self.depth => {
948948
self.vars.insert(match br.kind {
949949
ty::BoundRegionKind::Named(def_id) => def_id,
950950
ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
@@ -967,7 +967,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
967967
ty::ConstKind::Param(param) => {
968968
self.params.insert(param.index);
969969
}
970-
ty::ConstKind::Bound(db, _) if db >= self.depth => {
970+
ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(db), _) if db >= self.depth => {
971971
let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
972972
return ControlFlow::Break(guar);
973973
}

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ use rustc_hir as hir;
99
use rustc_hir::lang_items::LangItem;
1010
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
1111
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, InferResult};
12-
use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
12+
use rustc_infer::traits::{ObligationCause, ObligationCauseCode, PredicateObligations};
1313
use rustc_macros::{TypeFoldable, TypeVisitable};
1414
use rustc_middle::span_bug;
15+
use rustc_middle::ty::error::TypeError;
1516
use rustc_middle::ty::{
16-
self, ClosureKind, GenericArgs, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
17-
TypeVisitableExt, TypeVisitor,
17+
self, ClosureKind, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
18+
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
1819
};
1920
use rustc_span::def_id::LocalDefId;
2021
use rustc_span::{DUMMY_SP, Span};
2122
use rustc_trait_selection::error_reporting::traits::ArgKind;
22-
use rustc_trait_selection::traits;
23+
use rustc_trait_selection::traits::{self, ObligationCtxt};
2324
use tracing::{debug, instrument, trace};
2425

2526
use super::{CoroutineTypes, Expectation, FnCtxt, check_fn};
@@ -384,56 +385,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
384385
// Make sure that we didn't infer a signature that mentions itself.
385386
// This can happen when we elaborate certain supertrait bounds that
386387
// mention projections containing the `Self` type. See #105401.
387-
struct MentionsTy<'tcx> {
388-
expected_ty: Ty<'tcx>,
389-
}
390-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MentionsTy<'tcx> {
391-
type Result = ControlFlow<()>;
392-
393-
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
394-
if t == self.expected_ty {
395-
ControlFlow::Break(())
396-
} else {
397-
t.super_visit_with(self)
398-
}
399-
}
400-
}
401-
402-
// Don't infer a closure signature from a goal that names the closure type as this will
403-
// (almost always) lead to occurs check errors later in type checking.
388+
//
389+
// Doing so will (almost always) lead to occurs check errors later in
390+
// type checking.
404391
if self.next_trait_solver()
405392
&& let Some(inferred_sig) = inferred_sig
406393
{
407-
// In the new solver it is difficult to explicitly normalize the inferred signature as we
408-
// would have to manually handle universes and rewriting bound vars and placeholders back
409-
// and forth.
410-
//
411-
// Instead we take advantage of the fact that we relating an inference variable with an alias
412-
// will only instantiate the variable if the alias is rigid(*not quite). Concretely we:
413-
// - Create some new variable `?sig`
414-
// - Equate `?sig` with the unnormalized signature, e.g. `fn(<Foo<?x> as Trait>::Assoc)`
415-
// - Depending on whether `<Foo<?x> as Trait>::Assoc` is rigid, ambiguous or normalizeable,
416-
// we will either wind up with `?sig=<Foo<?x> as Trait>::Assoc/?y/ConcreteTy` respectively.
417-
//
418-
// *: In cases where there are ambiguous aliases in the signature that make use of bound vars
419-
// they will wind up present in `?sig` even though they are non-rigid.
394+
// If we've got `F: FnOnce(<u32 as Id<F>>::This)` we want to
395+
// use this to infer the signature `FnOnce(u32)` for the closure.
420396
//
421-
// This is a bit weird and means we may wind up discarding the goal due to it naming `expected_ty`
422-
// even though the normalized form may not name `expected_ty`. However, this matches the existing
423-
// behaviour of the old solver and would be technically a breaking change to fix.
397+
// We handle self-referential aliases here by relying on generalization
398+
// which replaces such aliases with inference variables. This is currently
399+
// a bit too weak, see trait-system-refactor-initiative#191.
400+
struct ReplaceTy<'tcx> {
401+
tcx: TyCtxt<'tcx>,
402+
expected_ty: Ty<'tcx>,
403+
with_ty: Ty<'tcx>,
404+
}
405+
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
406+
fn cx(&self) -> TyCtxt<'tcx> {
407+
self.tcx
408+
}
409+
410+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
411+
if t == self.expected_ty {
412+
self.with_ty
413+
} else {
414+
t.super_fold_with(self)
415+
}
416+
}
417+
}
424418
let generalized_fnptr_sig = self.next_ty_var(span);
425419
let inferred_fnptr_sig = Ty::new_fn_ptr(self.tcx, inferred_sig.sig);
426-
self.demand_eqtype(span, inferred_fnptr_sig, generalized_fnptr_sig);
427-
428-
let resolved_sig = self.resolve_vars_if_possible(generalized_fnptr_sig);
429-
430-
if resolved_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
431-
expected_sig = Some(ExpectedSig {
432-
cause_span: inferred_sig.cause_span,
433-
sig: resolved_sig.fn_sig(self.tcx),
434-
});
420+
let inferred_fnptr_sig = inferred_fnptr_sig.fold_with(&mut ReplaceTy {
421+
tcx: self.tcx,
422+
expected_ty,
423+
with_ty: generalized_fnptr_sig,
424+
});
425+
let resolved_sig = self.commit_if_ok(|snapshot| {
426+
let outer_universe = self.universe();
427+
let ocx = ObligationCtxt::new(self);
428+
ocx.eq(
429+
&ObligationCause::dummy(),
430+
self.param_env,
431+
generalized_fnptr_sig,
432+
inferred_fnptr_sig,
433+
)?;
434+
if ocx.select_where_possible().is_empty() {
435+
self.leak_check(outer_universe, Some(snapshot))?;
436+
Ok(self.resolve_vars_if_possible(generalized_fnptr_sig))
437+
} else {
438+
Err(TypeError::Mismatch)
439+
}
440+
});
441+
match resolved_sig {
442+
Ok(resolved_sig) => {
443+
expected_sig = Some(ExpectedSig {
444+
cause_span: inferred_sig.cause_span,
445+
sig: resolved_sig.fn_sig(self.tcx),
446+
})
447+
}
448+
Err(_) => {}
435449
}
436450
} else {
451+
struct MentionsTy<'tcx> {
452+
expected_ty: Ty<'tcx>,
453+
}
454+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MentionsTy<'tcx> {
455+
type Result = ControlFlow<()>;
456+
457+
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
458+
if t == self.expected_ty {
459+
ControlFlow::Break(())
460+
} else {
461+
t.super_visit_with(self)
462+
}
463+
}
464+
}
437465
if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() {
438466
expected_sig = inferred_sig;
439467
}

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! A utility module to inspect currently ambiguous obligations in the current context.
22
33
use rustc_infer::traits::{self, ObligationCause, PredicateObligations};
4-
use rustc_middle::traits::solve::GoalSource;
54
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
65
use rustc_span::Span;
76
use rustc_trait_selection::solve::Certainty;
@@ -37,10 +36,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3736
) -> bool {
3837
match predicate.kind().skip_binder() {
3938
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
40-
self.type_matches_expected_vid(expected_vid, data.self_ty())
39+
self.type_matches_expected_vid(data.self_ty(), expected_vid)
4140
}
4241
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
43-
self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty())
42+
self.type_matches_expected_vid(data.projection_term.self_ty(), expected_vid)
4443
}
4544
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
4645
| ty::PredicateKind::Subtype(..)
@@ -60,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6059
}
6160

6261
#[instrument(level = "debug", skip(self), ret)]
63-
fn type_matches_expected_vid(&self, expected_vid: ty::TyVid, ty: Ty<'tcx>) -> bool {
62+
fn type_matches_expected_vid(&self, ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
6463
let ty = self.shallow_resolve(ty);
6564
debug!(?ty);
6665

@@ -76,7 +75,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7675
&self,
7776
self_ty: ty::TyVid,
7877
) -> PredicateObligations<'tcx> {
79-
let obligations = self.fulfillment_cx.borrow().pending_obligations();
78+
let sub_root_var = self.sub_unification_table_root_var(self_ty);
79+
let obligations = self
80+
.fulfillment_cx
81+
.borrow()
82+
.pending_obligations_potentially_referencing_sub_root(sub_root_var);
8083
debug!(?obligations);
8184
let mut obligations_for_self_ty = PredicateObligations::new();
8285
for obligation in obligations {
@@ -125,23 +128,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
125128
return;
126129
}
127130

131+
// We don't care about any pending goals which don't actually
132+
// use the self type.
133+
if !inspect_goal
134+
.orig_values()
135+
.iter()
136+
.filter_map(|arg| arg.as_type())
137+
.any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty))
138+
{
139+
debug!(goal = ?inspect_goal.goal(), "goal does not mention self type");
140+
return;
141+
}
142+
128143
let tcx = self.fcx.tcx;
129144
let goal = inspect_goal.goal();
130-
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty)
131-
// We do not push the instantiated forms of goals as it would cause any
132-
// aliases referencing bound vars to go from having escaping bound vars to
133-
// being able to be normalized to an inference variable.
134-
//
135-
// This is mostly just a hack as arbitrary nested goals could still contain
136-
// such aliases while having a different `GoalSource`. Closure signature inference
137-
// however can't really handle *every* higher ranked `Fn` goal also being present
138-
// in the form of `?c: Fn<(<?x as Trait<'!a>>::Assoc)`.
139-
//
140-
// This also just better matches the behaviour of the old solver where we do not
141-
// encounter instantiated forms of goals, only nested goals that referred to bound
142-
// vars from instantiated goals.
143-
&& !matches!(inspect_goal.source(), GoalSource::InstantiateHigherRanked)
144-
{
145+
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
145146
self.obligations_for_self_ty.push(traits::Obligation::new(
146147
tcx,
147148
self.root_cause.clone(),

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ fn typeck_with_inspect<'tcx>(
219219
// the future.
220220
fcx.check_repeat_exprs();
221221

222+
// We need to handle opaque types before emitting ambiguity errors as applying
223+
// defining uses may guide type inference.
224+
if fcx.next_trait_solver() {
225+
fcx.try_handle_opaque_type_uses_next();
226+
}
227+
222228
fcx.type_inference_fallback();
223229

224230
// Even though coercion casts provide type hints, we check casts after fallback for

0 commit comments

Comments
 (0)