@@ -12,7 +12,7 @@ use crate::elaborate::Elaboratable;
12
12
use crate :: fold:: { TypeFoldable , TypeSuperFoldable } ;
13
13
use crate :: relate:: Relate ;
14
14
use crate :: solve:: { AdtDestructorKind , SizedTraitKind } ;
15
- use crate :: visit:: { Flags , TypeSuperVisitable , TypeVisitable } ;
15
+ use crate :: visit:: { Flags , TypeSuperVisitable , TypeVisitable , TypeVisitableExt } ;
16
16
use crate :: { self as ty, CollectAndApply , Interner , UpcastFrom } ;
17
17
18
18
pub trait Ty < I : Interner < Ty = Self > > :
@@ -538,6 +538,45 @@ pub trait PlaceholderLike<I: Interner>: Copy + Debug + Hash + Eq {
538
538
fn with_updated_universe ( self , ui : ty:: UniverseIndex ) -> Self ;
539
539
}
540
540
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
+
541
580
pub trait IntoKind {
542
581
type Kind ;
543
582
0 commit comments