Auto merge of #142712 - davidtwco:sized-hierarchy-missing-default-bounds, r=lcnr

hir_analysis: add missing sizedness bounds

Depends on rust-lang/rust#144064

Default sizedness bounds were not being added to `explicit_super_predicates_of` and `explicit_implied_predicates_of` which meant that a trait bound added to a associated type projection would be missing the implied predicate of the default sizedness supertrait of that trait.

An unexpected consequence of this change was that the check for multiple principals was now finding an additional `MetaSized` principal when eagerly expanding trait aliases - which is fixed by skipping `MetaSized` when elaborating trait aliases in lowering `dyn TraitAlias`.
This commit is contained in:
bors 2025-10-24 21:39:28 +00:00
commit f435972085
13 changed files with 215 additions and 194 deletions

View file

@ -12,7 +12,9 @@ use tracing::{debug, instrument};
use super::ItemCtxt;
use super::predicates_of::assert_only_contains_predicates_from;
use crate::hir_ty_lowering::{HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter};
use crate::hir_ty_lowering::{
HirTyLowerer, ImpliedBoundsContext, OverlappingAsssocItemConstraints, PredicateFilter,
};
/// For associated types we include both bounds written on the type
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
@ -52,15 +54,20 @@ fn associated_type_bounds<'tcx>(
| PredicateFilter::SelfTraitThatDefines(_)
| PredicateFilter::SelfAndAssociatedTypeBounds => {
// Implicit bounds are added to associated types unless a `?Trait` bound is found.
icx.lowerer().add_sizedness_bounds(
icx.lowerer().add_implicit_sizedness_bounds(
&mut bounds,
item_ty,
hir_bounds,
None,
None,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
span,
);
icx.lowerer().add_default_traits(
&mut bounds,
item_ty,
hir_bounds,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
span,
);
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
// Also collect `where Self::Assoc: Trait` from the parent trait's where clauses.
let trait_def_id = tcx.local_parent(assoc_item_def_id);
@ -372,15 +379,20 @@ fn opaque_type_bounds<'tcx>(
| PredicateFilter::SelfOnly
| PredicateFilter::SelfTraitThatDefines(_)
| PredicateFilter::SelfAndAssociatedTypeBounds => {
icx.lowerer().add_sizedness_bounds(
icx.lowerer().add_implicit_sizedness_bounds(
&mut bounds,
item_ty,
hir_bounds,
None,
None,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
span,
);
icx.lowerer().add_default_traits(
&mut bounds,
item_ty,
hir_bounds,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
span,
);
icx.lowerer().add_default_traits(&mut bounds, item_ty, hir_bounds, None, span);
}
//`ConstIfConst` is only interested in `[const]` bounds.
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}

View file

@ -19,7 +19,8 @@ use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::delegation::inherit_predicates_for_delegation_item;
use crate::hir_ty_lowering::{
HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
HirTyLowerer, ImpliedBoundsContext, OverlappingAsssocItemConstraints, PredicateFilter,
RegionInferReason,
};
/// Returns a list of all type predicates (explicit and implicit) for the definition with
@ -189,19 +190,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
PredicateFilter::All,
OverlappingAsssocItemConstraints::Allowed,
);
icx.lowerer().add_sizedness_bounds(
icx.lowerer().add_implicit_sizedness_bounds(
&mut bounds,
tcx.types.self_param,
self_bounds,
None,
Some(def_id),
ImpliedBoundsContext::TraitDef(def_id),
span,
);
icx.lowerer().add_default_super_traits(
def_id,
icx.lowerer().add_default_traits(
&mut bounds,
tcx.types.self_param,
self_bounds,
hir_generics,
ImpliedBoundsContext::TraitDef(def_id),
span,
);
predicates.extend(bounds);
@ -229,19 +229,18 @@ 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(
icx.lowerer().add_implicit_sizedness_bounds(
&mut bounds,
param_ty,
&[],
Some((param.def_id, hir_generics.predicates)),
None,
ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates),
param.span,
);
icx.lowerer().add_default_traits(
&mut bounds,
param_ty,
&[],
Some((param.def_id, hir_generics.predicates)),
ImpliedBoundsContext::TyParam(param.def_id, hir_generics.predicates),
param.span,
);
trace!(?bounds);
@ -676,11 +675,18 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
| PredicateFilter::SelfOnly
| PredicateFilter::SelfTraitThatDefines(_)
| PredicateFilter::SelfAndAssociatedTypeBounds => {
icx.lowerer().add_default_super_traits(
trait_def_id,
icx.lowerer().add_implicit_sizedness_bounds(
&mut bounds,
self_param_ty,
superbounds,
generics,
ImpliedBoundsContext::TraitDef(trait_def_id),
item.span,
);
icx.lowerer().add_default_traits(
&mut bounds,
self_param_ty,
superbounds,
ImpliedBoundsContext::TraitDef(trait_def_id),
item.span,
);
}

View file

@ -1,4 +1,3 @@
use std::assert_matches::assert_matches;
use std::ops::ControlFlow;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@ -7,7 +6,7 @@ use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
use rustc_hir::PolyTraitRef;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_middle::bug;
use rustc_middle::ty::{
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@ -18,11 +17,10 @@ use rustc_trait_selection::traits;
use smallvec::SmallVec;
use tracing::{debug, instrument};
use super::errors::GenericsArgsErrExtend;
use crate::errors;
use crate::hir_ty_lowering::{
AssocItemQSelf, FeedConstTy, HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter,
RegionInferReason,
AssocItemQSelf, FeedConstTy, GenericsArgsErrExtend, HirTyLowerer, ImpliedBoundsContext,
OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
};
#[derive(Debug, Default)]
@ -62,7 +60,7 @@ impl CollectedSizednessBounds {
fn search_bounds_for<'tcx>(
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
context: ImpliedBoundsContext<'tcx>,
mut f: impl FnMut(&'tcx PolyTraitRef<'tcx>),
) {
let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
@ -76,7 +74,7 @@ fn search_bounds_for<'tcx>(
};
search_bounds(hir_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
if let ImpliedBoundsContext::TyParam(self_ty, where_clause) = context {
for clause in where_clause {
if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
&& pred.is_param_bound(self_ty.to_def_id())
@ -89,10 +87,10 @@ fn search_bounds_for<'tcx>(
fn collect_relaxed_bounds<'tcx>(
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
context: ImpliedBoundsContext<'tcx>,
) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> {
let mut relaxed_bounds: SmallVec<[_; 1]> = SmallVec::new();
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
search_bounds_for(hir_bounds, context, |ptr| {
if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) {
relaxed_bounds.push(ptr);
}
@ -102,11 +100,11 @@ fn collect_relaxed_bounds<'tcx>(
fn collect_bounds<'a, 'tcx>(
hir_bounds: &'a [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
context: ImpliedBoundsContext<'tcx>,
target_did: DefId,
) -> CollectedBound {
let mut collect_into = CollectedBound::default();
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
search_bounds_for(hir_bounds, context, |ptr| {
if !matches!(ptr.trait_ref.path.res, Res::Def(DefKind::Trait, did) if did == target_did) {
return;
}
@ -123,17 +121,17 @@ fn collect_bounds<'a, 'tcx>(
fn collect_sizedness_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
context: ImpliedBoundsContext<'tcx>,
span: Span,
) -> CollectedSizednessBounds {
let sized_did = tcx.require_lang_item(hir::LangItem::Sized, span);
let sized = collect_bounds(hir_bounds, self_ty_where_predicates, sized_did);
let sized = collect_bounds(hir_bounds, context, sized_did);
let meta_sized_did = tcx.require_lang_item(hir::LangItem::MetaSized, span);
let meta_sized = collect_bounds(hir_bounds, self_ty_where_predicates, meta_sized_did);
let meta_sized = collect_bounds(hir_bounds, context, meta_sized_did);
let pointee_sized_did = tcx.require_lang_item(hir::LangItem::PointeeSized, span);
let pointee_sized = collect_bounds(hir_bounds, self_ty_where_predicates, pointee_sized_did);
let pointee_sized = collect_bounds(hir_bounds, context, pointee_sized_did);
CollectedSizednessBounds { sized, meta_sized, pointee_sized }
}
@ -161,13 +159,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// 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(
pub(crate) fn add_implicit_sizedness_bounds(
&self,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
self_ty: Ty<'tcx>,
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
trait_did: Option<LocalDefId>,
context: ImpliedBoundsContext<'tcx>,
span: Span,
) {
let tcx = self.tcx();
@ -181,33 +178,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let pointee_sized_did = tcx.require_lang_item(hir::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;
match context {
ImpliedBoundsContext::TraitDef(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;
}
}
// 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;
ImpliedBoundsContext::TyParam(..) | ImpliedBoundsContext::AssociatedTypeOrImplTrait => {
// Report invalid relaxed bounds.
// FIXME: Since we only call this validation function here in this function, we only
// fully validate relaxed bounds in contexts where we perform
// "sized elaboration". In most cases that doesn't matter because we *usually*
// reject such relaxed bounds outright during AST lowering.
// However, this can easily get out of sync! Ideally, we would perform this step
// where we are guaranteed to catch *all* bounds like in
// `Self::lower_poly_trait_ref`. List of concrete issues:
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
// bounds, trait alias bounds, assoc type bounds (ATB)!
let bounds = collect_relaxed_bounds(hir_bounds, context);
self.reject_duplicate_relaxed_bounds(bounds);
}
} else {
// Report invalid relaxed bounds.
// FIXME: Since we only call this validation function here in this function, we only
// fully validate relaxed bounds in contexts where we perform
// "sized elaboration". In most cases that doesn't matter because we *usually*
// reject such relaxed bounds outright during AST lowering.
// However, this can easily get out of sync! Ideally, we would perform this step
// where we are guaranteed to catch *all* bounds like in
// `Self::lower_poly_trait_ref`. List of concrete issues:
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
// bounds, trait alias bounds, assoc type bounds (ATB)!
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
self.reject_duplicate_relaxed_bounds(bounds);
}
let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span);
let collected = collect_sizedness_bounds(tcx, hir_bounds, context, span);
if (collected.sized.maybe || collected.sized.negative)
&& !collected.sized.positive
&& !collected.meta_sized.any()
@ -217,62 +217,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// 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(hir::LangItem::Sized, span);
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
match context {
ImpliedBoundsContext::TraitDef(..) => {
// 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);
}
ImpliedBoundsContext::TyParam(..)
| ImpliedBoundsContext::AssociatedTypeOrImplTrait => {
// If there are no explicit sizedness bounds on a parameter then add a default
// `Sized` bound.
let sized_did = tcx.require_lang_item(hir::LangItem::Sized, span);
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
}
}
}
}
/// Adds `experimental_default_bounds` bounds to the supertrait bounds.
pub(crate) fn add_default_super_traits(
&self,
trait_def_id: LocalDefId,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
hir_generics: &'tcx hir::Generics<'tcx>,
span: Span,
) {
assert_matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias);
// Supertraits for auto trait are unsound according to the unstable book:
// https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits
if self.tcx().trait_is_auto(trait_def_id.to_def_id()) {
return;
}
self.add_default_traits(
bounds,
self.tcx().types.self_param,
hir_bounds,
Some((trait_def_id, hir_generics.predicates)),
span,
);
}
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>])>,
context: ImpliedBoundsContext<'tcx>,
span: 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,
);
self.add_default_trait(*default_trait, bounds, self_ty, hir_bounds, context, span);
});
}
@ -285,15 +256,23 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
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>])>,
context: ImpliedBoundsContext<'tcx>,
span: Span,
) {
let tcx = self.tcx();
let trait_id = tcx.lang_items().get(trait_);
if let Some(trait_id) = trait_id
&& self.should_add_default_traits(trait_id, hir_bounds, self_ty_where_predicates)
// Supertraits for auto trait are unsound according to the unstable book:
// https://doc.rust-lang.org/beta/unstable-book/language-features/auto-traits.html#supertraits
if let ImpliedBoundsContext::TraitDef(trait_did) = context
&& self.tcx().trait_is_auto(trait_did.into())
{
add_trait_bound(tcx, bounds, self_ty, trait_id, span);
return;
}
if let Some(trait_did) = tcx.lang_items().get(trait_)
&& self.should_add_default_traits(trait_did, hir_bounds, context)
{
add_trait_bound(tcx, bounds, self_ty, trait_did, span);
}
}
@ -302,9 +281,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
&self,
trait_def_id: DefId,
hir_bounds: &'a [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
context: ImpliedBoundsContext<'tcx>,
) -> bool {
let collected = collect_bounds(hir_bounds, self_ty_where_predicates, trait_def_id);
let collected = collect_bounds(hir_bounds, context, trait_def_id);
!self.tcx().has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) && !collected.any()
}

