Skip to content

Commit 1229c82

Browse files
committed
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.
1 parent 7ab1321 commit 1229c82

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
use std::ops::ControlFlow;
88

99
use rustc_errors::FatalError;
10-
use rustc_hir as hir;
1110
use rustc_hir::def_id::DefId;
11+
use rustc_hir::{self as hir, LangItem};
1212
use rustc_middle::query::Providers;
1313
use 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};
1919
use smallvec::SmallVec;
2020
use 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

Comments
 (0)