33use std:: { collections:: hash_map:: Entry , sync:: Arc } ;
44
55use hir_expand:: { ast_id_map:: AstIdMap , hygiene:: Hygiene , HirFileId } ;
6- use syntax:: ast:: { self , HasModuleItem } ;
6+ use syntax:: ast:: { self , HasModuleItem , HasTypeBounds } ;
77
88use crate :: {
99 generics:: { GenericParams , TypeParamData , TypeParamProvenance } ,
@@ -148,7 +148,7 @@ impl<'a> Ctx<'a> {
148148 fn lower_struct ( & mut self , strukt : & ast:: Struct ) -> Option < FileItemTreeId < Struct > > {
149149 let visibility = self . lower_visibility ( strukt) ;
150150 let name = strukt. name ( ) ?. as_name ( ) ;
151- let generic_params = self . lower_generic_params ( GenericsOwner :: Struct , strukt) ;
151+ let generic_params = self . lower_generic_params ( HasImplicitSelf :: No , strukt) ;
152152 let fields = self . lower_fields ( & strukt. kind ( ) ) ;
153153 let ast_id = self . source_ast_id_map . ast_id ( strukt) ;
154154 let res = Struct { name, visibility, generic_params, fields, ast_id } ;
@@ -212,7 +212,7 @@ impl<'a> Ctx<'a> {
212212 fn lower_union ( & mut self , union : & ast:: Union ) -> Option < FileItemTreeId < Union > > {
213213 let visibility = self . lower_visibility ( union) ;
214214 let name = union. name ( ) ?. as_name ( ) ;
215- let generic_params = self . lower_generic_params ( GenericsOwner :: Union , union) ;
215+ let generic_params = self . lower_generic_params ( HasImplicitSelf :: No , union) ;
216216 let fields = match union. record_field_list ( ) {
217217 Some ( record_field_list) => self . lower_fields ( & StructKind :: Record ( record_field_list) ) ,
218218 None => Fields :: Record ( IdxRange :: new ( self . next_field_idx ( ) ..self . next_field_idx ( ) ) ) ,
@@ -225,7 +225,7 @@ impl<'a> Ctx<'a> {
225225 fn lower_enum ( & mut self , enum_ : & ast:: Enum ) -> Option < FileItemTreeId < Enum > > {
226226 let visibility = self . lower_visibility ( enum_) ;
227227 let name = enum_. name ( ) ?. as_name ( ) ;
228- let generic_params = self . lower_generic_params ( GenericsOwner :: Enum , enum_) ;
228+ let generic_params = self . lower_generic_params ( HasImplicitSelf :: No , enum_) ;
229229 let variants = match & enum_. variant_list ( ) {
230230 Some ( variant_list) => self . lower_variants ( variant_list) ,
231231 None => IdxRange :: new ( self . next_variant_idx ( ) ..self . next_variant_idx ( ) ) ,
@@ -373,8 +373,7 @@ impl<'a> Ctx<'a> {
373373 ast_id,
374374 flags,
375375 } ;
376- res. explicit_generic_params =
377- self . lower_generic_params ( GenericsOwner :: Function ( & res) , func) ;
376+ res. explicit_generic_params = self . lower_generic_params ( HasImplicitSelf :: No , func) ;
378377
379378 Some ( id ( self . data ( ) . functions . alloc ( res) ) )
380379 }
@@ -387,7 +386,7 @@ impl<'a> Ctx<'a> {
387386 let type_ref = type_alias. ty ( ) . map ( |it| self . lower_type_ref ( & it) ) ;
388387 let visibility = self . lower_visibility ( type_alias) ;
389388 let bounds = self . lower_type_bounds ( type_alias) ;
390- let generic_params = self . lower_generic_params ( GenericsOwner :: TypeAlias , type_alias) ;
389+ let generic_params = self . lower_generic_params ( HasImplicitSelf :: No , type_alias) ;
391390 let ast_id = self . source_ast_id_map . ast_id ( type_alias) ;
392391 let res = TypeAlias {
393392 name,
@@ -443,7 +442,8 @@ impl<'a> Ctx<'a> {
443442 fn lower_trait ( & mut self , trait_def : & ast:: Trait ) -> Option < FileItemTreeId < Trait > > {
444443 let name = trait_def. name ( ) ?. as_name ( ) ;
445444 let visibility = self . lower_visibility ( trait_def) ;
446- let generic_params = self . lower_generic_params ( GenericsOwner :: Trait ( trait_def) , trait_def) ;
445+ let generic_params =
446+ self . lower_generic_params ( HasImplicitSelf :: Yes ( trait_def. type_bound_list ( ) ) , trait_def) ;
447447 let is_auto = trait_def. auto_token ( ) . is_some ( ) ;
448448 let is_unsafe = trait_def. unsafe_token ( ) . is_some ( ) ;
449449 let items = trait_def. assoc_item_list ( ) . map ( |list| {
@@ -463,7 +463,9 @@ impl<'a> Ctx<'a> {
463463 }
464464
465465 fn lower_impl ( & mut self , impl_def : & ast:: Impl ) -> Option < FileItemTreeId < Impl > > {
466- let generic_params = self . lower_generic_params ( GenericsOwner :: Impl , impl_def) ;
466+ // Note that trait impls don't get implicit `Self` unlike traits, because here they are a
467+ // type alias rather than a type parameter, so this is handled by the resolver.
468+ let generic_params = self . lower_generic_params ( HasImplicitSelf :: No , impl_def) ;
467469 // FIXME: If trait lowering fails, due to a non PathType for example, we treat this impl
468470 // as if it was an non-trait impl. Ideally we want to create a unique missing ref that only
469471 // equals itself.
@@ -567,42 +569,29 @@ impl<'a> Ctx<'a> {
567569
568570 fn lower_generic_params (
569571 & mut self ,
570- owner : GenericsOwner < ' _ > ,
572+ has_implicit_self : HasImplicitSelf ,
571573 node : & dyn ast:: HasGenericParams ,
572574 ) -> Interned < GenericParams > {
573575 let mut generics = GenericParams :: default ( ) ;
574- match owner {
575- GenericsOwner :: Function ( _)
576- | GenericsOwner :: Struct
577- | GenericsOwner :: Enum
578- | GenericsOwner :: Union
579- | GenericsOwner :: TypeAlias => {
580- generics. fill ( & self . body_ctx , node) ;
581- }
582- GenericsOwner :: Trait ( trait_def) => {
583- // traits get the Self type as an implicit first type parameter
584- generics. type_or_consts . alloc (
585- TypeParamData {
586- name : Some ( name ! [ Self ] ) ,
587- default : None ,
588- provenance : TypeParamProvenance :: TraitSelf ,
589- }
590- . into ( ) ,
591- ) ;
592- // add super traits as bounds on Self
593- // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
594- let self_param = TypeRef :: Path ( name ! [ Self ] . into ( ) ) ;
595- generics. fill_bounds ( & self . body_ctx , trait_def, Either :: Left ( self_param) ) ;
596- generics. fill ( & self . body_ctx , node) ;
597- }
598- GenericsOwner :: Impl => {
599- // Note that we don't add `Self` here: in `impl`s, `Self` is not a
600- // type-parameter, but rather is a type-alias for impl's target
601- // type, so this is handled by the resolver.
602- generics. fill ( & self . body_ctx , node) ;
603- }
576+
577+ if let HasImplicitSelf :: Yes ( bounds) = has_implicit_self {
578+ // Traits and trait aliases get the Self type as an implicit first type parameter.
579+ generics. type_or_consts . alloc (
580+ TypeParamData {
581+ name : Some ( name ! [ Self ] ) ,
582+ default : None ,
583+ provenance : TypeParamProvenance :: TraitSelf ,
584+ }
585+ . into ( ) ,
586+ ) ;
587+ // add super traits as bounds on Self
588+ // i.e., `trait Foo: Bar` is equivalent to `trait Foo where Self: Bar`
589+ let self_param = TypeRef :: Path ( name ! [ Self ] . into ( ) ) ;
590+ generics. fill_bounds ( & self . body_ctx , bounds, Either :: Left ( self_param) ) ;
604591 }
605592
593+ generics. fill ( & self . body_ctx , node) ;
594+
606595 generics. shrink_to_fit ( ) ;
607596 Interned :: new ( generics)
608597 }
@@ -674,17 +663,10 @@ fn desugar_future_path(orig: TypeRef) -> Path {
674663 Path :: from_known_path ( path, generic_args)
675664}
676665
677- enum GenericsOwner < ' a > {
678- /// We need access to the partially-lowered `Function` for lowering `impl Trait` in argument
679- /// position.
680- Function ( & ' a Function ) ,
681- Struct ,
682- Enum ,
683- Union ,
684- /// The `TraitDef` is needed to fill the source map for the implicit `Self` parameter.
685- Trait ( & ' a ast:: Trait ) ,
686- TypeAlias ,
687- Impl ,
666+ enum HasImplicitSelf {
667+ /// Inner list is a type bound list for the implicit `Self`.
668+ Yes ( Option < ast:: TypeBoundList > ) ,
669+ No ,
688670}
689671
690672fn lower_abi ( abi : ast:: Abi ) -> Interned < str > {
0 commit comments