View file

@ -4,9 +4,9 @@ use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, EmissionGuarantee, StashKey, Suggestions, struct_span_code_err,
};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};
use rustc_lint_defs::builtin::{BARE_TRAIT_OBJECTS, UNUSED_ASSOCIATED_TYPE_BOUNDS};
use rustc_middle::ty::elaborate::ClauseWithSupertraitSpan;
use rustc_middle::ty::{
@ -24,7 +24,8 @@ use tracing::{debug, instrument};
use super::HirTyLowerer;
use crate::errors::SelfInTypeAlias;
use crate::hir_ty_lowering::{
GenericArgCountMismatch, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
GenericArgCountMismatch, ImpliedBoundsContext, OverlappingAsssocItemConstraints,
PredicateFilter, RegionInferReason,
};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
@ -76,12 +77,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.iter()
.map(|&trait_ref| hir::GenericBound::Trait(trait_ref))
.collect::<Vec<_>>(),
None,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
span,
);
let (elaborated_trait_bounds, elaborated_projection_bounds) =
let (mut elaborated_trait_bounds, elaborated_projection_bounds) =
traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied());
// FIXME(sized-hierarchy): https://github.com/rust-lang/rust/pull/142712#issuecomment-3013231794
debug!(?user_written_bounds, ?elaborated_trait_bounds);
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
// Don't strip out `MetaSized` when the user wrote it explicitly, only when it was
// elaborated
if user_written_bounds
.iter()
.all(|(clause, _)| clause.as_trait_clause().map(|p| p.def_id()) != Some(meta_sized_did))
{
elaborated_trait_bounds.retain(|(pred, _)| pred.def_id() != meta_sized_did);
}
debug!(?user_written_bounds, ?elaborated_trait_bounds);
let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds
.into_iter()
.partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));

