Add AliasKind::Weak for type aliases.
Only use it when the type alias contains an opaque type. Also does wf-checking on such type aliases.
This commit is contained in:
@@ -508,10 +508,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
| ty::Alias(ty::Inherent, _)
|
||||
| ty::Alias(ty::Weak, _)
|
||||
| ty::Error(_) => return,
|
||||
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
|
||||
| ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
|
||||
// Excluding IATs here as they don't have meaningful item bounds.
|
||||
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
|
||||
ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
||||
ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(_) => {
|
||||
|
||||
@@ -29,6 +29,7 @@ mod opaques;
|
||||
mod project_goals;
|
||||
mod search_graph;
|
||||
mod trait_goals;
|
||||
mod weak_types;
|
||||
|
||||
pub use eval_ctxt::{EvalCtxt, InferCtxtEvalExt};
|
||||
pub use fulfill::FulfillmentCtxt;
|
||||
|
||||
@@ -57,6 +57,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
}
|
||||
DefKind::AnonConst => self.normalize_anon_const(goal),
|
||||
DefKind::OpaqueTy => self.normalize_opaque_type(goal),
|
||||
DefKind::TyAlias => self.normalize_weak_type(goal),
|
||||
kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Alias(ty::Projection | ty::Inherent, ..)
|
||||
| ty::Alias(ty::Projection | ty::Weak | ty::Inherent, ..)
|
||||
| ty::Placeholder(..) => Some(Err(NoSolution)),
|
||||
|
||||
ty::Infer(_) | ty::Bound(_, _) => bug!("unexpected type `{self_ty}`"),
|
||||
|
||||
19
compiler/rustc_trait_selection/src/solve/weak_types.rs
Normal file
19
compiler/rustc_trait_selection/src/solve/weak_types.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
|
||||
use rustc_middle::ty;
|
||||
|
||||
use super::EvalCtxt;
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
pub(super) fn normalize_weak_type(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
let weak_ty = goal.predicate.projection_ty;
|
||||
let expected = goal.predicate.term.ty().expect("no such thing as a const alias");
|
||||
|
||||
let actual = tcx.type_of(weak_ty.def_id).subst(tcx, weak_ty.substs);
|
||||
self.eq(goal.param_env, expected, actual)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user