trait_sel: {Meta,Pointee}Sized on ?Sized types

Expand the automatic implementation of `MetaSized` and `PointeeSized` so
that it is also implemented on non-`Sized` types, just not `ty::Foreign`
(extern type).
This commit is contained in:
David Wood
2025-01-16 14:27:49 +00:00
parent d43da6f4de
commit 3b0e1c17d2
22 changed files with 907 additions and 220 deletions

View File

@@ -14,7 +14,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind};
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate};
use rustc_middle::ty::{self, SizedTraitKind, Ty, TypeVisitableExt, TypingMode, elaborate};
use rustc_middle::{bug, span_bug};
use tracing::{debug, instrument, trace};
@@ -87,13 +87,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.vec.push(BuiltinCandidate { has_nested: false });
}
Some(LangItem::Sized) => {
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
self.assemble_builtin_sized_candidate(
obligation,
&mut candidates,
SizedTraitKind::Sized,
);
}
Some(LangItem::MetaSized) => {
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
self.assemble_builtin_sized_candidate(
obligation,
&mut candidates,
SizedTraitKind::MetaSized,
);
}
Some(LangItem::PointeeSized) => {
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
bug!("`PointeeSized` is removed during lowering");
}
Some(LangItem::Unsize) => {
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
@@ -1092,15 +1100,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
/// Assembles the trait which are built-in to the language itself:
/// `Copy`, `Clone` and `Sized`.
/// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
#[instrument(level = "debug", skip(self, candidates))]
fn assemble_builtin_sized_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
sizedness: SizedTraitKind,
) {
match self.sized_conditions(obligation) {
match self.sizedness_conditions(obligation, sizedness) {
BuiltinImplConditions::Where(nested) => {
candidates
.vec

View File

@@ -14,7 +14,9 @@ use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, Upcast, elaborate};
use rustc_middle::ty::{
self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate,
};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId;
use thin_vec::thin_vec;
@@ -251,9 +253,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let obligations = if has_nested {
let trait_def = obligation.predicate.def_id();
let conditions = match tcx.as_lang_item(trait_def) {
Some(LangItem::Sized) => self.sized_conditions(obligation),
Some(LangItem::MetaSized) => self.sized_conditions(obligation),
Some(LangItem::PointeeSized) => self.sized_conditions(obligation),
Some(LangItem::Sized) => {
self.sizedness_conditions(obligation, SizedTraitKind::Sized)
}
Some(LangItem::MetaSized) => {
self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
}
Some(LangItem::PointeeSized) => {
bug!("`PointeeSized` is removing during lowering");
}
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),

View File

@@ -27,8 +27,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{
self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable,
TypeVisitableExt, TypingMode, Upcast, elaborate,
self, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt,
TypeFoldable, TypeVisitableExt, TypingMode, Upcast, elaborate,
};
use rustc_span::{Symbol, sym};
use tracing::{debug, instrument, trace};
@@ -2094,9 +2094,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
impl<'tcx> SelectionContext<'_, 'tcx> {
fn sized_conditions(
fn sizedness_conditions(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
sizedness: SizedTraitKind,
) -> BuiltinImplConditions<'tcx> {
use self::BuiltinImplConditions::{Ambiguous, None, Where};
@@ -2126,7 +2127,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
Where(ty::Binder::dummy(Vec::new()))
}
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness {
SizedTraitKind::Sized => None,
SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())),
},
ty::Foreign(..) => None,
ty::Tuple(tys) => Where(
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
@@ -2135,11 +2141,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])),
ty::Adt(def, args) => {
if let Some(sized_crit) = def.sized_constraint(self.tcx()) {
if let Some(crit) = def.sizedness_constraint(self.tcx(), sizedness) {
// (*) binder moved here
Where(
obligation.predicate.rebind(vec![sized_crit.instantiate(self.tcx(), args)]),
)
Where(obligation.predicate.rebind(vec![crit.instantiate(self.tcx(), args)]))
} else {
Where(ty::Binder::dummy(Vec::new()))
}