77use std:: ops:: ControlFlow ;
88
99use rustc_errors:: FatalError ;
10- use rustc_hir as hir;
1110use rustc_hir:: def_id:: DefId ;
11+ use rustc_hir:: { self as hir, LangItem } ;
1212use rustc_middle:: query:: Providers ;
1313use rustc_middle:: ty:: {
1414 self , EarlyBinder , GenericArgs , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable ,
1515 TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , TypingMode , Upcast ,
1616 elaborate,
1717} ;
18- use rustc_span:: Span ;
18+ use rustc_span:: { DUMMY_SP , Span } ;
1919use smallvec:: SmallVec ;
2020use tracing:: { debug, instrument} ;
2121
@@ -543,11 +543,11 @@ fn receiver_for_self_ty<'tcx>(
543543/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in
544544/// a new check that `Trait` is dyn-compatible, creating a cycle.
545545/// Instead, we emulate a placeholder by introducing a new type parameter `U` such that
546- /// `Self: Unsize<U>` and `U: Trait + ?Sized `, and use `U` in place of `dyn Trait`.
546+ /// `Self: Unsize<U>` and `U: Trait + MetaSized `, and use `U` in place of `dyn Trait`.
547547///
548548/// Written as a chalk-style query:
549549/// ```ignore (not-rust)
550- /// forall (U: Trait + ?Sized ) {
550+ /// forall (U: Trait + MetaSized ) {
551551/// if (Self: Unsize<U>) {
552552/// Receiver: DispatchFromDyn<Receiver[Self => U]>
553553/// }
@@ -567,9 +567,10 @@ fn receiver_is_dispatchable<'tcx>(
567567) -> bool {
568568 debug ! ( "receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}" , method, receiver_ty) ;
569569
570- let traits = ( tcx. lang_items ( ) . unsize_trait ( ) , tcx. lang_items ( ) . dispatch_from_dyn_trait ( ) ) ;
571- let ( Some ( unsize_did) , Some ( dispatch_from_dyn_did) ) = traits else {
572- debug ! ( "receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits" ) ;
570+ let ( Some ( unsize_did) , Some ( dispatch_from_dyn_did) ) =
571+ ( tcx. lang_items ( ) . unsize_trait ( ) , tcx. lang_items ( ) . dispatch_from_dyn_trait ( ) )
572+ else {
573+ debug ! ( "receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits" ) ;
573574 return false ;
574575 } ;
575576
@@ -583,7 +584,7 @@ fn receiver_is_dispatchable<'tcx>(
583584 receiver_for_self_ty ( tcx, receiver_ty, unsized_self_ty, method. def_id ) ;
584585
585586 // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
586- // its supertraits) added to caller bounds. `U: ?Sized ` is already implied here.
587+ // its supertraits) added to caller bounds. `U: MetaSized ` is already implied here.
587588 let param_env = {
588589 // N.B. We generally want to emulate the construction of the `unnormalized_param_env`
589590 // in the param-env query here. The fact that we don't just start with the clauses
@@ -612,6 +613,12 @@ fn receiver_is_dispatchable<'tcx>(
612613 let trait_predicate = ty:: TraitRef :: new_from_args ( tcx, trait_def_id, args) ;
613614 predicates. push ( trait_predicate. upcast ( tcx) ) ;
614615
616+ let meta_sized_predicate = {
617+ let meta_sized_did = tcx. require_lang_item ( LangItem :: MetaSized , DUMMY_SP ) ;
618+ ty:: TraitRef :: new ( tcx, meta_sized_did, [ unsized_self_ty] ) . upcast ( tcx)
619+ } ;
620+ predicates. push ( meta_sized_predicate) ;
621+
615622 normalize_param_env_or_error (
616623 tcx,
617624 ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) ) ,
0 commit comments