View file

@ -56,6 +56,19 @@ use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
use crate::middle::resolve_bound_vars as rbv;
/// The context in which an implied bound is being added to a item being lowered (i.e. a sizedness
/// trait or a default trait)
#[derive(Clone, Copy)]
pub(crate) enum ImpliedBoundsContext<'tcx> {
/// An implied bound is added to a trait definition (i.e. a new supertrait), used when adding
/// a default `MetaSized` supertrait
TraitDef(LocalDefId),
/// An implied bound is added to a type parameter
TyParam(LocalDefId, &'tcx [hir::WherePredicate<'tcx>]),
/// An implied bound being added in any other context
AssociatedTypeOrImplTrait,
}
/// A path segment that is semantically allowed to have generic arguments.
#[derive(Debug)]
pub struct GenericPathSegment(pub DefId, pub usize);
@ -2513,12 +2526,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
PredicateFilter::All,
OverlappingAsssocItemConstraints::Allowed,
);
self.add_sizedness_bounds(
self.add_implicit_sizedness_bounds(
&mut bounds,
self_ty,
hir_bounds,
None,
None,
ImpliedBoundsContext::AssociatedTypeOrImplTrait,
hir_ty.span,
);
self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);

View file

@ -0,0 +1,18 @@
//@ check-pass
#![crate_type = "lib"]
#![feature(sized_hierarchy)]
// Tests that a bound on an associated type projection, of a trait with a sizedness bound, will be
// elaborated.
trait FalseDeref {
type Target: std::marker::PointeeSized;
}
trait Bar {}
fn foo<T: FalseDeref>()
where
T::Target: Bar,
{
}

