7
7
use std:: ops:: ControlFlow ;
8
8
9
9
use rustc_errors:: FatalError ;
10
- use rustc_hir as hir;
11
10
use rustc_hir:: def_id:: DefId ;
11
+ use rustc_hir:: { self as hir, LangItem } ;
12
12
use rustc_middle:: bug;
13
13
use rustc_middle:: query:: Providers ;
14
14
use rustc_middle:: ty:: {
@@ -540,11 +540,11 @@ fn receiver_for_self_ty<'tcx>(
540
540
/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in
541
541
/// a new check that `Trait` is dyn-compatible, creating a cycle.
542
542
/// Instead, we emulate a placeholder by introducing a new type parameter `U` such that
543
- /// `Self: Unsize<U>` and `U: Trait + ?Sized `, and use `U` in place of `dyn Trait`.
543
+ /// `Self: Unsize<U>` and `U: Trait + MetaSized `, and use `U` in place of `dyn Trait`.
544
544
///
545
545
/// Written as a chalk-style query:
546
546
/// ```ignore (not-rust)
547
- /// forall (U: Trait + ?Sized ) {
547
+ /// forall (U: Trait + MetaSized ) {
548
548
/// if (Self: Unsize<U>) {
549
549
/// Receiver: DispatchFromDyn<Receiver[Self => U]>
550
550
/// }
@@ -564,9 +564,10 @@ fn receiver_is_dispatchable<'tcx>(
564
564
) -> bool {
565
565
debug ! ( "receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}" , method, receiver_ty) ;
566
566
567
- let traits = ( tcx. lang_items ( ) . unsize_trait ( ) , tcx. lang_items ( ) . dispatch_from_dyn_trait ( ) ) ;
568
- let ( Some ( unsize_did) , Some ( dispatch_from_dyn_did) ) = traits else {
569
- debug ! ( "receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits" ) ;
567
+ let ( Some ( unsize_did) , Some ( dispatch_from_dyn_did) ) =
568
+ ( tcx. lang_items ( ) . unsize_trait ( ) , tcx. lang_items ( ) . dispatch_from_dyn_trait ( ) )
569
+ else {
570
+ debug ! ( "receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits" ) ;
570
571
return false ;
571
572
} ;
572
573
@@ -580,7 +581,7 @@ fn receiver_is_dispatchable<'tcx>(
580
581
receiver_for_self_ty ( tcx, receiver_ty, unsized_self_ty, method. def_id ) ;
581
582
582
583
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
583
- // `U: ?Sized ` is already implied here
584
+ // `U: MetaSized ` is already implied here
584
585
let param_env = {
585
586
let param_env = tcx. param_env ( method. def_id ) ;
586
587
@@ -598,8 +599,21 @@ fn receiver_is_dispatchable<'tcx>(
598
599
ty:: TraitRef :: new_from_args ( tcx, trait_def_id, args) . upcast ( tcx)
599
600
} ;
600
601
601
- let caller_bounds =
602
- param_env. caller_bounds ( ) . iter ( ) . chain ( [ unsize_predicate, trait_predicate] ) ;
602
+ let metasized_predicate = {
603
+ let metasized_did = tcx. require_lang_item ( LangItem :: MetaSized , None ) ;
604
+ ty:: TraitRef :: new ( tcx, metasized_did, [ unsized_self_ty] ) . upcast ( tcx)
605
+ } ;
606
+ let pointeesized_predicate = {
607
+ let pointeesized_did = tcx. require_lang_item ( LangItem :: PointeeSized , None ) ;
608
+ ty:: TraitRef :: new ( tcx, pointeesized_did, [ unsized_self_ty] ) . upcast ( tcx)
609
+ } ;
610
+
611
+ let caller_bounds = param_env. caller_bounds ( ) . iter ( ) . chain ( [
612
+ unsize_predicate,
613
+ metasized_predicate,
614
+ pointeesized_predicate,
615
+ trait_predicate,
616
+ ] ) ;
603
617
604
618
ty:: ParamEnv :: new ( tcx. mk_clauses_from_iter ( caller_bounds) )
605
619
} ;
0 commit comments