about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorDavid Wood <david.wood2@arm.com>2025-02-27 21:22:27 +0000
committerDavid Wood <david.wood2@arm.com>2025-06-16 23:04:34 +0000
commit1229c820941d6788352f061b7edcb9b5a3c28513 (patch)
tree3cc2e2f482c92beb0e0cdf28e16018f07aa7fc78 /compiler/rustc_trait_selection/src
parent7ab1321f976f0b0452f6d8339ecb954d666d9f8a (diff)
trait_sel: `MetaSized` bounds in dispatchable check
Given the necessary additions of bounds to these traits and their impls
in the standard library, it is necessary to add `MetaSized` bounds to
the obligation which is proven as part of checking for dyn
dispatchability.
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs23
1 files changed, 15 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
index 47d207e8d41..ee30956295a 100644
--- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
+++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs
@@ -7,15 +7,15 @@
 use std::ops::ControlFlow;
 
 use rustc_errors::FatalError;
-use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::{self as hir, LangItem};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
     self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
     elaborate,
 };
-use rustc_span::Span;
+use rustc_span::{DUMMY_SP, Span};
 use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
@@ -543,11 +543,11 @@ fn receiver_for_self_ty<'tcx>(
 /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in
 /// a new check that `Trait` is dyn-compatible, creating a cycle.
 /// Instead, we emulate a placeholder by introducing a new type parameter `U` such that
-/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`.
+/// `Self: Unsize<U>` and `U: Trait + MetaSized`, and use `U` in place of `dyn Trait`.
 ///
 /// Written as a chalk-style query:
 /// ```ignore (not-rust)
-/// forall (U: Trait + ?Sized) {
+/// forall (U: Trait + MetaSized) {
 ///     if (Self: Unsize<U>) {
 ///         Receiver: DispatchFromDyn<Receiver[Self => U]>
 ///     }
@@ -567,9 +567,10 @@ fn receiver_is_dispatchable<'tcx>(
 ) -> bool {
     debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty);
 
-    let traits = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait());
-    let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
-        debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits");
+    let (Some(unsize_did), Some(dispatch_from_dyn_did)) =
+        (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait())
+    else {
+        debug!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits");
         return false;
     };
 
@@ -583,7 +584,7 @@ fn receiver_is_dispatchable<'tcx>(
         receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id);
 
     // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
-    // its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
+    // its supertraits) added to caller bounds. `U: MetaSized` is already implied here.
     let param_env = {
         // N.B. We generally want to emulate the construction of the `unnormalized_param_env`
         // 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>(
         let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
         predicates.push(trait_predicate.upcast(tcx));
 
+        let meta_sized_predicate = {
+            let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, DUMMY_SP);
+            ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty]).upcast(tcx)
+        };
+        predicates.push(meta_sized_predicate);
+
         normalize_param_env_or_error(
             tcx,
             ty::ParamEnv::new(tcx.mk_clauses(&predicates)),