@@ -21,39 +21,64 @@ use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy};
2121
2222mod closure;
2323
24- #[ derive ( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
25- #[ derive( GenericTypeVisitable ) ]
24+ #[ derive_where ( Clone , Copy , Hash , PartialEq , Debug ; I : Interner ) ]
25+ #[ derive( GenericTypeVisitable , Lift_Generic ) ]
2626#[ cfg_attr(
2727 feature = "nightly" ,
2828 derive( Encodable_NoContext , Decodable_NoContext , HashStable_NoContext )
2929) ]
30- pub enum AliasTyKind {
30+ pub enum AliasTyKind < I : Interner > {
3131 /// A projection `<Type as Trait>::AssocType`.
3232 ///
3333 /// Can get normalized away if monomorphic enough.
34- Projection ,
34+ Projection {
35+ /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
36+ /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
37+ /// this is an opaque.
38+ ///
39+ /// During codegen, `interner.type_of(def_id)` can be used to get the type of the
40+ /// underlying type if the type is an opaque.
41+ ///
42+ /// Note that if this is an associated type, this is not the `DefId` of the
43+ /// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
44+ /// aka. `interner.parent(def_id)`.
45+ def_id : I :: DefId ,
46+ } ,
3547 /// An associated type in an inherent `impl`
36- Inherent ,
48+ Inherent { def_id : I :: DefId } ,
3749 /// An opaque type (usually from `impl Trait` in type aliases or function return types)
3850 ///
3951 /// Can only be normalized away in PostAnalysis mode or its defining scope.
40- Opaque ,
52+ Opaque { def_id : I :: DefId } ,
4153 /// A type alias that actually checks its trait bounds.
4254 ///
4355 /// Currently only used if the type alias references opaque types.
4456 /// Can always be normalized away.
45- Free ,
57+ Free { def_id : I :: DefId } ,
4658}
4759
48- impl AliasTyKind {
60+ impl < I : Interner > AliasTyKind < I > {
61+ pub fn new_from_def_id ( interner : I , def_id : I :: DefId ) -> Self {
62+ interner. alias_ty_kind_from_def_id ( def_id)
63+ }
64+
4965 pub fn descr ( self ) -> & ' static str {
5066 match self {
51- AliasTyKind :: Projection => "associated type" ,
52- AliasTyKind :: Inherent => "inherent associated type" ,
53- AliasTyKind :: Opaque => "opaque type" ,
54- AliasTyKind :: Free => "type alias" ,
67+ AliasTyKind :: Projection { .. } => "associated type" ,
68+ AliasTyKind :: Inherent { .. } => "inherent associated type" ,
69+ AliasTyKind :: Opaque { .. } => "opaque type" ,
70+ AliasTyKind :: Free { .. } => "type alias" ,
5571 }
5672 }
73+
74+ pub fn def_id ( self ) -> I :: DefId {
75+ let ( AliasTyKind :: Projection { def_id }
76+ | AliasTyKind :: Inherent { def_id }
77+ | AliasTyKind :: Opaque { def_id }
78+ | AliasTyKind :: Free { def_id } ) = self ;
79+
80+ def_id
81+ }
5782}
5883
5984/// Defines the kinds of types used by the type system.
@@ -222,7 +247,7 @@ pub enum TyKind<I: Interner> {
222247 ///
223248 /// All of these types are represented as pairs of def-id and args, and can
224249 /// be normalized, so they are grouped conceptually.
225- Alias ( AliasTyKind , AliasTy < I > ) ,
250+ Alias ( AliasTy < I > ) ,
226251
227252 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
228253 Param ( I :: ParamTy ) ,
@@ -327,7 +352,7 @@ impl<I: Interner> TyKind<I> {
327352
328353 ty:: Error ( _)
329354 | ty:: Infer ( _)
330- | ty:: Alias ( _, _ )
355+ | ty:: Alias ( _)
331356 | ty:: Param ( _)
332357 | ty:: Bound ( _, _)
333358 | ty:: Placeholder ( _) => false ,
@@ -392,7 +417,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
392417 }
393418 write ! ( f, ")" )
394419 }
395- Alias ( i , a) => f. debug_tuple ( "Alias" ) . field ( i ) . field ( & a) . finish ( ) ,
420+ Alias ( a) => f. debug_tuple ( "Alias" ) . field ( & a) . finish ( ) ,
396421 Param ( p) => write ! ( f, "{p:?}" ) ,
397422 Bound ( d, b) => crate :: debug_bound_var ( f, * d, b) ,
398423 Placeholder ( p) => write ! ( f, "{p:?}" ) ,
@@ -426,17 +451,9 @@ pub struct AliasTy<I: Interner> {
426451 /// while for TAIT it is used for the generic parameters of the alias.
427452 pub args : I :: GenericArgs ,
428453
429- /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
430- /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
431- /// this is an opaque.
432- ///
433- /// During codegen, `interner.type_of(def_id)` can be used to get the type of the
434- /// underlying type if the type is an opaque.
435- ///
436- /// Note that if this is an associated type, this is not the `DefId` of the
437- /// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
438- /// aka. `interner.parent(def_id)`.
439- pub def_id : I :: DefId ,
454+ #[ type_foldable( identity) ]
455+ #[ type_visitable( ignore) ]
456+ pub kind : AliasTyKind < I > ,
440457
441458 /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`].
442459 #[ derive_where( skip( Debug ) ) ]
@@ -446,31 +463,27 @@ pub struct AliasTy<I: Interner> {
446463impl < I : Interner > Eq for AliasTy < I > { }
447464
448465impl < I : Interner > AliasTy < I > {
449- pub fn new_from_args ( interner : I , def_id : I :: DefId , args : I :: GenericArgs ) -> AliasTy < I > {
450- interner. debug_assert_args_compatible ( def_id, args) ;
451- AliasTy { def_id , args, _use_alias_ty_new_instead : ( ) }
466+ pub fn new_from_args ( interner : I , kind : AliasTyKind < I > , args : I :: GenericArgs ) -> AliasTy < I > {
467+ interner. debug_assert_args_compatible ( kind . def_id ( ) , args) ;
468+ AliasTy { kind , args, _use_alias_ty_new_instead : ( ) }
452469 }
453470
454471 pub fn new (
455472 interner : I ,
456- def_id : I :: DefId ,
473+ kind : AliasTyKind < I > ,
457474 args : impl IntoIterator < Item : Into < I :: GenericArg > > ,
458475 ) -> AliasTy < I > {
459476 let args = interner. mk_args_from_iter ( args. into_iter ( ) . map ( Into :: into) ) ;
460- Self :: new_from_args ( interner, def_id, args)
461- }
462-
463- pub fn kind ( self , interner : I ) -> AliasTyKind {
464- interner. alias_ty_kind ( self )
477+ Self :: new_from_args ( interner, kind, args)
465478 }
466479
467480 /// Whether this alias type is an opaque.
468- pub fn is_opaque ( self , interner : I ) -> bool {
469- matches ! ( self . kind( interner ) , AliasTyKind :: Opaque )
481+ pub fn is_opaque ( self ) -> bool {
482+ matches ! ( self . kind, AliasTyKind :: Opaque { .. } )
470483 }
471484
472485 pub fn to_ty ( self , interner : I ) -> I :: Ty {
473- Ty :: new_alias ( interner, self . kind ( interner ) , self )
486+ Ty :: new_alias ( interner, self )
474487 }
475488}
476489
@@ -483,14 +496,15 @@ impl<I: Interner> AliasTy<I> {
483496 pub fn with_replaced_self_ty ( self , interner : I , self_ty : I :: Ty ) -> Self {
484497 AliasTy :: new (
485498 interner,
486- self . def_id ,
499+ self . kind ,
487500 [ self_ty. into ( ) ] . into_iter ( ) . chain ( self . args . iter ( ) . skip ( 1 ) ) ,
488501 )
489502 }
490503
491504 pub fn trait_def_id ( self , interner : I ) -> I :: DefId {
492- assert_eq ! ( self . kind( interner) , AliasTyKind :: Projection , "expected a projection" ) ;
493- interner. parent ( self . def_id )
505+ let AliasTyKind :: Projection { def_id } = self . kind else { panic ! ( "expected a projection" ) } ;
506+
507+ interner. parent ( def_id)
494508 }
495509
496510 /// Extracts the underlying trait reference and own args from this projection.
@@ -499,8 +513,9 @@ impl<I: Interner> AliasTy<I> {
499513 /// then this function would return a `T: StreamingIterator` trait reference and
500514 /// `['a]` as the own args.
501515 pub fn trait_ref_and_own_args ( self , interner : I ) -> ( ty:: TraitRef < I > , I :: GenericArgsSlice ) {
502- debug_assert_eq ! ( self . kind( interner) , AliasTyKind :: Projection ) ;
503- interner. trait_ref_and_own_args_for_alias ( self . def_id , self . args )
516+ let AliasTyKind :: Projection { def_id } = self . kind else { panic ! ( "expected a projection" ) } ;
517+
518+ interner. trait_ref_and_own_args_for_alias ( def_id, self . args )
504519 }
505520
506521 /// Extracts the underlying trait reference from this projection.
0 commit comments