diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 24383eea3600f..c2b70e2ea5e42 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -597,27 +597,7 @@ impl<'b, 'tcx> PredicateEmittingRelation> for NllTypeRelating<'_ ); } - fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Covariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Subtype, - ), - // a :> b is b <: a - ty::Contravariant => ty::PredicateKind::AliasRelate( - b.into(), - a.into(), - ty::AliasRelationDirection::Subtype, - ), - ty::Invariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Equate, - ), - ty::Bivariant => { - unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)") - } - })]); + fn ambient_variance(&self) -> ty::Variance { + self.ambient_variance } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f7a58d278a519..91bc4e4f6366c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -737,19 +737,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { { self.resolve_vars_if_possible(trait_pred) } - // Eagerly process alias-relate obligations in new trait solver, - // since these can be emitted in the process of solving trait goals, - // but we need to constrain vars before processing goals mentioning - // them. - Some(ty::PredicateKind::AliasRelate(..)) => { - let ocx = ObligationCtxt::new(self); - ocx.register_obligation(obligation); - if !ocx.try_evaluate_obligations().is_empty() { - return Err(TypeError::Mismatch); - } - coercion.obligations.extend(ocx.into_pending_obligations()); - continue; - } _ => { coercion.obligations.push(obligation); continue; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 8142b6ad57f3f..04b095dc8c92c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -55,7 +55,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) | ty::PredicateKind::DynCompatible(..) | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 7881b85997e8c..ee6e13250e709 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -6,8 +6,8 @@ use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ - self, AliasRelationDirection, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, + self, InferConst, Term, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + TypeVisitor, }; use rustc_span::Span; use tracing::{debug, instrument, warn}; @@ -168,25 +168,61 @@ impl<'tcx> InferCtxt<'tcx> { // cyclic type. We instead delay the unification in case // the alias can be normalized to something which does not // mention `?0`. + let Some(source_alias) = source_term.to_alias_term() else { + bug!("generalized `{source_term:?} to infer, not an alias"); + }; if self.next_trait_solver() { - let (lhs, rhs, direction) = match instantiation_variance { - ty::Invariant => { - (generalized_term, source_term, AliasRelationDirection::Equate) - } - ty::Covariant => { - (generalized_term, source_term, AliasRelationDirection::Subtype) - } - ty::Contravariant => { - (source_term, generalized_term, AliasRelationDirection::Subtype) + if let Some(generalized_ty) = generalized_term.as_type() { + match instantiation_variance { + ty::Invariant => relation.register_predicates([ty::ProjectionPredicate { + projection_term: source_alias.into(), + term: generalized_ty.into(), + }]), + ty::Covariant => { + // Generate a new var, then do: + // `source_alias == ?A && ?A <: generalized_ty` + let new_var = self.next_ty_var(relation.span()); + relation.register_predicates([ + ty::PredicateKind::Subtype(ty::SubtypePredicate { + a_is_expected: !target_is_expected, + a: new_var, + b: generalized_ty, + }), + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + ty::ProjectionPredicate { + projection_term: source_alias.into(), + term: new_var.into(), + }, + )), + ]); + } + ty::Contravariant => { + // a :> b is b <: a + let new_var = self.next_ty_var(relation.span()); + relation.register_predicates([ + ty::PredicateKind::Subtype(ty::SubtypePredicate { + a_is_expected: target_is_expected, + a: generalized_ty, + b: new_var, + }), + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + ty::ProjectionPredicate { + projection_term: source_alias.into(), + term: new_var.into(), + }, + )), + ]); + } + ty::Bivariant => unreachable!("bivariant generalization"), } - ty::Bivariant => unreachable!("bivariant generalization"), - }; - - relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]); + } else { + debug_assert_eq!(instantiation_variance, ty::Variance::Invariant); + relation.register_predicates([ty::ProjectionPredicate { + projection_term: source_alias, + term: generalized_term, + }]); + } } else { - let Some(source_alias) = source_term.to_alias_term() else { - bug!("generalized `{source_term:?} to infer, not an alias"); - }; match source_alias.kind { ty::AliasTermKind::ProjectionTy { .. } | ty::AliasTermKind::ProjectionConst { .. } => { diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 2c14a7d44e8c6..0ae7842a9d593 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -291,12 +291,8 @@ impl<'tcx> PredicateEmittingRelation> for LatticeOp<'_, 'tcx> { })) } - fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - // FIXME(deferred_projection_equality): This isn't right, I think? - ty::AliasRelationDirection::Equate, - ))]); + fn ambient_variance(&self) -> ty::Variance { + // FIXME(deferred_projection_equality): This isn't right, I think? + ty::Variance::Invariant } } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index d5e98f262db39..2e3a50ac953e7 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -384,27 +384,7 @@ impl<'tcx> PredicateEmittingRelation> for TypeRelating<'_, 'tcx> })) } - fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { - self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Covariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Subtype, - ), - // a :> b is b <: a - ty::Contravariant => ty::PredicateKind::AliasRelate( - b.into(), - a.into(), - ty::AliasRelationDirection::Subtype, - ), - ty::Invariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Equate, - ), - ty::Bivariant => { - unreachable!("Expected bivariance to be handled in relate_with_variance") - } - })]); + fn ambient_variance(&self) -> ty::Variance { + self.ambient_variance } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 6852c952658e7..03d13e6a81a6e 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -3269,11 +3269,6 @@ define_print! { } ty::PredicateKind::Ambiguous => write!(p, "ambiguous")?, ty::PredicateKind::NormalizesTo(data) => data.print(p)?, - ty::PredicateKind::AliasRelate(t1, t2, dir) => { - t1.print(p)?; - write!(p, " {dir} ")?; - t2.print(p)?; - } } } diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 80b4d3be172ef..b2f6ac78040b6 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -100,7 +100,6 @@ pub(super) fn instantiate_and_apply_query_response( param_env: I::ParamEnv, original_values: &[I::GenericArg], response: CanonicalResponse, - visible_for_leak_check: VisibleForLeakCheck, span: I::Span, ) -> (NestedNormalizationGoals, Certainty) where @@ -121,7 +120,15 @@ where match region_constraints { ExternalRegionConstraints::Old(r) => register_region_constraints( delegate, - r.iter().map(|(c, vis)| (*c, vis.and(visible_for_leak_check))), + r.iter().map(|(c, vis)| { + // FIXME: We should revisit and consider removing this after *assumptions on + // binders* is available, like once we had done in the stabilization of + // `-Znext-solver=coherence`(#121848). + // We ignore constraints from the nested goals in leak check. This is to match with + // the old solver's behavior, which has separated evaluation and fulfillment, and + // the former doesn't consider outlives obligations from the later. + (*c, vis.and(VisibleForLeakCheck::No)) + }), span, ), ExternalRegionConstraints::NextGen(r) => { diff --git a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs b/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs deleted file mode 100644 index 9d94a2b5ac520..0000000000000 --- a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! Implements the `AliasRelate` goal, which is used when unifying aliases. -//! Doing this via a separate goal is called "deferred alias relation" and part -//! of our more general approach to "lazy normalization". -//! -//! This is done by first structurally normalizing both sides of the goal, ending -//! up in either a concrete type, rigid alias, or an infer variable. -//! These are related further according to the rules below: -//! -//! (1.) If we end up with two rigid aliases, then we relate them structurally. -//! -//! (2.) If we end up with an infer var and a rigid alias, then we instantiate -//! the infer var with the constructor of the alias and then recursively relate -//! the terms. -//! -//! (3.) Otherwise, if we end with two rigid (non-projection) or infer types, -//! relate them structurally. - -use rustc_type_ir::inherent::*; -use rustc_type_ir::solve::{GoalSource, QueryResultOrRerunNonErased}; -use rustc_type_ir::{self as ty, Interner}; -use tracing::{instrument, trace}; - -use crate::delegate::SolverDelegate; -use crate::solve::{Certainty, EvalCtxt, Goal}; - -impl EvalCtxt<'_, D> -where - D: SolverDelegate, - I: Interner, -{ - #[instrument(level = "trace", skip(self), ret)] - pub(super) fn compute_alias_relate_goal( - &mut self, - goal: Goal, - ) -> QueryResultOrRerunNonErased { - let cx = self.cx(); - let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; - - // Check that the alias-relate goal is reasonable. Writeback for - // `coroutine_stalled_predicates` can replace alias terms with - // `{type error}` if the alias still contains infer vars, so we also - // accept alias-relate goals where one of the terms is an error. - debug_assert!( - lhs.to_alias_term().is_some() - || rhs.to_alias_term().is_some() - || lhs.is_error() - || rhs.is_error() - ); - - // Structurally normalize the lhs. - let lhs = if let Some(alias) = lhs.to_alias_term() { - let term = self.next_term_infer_of_alias_kind(alias); - self.add_goal( - GoalSource::TypeRelating, - goal.with(cx, ty::ProjectionPredicate { projection_term: alias, term }), - )?; - term - } else { - lhs - }; - - // Structurally normalize the rhs. - let rhs = if let Some(alias) = rhs.to_alias_term() { - let term = self.next_term_infer_of_alias_kind(alias); - self.add_goal( - GoalSource::TypeRelating, - goal.with(cx, ty::ProjectionPredicate { projection_term: alias, term }), - )?; - term - } else { - rhs - }; - - // Add a `make_canonical_response` probe step so that we treat this as - // a candidate, even if `try_evaluate_added_goals` bails due to an error. - // It's `Certainty::AMBIGUOUS` because this candidate is not "finished", - // since equating the normalized terms will lead to additional constraints. - self.inspect.make_canonical_response(Certainty::AMBIGUOUS); - - // Apply the constraints. - self.try_evaluate_added_goals()?; - let lhs = self.resolve_vars_if_possible(lhs); - let rhs = self.resolve_vars_if_possible(rhs); - trace!(?lhs, ?rhs); - - let variance = match direction { - ty::AliasRelationDirection::Equate => ty::Invariant, - ty::AliasRelationDirection::Subtype => ty::Covariant, - }; - self.relate(param_env, lhs, variance, rhs)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } -} diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index fe573025c87f4..5c7cd3d8c736d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -729,29 +729,11 @@ where let has_changed = if !has_only_region_constraints(response) { HasChanged::Yes } else { HasChanged::No }; - // FIXME: We should revisit and consider removing this after - // *assumptions on binders* is available, like once we had done in the - // stabilization of `-Znext-solver=coherence`(#121848). - // We ignore constraints from the nested goals in leak check. This is to match - // with the old solver's behavior, which has separated evaluation and fulfillment, - // and the former doesn't consider outlives obligations from the later. - let vis = match goal.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(_) - | ty::PredicateKind::DynCompatible(_) - | ty::PredicateKind::Subtype(_) - | ty::PredicateKind::Coerce(_) - | ty::PredicateKind::ConstEquate(_, _) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::NormalizesTo(_) => VisibleForLeakCheck::No, - ty::PredicateKind::AliasRelate(_, _, _) => VisibleForLeakCheck::Yes, - }; - let (normalization_nested_goals, certainty) = instantiate_and_apply_query_response( self.delegate, goal.param_env, &orig_values, response, - vis, self.origin_span, ); @@ -961,11 +943,6 @@ where ty::PredicateKind::NormalizesTo(predicate) => { ecx.compute_normalizes_to_goal(Goal { param_env, predicate })? } - ty::PredicateKind::AliasRelate(lhs, rhs, direction) => ecx - .compute_alias_relate_goal(Goal { - param_env, - predicate: (lhs, rhs, direction), - })?, ty::PredicateKind::Ambiguous => { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)? } @@ -1272,7 +1249,8 @@ where let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; for &goal in goals.iter() { let source = match goal.predicate.kind().skip_binder() { - ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => { + ty::PredicateKind::Subtype { .. } + | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => { GoalSource::TypeRelating } // FIXME(-Znext-solver=coinductive): should these WF goals also be unproductive? @@ -1810,7 +1788,6 @@ pub(super) fn evaluate_root_goal_for_proof_tree, goal.param_env, &proof_tree.orig_values, response, - VisibleForLeakCheck::Yes, origin_span, ); diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 8b838f3567c84..fcf8ddf59fe3c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -11,7 +11,6 @@ //! For a high-level overview of how this solver works, check out the relevant //! section of the rustc-dev-guide. -mod alias_relate; mod assembly; mod effect_goals; mod eval_ctxt; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 3427044915f88..bf25617df6573 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -82,7 +82,7 @@ where }, |ecx| { ecx.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| { - this.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + this.instantiate_normalizes_to_as_rigid(goal)?; this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) }, @@ -111,13 +111,9 @@ where Ok(()) } - /// When normalizing an associated item, constrain the expected term to `term`. + /// When normalizing an associated item, constrain the expected term to `value`. /// - /// We know `term` to always be a fully unconstrained inference variable, so - /// `eq` should never fail here. However, in case `term` contains aliases, we - /// emit nested `AliasRelate` goals to structurally normalize the alias. - /// - /// Additionally, when `term` is a const, this registers a `ConstArgHasType` + /// Additionally, when `value` is a const, this registers a `ConstArgHasType` /// goal to ensure that the const value's type matches the declared type of /// the alias it was normalized from. /// @@ -140,28 +136,25 @@ where fn instantiate_normalizes_to_term( &mut self, goal: Goal>, - term: I::Term, + value: I::Term, ) -> Result<(), NoSolutionOrRerunNonErased> { - self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.alias, term)?; - self.eq(goal.param_env, goal.predicate.term, term) - .expect("expected goal term to be fully unconstrained"); + self.push_const_arg_has_type_goal(goal.param_env, goal.predicate.alias, value)?; + // While `goal.predicate.term` should always be a fully unconstrained inference variable, + // `eq` can still fail if `value` is not fully normalized, due to `eq` eagerly normalizing, + // and that normalization can fail. + self.eq(goal.param_env, goal.predicate.term, value)?; Ok(()) } - /// Unlike `instantiate_normalizes_to_term` this instantiates the expected term - /// with a rigid alias. Using this is pretty much always wrong. - fn structurally_instantiate_normalizes_to_term( + fn instantiate_normalizes_to_as_rigid( &mut self, goal: Goal>, - term: ty::AliasTerm, - ) { - self.relate( + ) -> Result<(), NoSolutionOrRerunNonErased> { + self.eq( goal.param_env, - term.to_term(self.cx(), ty::IsRigid::Yes), - ty::Invariant, goal.predicate.term, + goal.predicate.alias.to_term(self.cx(), ty::IsRigid::Yes), ) - .expect("expected goal term to be fully unconstrained"); } } @@ -356,10 +349,7 @@ where | ty::TypingMode::PostBorrowck { .. } | ty::TypingMode::PostAnalysis | ty::TypingMode::Codegen => { - ecx.structurally_instantiate_normalizes_to_term( - goal, - goal.predicate.alias, - ); + ecx.instantiate_normalizes_to_as_rigid(goal)?; return ecx.evaluate_added_goals_and_make_canonical_response( Certainty::Yes, ); @@ -394,7 +384,7 @@ where ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous))?; return then(ecx, Certainty::Yes); } else { - ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + ecx.instantiate_normalizes_to_as_rigid(goal)?; return then(ecx, Certainty::Yes); } } else { @@ -767,10 +757,7 @@ where // as rigid. return alias_bound_result.or_else(|NoSolution| { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|this| { - this.structurally_instantiate_normalizes_to_term( - goal, - goal.predicate.alias, - ); + this.instantiate_normalizes_to_as_rigid(goal)?; this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) }); @@ -1026,7 +1013,7 @@ where // this impl candidate anyways. It's still a bit scuffed. ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) | ty::Placeholder(..) => { return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { - ecx.structurally_instantiate_normalizes_to_term(goal, goal.predicate.alias); + ecx.instantiate_normalizes_to_as_rigid(goal)?; ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }); } diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs index cf62b2c623381..8a739df7d9ad2 100644 --- a/compiler/rustc_public/src/ty.rs +++ b/compiler/rustc_public/src/ty.rs @@ -1526,7 +1526,6 @@ pub enum PredicateKind { Coerce(CoercePredicate), ConstEquate(TyConst, TyConst), Ambiguous, - AliasRelate(TermKind, TermKind, AliasRelationDirection), } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] @@ -1559,12 +1558,6 @@ pub struct CoercePredicate { pub b: Ty, } -#[derive(Clone, Debug, Eq, PartialEq, Serialize)] -pub enum AliasRelationDirection { - Equate, - Subtype, -} - #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TraitPredicate { pub trait_ref: TraitRef, diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs index 2f280ef9fe4c0..e0e212ee47d59 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs @@ -749,13 +749,6 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { } PredicateKind::Ambiguous => crate::ty::PredicateKind::Ambiguous, PredicateKind::NormalizesTo(_pred) => unimplemented!(), - PredicateKind::AliasRelate(a, b, alias_relation_direction) => { - crate::ty::PredicateKind::AliasRelate( - a.kind().stable(tables, cx), - b.kind().stable(tables, cx), - alias_relation_direction.stable(tables, cx), - ) - } } } } @@ -845,18 +838,6 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { } } -impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { - type T = crate::ty::AliasRelationDirection; - - fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T { - use rustc_middle::ty::AliasRelationDirection::*; - match self { - Equate => crate::ty::AliasRelationDirection::Equate, - Subtype => crate::ty::AliasRelationDirection::Subtype, - } - } -} - impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { type T = crate::ty::TraitPredicate; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 973a088a7f5d4..07fef19751ebf 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -735,7 +735,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ty::PredicateKind::Ambiguous | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. }) | ty::PredicateKind::NormalizesTo { .. } - | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => { span_bug!( span, @@ -1643,55 +1642,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (None, error.err) } } - ty::PredicateKind::AliasRelate(lhs, rhs, _) => { - let derive_better_type_error = - |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| { - let ocx = ObligationCtxt::new(self); - - let normalized_term = ocx.normalize( - &ObligationCause::dummy(), - obligation.param_env, - Unnormalized::new_wip( - alias_term.to_term(self.tcx, ty::IsRigid::No), - ), - ); - - if let Err(terr) = ocx.eq( - &ObligationCause::dummy(), - obligation.param_env, - expected_term, - normalized_term, - ) { - Some((terr, self.resolve_vars_if_possible(normalized_term))) - } else { - None - } - }; - - if let Some(lhs) = lhs.to_alias_term() - && let ty::AliasTermKind::ProjectionTy { .. } - | ty::AliasTermKind::ProjectionConst { .. } = lhs.kind - && let Some((better_type_err, expected_term)) = - derive_better_type_error(lhs, rhs) - { - ( - Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)), - better_type_err, - ) - } else if let Some(rhs) = rhs.to_alias_term() - && let ty::AliasTermKind::ProjectionTy { .. } - | ty::AliasTermKind::ProjectionConst { .. } = rhs.kind - && let Some((better_type_err, expected_term)) = - derive_better_type_error(rhs, lhs) - { - ( - Some((rhs, self.resolve_vars_if_possible(expected_term), lhs)), - better_type_err, - ) - } else { - (None, error.err) - } - } _ => (None, error.err), }; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 098dcfb30a7b6..960e143ebd21f 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -52,9 +52,6 @@ pub(super) fn fulfillment_error_for_no_solution<'tcx>( expected_ty, }) } - ty::PredicateKind::AliasRelate(_, _, _) => { - FulfillmentErrorCode::Project(MismatchedProjectionTypes { err: TypeError::Mismatch }) - } ty::PredicateKind::Subtype(pred) => { let (a, b) = infcx.enter_forall_and_leak_universe( obligation.predicate.kind().rebind((pred.a, pred.b)), @@ -544,21 +541,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?; } - // alias-relate may fail because the lhs or rhs can't be normalized, - // and therefore is treated as rigid. - if let Some(ty::PredicateKind::AliasRelate(lhs, rhs, _)) = pred.kind().no_bound_vars() { - goal.infcx().visit_proof_tree_at_depth( - goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs)), - goal.depth() + 1, - self, - )?; - goal.infcx().visit_proof_tree_at_depth( - goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs)), - goal.depth() + 1, - self, - )?; - } - self.detect_trait_error_in_higher_ranked_projection(goal)?; ControlFlow::Break(self.obligation.clone()) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index a39f498e36fd8..469eb4fc0630c 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -813,7 +813,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::DynCompatible(..) | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 12b9940a83f44..00ad863f38346 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -461,9 +461,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::NormalizesTo(..) => { bug!("NormalizesTo is only used by the new solver") } - ty::PredicateKind::AliasRelate(..) => { - bug!("AliasRelate is only used by the new solver") - } ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => { unreachable!("unexpected higher ranked `UnstableFeature` goal") } @@ -535,9 +532,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::NormalizesTo(..) => { bug!("NormalizesTo is only used by the new solver") } - ty::PredicateKind::AliasRelate(..) => { - bug!("AliasRelate is only used by the new solver") - } // Compute `ConstArgHasType` above the overflow check below. // This is because this is not ever a useful obligation to report // as the cause of an overflow. diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 233e124fc60f5..69fc62a96fca1 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -125,8 +125,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) - | ty::PredicateKind::AliasRelate(..) => {} + | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {} // We need to search through *all* WellFormed predicates ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1f3d247a2f7d3..d03a92611e834 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -974,9 +974,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::NormalizesTo(..) => { bug!("NormalizesTo is only used by the new solver") } - ty::PredicateKind::AliasRelate(..) => { - bug!("AliasRelate is only used by the new solver") - } ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { let ct = self.infcx.shallow_resolve_const(ct); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 1e6089dc37f95..1ba385e86b310 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -70,7 +70,6 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) | ty::PredicateKind::NormalizesTo(..) - | ty::PredicateKind::AliasRelate(..) | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) | ty::PredicateKind::DynCompatible(..) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index da7d8b5acbc1e..e63b72e47833e 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -443,10 +443,6 @@ impl FlagComputation { self.add_alias_term(alias); self.add_term(term); } - ty::PredicateKind::AliasRelate(t1, t2, _) => { - self.add_term(t1); - self.add_term(t2); - } ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_sym)) => {} ty::PredicateKind::Ambiguous => {} } diff --git a/compiler/rustc_type_ir/src/generic_visit.rs b/compiler/rustc_type_ir/src/generic_visit.rs index 6adaf4d158f40..4010ac3da5ece 100644 --- a/compiler/rustc_type_ir/src/generic_visit.rs +++ b/compiler/rustc_type_ir/src/generic_visit.rs @@ -198,7 +198,6 @@ trivial_impls!( usize, crate::PredicatePolarity, crate::BoundConstness, - crate::AliasRelationDirection, crate::DebruijnIndex, crate::solve::Certainty, crate::UniverseIndex, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 77e5fcac07b3f..d730696a38677 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -499,9 +499,7 @@ pub trait Predicate>: fn allow_normalization(self) -> bool { match self.kind().skip_binder() { - PredicateKind::Clause(ClauseKind::WellFormed(_)) | PredicateKind::AliasRelate(..) => { - false - } + PredicateKind::Clause(ClauseKind::WellFormed(_)) => false, PredicateKind::Clause(ClauseKind::Trait(_)) | PredicateKind::Clause(ClauseKind::HostEffect(..)) | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index ea92699958094..6a2d86b4419c3 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -50,7 +50,6 @@ TrivialTypeTraversalImpls! { u32, u64, // tidy-alphabetical-start - crate::AliasRelationDirection, crate::BoundConstness, crate::DebruijnIndex, crate::PredicatePolarity, diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index e905c1849a31d..ddb4fecb3eb1a 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -2,7 +2,7 @@ use std::fmt; use derive_where::derive_where; #[cfg(feature = "nightly")] -use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash, StableHash_NoContext}; +use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; use rustc_type_ir_macros::{GenericTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic}; use crate::{self as ty, Interner}; @@ -103,32 +103,10 @@ pub enum PredicateKind { /// It is likely more useful to think of this as a function `normalizes_to(alias)`, /// whose return value is written into `term`. NormalizesTo(ty::NormalizesTo), - - /// Separate from `ClauseKind::Projection` which is used for normalization in new solver. - /// This predicate requires two terms to be equal to eachother. - /// - /// Only used for new solver. - AliasRelate(I::Term, I::Term, AliasRelationDirection), } impl Eq for PredicateKind {} -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[cfg_attr(feature = "nightly", derive(StableHash, Encodable_NoContext, Decodable_NoContext))] -pub enum AliasRelationDirection { - Equate, - Subtype, -} - -impl std::fmt::Display for AliasRelationDirection { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AliasRelationDirection::Equate => write!(f, "=="), - AliasRelationDirection::Subtype => write!(f, "<:"), - } - } -} - impl fmt::Debug for ClauseKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -161,9 +139,6 @@ impl fmt::Debug for PredicateKind { PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"), PredicateKind::Ambiguous => write!(f, "Ambiguous"), PredicateKind::NormalizesTo(p) => p.fmt(f), - PredicateKind::AliasRelate(t1, t2, dir) => { - write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})") - } } } } diff --git a/compiler/rustc_type_ir/src/relate/combine.rs b/compiler/rustc_type_ir/src/relate/combine.rs index d5f9df2249df7..b292be195e103 100644 --- a/compiler/rustc_type_ir/src/relate/combine.rs +++ b/compiler/rustc_type_ir/src/relate/combine.rs @@ -38,8 +38,7 @@ where obligations: impl IntoIterator>, ); - /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); + fn ambient_variance(&self) -> ty::Variance; } pub fn super_combine_tys( @@ -115,60 +114,69 @@ where panic!("We do not expect to encounter `Fresh` variables in the new solver") } - (ty::Alias(is_rigid_a, _), ty::Alias(is_rigid_b, _)) if infcx.next_trait_solver() => { - match (is_rigid_a, is_rigid_b) { - (ty::IsRigid::Yes, ty::IsRigid::Yes) => structurally_relate_tys(relation, a, b), - _ => match relation.structurally_relate_aliases() { - StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b), - StructurallyRelateAliases::No => { - relation.register_alias_relate_predicate(a, b); - Ok(a) - } - }, - } - } - - (other, ty::Alias(is_rigid, _)) | (ty::Alias(is_rigid, _), other) - if infcx.next_trait_solver() => + (ty::Alias(ty::IsRigid::No, alias), _) | (_, ty::Alias(ty::IsRigid::No, alias)) + if infcx.next_trait_solver() + && let StructurallyRelateAliases::No = relation.structurally_relate_aliases() => { - if let StructurallyRelateAliases::No = relation.structurally_relate_aliases() - && is_rigid == ty::IsRigid::No - { - relation.register_alias_relate_predicate(a, b); - Ok(a) - } else { - match other { - ty::Infer(infer_ty) => match infer_ty { - // Normally, we shouldn't be combining an infer ty with an alias here. But - // when we evaluate a `Projection(assoc_ty, expected)` goal, we normalize - // the projection term and structurally equate it with the expected term. If - // the normalized term is an alias type and the expected term is a ty var, - // the ty var just instantiated with the alias type without combining them. - // However, if the expected term is either an int var or a float var, e.g., - // when the expected term is an int literal that only can be fully inferred - // after the fallback, they are passed to this function because int/float - // vars can't be instantiated. As we can't structurally relate infer ty with - // another type, we just error them out here instead. - ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_) => { - Err(TypeError::Sorts(ExpectedFound::new(a, b))) - } - - ty::InferTy::TyVar(_) - | ty::InferTy::FreshTy(_) - | ty::InferTy::FreshIntTy(_) - | ty::InferTy::FreshFloatTy(_) => unreachable!(), - }, - _ => structurally_relate_tys(relation, a, b), + // If both sides are aliases, arbitrarily do the LHS first + let terms_are_inverted = !matches!(a.kind(), ty::Alias(ty::IsRigid::No, _)); + let other = if terms_are_inverted { a } else { b }; + match (relation.ambient_variance(), terms_are_inverted) { + (ty::Invariant, _) => relation.register_predicates([ty::ProjectionPredicate { + projection_term: alias.into(), + term: other.into(), + }]), + (ty::Covariant, false) | (ty::Contravariant, true) => { + // Generate a new var to represent `alias <: other` + // with `alias == ?A && ?A <: other` + let new_var = infcx.next_ty_infer(); + relation.register_predicates([ + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + ty::ProjectionPredicate { + projection_term: alias.into(), + term: new_var.into(), + }, + )), + ty::PredicateKind::Subtype(ty::SubtypePredicate { + a_is_expected: !terms_are_inverted, + a: new_var, + b: other, + }), + ]); + } + (ty::Contravariant, false) | (ty::Covariant, true) => { + // a :> b is b <: a + let new_var = infcx.next_ty_infer(); + relation.register_predicates([ + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + ty::ProjectionPredicate { + projection_term: alias.into(), + term: new_var.into(), + }, + )), + ty::PredicateKind::Subtype(ty::SubtypePredicate { + a_is_expected: terms_are_inverted, + a: other, + b: new_var, + }), + ]); + } + (ty::Bivariant, _) => { + unreachable!( + "cannot handle bivariant aliases in register_projection_with_variance" + ) } } + Ok(a) } // All other cases of inference are errors (ty::Infer(_), _) | (_, ty::Infer(_)) => Err(TypeError::Sorts(ExpectedFound::new(a, b))), (ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }), _) - | (_, ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })) => { - assert!(!infcx.next_trait_solver()); + | (_, ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })) + if !infcx.next_trait_solver() => + { match infcx.typing_mode_raw().assert_not_erased() { // During coherence, opaque types should be treated as *possibly* // equal to any other type. This is an @@ -239,32 +247,24 @@ where Ok(a) } - (ty::ConstKind::Alias(ty::IsRigid::Yes, _), ty::ConstKind::Alias(ty::IsRigid::Yes, _)) - if (infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver()) => + (ty::ConstKind::Alias(ty::IsRigid::No, alias), _) + | (_, ty::ConstKind::Alias(ty::IsRigid::No, alias)) + if (infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver()) + && let StructurallyRelateAliases::No = relation.structurally_relate_aliases() => { - structurally_relate_consts(relation, a, b) - } - - (ty::ConstKind::Alias(..), _) | (_, ty::ConstKind::Alias(..)) - if infcx.cx().features().generic_const_exprs() || infcx.next_trait_solver() => - { - match relation.structurally_relate_aliases() { - StructurallyRelateAliases::No => { - relation.register_predicates([if infcx.next_trait_solver() { - ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Equate, - ) - } else { - ty::PredicateKind::ConstEquate(a, b) - }]); - - Ok(b) - } - StructurallyRelateAliases::Yes => structurally_relate_consts(relation, a, b), + if infcx.next_trait_solver() { + let other = if matches!(a.kind(), ty::ConstKind::Alias(..)) { b } else { a }; + relation.register_predicates([ty::ProjectionPredicate { + projection_term: alias.into(), + term: other.into(), + }]) + } else { + relation.register_predicates([ty::PredicateKind::ConstEquate(a, b)]); } + + Ok(b) } + _ => structurally_relate_consts(relation, a, b), } } diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index 96e30f06473cf..a3ed4ac4b6e7f 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -383,27 +383,7 @@ where self.goals.extend(obligations); } - fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty) { - self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Covariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Subtype, - ), - // a :> b is b <: a - ty::Contravariant => ty::PredicateKind::AliasRelate( - b.into(), - a.into(), - ty::AliasRelationDirection::Subtype, - ), - ty::Invariant => ty::PredicateKind::AliasRelate( - a.into(), - b.into(), - ty::AliasRelationDirection::Equate, - ), - ty::Bivariant => { - unreachable!("Expected bivariance to be handled in relate_with_variance") - } - })]); + fn ambient_variance(&self) -> ty::Variance { + self.ambient_variance } } diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index 34a45e9363069..ebf3f22276241 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -7,7 +7,7 @@ LL | struct LocalTy; LL | impl Trait for ::Assoc {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation | - = note: overflow evaluating the requirement `_ == ::Assoc` + = note: overflow evaluating the requirement `::Assoc == _` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`) error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.rs b/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.rs new file mode 100644 index 0000000000000..b469165e4b568 --- /dev/null +++ b/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Znext-solver + +//! This test is extremely similar to `nested-rerun-not-erased-in-normalizes-to.rs`, however, +//! instead of the eager normalization failing due to an anon const when in ErasedNotCoherence, this +//! just straight up fails normalization because u32 is not Iterator + +#![feature(ptr_metadata)] + +struct ThisStructAintValid(::Item); +//~^ ERROR `u32` is not an iterator + +fn main() { + let y: ::Metadata; + //~^ ERROR type mismatch resolving `::Metadata == _` +} diff --git a/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.stderr b/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.stderr new file mode 100644 index 0000000000000..60fd1b35b26a7 --- /dev/null +++ b/tests/ui/traits/next-solver/consider_builtin_pointee_candidate-instantiate-result-fail.stderr @@ -0,0 +1,18 @@ +error[E0277]: `u32` is not an iterator + --> $DIR/consider_builtin_pointee_candidate-instantiate-result-fail.rs:9:28 + | +LL | struct ThisStructAintValid(::Item); + | ^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not an iterator + | + = help: the trait `Iterator` is not implemented for `u32` + +error[E0271]: type mismatch resolving `::Metadata == _` + --> $DIR/consider_builtin_pointee_candidate-instantiate-result-fail.rs:13:12 + | +LL | let y: ::Metadata; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/nested-rerun-not-erased-in-normalizes-to.rs b/tests/ui/traits/next-solver/nested-rerun-not-erased-in-normalizes-to.rs new file mode 100644 index 0000000000000..b75598d11c83e --- /dev/null +++ b/tests/ui/traits/next-solver/nested-rerun-not-erased-in-normalizes-to.rs @@ -0,0 +1,28 @@ +//@ build-pass +//@ compile-flags: -Znext-solver + +//! Consider: +//! +//! goal is ::Metadata == ?0, in a typing context of +//! ErasedNotCoherence +//! +//! `consider_builtin_pointee_candidate` looks at StructTailHasAnonConst, realizes it's an ADT, +//! fetches the struct tail (which is `S<{ 2 + 2 }>`), and calls `instantiate_normalizes_to_term` +//! with the result of ` as Pointee>::Metadata` +//! +//! `instantiate_normalizes_to_term` `.eq()`s ` as Pointee>::Metadata` and `?0` +//! +//! this eagerly normalizes, which normalizes the anon const, which fails due to ErasedNotCoherence +//! +//! this causes the `.eq()` in `instantiate_normalizes_to_term` to fail, which used to have an +//! unwrap, which ICEd + +#![feature(ptr_metadata)] + +struct S; + +struct StructTailHasAnonConst(S<{ 2 + 2 }>); + +fn main() { + let y: ::Metadata; +} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index c61fbef05b224..ed52d05b39c99 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -14,6 +14,7 @@ fn needs_bar() {} fn test::Assoc2> + Foo2::Assoc1>>() { needs_bar::(); //~^ ERROR: the trait bound `::Assoc2: Bar` is not satisfied + //~| ERROR: the size for values of type `::Assoc2` cannot be known at compilation time } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index c4be47e3520da..40291ce0cfb86 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr @@ -14,6 +14,27 @@ help: consider further restricting the associated type LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc2: Bar { | ++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the size for values of type `::Assoc2` cannot be known at compilation time + --> $DIR/recursive-self-normalization-2.rs:15:17 + | +LL | needs_bar::(); + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `::Assoc2` +note: required by an implicit `Sized` bound in `needs_bar` + --> $DIR/recursive-self-normalization-2.rs:12:14 + | +LL | fn needs_bar() {} + | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` +help: consider further restricting the associated type + | +LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc2: Sized { + | ++++++++++++++++++++++++++++++++ +help: consider relaxing the implicit `Sized` restriction + | +LL | fn needs_bar() {} + | ++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.