@@ -323,33 +323,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
323323 }
324324}
325325
326- pub type CanonicalSubsts < ' gcx > = Canonical < ' gcx , & ' gcx Substs < ' gcx > > ;
327-
328- impl < ' gcx > CanonicalSubsts < ' gcx > {
329- /// True if this represents a substitution like
330- ///
331- /// ```text
332- /// [?0, ?1, ?2]
333- /// ```
334- ///
335- /// i.e., each thing is mapped to a canonical variable with the same index.
336- pub fn is_identity ( & self ) -> bool {
337- self . value . iter ( ) . zip ( CanonicalVar :: new ( 0 ) ..) . all ( |( kind, cvar) | {
338- match kind. unpack ( ) {
339- UnpackedKind :: Type ( ty) => match ty. sty {
340- ty:: Infer ( ty:: CanonicalTy ( cvar1) ) => cvar == cvar1,
341- _ => false ,
342- } ,
343-
344- UnpackedKind :: Lifetime ( r) => match r {
345- ty:: ReCanonical ( cvar1) => cvar == * cvar1,
346- _ => false ,
347- } ,
348- }
349- } )
350- }
351- }
352-
353326impl < ' tcx > serialize:: UseSpecializedDecodable for & ' tcx Substs < ' tcx > { }
354327
355328///////////////////////////////////////////////////////////////////////////
@@ -564,3 +537,98 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
564537 self . tcx ( ) . mk_region ( ty:: fold:: shift_region ( * region, self . region_binders_passed ) )
565538 }
566539}
540+
541+ pub type CanonicalUserSubsts < ' tcx > = Canonical < ' tcx , UserSubsts < ' tcx > > ;
542+
543+ impl CanonicalUserSubsts < ' tcx > {
544+ /// True if this represents a substitution like
545+ ///
546+ /// ```text
547+ /// [?0, ?1, ?2]
548+ /// ```
549+ ///
550+ /// i.e., each thing is mapped to a canonical variable with the same index.
551+ pub fn is_identity ( & self ) -> bool {
552+ if self . value . user_self_ty . is_some ( ) {
553+ return false ;
554+ }
555+
556+ self . value . substs . iter ( ) . zip ( CanonicalVar :: new ( 0 ) ..) . all ( |( kind, cvar) | {
557+ match kind. unpack ( ) {
558+ UnpackedKind :: Type ( ty) => match ty. sty {
559+ ty:: Infer ( ty:: CanonicalTy ( cvar1) ) => cvar == cvar1,
560+ _ => false ,
561+ } ,
562+
563+ UnpackedKind :: Lifetime ( r) => match r {
564+ ty:: ReCanonical ( cvar1) => cvar == * cvar1,
565+ _ => false ,
566+ } ,
567+ }
568+ } )
569+ }
570+ }
571+
572+ /// Stores the user-given substs to reach some fully qualified path
573+ /// (e.g., `<T>::Item` or `<T as Trait>::Item`).
574+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
575+ pub struct UserSubsts < ' tcx > {
576+ /// The substitutions for the item as given by the user.
577+ pub substs : & ' tcx Substs < ' tcx > ,
578+
579+ /// The self-type, in the case of a `<T>::Item` path (when applied
580+ /// to an inherent impl). See `UserSubsts` below.
581+ pub user_self_ty : Option < UserSelfTy < ' tcx > > ,
582+ }
583+
584+ BraceStructTypeFoldableImpl ! {
585+ impl <' tcx> TypeFoldable <' tcx> for UserSubsts <' tcx> {
586+ substs,
587+ user_self_ty,
588+ }
589+ }
590+
591+ BraceStructLiftImpl ! {
592+ impl <' a, ' tcx> Lift <' tcx> for UserSubsts <' a> {
593+ type Lifted = UserSubsts <' tcx>;
594+ substs,
595+ user_self_ty,
596+ }
597+ }
598+
599+ /// Specifies the user-given self-type. In the case of a path that
600+ /// refers to a member in an inherent impl, this self-type is
601+ /// sometimes needed to constrain the type parameters on the impl. For
602+ /// example, in this code:
603+ ///
604+ /// ```
605+ /// struct Foo<T> { }
606+ /// impl<A> Foo<A> { fn method() { } }
607+ /// ```
608+ ///
609+ /// when you then have a path like `<Foo<&'static u32>>::method`,
610+ /// this struct would carry the def-id of the impl along with the
611+ /// self-type `Foo<u32>`. Then we can instantiate the parameters of
612+ /// the impl (with the substs from `UserSubsts`) and apply those to
613+ /// the self-type, giving `Foo<?A>`. Finally, we unify that with
614+ /// the self-type here, which contains `?A` to be `&'static u32`
615+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
616+ pub struct UserSelfTy < ' tcx > {
617+ pub impl_def_id : DefId ,
618+ pub self_ty : Ty < ' tcx > ,
619+ }
620+
621+ BraceStructTypeFoldableImpl ! {
622+ impl <' tcx> TypeFoldable <' tcx> for UserSelfTy <' tcx> {
623+ impl_def_id,
624+ self_ty,
625+ }
626+ }
627+
628+ BraceStructLiftImpl ! {
629+ impl <' a, ' tcx> Lift <' tcx> for UserSelfTy <' a> {
630+ type Lifted = UserSelfTy <' tcx>;
631+ impl_def_id,
632+ self_ty,
633+ }
634+ }
0 commit comments