@@ -12,7 +12,7 @@ use crate::elaborate::Elaboratable;
1212use crate :: fold:: { TypeFoldable , TypeSuperFoldable } ;
1313use crate :: relate:: Relate ;
1414use crate :: solve:: { AdtDestructorKind , SizedTraitKind } ;
15- use crate :: visit:: { Flags , TypeSuperVisitable , TypeVisitable } ;
15+ use crate :: visit:: { Flags , TypeSuperVisitable , TypeVisitable , TypeVisitableExt } ;
1616use crate :: { self as ty, CollectAndApply , Interner , UpcastFrom } ;
1717
1818pub trait Ty < I : Interner < Ty = Self > > :
@@ -538,6 +538,45 @@ pub trait PlaceholderLike<I: Interner>: Copy + Debug + Hash + Eq {
538538 fn with_updated_universe ( self , ui : ty:: UniverseIndex ) -> Self ;
539539}
540540
541+ pub trait PlaceholderConst < I : Interner > : PlaceholderLike < I , Bound = I :: BoundConst > {
542+ fn find_const_ty_from_env ( self , env : I :: ParamEnv ) -> I :: Ty ;
543+ }
544+ impl < I : Interner > PlaceholderConst < I > for I :: PlaceholderConst {
545+ fn find_const_ty_from_env ( self , env : I :: ParamEnv ) -> I :: Ty {
546+ let mut candidates = env. caller_bounds ( ) . iter ( ) . filter_map ( |clause| {
547+ // `ConstArgHasType` are never desugared to be higher ranked.
548+ match clause. kind ( ) . skip_binder ( ) {
549+ ty:: ClauseKind :: ConstArgHasType ( placeholder_ct, ty) => {
550+ assert ! ( !( placeholder_ct, ty) . has_escaping_bound_vars( ) ) ;
551+
552+ match placeholder_ct. kind ( ) {
553+ ty:: ConstKind :: Placeholder ( placeholder_ct) if placeholder_ct == self => {
554+ Some ( ty)
555+ }
556+ _ => None ,
557+ }
558+ }
559+ _ => None ,
560+ }
561+ } ) ;
562+
563+ // N.B. it may be tempting to fix ICEs by making this function return
564+ // `Option<Ty<'tcx>>` instead of `Ty<'tcx>`; however, this is generally
565+ // considered to be a bandaid solution, since it hides more important
566+ // underlying issues with how we construct generics and predicates of
567+ // items. It's advised to fix the underlying issue rather than trying
568+ // to modify this function.
569+ let ty = candidates. next ( ) . unwrap_or_else ( || {
570+ panic ! ( "cannot find `{self:?}` in param-env: {env:#?}" ) ;
571+ } ) ;
572+ assert ! (
573+ candidates. next( ) . is_none( ) ,
574+ "did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}"
575+ ) ;
576+ ty
577+ }
578+ }
579+
541580pub trait IntoKind {
542581 type Kind ;
543582
0 commit comments