View file

@ -52,14 +52,11 @@ fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
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.
// `T` inherits the `const MetaSized` implicit supertrait of `Bare`.
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>();
}

View file

@ -62,22 +62,6 @@ LL | trait NegPointeeSized: ?PointeeSized { }
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: the size for values of type `T` cannot be known
--> $DIR/default-supertrait.rs:57: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:27: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:40:22
|
@ -123,11 +107,10 @@ LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::mark
| ++++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/default-supertrait.rs:59:22
--> $DIR/default-supertrait.rs:57: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
|
@ -137,22 +120,6 @@ note: required by a bound in `requires_sized`
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:61:26
|
LL | requires_metasized::<T>();
| ^ doesn't have a known size
|
note: required by a bound in `requires_metasized`
--> $DIR/default-supertrait.rs:30: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 15 previous errors
error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,13 @@
//@ check-pass
//@ compile-flags: --crate-type=lib
#![feature(sized_hierarchy)]
// Test demonstrating that elaboration of sizedness bounds works in the simplest cases.
trait Trait {}
fn f<T: Trait + std::marker::PointeeSized>() {
require_metasized::<T>();
}
fn require_metasized<T: std::marker::MetaSized>() {}

View file

@ -0,0 +1,16 @@
#![feature(sized_hierarchy, trait_alias)]
use std::marker::MetaSized;
// Trait aliases also have implicit `MetaSized` bounds, like traits. These are filtered out during
// elaboration of trait aliases when lowering `dyn TraitAlias` - however, if the user explicitly
// wrote `MetaSized` in the `dyn Trait` then that should still be an error so as not to accidentally
// accept this going forwards.
trait Qux = Clone;
type Foo = dyn Qux + MetaSized;
//~^ ERROR: only auto traits can be used as additional traits in a trait object
type Bar = dyn Qux;
fn main() {}

