Skip to content

Commit 7aeab7a

Browse files
Auto merge of #133502 - lcnr:rust4, r=<try>
[DO NOT MERGE] bootstrap with `-Znext-solver=globally`
2 parents 4cd91ef + aae1efe commit 7aeab7a

File tree

50 files changed

+224
-294
lines changed

Some content is hidden

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

50 files changed

+224
-294
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_hir_typeck/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16341634
) -> Ty<'tcx> {
16351635
let rcvr_t = self.check_expr(rcvr);
16361636
// no need to check for bot/err -- callee does that
1637-
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
1637+
let rcvr_t = self.try_structurally_resolve_type(rcvr.span, rcvr_t);
16381638

16391639
match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args) {
16401640
Ok(method) => {

compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs

Lines changed: 1 addition & 16 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;
@@ -127,21 +126,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> {
127126

128127
let tcx = self.fcx.tcx;
129128
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-
{
129+
if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
145130
self.obligations_for_self_ty.push(traits::Obligation::new(
146131
tcx,
147132
self.root_cause.clone(),

compiler/rustc_hir_typeck/src/method/confirm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
182182
assert_eq!(n, pick.autoderefs);
183183

184184
let mut adjustments = self.adjust_steps(&autoderef);
185-
let mut target = self.structurally_resolve_type(autoderef.span(), ty);
185+
let mut target = self.try_structurally_resolve_type(autoderef.span(), ty);
186186

187187
match pick.autoref_or_ptr_adjustment {
188188
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => {

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ use rustc_hir::HirId;
1212
use rustc_hir::def::DefKind;
1313
use rustc_hir_analysis::autoderef::{self, Autoderef};
1414
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
15-
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt};
15+
use rustc_infer::infer::{
16+
BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt,
17+
};
1618
use rustc_infer::traits::ObligationCauseCode;
1719
use rustc_middle::middle::stability;
1820
use rustc_middle::ty::elaborate::supertrait_def_ids;
@@ -441,7 +443,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
441443
// If we encountered an `_` type or an error type during autoderef, this is
442444
// ambiguous.
443445
if let Some(bad_ty) = &steps.opt_bad_ty {
444-
if is_suggestion.0 {
446+
// Ended up encountering a type variable when doing autoderef,
447+
// but it may not be a type variable after processing obligations
448+
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
449+
let ty = &bad_ty.ty;
450+
let ty = self
451+
.probe_instantiate_query_response(span, &orig_values, ty)
452+
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
453+
if bad_ty.is_opaque_type || final_ty_is_opaque(&self.infcx, ty.value) {
454+
// FIXME(-Znext-solver): This isn't really what we want :<
455+
assert!(self.tcx.next_trait_solver_globally());
456+
} else if is_suggestion.0 {
445457
// Ambiguity was encountered during a suggestion. There's really
446458
// not much use in suggesting methods in this case.
447459
return Err(MethodError::NoMatch(NoMatchData {
@@ -467,13 +479,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
467479
},
468480
);
469481
} else {
470-
// Ended up encountering a type variable when doing autoderef,
471-
// but it may not be a type variable after processing obligations
472-
// in our local `FnCtxt`, so don't call `structurally_resolve_type`.
473-
let ty = &bad_ty.ty;
474-
let ty = self
475-
.probe_instantiate_query_response(span, &orig_values, ty)
476-
.unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
477482
let ty = self.resolve_vars_if_possible(ty.value);
478483
let guar = match *ty.kind() {
479484
ty::Infer(ty::TyVar(_)) => {
@@ -629,8 +634,14 @@ pub(crate) fn method_autoderef_steps<'tcx>(
629634
};
630635
let final_ty = autoderef_via_deref.final_ty();
631636
let opt_bad_ty = match final_ty.kind() {
632-
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
637+
ty::Infer(ty::TyVar(_)) => Some(MethodAutoderefBadTy {
633638
reached_raw_pointer,
639+
is_opaque_type: final_ty_is_opaque(infcx, final_ty),
640+
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
641+
}),
642+
ty::Error(_) => Some(MethodAutoderefBadTy {
643+
reached_raw_pointer,
644+
is_opaque_type: false,
634645
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
635646
}),
636647
ty::Array(elem_ty, _) => {
@@ -663,6 +674,15 @@ pub(crate) fn method_autoderef_steps<'tcx>(
663674
}
664675
}
665676

677+
/// Returns `true` in case the final type is the hidden type of an opaque.
678+
#[instrument(level = "debug", skip(infcx), ret)]
679+
fn final_ty_is_opaque<'tcx>(infcx: &InferCtxt<'tcx>, final_ty: Ty<'tcx>) -> bool {
680+
let &ty::Infer(ty::TyVar(vid)) = final_ty.kind() else {
681+
return false;
682+
};
683+
infcx.has_opaques_with_sub_unified_hidden_type(vid)
684+
}
685+
666686
impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
667687
fn new(
668688
fcx: &'a FnCtxt<'a, 'tcx>,
@@ -1871,31 +1891,39 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
18711891
(xform_self_ty, xform_ret_ty) =
18721892
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
18731893
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
1874-
match self_ty.kind() {
1875-
// HACK: opaque types will match anything for which their bounds hold.
1876-
// Thus we need to prevent them from trying to match the `&_` autoref
1877-
// candidates that get created for `&self` trait methods.
1878-
ty::Alias(ty::Opaque, alias_ty)
1879-
if !self.next_trait_solver()
1880-
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
1881-
&& !xform_self_ty.is_ty_var() =>
1882-
{
1883-
return ProbeResult::NoMatch;
1884-
}
1885-
_ => match ocx.relate(
1886-
cause,
1887-
self.param_env,
1888-
self.variance(),
1889-
self_ty,
1890-
xform_self_ty,
1891-
) {
1892-
Ok(()) => {}
1893-
Err(err) => {
1894-
debug!("--> cannot relate self-types {:?}", err);
1894+
1895+
// HACK: opaque types will match anything for which their bounds hold.
1896+
// Thus we need to prevent them from trying to match the `&_` autoref
1897+
// candidates that get created for `&self` trait methods.
1898+
if self.mode == Mode::MethodCall {
1899+
match self_ty.kind() {
1900+
ty::Infer(ty::TyVar(_)) => {
1901+
assert!(self.infcx.next_trait_solver());
1902+
if !xform_self_ty.is_ty_var() {
1903+
return ProbeResult::NoMatch;
1904+
}
1905+
}
1906+
ty::Alias(ty::Opaque, alias_ty)
1907+
if !self.infcx.next_trait_solver()
1908+
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
1909+
&& !xform_self_ty.is_ty_var() =>
1910+
{
1911+
assert!(!self.infcx.next_trait_solver());
18951912
return ProbeResult::NoMatch;
18961913
}
1897-
},
1914+
_ => {}
1915+
}
1916+
}
1917+
1918+
match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
1919+
{
1920+
Ok(()) => {}
1921+
Err(err) => {
1922+
debug!("--> cannot relate self-types {:?}", err);
1923+
return ProbeResult::NoMatch;
1924+
}
18981925
}
1926+
18991927
let obligation = traits::Obligation::new(
19001928
self.tcx,
19011929
cause.clone(),

compiler/rustc_middle/src/traits/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ pub struct MethodAutoderefStepsResult<'tcx> {
178178
#[derive(Debug, HashStable)]
179179
pub struct MethodAutoderefBadTy<'tcx> {
180180
pub reached_raw_pointer: bool,
181+
pub is_opaque_type: bool,
181182
pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
182183
}
183184

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3433,7 +3433,7 @@ impl<'tcx> TyCtxt<'tcx> {
34333433
}
34343434

34353435
pub fn next_trait_solver_globally(self) -> bool {
3436-
self.sess.opts.unstable_opts.next_solver.globally
3436+
self.sess.opts.unstable_opts.next_solver.globally && !self.features().generic_const_exprs()
34373437
}
34383438

34393439
pub fn next_trait_solver_in_coherence(self) -> bool {

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

Lines changed: 49 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,6 @@ where
293293
// corecursive functions as explained in #136824, relating types never
294294
// introduces a constructor which could cause the recursion to be guarded.
295295
GoalSource::TypeRelating => PathKind::Inductive,
296-
// Instantiating a higher ranked goal can never cause the recursion to be
297-
// guarded and is therefore unproductive.
298-
GoalSource::InstantiateHigherRanked => PathKind::Inductive,
299296
// These goal sources are likely unproductive and can be changed to
300297
// `PathKind::Inductive`. Keeping them as unknown until we're confident
301298
// about this and have an example where it is necessary.
@@ -565,66 +562,56 @@ where
565562
pub(super) fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
566563
let Goal { param_env, predicate } = goal;
567564
let kind = predicate.kind();
568-
if let Some(kind) = kind.no_bound_vars() {
569-
match kind {
570-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
571-
self.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
572-
}
573-
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
574-
self.compute_host_effect_goal(Goal { param_env, predicate })
575-
}
576-
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
577-
self.compute_projection_goal(Goal { param_env, predicate })
578-
}
579-
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
580-
self.compute_type_outlives_goal(Goal { param_env, predicate })
581-
}
582-
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
583-
self.compute_region_outlives_goal(Goal { param_env, predicate })
584-
}
585-
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
586-
self.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
587-
}
588-
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
589-
self.compute_unstable_feature_goal(param_env, symbol)
590-
}
591-
ty::PredicateKind::Subtype(predicate) => {
592-
self.compute_subtype_goal(Goal { param_env, predicate })
593-
}
594-
ty::PredicateKind::Coerce(predicate) => {
595-
self.compute_coerce_goal(Goal { param_env, predicate })
596-
}
597-
ty::PredicateKind::DynCompatible(trait_def_id) => {
598-
self.compute_dyn_compatible_goal(trait_def_id)
599-
}
600-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
601-
self.compute_well_formed_goal(Goal { param_env, predicate: term })
602-
}
603-
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
604-
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
605-
}
606-
ty::PredicateKind::ConstEquate(_, _) => {
607-
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
608-
}
609-
ty::PredicateKind::NormalizesTo(predicate) => {
610-
self.compute_normalizes_to_goal(Goal { param_env, predicate })
611-
}
612-
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self
613-
.compute_alias_relate_goal(Goal {
614-
param_env,
615-
predicate: (lhs, rhs, direction),
616-
}),
617-
ty::PredicateKind::Ambiguous => {
618-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
619-
}
565+
self.enter_forall(kind, |ecx, kind| match kind {
566+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
567+
ecx.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r)
620568
}
621-
} else {
622-
self.enter_forall(kind, |ecx, kind| {
623-
let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind));
624-
ecx.add_goal(GoalSource::InstantiateHigherRanked, goal);
625-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
626-
})
627-
}
569+
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
570+
ecx.compute_host_effect_goal(Goal { param_env, predicate })
571+
}
572+
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
573+
ecx.compute_projection_goal(Goal { param_env, predicate })
574+
}
575+
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => {
576+
ecx.compute_type_outlives_goal(Goal { param_env, predicate })
577+
}
578+
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => {
579+
ecx.compute_region_outlives_goal(Goal { param_env, predicate })
580+
}
581+
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
582+
ecx.compute_const_arg_has_type_goal(Goal { param_env, predicate: (ct, ty) })
583+
}
584+
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
585+
ecx.compute_unstable_feature_goal(param_env, symbol)
586+
}
587+
ty::PredicateKind::Subtype(predicate) => {
588+
ecx.compute_subtype_goal(Goal { param_env, predicate })
589+
}
590+
ty::PredicateKind::Coerce(predicate) => {
591+
ecx.compute_coerce_goal(Goal { param_env, predicate })
592+
}
593+
ty::PredicateKind::DynCompatible(trait_def_id) => {
594+
ecx.compute_dyn_compatible_goal(trait_def_id)
595+
}
596+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
597+
ecx.compute_well_formed_goal(Goal { param_env, predicate: term })
598+
}
599+
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
600+
ecx.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
601+
}
602+
ty::PredicateKind::ConstEquate(_, _) => {
603+
panic!("ConstEquate should not be emitted when `-Znext-solver` is active")
604+
}
605+
ty::PredicateKind::NormalizesTo(predicate) => {
606+
ecx.compute_normalizes_to_goal(Goal { param_env, predicate })
607+
}
608+
ty::PredicateKind::AliasRelate(lhs, rhs, direction) => {
609+
ecx.compute_alias_relate_goal(Goal { param_env, predicate: (lhs, rhs, direction) })
610+
}
611+
ty::PredicateKind::Ambiguous => {
612+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
613+
}
614+
})
628615
}
629616

630617
// Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning

compiler/rustc_session/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ pub struct NextSolverConfig {
10551055
pub coherence: bool = true,
10561056
/// Whether the new trait solver should be enabled everywhere.
10571057
/// This is only `true` if `coherence` is also enabled.
1058-
pub globally: bool = false,
1058+
pub globally: bool = true,
10591059
}
10601060

10611061
#[derive(Clone)]

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ impl<'tcx> BestObligation<'tcx> {
231231
nested_goal.source(),
232232
GoalSource::ImplWhereBound
233233
| GoalSource::AliasBoundConstCondition
234-
| GoalSource::InstantiateHigherRanked
235234
| GoalSource::AliasWellFormed
236235
) && nested_goal.result().is_err()
237236
},
@@ -523,10 +522,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
523522
));
524523
impl_where_bound_count += 1;
525524
}
526-
// Skip over a higher-ranked predicate.
527-
(_, GoalSource::InstantiateHigherRanked) => {
528-
obligation = self.obligation.clone();
529-
}
530525
(ChildMode::PassThrough, _)
531526
| (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
532527
obligation = make_obligation(self.obligation.cause.clone());

0 commit comments

Comments
 (0)