@@ -538,80 +538,92 @@ where
538538 let cx = ecx. cx ( ) ;
539539 let metadata_def_id = cx. require_lang_item ( TraitSolverLangItem :: Metadata ) ;
540540 assert_eq ! ( metadata_def_id, goal. predicate. def_id( ) ) ;
541- ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
542- let metadata_ty = match goal. predicate . self_ty ( ) . kind ( ) {
543- ty:: Bool
544- | ty:: Char
545- | ty:: Int ( ..)
546- | ty:: Uint ( ..)
547- | ty:: Float ( ..)
548- | ty:: Array ( ..)
549- | ty:: Pat ( ..)
550- | ty:: RawPtr ( ..)
551- | ty:: Ref ( ..)
552- | ty:: FnDef ( ..)
553- | ty:: FnPtr ( ..)
554- | ty:: Closure ( ..)
555- | ty:: CoroutineClosure ( ..)
556- | ty:: Infer ( ty:: IntVar ( ..) | ty:: FloatVar ( ..) )
557- | ty:: Coroutine ( ..)
558- | ty:: CoroutineWitness ( ..)
559- | ty:: Never
560- | ty:: Foreign ( ..)
561- | ty:: Dynamic ( _, _, ty:: DynStar ) => Ty :: new_unit ( cx) ,
562-
563- ty:: Error ( e) => Ty :: new_error ( cx, e) ,
564-
565- ty:: Str | ty:: Slice ( _) => Ty :: new_usize ( cx) ,
566-
567- ty:: Dynamic ( _, _, ty:: Dyn ) => {
568- let dyn_metadata = cx. require_lang_item ( TraitSolverLangItem :: DynMetadata ) ;
569- cx. type_of ( dyn_metadata)
570- . instantiate ( cx, & [ I :: GenericArg :: from ( goal. predicate . self_ty ( ) ) ] )
571- }
541+ let metadata_ty = match goal. predicate . self_ty ( ) . kind ( ) {
542+ ty:: Bool
543+ | ty:: Char
544+ | ty:: Int ( ..)
545+ | ty:: Uint ( ..)
546+ | ty:: Float ( ..)
547+ | ty:: Array ( ..)
548+ | ty:: Pat ( ..)
549+ | ty:: RawPtr ( ..)
550+ | ty:: Ref ( ..)
551+ | ty:: FnDef ( ..)
552+ | ty:: FnPtr ( ..)
553+ | ty:: Closure ( ..)
554+ | ty:: CoroutineClosure ( ..)
555+ | ty:: Infer ( ty:: IntVar ( ..) | ty:: FloatVar ( ..) )
556+ | ty:: Coroutine ( ..)
557+ | ty:: CoroutineWitness ( ..)
558+ | ty:: Never
559+ | ty:: Foreign ( ..)
560+ | ty:: Dynamic ( _, _, ty:: DynStar ) => Ty :: new_unit ( cx) ,
572561
573- ty:: Alias ( _, _) | ty:: Param ( _) | ty:: Placeholder ( ..) => {
574- // This is the "fallback impl" for type parameters, unnormalizable projections
575- // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
576- // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
577- // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
578- let sized_predicate = ty:: TraitRef :: new (
579- cx,
580- cx. require_lang_item ( TraitSolverLangItem :: Sized ) ,
581- [ I :: GenericArg :: from ( goal. predicate . self_ty ( ) ) ] ,
582- ) ;
583- // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
584- ecx. add_goal ( GoalSource :: Misc , goal. with ( cx, sized_predicate) ) ;
585- Ty :: new_unit ( cx)
586- }
562+ ty:: Error ( e) => Ty :: new_error ( cx, e) ,
587563
588- ty:: Adt ( def, args) if def. is_struct ( ) => match def. struct_tail_ty ( cx) {
589- None => Ty :: new_unit ( cx) ,
590- Some ( tail_ty) => {
591- Ty :: new_projection ( cx, metadata_def_id, [ tail_ty. instantiate ( cx, args) ] )
592- }
593- } ,
594- ty:: Adt ( _, _) => Ty :: new_unit ( cx) ,
564+ ty:: Str | ty:: Slice ( _) => Ty :: new_usize ( cx) ,
595565
596- ty:: Tuple ( elements) => match elements. last ( ) {
597- None => Ty :: new_unit ( cx) ,
598- Some ( tail_ty) => Ty :: new_projection ( cx, metadata_def_id, [ tail_ty] ) ,
599- } ,
566+ ty:: Dynamic ( _, _, ty:: Dyn ) => {
567+ let dyn_metadata = cx. require_lang_item ( TraitSolverLangItem :: DynMetadata ) ;
568+ cx. type_of ( dyn_metadata)
569+ . instantiate ( cx, & [ I :: GenericArg :: from ( goal. predicate . self_ty ( ) ) ] )
570+ }
600571
601- ty:: UnsafeBinder ( _) => {
602- // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders.
603- todo ! ( )
572+ ty:: Alias ( _, _) | ty:: Param ( _) | ty:: Placeholder ( ..) => {
573+ // This is the "fallback impl" for type parameters, unnormalizable projections
574+ // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
575+ // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
576+ // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
577+ let alias_bound_result =
578+ ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
579+ let sized_predicate = ty:: TraitRef :: new (
580+ cx,
581+ cx. require_lang_item ( TraitSolverLangItem :: Sized ) ,
582+ [ I :: GenericArg :: from ( goal. predicate . self_ty ( ) ) ] ,
583+ ) ;
584+ ecx. add_goal ( GoalSource :: Misc , goal. with ( cx, sized_predicate) ) ;
585+ ecx. instantiate_normalizes_to_term ( goal, Ty :: new_unit ( cx) . into ( ) ) ;
586+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
587+ } ) ;
588+ // In case the dummy alias-bound candidate does not apply, we instead treat this projection
589+ // as rigid.
590+ return alias_bound_result. or_else ( |NoSolution | {
591+ ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |this| {
592+ this. structurally_instantiate_normalizes_to_term (
593+ goal,
594+ goal. predicate . alias ,
595+ ) ;
596+ this. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
597+ } )
598+ } ) ;
599+ }
600+
601+ ty:: Adt ( def, args) if def. is_struct ( ) => match def. struct_tail_ty ( cx) {
602+ None => Ty :: new_unit ( cx) ,
603+ Some ( tail_ty) => {
604+ Ty :: new_projection ( cx, metadata_def_id, [ tail_ty. instantiate ( cx, args) ] )
604605 }
606+ } ,
607+ ty:: Adt ( _, _) => Ty :: new_unit ( cx) ,
605608
606- ty:: Infer (
607- ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ,
608- )
609- | ty:: Bound ( ..) => panic ! (
610- "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`" ,
611- goal. predicate. self_ty( )
612- ) ,
613- } ;
609+ ty:: Tuple ( elements) => match elements. last ( ) {
610+ None => Ty :: new_unit ( cx) ,
611+ Some ( tail_ty) => Ty :: new_projection ( cx, metadata_def_id, [ tail_ty] ) ,
612+ } ,
614613
614+ ty:: UnsafeBinder ( _) => {
615+ // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders.
616+ todo ! ( )
617+ }
618+
619+ ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) )
620+ | ty:: Bound ( ..) => panic ! (
621+ "unexpected self ty `{:?}` when normalizing `<T as Pointee>::Metadata`" ,
622+ goal. predicate. self_ty( )
623+ ) ,
624+ } ;
625+
626+ ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
615627 ecx. instantiate_normalizes_to_term ( goal, metadata_ty. into ( ) ) ;
616628 ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
617629 } )
0 commit comments