View file

@ -0,0 +1,17 @@
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-alias-elaboration.rs:11:16
|
LL | trait Qux = Clone;
| ------------------ additional non-auto trait
LL |
LL | type Foo = dyn Qux + MetaSized;
| ^^^ --------- first non-auto trait
| |
| second non-auto trait comes from this alias
|
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: MetaSized + MetaSized + Clone {}`
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0225`.

View file

@ -19,23 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
LL | Self::Assoc: A<T>,
| ^^^^
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized`
--> $DIR/normalize-param-env-2.rs:24:22
|
LL | Self::Assoc: A<T>,
| ^^^^
|
note: required by a bound in `A`
--> $DIR/normalize-param-env-2.rs:9:1
|
LL | / trait A<T> {
LL | | type Assoc;
LL | |
LL | | fn f()
... |
LL | | }
| |_^ required by this bound in `A`
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
--> $DIR/normalize-param-env-2.rs:24:22
|
@ -63,6 +46,6 @@ LL | where
LL | Self::Assoc: A<T>,
| ^^^^ required by this bound in `A::f`
error: aborting due to 6 previous errors
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -4,20 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
LL | <T as Trait>::Assoc: Trait,
| ^^^^^
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized`
--> $DIR/normalize-param-env-4.rs:19:26
|
LL | <T as Trait>::Assoc: Trait,
| ^^^^^
|
note: required by a bound in `Trait`
--> $DIR/normalize-param-env-4.rs:7:1
|
LL | / trait Trait {
LL | | type Assoc;
LL | | }
| |_^ required by this bound in `Trait`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.