@@ -944,14 +944,17 @@ impl Module {
944944 . collect ( ) ;
945945
946946 if !missing. is_empty ( ) {
947+ let env = ParamEnvAndCrate {
948+ param_env : db. trait_environment ( GenericDefId :: from ( impl_id) . into ( ) ) ,
949+ krate : self . id . krate ( db) ,
950+ } ;
947951 let self_ty = db. impl_self_ty ( impl_id) . instantiate_identity ( ) . skip_norm_wip ( ) ;
948- let self_ty = structurally_normalize_ty (
949- & infcx,
950- self_ty,
951- db. trait_environment ( GenericDefId :: from ( impl_id) . into ( ) ) ,
952- ) ;
952+ let self_ty = structurally_normalize_ty ( & infcx, self_ty, env. param_env ) ;
953+ let tail_ty = struct_tail_raw ( db, interner, self_ty, |ty| {
954+ structurally_normalize_ty ( & infcx, ty, env. param_env )
955+ } ) ;
953956 let self_ty_is_guaranteed_unsized = matches ! (
954- self_ty . kind( ) ,
957+ tail_ty . kind( ) ,
955958 TyKind :: Dynamic ( ..) | TyKind :: Slice ( ..) | TyKind :: Str
956959 ) ;
957960 if self_ty_is_guaranteed_unsized {
@@ -7472,5 +7475,43 @@ impl MacroCallIdExt for span::MacroCallId {
74727475 }
74737476}
74747477
7478+ // Like https://github.com/rust-lang/rust/blob/7c3c88f42ad444f4688b865591d84660be4ece2f/compiler/rustc_middle/src/ty/util.rs#L254-L310
7479+ pub fn struct_tail_raw < ' db > (
7480+ db : & ' db dyn HirDatabase ,
7481+ interner : DbInterner < ' db > ,
7482+ mut ty : Ty < ' db > ,
7483+ mut normalize : impl FnMut ( Ty < ' db > ) -> Ty < ' db > ,
7484+ ) -> Ty < ' db > {
7485+ let recursion_limit = 16 ;
7486+ for iteration in 0 .. {
7487+ if iteration >= recursion_limit {
7488+ return Ty :: new_error ( interner, ErrorGuaranteed ) ;
7489+ }
7490+ match ty. kind ( ) {
7491+ TyKind :: Adt ( def, args) => {
7492+ let AdtId :: StructId ( def_id) = def. def_id ( ) else { break } ;
7493+ let last_field = db. field_types ( def_id. into ( ) ) . iter ( ) . next_back ( ) ;
7494+ match last_field {
7495+ Some ( ( _, field) ) => {
7496+ ty = normalize ( field. get ( ) . instantiate ( interner, args) . skip_norm_wip ( ) )
7497+ }
7498+ None => break ,
7499+ }
7500+ }
7501+ TyKind :: Tuple ( tys) if let Some ( ( & last_ty, _) ) = tys. split_last ( ) => {
7502+ ty = last_ty;
7503+ }
7504+ TyKind :: Tuple ( _) => break ,
7505+ TyKind :: Pat ( inner, _) => {
7506+ ty = inner;
7507+ }
7508+ _ => {
7509+ break ;
7510+ }
7511+ }
7512+ }
7513+ ty
7514+ }
7515+
74757516pub use hir_ty:: next_solver;
74767517pub use hir_ty:: setup_tracing;
0 commit comments