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