diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 67284e1621568..6b51e31579616 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -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, + ImpliedBoundsContext::AssociatedTypeOrImplTrait, + span, + ); + icx.lowerer().add_default_traits( &mut bounds, item_ty, hir_bounds, - None, - None, + 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, + ImpliedBoundsContext::AssociatedTypeOrImplTrait, + span, + ); + icx.lowerer().add_default_traits( &mut bounds, item_ty, hir_bounds, - None, - None, + 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 => {} diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e66accc7dcffd..79aaa0cb79701 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -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, + ImpliedBoundsContext::TraitDef(trait_def_id), + item.span, + ); + icx.lowerer().add_default_traits( &mut bounds, + self_param_ty, superbounds, - generics, + ImpliedBoundsContext::TraitDef(trait_def_id), item.span, ); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a3cb49e32d808..1832e6e890b9b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -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, + 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()) + { + 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_id, span); + 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() } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index c0b1377308923..15d7da3a00707 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -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::>(), - 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())); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 00f9095757806..82a931dcca2a0 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -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); diff --git a/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs new file mode 100644 index 0000000000000..48d17ac9a3af5 --- /dev/null +++ b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs @@ -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() +where + T::Target: Bar, +{ +} diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs index d5bf152b7963b..b13f9d90081cd 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.rs +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -52,14 +52,11 @@ fn with_pointeesized_supertrait() { requires_pointeesized::(); } -// `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() { -//~^ ERROR the size for values of type `T` cannot be known requires_sized::(); //~^ ERROR the size for values of type `T` cannot be known requires_metasized::(); - //~^ ERROR the size for values of type `T` cannot be known requires_pointeesized::(); } diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index 2a521dce8b6bb..35875163774d4 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -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() { - | ^^^^ 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() { - | ++++++++++++++++++++++++ - 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 $DIR/default-supertrait.rs:59:22 + --> $DIR/default-supertrait.rs:57:22 | LL | fn with_bare_trait() { | - this type parameter needs to be `Sized` -LL | LL | requires_sized::(); | ^ 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() {} | ^^^^^ 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::(); - | ^ doesn't have a known size - | -note: required by a bound in `requires_metasized` - --> $DIR/default-supertrait.rs:30:26 - | -LL | fn requires_metasized() {} - | ^^^^^^^^^ required by this bound in `requires_metasized` -help: consider further restricting type parameter `T` with unstable trait `MetaSized` - | -LL | fn with_bare_trait() { - | ++++++++++++++++++++++++ - -error: aborting due to 15 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/elaboration-simple.rs b/tests/ui/sized-hierarchy/elaboration-simple.rs new file mode 100644 index 0000000000000..87e100166a298 --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-simple.rs @@ -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() { + require_metasized::(); +} + +fn require_metasized() {} diff --git a/tests/ui/sized-hierarchy/trait-alias-elaboration.rs b/tests/ui/sized-hierarchy/trait-alias-elaboration.rs new file mode 100644 index 0000000000000..a5b4443ffddd3 --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-alias-elaboration.rs @@ -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() {} diff --git a/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr b/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr new file mode 100644 index 0000000000000..394aae6f8e32f --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr @@ -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 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index 8d8909625ffc8..d179c80596238 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -19,23 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` LL | Self::Assoc: A, | ^^^^ -error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: MetaSized` - --> $DIR/normalize-param-env-2.rs:24:22 - | -LL | Self::Assoc: A, - | ^^^^ - | -note: required by a bound in `A` - --> $DIR/normalize-param-env-2.rs:9:1 - | -LL | / trait A { -LL | | type Assoc; -LL | | -LL | | fn f() -... | -LL | | } - | |_^ required by this bound in `A` - error[E0275]: overflow evaluating the requirement `<() as A>::Assoc well-formed` --> $DIR/normalize-param-env-2.rs:24:22 | @@ -63,6 +46,6 @@ LL | where LL | Self::Assoc: A, | ^^^^ 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`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index 9f7f74f94664b..f5fd9ce9864ce 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,20 +4,6 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` LL | ::Assoc: Trait, | ^^^^^ -error[E0275]: overflow evaluating the requirement `::Assoc: MetaSized` - --> $DIR/normalize-param-env-4.rs:19:26 - | -LL | ::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`.