hir_analysis: add {Meta,Pointee}Sized bounds

Opting-out of `Sized` with `?Sized` is now equivalent to adding a
`MetaSized` bound, and adding a `MetaSized` or `PointeeSized` bound
is equivalent to removing the default `Sized` bound - this commit
implements this change in `rustc_hir_analysis::hir_ty_lowering`.

`MetaSized` is also added as a supertrait of all traits, as this is
necessary to preserve backwards compatibility.

Unfortunately, non-global where clauses being preferred over item bounds
(where `PointeeSized` bounds would be proven) - which can result in
errors when a `PointeeSized` supertrait/bound/predicate is added to some
items. Rather than `PointeeSized` being a bound on everything, it can
be the absence of a bound on everything, as `?Sized` was.
This commit is contained in:
David Wood 2025-02-27 21:19:51 +00:00
parent f0b84b8dcf
commit 86ab2b60cd
No known key found for this signature in database
20 changed files with 798 additions and 207 deletions

View file

@ -76,6 +76,7 @@ pub use check::{check_abi, check_abi_fn_ptr, check_custom_abi};
use rustc_abi::{ExternAbi, VariantIdx};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::{Diag, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir::LangItem;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::DenseBitSet;
@ -331,7 +332,7 @@ fn bounds_from_generic_predicates<'tcx>(
ty::ClauseKind::Trait(trait_predicate) => {
let entry = types.entry(trait_predicate.self_ty()).or_default();
let def_id = trait_predicate.def_id();
if !tcx.is_default_trait(def_id) {
if !tcx.is_default_trait(def_id) && !tcx.is_lang_item(def_id, LangItem::Sized) {
// Do not add that restriction to the list if it is a positive requirement.
entry.push(trait_predicate.def_id());
}

View file

@ -44,6 +44,14 @@ fn associated_type_bounds<'tcx>(
| PredicateFilter::SelfOnly
| PredicateFilter::SelfTraitThatDefines(_)
| PredicateFilter::SelfAndAssociatedTypeBounds => {
icx.lowerer().add_sizedness_bounds(
&mut bounds,
item_ty,
hir_bounds,
None,
None,
span,
);
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
}
// `ConstIfConst` is only interested in `~const` bounds.
@ -333,6 +341,14 @@ fn opaque_type_bounds<'tcx>(
| PredicateFilter::SelfOnly
| PredicateFilter::SelfTraitThatDefines(_)
| PredicateFilter::SelfAndAssociatedTypeBounds => {
icx.lowerer().add_sizedness_bounds(
&mut bounds,
item_ty,
hir_bounds,
None,
None,
span,
);
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
}
//`ConstIfConst` is only interested in `~const` bounds.

View file

@ -162,7 +162,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
.map(|t| ty::Binder::dummy(t.instantiate_identity()));
}
}
ItemKind::Trait(_, _, _, _, self_bounds, ..)
| ItemKind::TraitAlias(_, _, self_bounds) => {
is_trait = Some((self_bounds, item.span));
@ -183,21 +182,29 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// and the explicit where-clauses, but to get the full set of predicates
// on a trait we must also consider the bounds that follow the trait's name,
// like `trait Foo: A + B + C`.
if let Some(self_bounds) = is_trait {
if let Some((self_bounds, span)) = is_trait {
let mut bounds = Vec::new();
icx.lowerer().lower_bounds(
tcx.types.self_param,
self_bounds.0,
self_bounds,
&mut bounds,
ty::List::empty(),
PredicateFilter::All,
);
icx.lowerer().add_sizedness_bounds(
&mut bounds,
tcx.types.self_param,
self_bounds,
None,
Some(def_id),
span,
);
icx.lowerer().add_default_super_traits(
def_id,
&mut bounds,
self_bounds.0,
self_bounds,
hir_generics,
self_bounds.1,
span,
);
predicates.extend(bounds);
}
@ -224,6 +231,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
let mut bounds = Vec::new();
// Implicit bounds are added to type params unless a `?Trait` bound is found
icx.lowerer().add_sizedness_bounds(
&mut bounds,
param_ty,
&[],
Some((param.def_id, hir_generics.predicates)),
None,
param.span,
);
icx.lowerer().add_default_traits(
&mut bounds,
param_ty,

View file

@ -4,15 +4,15 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
use rustc_hir::AmbigArg;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{AmbigArg, LangItem, PolyTraitRef};
use rustc_middle::bug;
use rustc_middle::ty::{
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor, Upcast,
};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw};
use rustc_trait_selection::traits;
use smallvec::SmallVec;
use tracing::{debug, instrument};
@ -23,23 +23,213 @@ use crate::hir_ty_lowering::{
AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
};
#[derive(Debug, Default)]
struct CollectedBound {
/// `Trait`
positive: bool,
/// `?Trait`
maybe: bool,
/// `!Trait`
negative: bool,
}
impl CollectedBound {
/// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered.
fn any(&self) -> bool {
self.positive || self.maybe || self.negative
}
}
#[derive(Debug)]
struct CollectedSizednessBounds {
// Collected `Sized` bounds
sized: CollectedBound,
// Collected `MetaSized` bounds
meta_sized: CollectedBound,
// Collected `PointeeSized` bounds
pointee_sized: CollectedBound,
}
impl CollectedSizednessBounds {
/// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered for `Sized`,
/// `MetaSized` or `PointeeSized`.
fn any(&self) -> bool {
self.sized.any() || self.meta_sized.any() || self.pointee_sized.any()
}
}
fn search_bounds_for<'tcx>(
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
mut f: impl FnMut(&'tcx PolyTraitRef<'tcx>),
) {
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for hir_bound in hir_bounds {
let hir::GenericBound::Trait(ptr) = hir_bound else {
continue;
};
f(ptr)
}
};
search_bounds(hir_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause {
if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
&& pred.is_param_bound(self_ty.to_def_id())
{
search_bounds(pred.bounds);
}
}
}
}
fn collect_unbounds<'tcx>(
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> {
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) {
unbounds.push(ptr);
}
});
unbounds
}
fn collect_bounds<'a, 'tcx>(
hir_bounds: &'a [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
target_did: DefId,
) -> CollectedBound {
let mut collect_into = CollectedBound::default();
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
if !matches!(ptr.trait_ref.path.res, Res::Def(DefKind::Trait, did) if did == target_did) {
return;
}
match ptr.modifiers.polarity {
hir::BoundPolarity::Maybe(_) => collect_into.maybe = true,
hir::BoundPolarity::Negative(_) => collect_into.negative = true,
hir::BoundPolarity::Positive => collect_into.positive = true,
}
});
collect_into
}
fn collect_sizedness_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
span: Span,
) -> CollectedSizednessBounds {
let sized_did = tcx.require_lang_item(LangItem::Sized, span);
let sized = collect_bounds(hir_bounds, self_ty_where_predicates, sized_did);
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
let meta_sized = collect_bounds(hir_bounds, self_ty_where_predicates, meta_sized_did);
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
let pointee_sized = collect_bounds(hir_bounds, self_ty_where_predicates, pointee_sized_did);
CollectedSizednessBounds { sized, meta_sized, pointee_sized }
}
/// Add a trait bound for `did`.
fn add_trait_bound<'tcx>(
tcx: TyCtxt<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
self_ty: Ty<'tcx>,
did: DefId,
span: Span,
) {
let trait_ref = ty::TraitRef::new(tcx, did, [self_ty]);
// Preferable to put sizedness obligations first, since we report better errors for `Sized`
// ambiguity.
bounds.insert(0, (trait_ref.upcast(tcx), span));
}
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
pub(crate) fn add_default_traits(
/// Skip `PointeeSized` bounds.
///
/// `PointeeSized` is a "fake bound" insofar as anywhere a `PointeeSized` bound exists, there
/// is actually the absence of any bounds. This avoids limitations around non-global where
/// clauses being preferred over item bounds (where `PointeeSized` bounds would be
/// proven) - which can result in errors when a `PointeeSized` supertrait/bound/predicate is
/// added to some items.
pub(crate) fn should_skip_sizedness_bound<'hir>(
&self,
bound: &'hir hir::GenericBound<'tcx>,
) -> bool {
bound
.trait_ref()
.and_then(|tr| tr.trait_def_id())
.map(|did| self.tcx().is_lang_item(did, LangItem::PointeeSized))
.unwrap_or(false)
}
/// Adds sizedness bounds to a trait, trait alias, parameter, opaque type or associated type.
///
/// - On parameters, opaque type and associated types, add default `Sized` bound if no explicit
/// sizedness bounds are present.
/// - On traits and trait aliases, add default `MetaSized` supertrait if no explicit sizedness
/// bounds are present.
/// - On parameters, opaque type, associated types and trait aliases, add a `MetaSized` bound if
/// a `?Sized` bound is present.
pub(crate) fn add_sizedness_bounds(
&self,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
self_ty: Ty<'tcx>,
hir_bounds: &[hir::GenericBound<'tcx>],
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
trait_did: Option<LocalDefId>,
span: Span,
) {
self.add_default_traits_with_filter(
bounds,
self_ty,
hir_bounds,
self_ty_where_predicates,
span,
|_| true,
);
let tcx = self.tcx();
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
// If adding sizedness bounds to a trait, then there are some relevant early exits
if let Some(trait_did) = trait_did {
let trait_did = trait_did.to_def_id();
// Never add a default supertrait to `PointeeSized`.
if trait_did == pointee_sized_did {
return;
}
// Don't add default sizedness supertraits to auto traits because it isn't possible to
// relax an automatically added supertrait on the defn itself.
if tcx.trait_is_auto(trait_did) {
return;
}
} else {
// Report invalid unbounds on sizedness-bounded generic parameters.
let unbounds = collect_unbounds(hir_bounds, self_ty_where_predicates);
self.check_and_report_invalid_unbounds_on_param(unbounds);
}
let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span);
if (collected.sized.maybe || collected.sized.negative)
&& !collected.sized.positive
&& !collected.meta_sized.any()
&& !collected.pointee_sized.any()
{
// `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any
// other explicit ones) - this can happen for trait aliases as well as bounds.
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
} else if !collected.any() {
if trait_did.is_some() {
// If there are no explicit sizedness bounds on a trait then add a default
// `MetaSized` supertrait.
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
} else {
// If there are no explicit sizedness bounds on a parameter then add a default
// `Sized` bound.
let sized_did = tcx.require_lang_item(LangItem::Sized, span);
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
}
}
}
/// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
@ -146,13 +336,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if !self.requires_default_supertraits(trait_bounds, trait_generics) {
let self_ty_where_predicates = (parent, trait_item.generics.predicates);
self.add_default_traits_with_filter(
self.add_default_traits(
bounds,
tcx.types.self_param,
&[],
Some(self_ty_where_predicates),
trait_item.span,
|tr| tr != hir::LangItem::Sized,
);
}
}
@ -174,41 +363,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
if self.requires_default_supertraits(hir_bounds, hir_generics) {
let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
self.add_default_traits_with_filter(
self.add_default_traits(
bounds,
self.tcx().types.self_param,
hir_bounds,
Some(self_ty_where_predicates),
span,
|default_trait| default_trait != hir::LangItem::Sized,
);
}
}
pub(crate) fn add_default_traits_with_filter(
pub(crate) fn add_default_traits(
&self,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
self_ty: Ty<'tcx>,
hir_bounds: &[hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
span: Span,
f: impl Fn(hir::LangItem) -> bool,
) {
self.tcx().default_traits().iter().filter(|&&default_trait| f(default_trait)).for_each(
|default_trait| {
self.add_default_trait(
*default_trait,
bounds,
self_ty,
hir_bounds,
self_ty_where_predicates,
span,
);
},
);
self.tcx().default_traits().iter().for_each(|default_trait| {
self.add_default_trait(
*default_trait,
bounds,
self_ty,
hir_bounds,
self_ty_where_predicates,
span,
);
});
}
/// Add a `Sized` or `experimental_default_bounds` bounds to the `bounds` if appropriate.
/// Add a `experimental_default_bounds` bound to the `bounds` if appropriate.
///
/// Doesn't add the bound if the HIR bounds contain any of `Trait`, `?Trait` or `!Trait`.
pub(crate) fn add_default_trait(
@ -220,7 +405,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
span: Span,
) {
let trait_id = self.tcx().lang_items().get(trait_);
let tcx = self.tcx();
let trait_id = tcx.lang_items().get(trait_);
if let Some(trait_id) = trait_id
&& self.do_not_provide_default_trait_bound(
trait_id,
@ -228,11 +414,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self_ty_where_predicates,
)
{
// There was no `?Trait` or `!Trait` bound;
// add `Trait` if it's available.
let trait_ref = ty::TraitRef::new(self.tcx(), trait_id, [self_ty]);
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
bounds.insert(0, (trait_ref.upcast(self.tcx()), span));
add_trait_bound(tcx, bounds, self_ty, trait_id, span);
}
}
@ -242,90 +424,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir_bounds: &'a [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
) -> bool {
let tcx = self.tcx();
let mut seen_negative_bound = false;
let mut seen_positive_bound = false;
// Try to find an unbound in bounds.
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |hir_bounds: &'a [hir::GenericBound<'tcx>]| {
for hir_bound in hir_bounds {
let hir::GenericBound::Trait(ptr) = hir_bound else {
continue;
};
match ptr.modifiers.polarity {
hir::BoundPolarity::Maybe(_) => unbounds.push(ptr),
hir::BoundPolarity::Negative(_) => {
if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) {
seen_negative_bound = true;
}
}
hir::BoundPolarity::Positive => {
if ptr.trait_ref.path.res == Res::Def(DefKind::Trait, trait_def_id) {
seen_positive_bound = true;
}
}
}
}
};
search_bounds(hir_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause {
if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
&& pred.is_param_bound(self_ty.to_def_id())
{
search_bounds(pred.bounds);
}
}
}
let mut unique_bounds = FxIndexSet::default();
let mut seen_repeat = false;
for unbound in &unbounds {
if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
seen_repeat |= !unique_bounds.insert(unbound_def_id);
}
}
if unbounds.len() > 1 {
let err = errors::MultipleRelaxedDefaultBounds {
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
};
if seen_repeat {
self.dcx().emit_err(err);
} else if !tcx.features().more_maybe_bounds() {
self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit();
};
}
let mut seen_unbound = false;
for unbound in unbounds {
let unbound_def_id = unbound.trait_ref.trait_def_id();
if unbound_def_id == Some(trait_def_id) {
seen_unbound = true;
}
let emit_relax_err = || {
let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
true => "`?Sized` and `experimental_default_bounds`",
false => "`?Sized`",
};
// There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
self.dcx().span_err(
unbound.span,
format!(
"relaxing a default bound only does something for {}; \
all other traits are not bound by default",
unbound_traits
),
);
};
match unbound_def_id {
Some(def_id) if !tcx.is_default_trait(def_id) => emit_relax_err(),
None => emit_relax_err(),
_ => {}
}
}
!(seen_unbound || seen_negative_bound || seen_positive_bound)
let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id);
!collected.any()
}
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
@ -361,6 +461,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
'tcx: 'hir,
{
for hir_bound in hir_bounds {
if self.should_skip_sizedness_bound(hir_bound) {
continue;
}
// In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
// we skip over any traits that don't define the given associated type.
if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter {

View file

@ -61,14 +61,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let ast_bounds: Vec<_> =
hir_bounds.iter().map(|&trait_ref| hir::GenericBound::Trait(trait_ref)).collect();
self.add_default_traits_with_filter(
&mut user_written_bounds,
dummy_self,
&ast_bounds,
None,
span,
|tr| tr != hir::LangItem::Sized,
);
self.add_default_traits(&mut user_written_bounds, dummy_self, &ast_bounds, None, span);
let (elaborated_trait_bounds, elaborated_projection_bounds) =
traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied());

View file

@ -8,7 +8,7 @@ use rustc_errors::{
};
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, HirId};
use rustc_hir::{self as hir, HirId, LangItem, PolyTraitRef};
use rustc_middle::bug;
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@ -34,6 +34,57 @@ use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Check for multiple relaxed default bounds and relaxed bounds of non-sizedness traits.
pub(crate) fn check_and_report_invalid_unbounds_on_param(
&self,
unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
) {
let tcx = self.tcx();
let sized_did = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
let mut unique_bounds = FxIndexSet::default();
let mut seen_repeat = false;
for unbound in &unbounds {
if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
seen_repeat |= !unique_bounds.insert(unbound_def_id);
}
}
if unbounds.len() > 1 {
let err = errors::MultipleRelaxedDefaultBounds {
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
};
if seen_repeat {
tcx.dcx().emit_err(err);
} else if !tcx.features().more_maybe_bounds() {
tcx.sess.create_feature_err(err, sym::more_maybe_bounds).emit();
};
}
for unbound in unbounds {
if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res
&& ((did == sized_did) || tcx.is_default_trait(did))
{
continue;
}
let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
true => "`?Sized` and `experimental_default_bounds`",
false => "`?Sized`",
};
self.dcx().span_err(
unbound.span,
format!(
"relaxing a default bound only does something for {}; all other traits are \
not bound by default",
unbound_traits
),
);
}
}
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
/// the type parameter's name as a placeholder.
pub(crate) fn report_missing_type_params(

View file

@ -1619,16 +1619,17 @@ impl<'tcx> TyCtxt<'tcx> {
self.reserve_and_set_memory_dedup(alloc, salt)
}
/// Traits added on all bounds by default, excluding `Sized` which is treated separately.
pub fn default_traits(self) -> &'static [rustc_hir::LangItem] {
match self.sess.opts.unstable_opts.experimental_default_bounds {
true => &[
LangItem::Sized,
if self.sess.opts.unstable_opts.experimental_default_bounds {
&[
LangItem::DefaultTrait1,
LangItem::DefaultTrait2,
LangItem::DefaultTrait3,
LangItem::DefaultTrait4,
],
false => &[LangItem::Sized],
]
} else {
&[]
}
}

View file

@ -95,7 +95,7 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
/// `def_id` is assumed to be the `AdtDef` of a struct and will panic otherwise.
///
/// For `Sized`, there are only a few options for the types in the constraint:
/// - an metasized type (str, slices, trait objects, etc)
/// - an meta-sized type (str, slices, trait objects, etc)
/// - an pointee-sized type (extern types)
/// - a type parameter or projection whose sizedness can't be known
///

View file

@ -3,8 +3,8 @@
use std::marker::{MetaSized, PointeeSized};
fn needs_pointeesized<T: ?Sized + PointeeSized>() {}
fn needs_metasized<T: ?Sized + MetaSized>() {}
fn needs_pointeesized<T: PointeeSized>() {}
fn needs_metasized<T: MetaSized>() {}
fn needs_sized<T: Sized>() {}
fn main() {

View file

@ -19,10 +19,10 @@ LL | needs_metasized::<Foo>();
|
= help: the trait `MetaSized` is not implemented for `main::Foo`
note: required by a bound in `needs_metasized`
--> $DIR/feature-gate-sized-hierarchy.rs:7:32
--> $DIR/feature-gate-sized-hierarchy.rs:7:23
|
LL | fn needs_metasized<T: ?Sized + MetaSized>() {}
| ^^^^^^^^^ required by this bound in `needs_metasized`
LL | fn needs_metasized<T: MetaSized>() {}
| ^^^^^^^^^ required by this bound in `needs_metasized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/feature-gate-sized-hierarchy.rs:27:19

View file

@ -0,0 +1,28 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
#![feature(sized_hierarchy)]
use std::marker::{PointeeSized, MetaSized};
trait Id: PointeeSized {
type This: PointeeSized;
}
impl<T: PointeeSized> Id for T {
type This = T;
}
fn requires_metasized<T: MetaSized>() {}
fn foo<T>()
where
T: PointeeSized,
<T as Id>::This: Sized
{
// `T: Sized` from where bounds (`T: PointeeSized` removes any default bounds and
// `<T as Id>::This: Sized` normalizes to `T: Sized`). This should trivially satisfy
// `T: MetaSized`.
requires_metasized::<T>();
}

View file

@ -0,0 +1,49 @@
//@ check-fail
#![feature(extern_types, sized_hierarchy)]
use std::marker::{MetaSized, PointeeSized};
fn bare<T>() {}
fn sized<T: Sized>() {}
fn neg_sized<T: ?Sized>() {}
fn metasized<T: MetaSized>() {}
fn neg_metasized<T: ?MetaSized>() {}
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
fn pointeesized<T: PointeeSized>() { }
fn neg_pointeesized<T: ?PointeeSized>() { }
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
fn main() {
// Functions which should have a `T: Sized` bound - check for an error given a non-Sized type:
bare::<[u8]>();
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
sized::<[u8]>();
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
metasized::<[u8]>();
pointeesized::<[u8]>();
// Functions which should have a `T: MetaSized` bound - check for an error given a
// non-MetaSized type:
unsafe extern "C" {
type Foo;
}
bare::<Foo>();
//~^ ERROR the size for values of type `main::Foo` cannot be known
sized::<Foo>();
//~^ ERROR the size for values of type `main::Foo` cannot be known
metasized::<Foo>();
//~^ ERROR the size for values of type `main::Foo` cannot be known
pointeesized::<Foo>();
}

View file

@ -0,0 +1,88 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/default-bound.rs:16:21
|
LL | fn neg_metasized<T: ?MetaSized>() {}
| ^^^^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/default-bound.rs:22:24
|
LL | fn neg_pointeesized<T: ?PointeeSized>() { }
| ^^^^^^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/default-bound.rs:29:12
|
LL | bare::<[u8]>();
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by an implicit `Sized` bound in `bare`
--> $DIR/default-bound.rs:6:9
|
LL | fn bare<T>() {}
| ^ required by the implicit `Sized` requirement on this type parameter in `bare`
help: consider relaxing the implicit `Sized` restriction
|
LL | fn bare<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/default-bound.rs:31:13
|
LL | sized::<[u8]>();
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `sized`
--> $DIR/default-bound.rs:9:13
|
LL | fn sized<T: Sized>() {}
| ^^^^^ required by this bound in `sized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/default-bound.rs:42:12
|
LL | bare::<Foo>();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `main::Foo`
note: required by an implicit `Sized` bound in `bare`
--> $DIR/default-bound.rs:6:9
|
LL | fn bare<T>() {}
| ^ required by the implicit `Sized` requirement on this type parameter in `bare`
help: consider relaxing the implicit `Sized` restriction
|
LL | fn bare<T: ?Sized>() {}
| ++++++++
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/default-bound.rs:44:13
|
LL | sized::<Foo>();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `main::Foo`
note: required by a bound in `sized`
--> $DIR/default-bound.rs:9:13
|
LL | fn sized<T: Sized>() {}
| ^^^^^ required by this bound in `sized`
error[E0277]: the size for values of type `main::Foo` cannot be known
--> $DIR/default-bound.rs:46:17
|
LL | metasized::<Foo>();
| ^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `main::Foo`
note: required by a bound in `metasized`
--> $DIR/default-bound.rs:14:17
|
LL | fn metasized<T: MetaSized>() {}
| ^^^^^^^^^ required by this bound in `metasized`
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,61 @@
//@ check-fail
#![feature(sized_hierarchy)]
use std::marker::{MetaSized, PointeeSized};
trait Sized_: Sized { }
trait NegSized: ?Sized { }
//~^ ERROR `?Trait` is not permitted in supertraits
trait MetaSized_: MetaSized { }
trait NegMetaSized: ?MetaSized { }
//~^ ERROR `?Trait` is not permitted in supertraits
trait PointeeSized_: PointeeSized { }
trait NegPointeeSized: ?PointeeSized { }
//~^ ERROR `?Trait` is not permitted in supertraits
trait Bare {}
fn requires_sized<T: Sized>() {}
fn requires_metasized<T: MetaSized>() {}
fn requires_pointeesized<T: PointeeSized>() {}
fn with_sized_supertrait<T: PointeeSized + Sized_>() {
requires_sized::<T>();
requires_metasized::<T>();
requires_pointeesized::<T>();
}
fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() {
requires_sized::<T>();
//~^ ERROR the size for values of type `T` cannot be known at compilation time
requires_metasized::<T>();
requires_pointeesized::<T>();
}
// It isn't really possible to write this one..
fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
requires_sized::<T>();
//~^ ERROR the size for values of type `T` cannot be known
requires_metasized::<T>();
//~^ ERROR the size for values of type `T` cannot be known
requires_pointeesized::<T>();
}
// `T` won't inherit the `const MetaSized` implicit supertrait of `Bare`, so there is an error on
// the bound, which is expected.
fn with_bare_trait<T: PointeeSized + Bare>() {
//~^ ERROR the size for values of type `T` cannot be known
requires_sized::<T>();
//~^ ERROR the size for values of type `T` cannot be known
requires_metasized::<T>();
//~^ ERROR the size for values of type `T` cannot be known
requires_pointeesized::<T>();
}
fn main() { }

View file

@ -0,0 +1,125 @@
error[E0658]: `?Trait` is not permitted in supertraits
--> $DIR/default-supertrait.rs:8:17
|
LL | trait NegSized: ?Sized { }
| ^^^^^^
|
= note: traits are `?Sized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in supertraits
--> $DIR/default-supertrait.rs:13:21
|
LL | trait NegMetaSized: ?MetaSized { }
| ^^^^^^^^^^
|
= note: traits are `?MetaSized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in supertraits
--> $DIR/default-supertrait.rs:19:24
|
LL | trait NegPointeeSized: ?PointeeSized { }
| ^^^^^^^^^^^^^
|
= note: traits are `?PointeeSized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0277]: the size for values of type `T` cannot be known
--> $DIR/default-supertrait.rs:52:38
|
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
| ^^^^ doesn't have a known size
|
note: required by a bound in `Bare`
--> $DIR/default-supertrait.rs:22:1
|
LL | trait Bare {}
| ^^^^^^^^^^^^^ required by this bound in `Bare`
help: consider further restricting type parameter `T` with unstable trait `MetaSized`
|
LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
| ++++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/default-supertrait.rs:35:22
|
LL | fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() {
| - this type parameter needs to be `Sized`
LL | requires_sized::<T>();
| ^ doesn't have a size known at compile-time
|
note: required by a bound in `requires_sized`
--> $DIR/default-supertrait.rs:24:22
|
LL | fn requires_sized<T: Sized>() {}
| ^^^^^ required by this bound in `requires_sized`
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/default-supertrait.rs:43:22
|
LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
| - this type parameter needs to be `Sized`
LL | requires_sized::<T>();
| ^ doesn't have a size known at compile-time
|
note: required by a bound in `requires_sized`
--> $DIR/default-supertrait.rs:24:22
|
LL | fn requires_sized<T: Sized>() {}
| ^^^^^ required by this bound in `requires_sized`
error[E0277]: the size for values of type `T` cannot be known
--> $DIR/default-supertrait.rs:45:26
|
LL | requires_metasized::<T>();
| ^ doesn't have a known size
|
note: required by a bound in `requires_metasized`
--> $DIR/default-supertrait.rs:25:26
|
LL | fn requires_metasized<T: MetaSized>() {}
| ^^^^^^^^^ required by this bound in `requires_metasized`
help: consider further restricting type parameter `T` with unstable trait `MetaSized`
|
LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::marker::MetaSized>() {
| ++++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/default-supertrait.rs:54:22
|
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
| - this type parameter needs to be `Sized`
LL |
LL | requires_sized::<T>();
| ^ doesn't have a size known at compile-time
|
note: required by a bound in `requires_sized`
--> $DIR/default-supertrait.rs:24:22
|
LL | fn requires_sized<T: Sized>() {}
| ^^^^^ required by this bound in `requires_sized`
error[E0277]: the size for values of type `T` cannot be known
--> $DIR/default-supertrait.rs:56:26
|
LL | requires_metasized::<T>();
| ^ doesn't have a known size
|
note: required by a bound in `requires_metasized`
--> $DIR/default-supertrait.rs:25:26
|
LL | fn requires_metasized<T: MetaSized>() {}
| ^^^^^^^^^ required by this bound in `requires_metasized`
help: consider further restricting type parameter `T` with unstable trait `MetaSized`
|
LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
| ++++++++++++++++++++++++
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0277, E0658.
For more information about an error, try `rustc --explain E0277`.

View file

@ -0,0 +1,20 @@
//@ check-pass
#![feature(extern_types, sized_hierarchy)]
use std::marker::{MetaSized, PointeeSized};
pub fn hash<T: PointeeSized>(_: *const T) {
unimplemented!();
}
unsafe extern "C" {
type Foo;
}
fn get() -> *const Foo {
unimplemented!()
}
fn main() {
hash::<Foo>(get());
}

View file

@ -1,8 +1,10 @@
//@ check-fail
//@ edition:2021
//@ edition: 2024
#![allow(incomplete_features, internal_features)]
#![feature(sized_hierarchy)]
#![feature(coroutines, dyn_star, extern_types, f16, never_type, unsized_fn_params)]
use std::fmt::Debug;
use std::marker::{MetaSized, PointeeSized};
@ -11,11 +13,11 @@ use std::marker::{MetaSized, PointeeSized};
fn needs_sized<T: Sized>() { }
fn takes_sized<T: Sized>(_t: T) { }
fn needs_metasized<T: ?Sized + MetaSized>() { }
fn takes_metasized<T: ?Sized + MetaSized>(_t: T) { }
fn needs_metasized<T: MetaSized>() { }
fn takes_metasized<T: MetaSized>(_t: T) { }
fn needs_pointeesized<T: ?Sized + PointeeSized>() { }
fn takes_pointeesized<T: ?Sized + PointeeSized>(_t: T) { }
fn needs_pointeesized<T: PointeeSized>() { }
fn takes_pointeesized<T: PointeeSized>(_t: T) { }
fn main() {
// `bool`
@ -173,7 +175,7 @@ fn main() {
needs_pointeesized::<dyn Debug>();
// `extern type`
extern "C" {
unsafe extern "C" {
type Foo;
}
needs_sized::<Foo>();

View file

@ -1,5 +1,5 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:237:42
--> $DIR/impls.rs:239:42
|
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
| ^^^^ doesn't have a size known at compile-time
@ -17,7 +17,7 @@ LL | struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] }
| ++++ +
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:245:40
--> $DIR/impls.rs:247:40
|
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
| ^^^ doesn't have a size known at compile-time
@ -35,7 +35,7 @@ LL | struct StructAllFieldsUnsized { x: Box<Foo>, y: Foo }
| ++++ +
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:281:44
--> $DIR/impls.rs:283:44
|
LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } }
| ^^^^ doesn't have a size known at compile-time
@ -53,7 +53,7 @@ LL | enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } }
| ++++ +
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:288:42
--> $DIR/impls.rs:290:42
|
LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } }
| ^^^ doesn't have a size known at compile-time
@ -71,7 +71,7 @@ LL | enum EnumAllFieldsUnsized { Qux { x: Box<Foo>, y: Foo } }
| ++++ +
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:295:52
--> $DIR/impls.rs:297:52
|
LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } }
| ^^^^ doesn't have a size known at compile-time
@ -89,7 +89,7 @@ LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } }
| ++++ +
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:302:50
--> $DIR/impls.rs:304:50
|
LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } }
| ^^^ doesn't have a size known at compile-time
@ -107,72 +107,72 @@ LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Box<Foo> } }
| ++++ +
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/impls.rs:158:19
--> $DIR/impls.rs:160:19
|
LL | needs_sized::<str>();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:164:19
--> $DIR/impls.rs:166:19
|
LL | needs_sized::<[u8]>();
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
--> $DIR/impls.rs:170:19
--> $DIR/impls.rs:172:19
|
LL | needs_sized::<dyn Debug>();
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Debug`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:179:19
--> $DIR/impls.rs:181:19
|
LL | needs_sized::<Foo>();
| ^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `main::Foo`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known
--> $DIR/impls.rs:181:23
--> $DIR/impls.rs:183:23
|
LL | needs_metasized::<Foo>();
| ^^^ doesn't have a known size
|
= help: the trait `MetaSized` is not implemented for `main::Foo`
note: required by a bound in `needs_metasized`
--> $DIR/impls.rs:14:32
--> $DIR/impls.rs:16:23
|
LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
LL | fn needs_metasized<T: MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:196:19
--> $DIR/impls.rs:198:19
|
LL | needs_sized::<([u8], [u8])>();
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -181,7 +181,7 @@ LL | needs_sized::<([u8], [u8])>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:198:23
--> $DIR/impls.rs:200:23
|
LL | needs_metasized::<([u8], [u8])>();
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -190,7 +190,7 @@ LL | needs_metasized::<([u8], [u8])>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:200:26
--> $DIR/impls.rs:202:26
|
LL | needs_pointeesized::<([u8], [u8])>();
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
@ -199,7 +199,7 @@ LL | needs_pointeesized::<([u8], [u8])>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:204:19
--> $DIR/impls.rs:206:19
|
LL | needs_sized::<(Foo, Foo)>();
| ^^^^^^^^^^ doesn't have a size known at compile-time
@ -208,7 +208,7 @@ LL | needs_sized::<(Foo, Foo)>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:206:23
--> $DIR/impls.rs:208:23
|
LL | needs_metasized::<(Foo, Foo)>();
| ^^^^^^^^^^ doesn't have a size known at compile-time
@ -217,7 +217,7 @@ LL | needs_metasized::<(Foo, Foo)>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:208:26
--> $DIR/impls.rs:210:26
|
LL | needs_pointeesized::<(Foo, Foo)>();
| ^^^^^^^^^^ doesn't have a size known at compile-time
@ -226,7 +226,7 @@ LL | needs_pointeesized::<(Foo, Foo)>();
= note: only the last element of a tuple may have a dynamically sized type
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:212:19
--> $DIR/impls.rs:214:19
|
LL | needs_sized::<(u32, [u8])>();
| ^^^^^^^^^^^ doesn't have a size known at compile-time
@ -234,13 +234,13 @@ LL | needs_sized::<(u32, [u8])>();
= help: within `(u32, [u8])`, the trait `Sized` is not implemented for `[u8]`
= note: required because it appears within the type `(u32, [u8])`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:218:19
--> $DIR/impls.rs:220:19
|
LL | needs_sized::<(u32, Foo)>();
| ^^^^^^^^^^ doesn't have a size known at compile-time
@ -248,13 +248,13 @@ LL | needs_sized::<(u32, Foo)>();
= help: within `(u32, main::Foo)`, the trait `Sized` is not implemented for `main::Foo`
= note: required because it appears within the type `(u32, main::Foo)`
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known
--> $DIR/impls.rs:220:23
--> $DIR/impls.rs:222:23
|
LL | needs_metasized::<(u32, Foo)>();
| ^^^^^^^^^^ doesn't have a known size
@ -262,118 +262,118 @@ LL | needs_metasized::<(u32, Foo)>();
= help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
= note: required because it appears within the type `(u32, main::Foo)`
note: required by a bound in `needs_metasized`
--> $DIR/impls.rs:14:32
--> $DIR/impls.rs:16:23
|
LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
LL | fn needs_metasized<T: MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:239:19
--> $DIR/impls.rs:241:19
|
LL | needs_sized::<StructAllFieldsMetaSized>();
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `StructAllFieldsMetaSized`
--> $DIR/impls.rs:237:12
--> $DIR/impls.rs:239:12
|
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:247:19
--> $DIR/impls.rs:249:19
|
LL | needs_sized::<StructAllFieldsUnsized>();
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo`
note: required because it appears within the type `StructAllFieldsUnsized`
--> $DIR/impls.rs:245:12
--> $DIR/impls.rs:247:12
|
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
| ^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known
--> $DIR/impls.rs:249:23
--> $DIR/impls.rs:251:23
|
LL | needs_metasized::<StructAllFieldsUnsized>();
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
= help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
note: required because it appears within the type `StructAllFieldsUnsized`
--> $DIR/impls.rs:245:12
--> $DIR/impls.rs:247:12
|
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
| ^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_metasized`
--> $DIR/impls.rs:14:32
--> $DIR/impls.rs:16:23
|
LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
LL | fn needs_metasized<T: MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/impls.rs:255:19
--> $DIR/impls.rs:257:19
|
LL | needs_sized::<StructLastFieldMetaSized>();
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `StructLastFieldMetaSized`
--> $DIR/impls.rs:254:12
--> $DIR/impls.rs:256:12
|
LL | struct StructLastFieldMetaSized { x: u32, y: [u8] }
| ^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
--> $DIR/impls.rs:262:19
--> $DIR/impls.rs:264:19
|
LL | needs_sized::<StructLastFieldUnsized>();
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo`
note: required because it appears within the type `StructLastFieldUnsized`
--> $DIR/impls.rs:261:12
--> $DIR/impls.rs:263:12
|
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
| ^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_sized`
--> $DIR/impls.rs:11:19
--> $DIR/impls.rs:13:19
|
LL | fn needs_sized<T: Sized>() { }
| ^^^^^ required by this bound in `needs_sized`
error[E0277]: the size for values of type `main::Foo` cannot be known
--> $DIR/impls.rs:264:23
--> $DIR/impls.rs:266:23
|
LL | needs_metasized::<StructLastFieldUnsized>();
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
|
= help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
note: required because it appears within the type `StructLastFieldUnsized`
--> $DIR/impls.rs:261:12
--> $DIR/impls.rs:263:12
|
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
| ^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `needs_metasized`
--> $DIR/impls.rs:14:32
--> $DIR/impls.rs:16:23
|
LL | fn needs_metasized<T: ?Sized + MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
LL | fn needs_metasized<T: MetaSized>() { }
| ^^^^^^^^^ required by this bound in `needs_metasized`
error: aborting due to 26 previous errors

View file

@ -0,0 +1,28 @@
//@ check-pass
#![feature(sized_hierarchy)]
// This is a reduction of some code in `library/core/src/cmp.rs` that would ICE if a default
// `Pointee` bound is added - motivating the current status quo of `PointeeSized` being syntactic
// sugar for an absense of any bounds whatsoever.
use std::marker::PhantomData;
pub trait Bar<'a> {
type Foo;
}
pub struct Foo<'a, T: Bar<'a>> {
phantom: PhantomData<&'a T>,
}
impl<'a, 'b, T> PartialEq<Foo<'b, T>> for Foo<'a, T>
where
T: for<'c> Bar<'c>,
<T as Bar<'a>>::Foo: PartialEq<<T as Bar<'b>>::Foo>,
{
fn eq(&self, _: &Foo<'b, T>) -> bool {
loop {}
}
}
fn main() { }

View file

@ -0,0 +1,9 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
#![feature(trait_alias)]
// Checks that `?Sized` in a trait alias doesn't trigger an ICE.
use std::ops::{Index, IndexMut};
pub trait SlicePrereq<T> = ?Sized + IndexMut<usize, Output = <[T] as Index<usize>>::Output>;