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:
@@ -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
|
||||
|
||||
@@ -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:?})"),
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user