From cd6b7323f5b95a815ff8b00bc00ead8cc888395b Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 16 Jan 2025 11:30:39 +0000 Subject: [PATCH 01/43] trait_sel: `{Meta,Pointee}Sized` on `Sized` types Introduce the `MetaSized` and `PointeeSized` traits as supertraits of `Sized` and initially implement it on everything that currently implements `Sized` to isolate any changes that simply adding the traits introduces. --- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir/src/lang_items.rs | 2 + compiler/rustc_middle/src/traits/select.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 + .../src/solve/assembly/mod.rs | 24 ++++++ .../src/solve/effect_goals.rs | 14 ++++ .../src/solve/normalizes_to/mod.rs | 14 ++++ .../src/solve/trait_goals.rs | 30 +++++++ compiler/rustc_span/src/symbol.rs | 3 + .../src/traits/select/candidate_assembly.rs | 14 +++- .../src/traits/select/confirmation.rs | 4 + compiler/rustc_type_ir/src/lang_items.rs | 2 + library/core/src/marker.rs | 42 +++++++++- tests/ui/attributes/dump-preds.stderr | 1 + .../feature-gate-sized-hierarchy.rs | 32 ++++++++ .../feature-gate-sized-hierarchy.stderr | 81 +++++++++++++++++++ 16 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-sized-hierarchy.rs create mode 100644 tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 4707daea08910..86c4462e63ef7 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -235,6 +235,8 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), + /// Introduces a hierarchy of `Sized` traits (RFC 3729). + (unstable, sized_hierarchy, "CURRENT_RUSTC_VERSION", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Added for testing unstable lints; perma-unstable. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index e625514e9ffa1..ff866c56f453d 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -165,6 +165,8 @@ pub fn extract(attrs: &[impl AttributeExt]) -> Option<(Symbol, Span)> { language_item_table! { // Variant name, Name, Getter method name, Target Generic requirements; Sized, sym::sized, sized_trait, Target::Trait, GenericRequirement::Exact(0); + MetaSized, sym::meta_sized, meta_sized_trait, Target::Trait, GenericRequirement::Exact(0); + PointeeSized, sym::pointee_sized, pointee_sized_trait, Target::Trait, GenericRequirement::Exact(0); Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1); /// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ"). StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 811bd8fb4588a..d03b44d8b3d13 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -98,7 +98,7 @@ pub enum SelectionCandidate<'tcx> { /// A builtin implementation for some specific traits, used in cases /// where we cannot rely an ordinary library implementations. /// - /// The most notable examples are `sized`, `Copy` and `Clone`. This is also + /// The most notable examples are `Sized`, `Copy` and `Clone`. This is also /// used for the `DiscriminantKind` and `Pointee` trait, both of which have /// an associated type. BuiltinCandidate { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f54dd2b0040ae..33095258a74b4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -714,7 +714,9 @@ bidirectional_lang_item_map! { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 384a304c4a9d6..519b67dbf194f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -155,6 +155,24 @@ where goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution>; + /// A type is `MetaSized` if its tail component is `MetaSized`. + /// + /// These components are given by built-in rules from + /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. + fn consider_builtin_meta_sized_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution>; + + /// A type is `PointeeSized` if its tail component is `PointeeSized`. + /// + /// These components are given by built-in rules from + /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. + fn consider_builtin_pointee_sized_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution>; + /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. /// /// These components are given by built-in rules from @@ -397,6 +415,12 @@ where } else { match cx.as_lang_item(trait_def_id) { Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal), + Some(TraitSolverLangItem::MetaSized) => { + G::consider_builtin_meta_sized_candidate(self, goal) + } + Some(TraitSolverLangItem::PointeeSized) => { + G::consider_builtin_pointee_sized_candidate(self, goal) + } Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 0b61c368d8e8d..62eb0ebb23abd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -205,6 +205,20 @@ where unreachable!("Sized is never const") } + fn consider_builtin_meta_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + unreachable!("MetaSized is never const") + } + + fn consider_builtin_pointee_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + _goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + unreachable!("PointeeSized is never const") + } + fn consider_builtin_copy_clone_candidate( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal<I, Self>, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index de6d21da0f592..613948e3c8f37 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -319,6 +319,20 @@ where panic!("`Sized` does not have an associated type: {:?}", goal); } + fn consider_builtin_meta_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + panic!("`MetaSized` does not have an associated type: {:?}", goal); + } + + fn consider_builtin_pointee_sized_candidate( + _ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + panic!("`PointeeSized` does not have an associated type: {:?}", goal); + } + fn consider_builtin_copy_clone_candidate( _ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index b72f776e5cb48..c65ac041b7d5d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -232,6 +232,36 @@ where ) } + fn consider_builtin_meta_sized_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { + return Err(NoSolution); + } + + ecx.probe_and_evaluate_goal_for_constituent_tys( + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + goal, + structural_traits::instantiate_constituent_tys_for_sized_trait, + ) + } + + fn consider_builtin_pointee_sized_candidate( + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + ) -> Result<Candidate<I>, NoSolution> { + if goal.predicate.polarity != ty::PredicatePolarity::Positive { + return Err(NoSolution); + } + + ecx.probe_and_evaluate_goal_for_constituent_tys( + CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), + goal, + structural_traits::instantiate_constituent_tys_for_sized_trait, + ) + } + fn consider_builtin_copy_clone_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 210966bed6277..996e276c3a185 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1303,6 +1303,7 @@ symbols! { memtag, message, meta, + meta_sized, metadata_type, min_align_of, min_align_of_val, @@ -1552,6 +1553,7 @@ symbols! { plugin_registrar, plugins, pointee, + pointee_sized, pointee_trait, pointer, pointer_like, @@ -1949,6 +1951,7 @@ symbols! { size_of, size_of_val, sized, + sized_hierarchy, skip, slice, slice_from_raw_parts, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index fc352499146eb..6f8c9b1f091e1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -88,8 +88,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::Sized) { // Sized is never implementable by end-users, it is // always automatically computed. - let sized_conditions = self.sized_conditions(obligation); - self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); + let conditions = self.sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); + } else if tcx.is_lang_item(def_id, LangItem::MetaSized) { + // MetaSized is never implementable by end-users, it is + // always automatically computed. + let conditions = self.sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); + } else if tcx.is_lang_item(def_id, LangItem::PointeeSized) { + // PointeeSized is never implementable by end-users, it is + // always automatically computed. + let conditions = self.sized_conditions(obligation); + self.assemble_builtin_bound_candidates(conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Destruct) { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4404324d5cd74..8c41b8a32da97 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -257,6 +257,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_def = obligation.predicate.def_id(); let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) { self.sized_conditions(obligation) + } else if tcx.is_lang_item(trait_def, LangItem::MetaSized) { + self.sized_conditions(obligation) + } else if tcx.is_lang_item(trait_def, LangItem::PointeeSized) { + self.sized_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Copy) { self.copy_clone_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Clone) { diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 65f7cdf8f922b..283a6f2758105 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -31,7 +31,9 @@ pub enum TraitSolverLangItem { FutureOutput, Iterator, Metadata, + MetaSized, Option, + PointeeSized, PointeeTrait, Poll, Sized, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 68011310d2cad..6a9423cd4c40a 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -151,10 +151,50 @@ unsafe impl<T: Sync + ?Sized> Send for &T {} #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] #[rustc_coinductive] -pub trait Sized { +pub trait Sized: MetaSized { // Empty. } +/// Types with a size that can be determined from pointer metadata. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[cfg_attr(not(bootstrap), lang = "meta_sized")] +#[diagnostic::on_unimplemented( + message = "the size for values of type `{Self}` cannot be known", + label = "doesn't have a known size" +)] +#[fundamental] +#[rustc_specialization_trait] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[rustc_do_not_implement_via_object] +#[rustc_coinductive] +pub trait MetaSized: PointeeSized { + // Empty +} + +#[cfg(bootstrap)] +#[unstable(feature = "sized_hierarchy", issue = "none")] +impl<T: ?Sized> MetaSized for T {} + +/// Types that may or may not have a size. +#[unstable(feature = "sized_hierarchy", issue = "none")] +#[cfg_attr(not(bootstrap), lang = "pointee_sized")] +#[diagnostic::on_unimplemented( + message = "values of type `{Self}` may or may not have a size", + label = "may or may not have a known size" +)] +#[fundamental] +#[rustc_specialization_trait] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[rustc_do_not_implement_via_object] +#[rustc_coinductive] +pub trait PointeeSized { + // Empty +} + +#[cfg(bootstrap)] +#[unstable(feature = "sized_hierarchy", issue = "none")] +impl<T: ?Sized> PointeeSized for T {} + /// Types that can be "unsized" to a dynamically-sized type. /// /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index bdfcbed71e9a6..fe662dd48f4a2 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -34,6 +34,7 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> = note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(Projection, AliasTy { args: [Self/#0, T/#1, P/#2], def_id: DefId(..), .. })], def_id: DefId(..), .. }, Term::Ty(())), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs new file mode 100644 index 0000000000000..bc81a7e6c38f5 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -0,0 +1,32 @@ +#![feature(extern_types)] +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +fn needs_pointeesized<T: ?Sized + PointeeSized>() {} +fn needs_metasized<T: ?Sized + MetaSized>() {} +fn needs_sized<T: Sized>() {} + +fn main() { + needs_pointeesized::<u8>(); + needs_metasized::<u8>(); + needs_sized::<u8>(); + + needs_pointeesized::<str>(); +//~^ ERROR values of type `str` may or may not have a size + needs_metasized::<str>(); +//~^ ERROR the size for values of type `str` cannot be known + needs_sized::<str>(); +//~^ ERROR the size for values of type `str` cannot be known at compilation time + + extern "C" { + type Foo; + } + + needs_pointeesized::<Foo>(); +//~^ ERROR values of type `main::Foo` may or may not have a size + needs_metasized::<Foo>(); +//~^ ERROR the size for values of type `main::Foo` cannot be known + needs_sized::<Foo>(); +//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time +} diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr new file mode 100644 index 0000000000000..64f544c5d8fd4 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -0,0 +1,81 @@ +error[E0277]: values of type `str` may or may not have a size + --> $DIR/feature-gate-sized-hierarchy.rs:15:26 + | +LL | needs_pointeesized::<str>(); + | ^^^ may or may not have a known size + | + = help: the trait `PointeeSized` is not implemented for `str` +note: required by a bound in `needs_pointeesized` + --> $DIR/feature-gate-sized-hierarchy.rs:6:35 + | +LL | fn needs_pointeesized<T: ?Sized + PointeeSized>() {} + | ^^^^^^^^^^^^ required by this bound in `needs_pointeesized` + +error[E0277]: the size for values of type `str` cannot be known + --> $DIR/feature-gate-sized-hierarchy.rs:17:23 + | +LL | needs_metasized::<str>(); + | ^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `str` +note: required by a bound in `needs_metasized` + --> $DIR/feature-gate-sized-hierarchy.rs:7:32 + | +LL | fn needs_metasized<T: ?Sized + MetaSized>() {} + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/feature-gate-sized-hierarchy.rs:19: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/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized<T: Sized>() {} + | ^^^^^ required by this bound in `needs_sized` + +error[E0277]: values of type `main::Foo` may or may not have a size + --> $DIR/feature-gate-sized-hierarchy.rs:26:26 + | +LL | needs_pointeesized::<Foo>(); + | ^^^ may or may not have a known size + | + = help: the trait `PointeeSized` is not implemented for `main::Foo` +note: required by a bound in `needs_pointeesized` + --> $DIR/feature-gate-sized-hierarchy.rs:6:35 + | +LL | fn needs_pointeesized<T: ?Sized + PointeeSized>() {} + | ^^^^^^^^^^^^ required by this bound in `needs_pointeesized` + +error[E0277]: the size for values of type `main::Foo` cannot be known + --> $DIR/feature-gate-sized-hierarchy.rs:28: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/feature-gate-sized-hierarchy.rs:7:32 + | +LL | fn needs_metasized<T: ?Sized + 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:30: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/feature-gate-sized-hierarchy.rs:8:19 + | +LL | fn needs_sized<T: Sized>() {} + | ^^^^^ required by this bound in `needs_sized` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. From 71433130c029b8e11c63f8e2afd023f76215ba79 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 16 Jan 2025 14:27:49 +0000 Subject: [PATCH 02/43] trait_sel: `{Meta,Pointee}Sized` on `?Sized` types Expand the automatic implementation of `MetaSized` and `PointeeSized` so that it is also implemented on non-`Sized` types, just not `ty::Foreign` (extern type). --- compiler/rustc_middle/src/query/mod.rs | 6 + compiler/rustc_middle/src/ty/adt.rs | 29 ++ compiler/rustc_middle/src/ty/mod.rs | 1 + .../src/solve/assembly/mod.rs | 40 +- .../src/solve/assembly/structural_traits.rs | 65 ++- .../src/solve/effect_goals.rs | 20 +- .../src/solve/normalizes_to/mod.rs | 20 +- .../src/solve/trait_goals.rs | 41 +- .../src/traits/select/candidate_assembly.rs | 4 +- .../src/traits/select/confirmation.rs | 4 +- .../src/traits/select/mod.rs | 151 ++++--- compiler/rustc_ty_utils/src/ty.rs | 117 ++++-- compiler/rustc_type_ir/src/inherent.rs | 2 + compiler/rustc_type_ir/src/solve/mod.rs | 11 + tests/ui/attributes/dump-preds.stderr | 1 + .../feature-gate-sized-hierarchy.rs | 3 - .../feature-gate-sized-hierarchy.stderr | 47 +-- tests/ui/sized-hierarchy/impls.rs | 307 ++++++++++++++ tests/ui/sized-hierarchy/impls.stderr | 380 ++++++++++++++++++ 19 files changed, 1006 insertions(+), 243 deletions(-) create mode 100644 tests/ui/sized-hierarchy/impls.rs create mode 100644 tests/ui/sized-hierarchy/impls.stderr diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 527c18addbe12..dbf1d17769ec0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -813,6 +813,12 @@ rustc_queries! { query adt_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { desc { |tcx| "computing the `Sized` constraint for `{}`", tcx.def_path_str(key) } } + query adt_meta_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + desc { |tcx| "computing the `MetaSized` constraint for `{}`", tcx.def_path_str(key) } + } + query adt_pointee_sized_constraint(key: DefId) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + desc { |tcx| "computing the `PointeeSized` constraint for `{}`", tcx.def_path_str(key) } + } query adt_dtorck_constraint( key: DefId diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index cb245c0aec40a..9ec1752d0b0d7 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -231,6 +231,17 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> { self.sized_constraint(tcx) } + fn meta_sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + self.meta_sized_constraint(tcx) + } + + fn pointee_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + self.pointee_sized_constraint(tcx) + } + fn is_fundamental(self) -> bool { self.is_fundamental() } @@ -628,6 +639,24 @@ impl<'tcx> AdtDef<'tcx> { pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { if self.is_struct() { tcx.adt_sized_constraint(self.did()) } else { None } } + + /// Returns a type such that `Self: MetaSized` if and only if that type is `MetaSized`, + /// or `None` if the type is always `MetaSized`. + pub fn meta_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + if self.is_struct() { tcx.adt_meta_sized_constraint(self.did()) } else { None } + } + + /// Returns a type such that `Self: PointeeSized` if and only if that type is `PointeeSized`, + /// or `None` if the type is always `PointeeSized`. + pub fn pointee_sized_constraint( + self, + tcx: TyCtxt<'tcx>, + ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + if self.is_struct() { tcx.adt_pointee_sized_constraint(self.did()) } else { None } + } } #[derive(Clone, Copy, Debug, HashStable)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6bdd0a0647d30..46be9bb0a2eb9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -50,6 +50,7 @@ pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::relate::VarianceDiagInfo; +pub use rustc_type_ir::solve::SizedTraitKind; pub use rustc_type_ir::*; use tracing::{debug, instrument}; pub use vtable::*; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 519b67dbf194f..388965270ba65 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -5,6 +5,7 @@ pub(super) mod structural_traits; use derive_where::derive_where; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ self as ty, Interner, TypeFoldable, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, }; @@ -146,31 +147,16 @@ where goal: Goal<I, Self>, ) -> Result<Candidate<I>, NoSolution>; - /// A type is `Sized` if its tail component is `Sized`. + /// A type is `Sized` if its tail component is `Sized`, a type is `MetaSized` if its tail + /// component is `MetaSized` and a type is `PointeeSized` if its tail component is + /// `PointeeSized`. /// /// These components are given by built-in rules from - /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. - fn consider_builtin_sized_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution>; - - /// A type is `MetaSized` if its tail component is `MetaSized`. - /// - /// These components are given by built-in rules from - /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. - fn consider_builtin_meta_sized_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution>; - - /// A type is `PointeeSized` if its tail component is `PointeeSized`. - /// - /// These components are given by built-in rules from - /// [`structural_traits::instantiate_constituent_tys_for_sized_trait`]. - fn consider_builtin_pointee_sized_candidate( + /// [`structural_traits::instantiate_constituent_tys_for_sizedness_trait`]. + fn consider_builtin_sizedness_candidates( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution>; /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. @@ -414,12 +400,18 @@ where G::consider_trait_alias_candidate(self, goal) } else { match cx.as_lang_item(trait_def_id) { - Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal), + Some(TraitSolverLangItem::Sized) => { + G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::Sized) + } Some(TraitSolverLangItem::MetaSized) => { - G::consider_builtin_meta_sized_candidate(self, goal) + G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::MetaSized) } Some(TraitSolverLangItem::PointeeSized) => { - G::consider_builtin_pointee_sized_candidate(self, goal) + G::consider_builtin_sizedness_candidates( + self, + goal, + SizedTraitKind::PointeeSized, + ) } Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index a5142de2d3905..e32d86d0ce001 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -5,6 +5,7 @@ use derive_where::derive_where; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ self as ty, Interner, Movability, Mutability, TypeFoldable, TypeFolder, TypeSuperFoldable, Upcast as _, elaborate, @@ -99,8 +100,9 @@ where } #[instrument(level = "trace", skip(ecx), ret)] -pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<D, I>( +pub(in crate::solve) fn instantiate_constituent_tys_for_sizedness_trait<D, I>( ecx: &EvalCtxt<'_, D>, + sizedness: SizedTraitKind, ty: I::Ty, ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution> where @@ -108,8 +110,9 @@ where I: Interner, { match ty.kind() { - // impl Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char, &mut? T, [T; N], dyn* Trait, ! - // impl Sized for Coroutine, CoroutineWitness, Closure, CoroutineClosure + // impl {Meta,Pointee,}Sized for u*, i*, bool, f*, FnDef, FnPtr, *(const/mut) T, char + // impl {Meta,Pointee,}Sized for &mut? T, [T; N], dyn* Trait, !, Coroutine, CoroutineWitness + // impl {Meta,Pointee,}Sized for Closure, CoroutineClosure ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) | ty::Int(_) @@ -130,13 +133,21 @@ where | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => Ok(ty::Binder::dummy(vec![])), - ty::Str - | ty::Slice(_) - | ty::Dynamic(..) - | ty::Foreign(..) - | ty::Alias(..) - | ty::Param(_) - | ty::Placeholder(..) => Err(NoSolution), + // impl {Meta,Pointee,}Sized for str, [T], dyn Trait + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => Err(NoSolution), + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => { + Ok(ty::Binder::dummy(vec![])) + } + }, + + // impl PointeeSized for extern type + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Err(NoSolution), + SizedTraitKind::PointeeSized => Ok(ty::Binder::dummy(vec![])), + }, + + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => Err(NoSolution), ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { @@ -145,22 +156,32 @@ where ty::UnsafeBinder(bound_ty) => Ok(bound_ty.map_bound(|ty| vec![ty])), - // impl Sized for () - // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 + // impl {Meta,Pointee,}Sized for () + // impl {Meta,Pointee,}Sized for (T1, T2, .., Tn) where Tn: {Meta,Pointee,}Sized if n >= 1 ty::Tuple(tys) => Ok(ty::Binder::dummy(tys.last().map_or_else(Vec::new, |ty| vec![ty]))), - // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized - // `sized_constraint(Adt)` is the deepest struct trail that can be determined - // by the definition of `Adt`, independent of the generic args. - // impl Sized for Adt<Args...> if sized_constraint(Adt) == None - // As a performance optimization, `sized_constraint(Adt)` can return `None` - // if the ADTs definition implies that it is sized by for all possible args. + // impl {Meta,Pointee,}Sized for Adt<Args...> + // where {meta,pointee,}sized_constraint(Adt)<Args...>: {Meta,Pointee,}Sized + // + // `{meta,pointee,}sized_constraint(Adt)` is the deepest struct trail that can be + // determined by the definition of `Adt`, independent of the generic args. + // + // impl {Meta,Pointee,}Sized for Adt<Args...> + // if {meta,pointee,}sized_constraint(Adt) == None + // + // As a performance optimization, `{meta,pointee,}sized_constraint(Adt)` can return `None` + // if the ADTs definition implies that it is {meta,}sized by for all possible args. // In this case, the builtin impl will have no nested subgoals. This is a - // "best effort" optimization and `sized_constraint` may return `Some`, even - // if the ADT is sized for all possible args. + // "best effort" optimization and `{meta,pointee,}sized_constraint` may return `Some`, + // even if the ADT is {meta,pointee,}sized for all possible args. ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(ecx.cx()) { - Ok(ty::Binder::dummy(vec![sized_crit.instantiate(ecx.cx(), args)])) + let crit = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(ecx.cx()), + SizedTraitKind::MetaSized => def.meta_sized_constraint(ecx.cx()), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(ecx.cx()), + }; + if let Some(crit) = crit { + Ok(ty::Binder::dummy(vec![crit.instantiate(ecx.cx(), args)])) } else { Ok(ty::Binder::dummy(vec![])) } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 62eb0ebb23abd..b8666a1def3d7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -4,6 +4,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{self as ty, Interner, elaborate}; use tracing::instrument; @@ -198,25 +199,12 @@ where unreachable!("trait aliases are never const") } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal<I, Self>, + _sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { - unreachable!("Sized is never const") - } - - fn consider_builtin_meta_sized_candidate( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - unreachable!("MetaSized is never const") - } - - fn consider_builtin_pointee_sized_candidate( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - unreachable!("PointeeSized is never const") + unreachable!("Sized/MetaSized/PointeeSized is never const") } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 613948e3c8f37..6519b47058ce2 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -6,6 +6,7 @@ mod weak_types; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _}; use tracing::instrument; @@ -312,25 +313,12 @@ where panic!("trait aliases do not have associated types: {:?}", goal); } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( _ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + _sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { - panic!("`Sized` does not have an associated type: {:?}", goal); - } - - fn consider_builtin_meta_sized_candidate( - _ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - panic!("`MetaSized` does not have an associated type: {:?}", goal); - } - - fn consider_builtin_pointee_sized_candidate( - _ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - panic!("`PointeeSized` does not have an associated type: {:?}", goal); + panic!("`Sized`/`MetaSized`/`PointeeSized` does not have an associated type: {:?}", goal); } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index c65ac041b7d5d..3894631df6791 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -4,7 +4,7 @@ use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::solve::CanonicalResponse; +use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind}; use rustc_type_ir::{ self as ty, Interner, Movability, TraitPredicate, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate, @@ -217,9 +217,10 @@ where }) } - fn consider_builtin_sized_candidate( + fn consider_builtin_sizedness_candidates( ecx: &mut EvalCtxt<'_, D>, goal: Goal<I, Self>, + sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { if goal.predicate.polarity != ty::PredicatePolarity::Positive { return Err(NoSolution); @@ -228,37 +229,11 @@ where ecx.probe_and_evaluate_goal_for_constituent_tys( CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial), goal, - structural_traits::instantiate_constituent_tys_for_sized_trait, - ) - } - - fn consider_builtin_meta_sized_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - if goal.predicate.polarity != ty::PredicatePolarity::Positive { - return Err(NoSolution); - } - - ecx.probe_and_evaluate_goal_for_constituent_tys( - CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - goal, - structural_traits::instantiate_constituent_tys_for_sized_trait, - ) - } - - fn consider_builtin_pointee_sized_candidate( - ecx: &mut EvalCtxt<'_, D>, - goal: Goal<I, Self>, - ) -> Result<Candidate<I>, NoSolution> { - if goal.predicate.polarity != ty::PredicatePolarity::Positive { - return Err(NoSolution); - } - - ecx.probe_and_evaluate_goal_for_constituent_tys( - CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), - goal, - structural_traits::instantiate_constituent_tys_for_sized_trait, + |ecx, ty| { + structural_traits::instantiate_constituent_tys_for_sizedness_trait( + ecx, sizedness, ty, + ) + }, ) } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 6f8c9b1f091e1..922f7562d2a08 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -93,12 +93,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::MetaSized) { // MetaSized is never implementable by end-users, it is // always automatically computed. - let conditions = self.sized_conditions(obligation); + let conditions = self.meta_sized_conditions(obligation); self.assemble_builtin_bound_candidates(conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::PointeeSized) { // PointeeSized is never implementable by end-users, it is // always automatically computed. - let conditions = self.sized_conditions(obligation); + let conditions = self.pointee_sized_conditions(obligation); self.assemble_builtin_bound_candidates(conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8c41b8a32da97..6f61dc9a6f28c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -258,9 +258,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) { self.sized_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::MetaSized) { - self.sized_conditions(obligation) + self.meta_sized_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::PointeeSized) { - self.sized_conditions(obligation) + self.pointee_sized_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Copy) { self.copy_clone_conditions(obligation) } else if tcx.is_lang_item(trait_def, LangItem::Clone) { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e1adabbeaa662..ab146022ba646 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -32,6 +32,7 @@ use rustc_middle::ty::{ }; use rustc_span::{Symbol, sym}; use rustc_type_ir::elaborate; +use rustc_type_ir::solve::SizedTraitKind; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -2059,66 +2060,21 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx> { - use self::BuiltinImplConditions::{Ambiguous, None, Where}; - - // NOTE: binder moved to (*) - let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); - - match self_ty.kind() { - ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) - | ty::Uint(_) - | ty::Int(_) - | ty::Bool - | ty::Float(_) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::RawPtr(..) - | ty::Char - | ty::Ref(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Array(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Never - | ty::Dynamic(_, _, ty::DynStar) - | ty::Error(_) => { - // safe for everything - Where(ty::Binder::dummy(Vec::new())) - } - - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, - - ty::Tuple(tys) => Where( - obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), - ), - - ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), - - ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(self.tcx()) { - // (*) binder moved here - Where( - obligation.predicate.rebind(vec![sized_crit.instantiate(self.tcx(), args)]), - ) - } else { - Where(ty::Binder::dummy(Vec::new())) - } - } - - // FIXME(unsafe_binders): This binder needs to be squashed - ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])), - - ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, - ty::Infer(ty::TyVar(_)) => Ambiguous, + sizedness_conditions(self, obligation, SizedTraitKind::Sized) + } - // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. - ty::Bound(..) => None, + fn meta_sized_conditions( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> BuiltinImplConditions<'tcx> { + sizedness_conditions(self, obligation, SizedTraitKind::MetaSized) + } - ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); - } - } + fn pointee_sized_conditions( + &mut self, + obligation: &PolyTraitObligation<'tcx>, + ) -> BuiltinImplConditions<'tcx> { + sizedness_conditions(self, obligation, SizedTraitKind::PointeeSized) } fn copy_clone_conditions( @@ -2848,6 +2804,85 @@ fn rebind_coroutine_witness_types<'tcx>( ) } +fn sizedness_conditions<'cx, 'tcx>( + ctx: &mut SelectionContext<'cx, 'tcx>, + obligation: &PolyTraitObligation<'tcx>, + sizedness: SizedTraitKind, +) -> BuiltinImplConditions<'tcx> { + use self::BuiltinImplConditions::{Ambiguous, None, Where}; + + // NOTE: binder moved to (*) + let self_ty = ctx.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); + + match self_ty.kind() { + ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Float(_) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::RawPtr(..) + | ty::Char + | ty::Ref(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Array(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Never + | ty::Dynamic(_, _, ty::DynStar) + | ty::Error(_) => { + // safe for everything + Where(ty::Binder::dummy(Vec::new())) + } + + ty::Str | ty::Slice(_) | ty::Dynamic(..) => match sizedness { + SizedTraitKind::Sized => None, + SizedTraitKind::MetaSized => Where(ty::Binder::dummy(Vec::new())), + SizedTraitKind::PointeeSized => Where(ty::Binder::dummy(Vec::new())), + }, + + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => None, + SizedTraitKind::PointeeSized => Where(ty::Binder::dummy(Vec::new())), + }, + + ty::Tuple(tys) => { + Where(obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last]))) + } + + ty::Pat(ty, _) => Where(obligation.predicate.rebind(vec![*ty])), + + ty::Adt(def, args) => { + let constraint = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(ctx.tcx()), + SizedTraitKind::MetaSized => def.meta_sized_constraint(ctx.tcx()), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(ctx.tcx()), + }; + if let Some(crit) = constraint { + // (*) binder moved here + Where(obligation.predicate.rebind(vec![crit.instantiate(ctx.tcx(), args)])) + } else { + Where(ty::Binder::dummy(Vec::new())) + } + } + + // FIXME(unsafe_binders): This binder needs to be squashed + ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])), + + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, + ty::Infer(ty::TyVar(_)) => Ambiguous, + + // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. + ty::Bound(..) => None, + + ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); + } + } +} + impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList::with(self) diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9dc4f11e456e2..454e496e13f3c 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,17 +6,24 @@ use rustc_index::bit_set::DenseBitSet; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, fold_regions, + self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, + fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_trait_selection::traits; use tracing::instrument; +/// Returns `Some(ty)` if the type might not or does not implement the given `sizedness` trait +/// (`Sized`, `MetaSized` or `PointeeSized`). #[instrument(level = "debug", skip(tcx), ret)] -fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { +fn sizedness_constraint_for_ty<'tcx>( + tcx: TyCtxt<'tcx>, + sizedness: SizedTraitKind, + ty: Ty<'tcx>, +) -> Option<Ty<'tcx>> { match ty.kind() { - // these are always sized + // Always `Sized`, `MetaSized` or `PointeeSized` ty::Bool | ty::Char | ty::Int(..) @@ -34,31 +41,51 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<' | ty::Never | ty::Dynamic(_, _, ty::DynStar) => None, - // these are never sized - ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => Some(ty), - - ty::Pat(ty, _) => sized_constraint_for_ty(tcx, *ty), - - ty::Tuple(tys) => tys.last().and_then(|&ty| sized_constraint_for_ty(tcx, ty)), - - // recursive case - ty::Adt(adt, args) => adt.sized_constraint(tcx).and_then(|intermediate| { - let ty = intermediate.instantiate(tcx, args); - sized_constraint_for_ty(tcx, ty) - }), + ty::Str | ty::Slice(..) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { + // Never `Sized` + SizedTraitKind::Sized => Some(ty), + // Always `MetaSized` and `PointeeSized` + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => None, + }, - // these can be sized or unsized. + // Maybe `Sized`, `MetaSized` or `PointeeSized` ty::Param(..) | ty::Alias(..) | ty::Error(_) => Some(ty), // We cannot instantiate the binder, so just return the *original* type back, // but only if the inner type has a sized constraint. Thus we skip the binder, // but don't actually use the result from `sized_constraint_for_ty`. ty::UnsafeBinder(inner_ty) => { - sized_constraint_for_ty(tcx, inner_ty.skip_binder()).map(|_| ty) + sizedness_constraint_for_ty(tcx, sizedness, inner_ty.skip_binder()).map(|_| ty) + } + + ty::Foreign(..) => match sizedness { + // Never `MetaSized` or `Sized` + SizedTraitKind::Sized | SizedTraitKind::MetaSized => Some(ty), + // Always `PointeeSized` + SizedTraitKind::PointeeSized => None, + }, + + // Recursive cases + ty::Pat(ty, _) => sizedness_constraint_for_ty(tcx, sizedness, *ty), + + ty::Tuple(tys) => { + tys.last().and_then(|&ty| sizedness_constraint_for_ty(tcx, sizedness, ty)) + } + + ty::Adt(adt, args) => { + let constraint = match sizedness { + SizedTraitKind::Sized => adt.sized_constraint(tcx), + SizedTraitKind::MetaSized => adt.meta_sized_constraint(tcx), + SizedTraitKind::PointeeSized => adt.pointee_sized_constraint(tcx), + }; + constraint.and_then(|intermediate| { + let ty = intermediate.instantiate(tcx, args); + sizedness_constraint_for_ty(tcx, sizedness, ty) + }) } ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { - bug!("unexpected type `{ty:?}` in sized_constraint_for_ty") + bug!("unexpected type `{ty:?}` in `sizedness_constraint_for_ty`") } } } @@ -77,12 +104,47 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { /// Calculates the `Sized` constraint. /// /// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type +/// - an metasized type (str, slices, trait objects, etc) +/// - an pointee-sized type (extern types) /// - a type parameter or projection whose sizedness can't be known #[instrument(level = "debug", skip(tcx), ret)] fn adt_sized_constraint<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, +) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + adt_sizedness_constraint(tcx, SizedTraitKind::Sized, def_id) +} + +/// Calculates the `MetaSized` constraint. +/// +/// In fact, there are only a few options for the types in the constraint: +/// - an pointee-sized type (extern types) +/// - a type parameter or projection whose sizedness can't be known +#[instrument(level = "debug", skip(tcx), ret)] +fn adt_meta_sized_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + adt_sizedness_constraint(tcx, SizedTraitKind::MetaSized, def_id) +} + +/// Calculates the `PointeeSized` constraint. +/// +/// In fact, there is only one option for the types in the constraint: a type parameter or +/// projection whose sizedness can't be known. +#[instrument(level = "debug", skip(tcx), ret)] +fn adt_pointee_sized_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { + adt_sizedness_constraint(tcx, SizedTraitKind::PointeeSized, def_id) +} + +#[instrument(level = "debug", skip(tcx), ret)] +fn adt_sizedness_constraint<'tcx>( + tcx: TyCtxt<'tcx>, + sizedness: SizedTraitKind, + def_id: DefId, ) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> { if let Some(def_id) = def_id.as_local() { if let ty::Representability::Infinite(_) = tcx.representability(def_id) { @@ -92,21 +154,26 @@ fn adt_sized_constraint<'tcx>( let def = tcx.adt_def(def_id); if !def.is_struct() { - bug!("`adt_sized_constraint` called on non-struct type: {def:?}"); + bug!("`adt_sizedness_constraint` called on non-struct type: {def:?}"); } let tail_def = def.non_enum_variant().tail_opt()?; let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); - let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; + let constraint_ty = sizedness_constraint_for_ty(tcx, sizedness, tail_ty)?; - // perf hack: if there is a `constraint_ty: Sized` bound, then we know + // perf hack: if there is a `constraint_ty: {Meta,Pointee,}Sized` bound, then we know // that the type is sized and do not need to check it on the impl. - let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None); + let lang_item = match sizedness { + SizedTraitKind::Sized => LangItem::Sized, + SizedTraitKind::MetaSized => LangItem::MetaSized, + SizedTraitKind::PointeeSized => LangItem::PointeeSized, + }; + let sizedness_trait_def_id = tcx.require_lang_item(lang_item, None); let predicates = tcx.predicates_of(def.did()).predicates; if predicates.iter().any(|(p, _)| { p.as_trait_clause().is_some_and(|trait_pred| { - trait_pred.def_id() == sized_trait_def_id + trait_pred.def_id() == sizedness_trait_def_id && trait_pred.self_ty().skip_binder() == constraint_ty }) }) { @@ -316,6 +383,8 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { asyncness, adt_sized_constraint, + adt_meta_sized_constraint, + adt_pointee_sized_constraint, param_env, param_env_normalized_for_post_analysis, defaultness, diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index d4134bdf3a782..4854d79d43fea 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -559,6 +559,8 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq { fn all_field_tys(self, interner: I) -> ty::EarlyBinder<I, impl IntoIterator<Item = I::Ty>>; fn sized_constraint(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>; + fn meta_sized_constraint(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>; + fn pointee_sized_constraint(self, interner: I) -> Option<ty::EarlyBinder<I, I::Ty>>; fn is_fundamental(self) -> bool; diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 3aec4804b2799..8ac529d2cbd1e 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -309,3 +309,14 @@ pub enum AdtDestructorKind { NotConst, Const, } + +/// Which sizedness trait - `Sized`, `MetaSized` or `PointeeSized`? +#[derive(Copy, Clone, Debug)] +pub enum SizedTraitKind { + /// `Sized` trait + Sized, + /// `MetaSized` trait + MetaSized, + /// `PointeeSized` trait + PointeeSized, +} diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index fe662dd48f4a2..7db2abc5ffe6d 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -35,6 +35,7 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::PointeeSized>, polarity:Positive), bound_vars: [] } error: aborting due to 3 previous errors diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs index bc81a7e6c38f5..5e2a76ba254e8 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -13,9 +13,7 @@ fn main() { needs_sized::<u8>(); needs_pointeesized::<str>(); -//~^ ERROR values of type `str` may or may not have a size needs_metasized::<str>(); -//~^ ERROR the size for values of type `str` cannot be known needs_sized::<str>(); //~^ ERROR the size for values of type `str` cannot be known at compilation time @@ -24,7 +22,6 @@ fn main() { } needs_pointeesized::<Foo>(); -//~^ ERROR values of type `main::Foo` may or may not have a size needs_metasized::<Foo>(); //~^ ERROR the size for values of type `main::Foo` cannot be known needs_sized::<Foo>(); diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr index 64f544c5d8fd4..8cbea3b6ba430 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -1,31 +1,5 @@ -error[E0277]: values of type `str` may or may not have a size - --> $DIR/feature-gate-sized-hierarchy.rs:15:26 - | -LL | needs_pointeesized::<str>(); - | ^^^ may or may not have a known size - | - = help: the trait `PointeeSized` is not implemented for `str` -note: required by a bound in `needs_pointeesized` - --> $DIR/feature-gate-sized-hierarchy.rs:6:35 - | -LL | fn needs_pointeesized<T: ?Sized + PointeeSized>() {} - | ^^^^^^^^^^^^ required by this bound in `needs_pointeesized` - -error[E0277]: the size for values of type `str` cannot be known - --> $DIR/feature-gate-sized-hierarchy.rs:17:23 - | -LL | needs_metasized::<str>(); - | ^^^ doesn't have a known size - | - = help: the trait `MetaSized` is not implemented for `str` -note: required by a bound in `needs_metasized` - --> $DIR/feature-gate-sized-hierarchy.rs:7:32 - | -LL | fn needs_metasized<T: ?Sized + MetaSized>() {} - | ^^^^^^^^^ required by this bound in `needs_metasized` - error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/feature-gate-sized-hierarchy.rs:19:19 + --> $DIR/feature-gate-sized-hierarchy.rs:17:19 | LL | needs_sized::<str>(); | ^^^ doesn't have a size known at compile-time @@ -37,21 +11,8 @@ note: required by a bound in `needs_sized` LL | fn needs_sized<T: Sized>() {} | ^^^^^ required by this bound in `needs_sized` -error[E0277]: values of type `main::Foo` may or may not have a size - --> $DIR/feature-gate-sized-hierarchy.rs:26:26 - | -LL | needs_pointeesized::<Foo>(); - | ^^^ may or may not have a known size - | - = help: the trait `PointeeSized` is not implemented for `main::Foo` -note: required by a bound in `needs_pointeesized` - --> $DIR/feature-gate-sized-hierarchy.rs:6:35 - | -LL | fn needs_pointeesized<T: ?Sized + PointeeSized>() {} - | ^^^^^^^^^^^^ required by this bound in `needs_pointeesized` - error[E0277]: the size for values of type `main::Foo` cannot be known - --> $DIR/feature-gate-sized-hierarchy.rs:28:23 + --> $DIR/feature-gate-sized-hierarchy.rs:25:23 | LL | needs_metasized::<Foo>(); | ^^^ doesn't have a known size @@ -64,7 +25,7 @@ LL | fn needs_metasized<T: ?Sized + 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:30:19 + --> $DIR/feature-gate-sized-hierarchy.rs:27:19 | LL | needs_sized::<Foo>(); | ^^^ doesn't have a size known at compile-time @@ -76,6 +37,6 @@ note: required by a bound in `needs_sized` LL | fn needs_sized<T: Sized>() {} | ^^^^^ required by this bound in `needs_sized` -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs new file mode 100644 index 0000000000000..b05313dccae49 --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.rs @@ -0,0 +1,307 @@ +//@ check-fail +//@ edition:2021 +#![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}; + +// This test checks that `Sized` and `MetaSized` are automatically implemented appropriately. + +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_pointeesized<T: ?Sized + PointeeSized>() { } +fn takes_pointeesized<T: ?Sized + PointeeSized>(_t: T) { } + +fn main() { + // `bool` + needs_sized::<bool>(); + needs_metasized::<bool>(); + needs_pointeesized::<bool>(); + + // `char` + needs_sized::<char>(); + needs_metasized::<char>(); + needs_pointeesized::<char>(); + + // `i8` + needs_sized::<i8>(); + needs_metasized::<i8>(); + needs_pointeesized::<i8>(); + + // `i16` + needs_sized::<i16>(); + needs_metasized::<i16>(); + needs_pointeesized::<i16>(); + + // `i32` + needs_sized::<i32>(); + needs_metasized::<i32>(); + needs_pointeesized::<i32>(); + + // `i64` + needs_sized::<i64>(); + needs_metasized::<i64>(); + needs_pointeesized::<i64>(); + + // `i128` + needs_sized::<i128>(); + needs_metasized::<i128>(); + needs_pointeesized::<i128>(); + + // `u8` + needs_sized::<u8>(); + needs_metasized::<u8>(); + needs_pointeesized::<u8>(); + + // `u16` + needs_sized::<u16>(); + needs_metasized::<u16>(); + needs_pointeesized::<u16>(); + + // `u32` + needs_sized::<u32>(); + needs_metasized::<u32>(); + needs_pointeesized::<u32>(); + + // `u64` + needs_sized::<u64>(); + needs_metasized::<u64>(); + needs_pointeesized::<u64>(); + + // `u128` + needs_sized::<u128>(); + needs_metasized::<u128>(); + needs_pointeesized::<u128>(); + + // `f16` + needs_sized::<f16>(); + needs_metasized::<f16>(); + needs_pointeesized::<f16>(); + + // `f32` + needs_sized::<f32>(); + needs_metasized::<f32>(); + needs_pointeesized::<f32>(); + + // `f64` + needs_sized::<f64>(); + needs_metasized::<f64>(); + needs_pointeesized::<f64>(); + + // `*const` + needs_sized::<*const u8>(); + needs_metasized::<*const u8>(); + needs_pointeesized::<*const u8>(); + + // `*mut` + needs_sized::<*mut u8>(); + needs_metasized::<*mut u8>(); + needs_pointeesized::<*mut u8>(); + + // `&` + needs_sized::<&u8>(); + needs_metasized::<&u8>(); + needs_pointeesized::<&u8>(); + + // `&mut` + needs_sized::<&mut u8>(); + needs_metasized::<&mut u8>(); + needs_pointeesized::<&mut u8>(); + + // fn-def + fn foo(x: u8) -> u8 { x } + takes_sized(foo); + takes_metasized(foo); + takes_pointeesized(foo); + + // fn-ptr + takes_sized::<fn(u8) -> u8>(foo); + takes_metasized::<fn(u8) -> u8>(foo); + takes_pointeesized::<fn(u8) -> u8>(foo); + + // `[T; x]` + needs_sized::<[u8; 1]>(); + needs_metasized::<[u8; 1]>(); + needs_pointeesized::<[u8; 1]>(); + + // `|a| { a }` + takes_sized(|a| { a }); + takes_metasized(|a| { a }); + takes_pointeesized(|a| { a }); + + // `async |a| { a }` + takes_sized(async |a| { a }); + takes_metasized(async |a| { a }); + takes_pointeesized(async |a| { a }); + + // `|a| { yield a }` + takes_sized(#[coroutine] |a| { yield a }); + takes_metasized(#[coroutine] |a| { yield a }); + takes_pointeesized(#[coroutine] |a| { yield a }); + + // `!` + needs_sized::<!>(); + needs_metasized::<!>(); + needs_pointeesized::<!>(); + + // `dyn*` + needs_sized::<dyn* Debug>(); + needs_metasized::<dyn* Debug>(); + needs_pointeesized::<dyn* Debug>(); + + // `str` + needs_sized::<str>(); + //~^ ERROR the size for values of type `str` cannot be known at compilation time + needs_metasized::<str>(); + needs_pointeesized::<str>(); + + // `[T]` + needs_sized::<[u8]>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<[u8]>(); + needs_pointeesized::<[u8]>(); + + // `dyn Debug` + needs_sized::<dyn Debug>(); + //~^ ERROR the size for values of type `dyn Debug` cannot be known at compilation time + needs_metasized::<dyn Debug>(); + needs_pointeesized::<dyn Debug>(); + + // `extern type` + extern "C" { + type Foo; + } + needs_sized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<Foo>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<Foo>(); + + // empty tuple + needs_sized::<()>(); + needs_metasized::<()>(); + needs_pointeesized::<()>(); + + // tuple w/ all elements sized + needs_sized::<(u32, u32)>(); + needs_metasized::<(u32, u32)>(); + needs_pointeesized::<(u32, u32)>(); + + // tuple w/ all elements metasized + needs_sized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_pointeesized::<([u8], [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + // tuple w/ all elements pointeesized + needs_sized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_pointeesized::<(Foo, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + + // tuple w/ last element metasized + needs_sized::<(u32, [u8])>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<(u32, [u8])>(); + needs_pointeesized::<(u32, [u8])>(); + + // tuple w/ last element pointeesized + needs_sized::<(u32, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<(u32, Foo)>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<(u32, Foo)>(); + + // struct w/ no fields + struct StructEmpty {} + needs_sized::<StructEmpty>(); + needs_metasized::<StructEmpty>(); + needs_pointeesized::<StructEmpty>(); + + // struct w/ all fields sized + struct StructAllFieldsSized { x: u32, y: u32 } + needs_sized::<StructAllFieldsSized>(); + needs_metasized::<StructAllFieldsSized>(); + needs_pointeesized::<StructAllFieldsSized>(); + + // struct w/ all fields metasized + struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<StructAllFieldsMetaSized>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<StructAllFieldsMetaSized>(); + needs_pointeesized::<StructAllFieldsMetaSized>(); + + // struct w/ all fields unsized + struct StructAllFieldsUnsized { x: Foo, y: Foo } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<StructAllFieldsUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<StructAllFieldsUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<StructAllFieldsUnsized>(); + + // struct w/ last fields metasized + struct StructLastFieldMetaSized { x: u32, y: [u8] } + needs_sized::<StructLastFieldMetaSized>(); + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_metasized::<StructLastFieldMetaSized>(); + needs_pointeesized::<StructLastFieldMetaSized>(); + + // struct w/ last fields unsized + struct StructLastFieldUnsized { x: u32, y: Foo } + needs_sized::<StructLastFieldUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_metasized::<StructLastFieldUnsized>(); + //~^ ERROR the size for values of type `main::Foo` cannot be known + needs_pointeesized::<StructLastFieldUnsized>(); + + // enum w/ no fields + enum EnumEmpty {} + needs_sized::<EnumEmpty>(); + needs_metasized::<EnumEmpty>(); + needs_pointeesized::<EnumEmpty>(); + + // enum w/ all variant fields sized + enum EnumAllFieldsSized { Qux { x: u32, y: u32 } } + needs_sized::<StructAllFieldsSized>(); + needs_metasized::<StructAllFieldsSized>(); + needs_pointeesized::<StructAllFieldsSized>(); + + // enum w/ all variant fields metasized + enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<EnumAllFieldsMetaSized>(); + needs_metasized::<EnumAllFieldsMetaSized>(); + needs_pointeesized::<EnumAllFieldsMetaSized>(); + + // enum w/ all variant fields unsized + enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<EnumAllFieldsUnsized>(); + needs_metasized::<EnumAllFieldsUnsized>(); + needs_pointeesized::<EnumAllFieldsUnsized>(); + + // enum w/ last variant fields metasized + enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } } + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + needs_sized::<EnumLastFieldMetaSized>(); + needs_metasized::<EnumLastFieldMetaSized>(); + needs_pointeesized::<EnumLastFieldMetaSized>(); + + // enum w/ last variant fields unsized + enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } + //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + needs_sized::<EnumLastFieldUnsized>(); + needs_metasized::<EnumLastFieldUnsized>(); + needs_pointeesized::<EnumLastFieldUnsized>(); +} diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr new file mode 100644 index 0000000000000..5fffe47866350 --- /dev/null +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -0,0 +1,380 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/impls.rs:237:42 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsMetaSized { x: &[u8], y: [u8] } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: only the last field of a struct may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | struct StructAllFieldsUnsized { x: &Foo, y: Foo } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsMetaSized { Qux { x: &[u8], y: [u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumAllFieldsUnsized { Qux { x: &Foo, y: Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } } + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: &[u8] } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::Foo` + = note: no field of an enum variant may have a dynamically sized type + = help: change the field's type to have a statically known size +help: borrowed types always have a statically known size + | +LL | enum EnumLastFieldUnsized { Qux { x: u32, y: &Foo } } + | + +help: the `Box` type always has a statically known size and allocates its contents in the heap + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +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 + | +LL | fn needs_metasized<T: ?Sized + 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 + | +LL | needs_sized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[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 + | +LL | needs_metasized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[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 + | +LL | needs_pointeesized::<([u8], [u8])>(); + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[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 + | +LL | needs_sized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::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 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::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 + | +LL | needs_pointeesized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `main::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 + | +LL | needs_sized::<(u32, [u8])>(); + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = 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 + | +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 + | +LL | needs_sized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = 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 + | +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 + | +LL | needs_metasized::<(u32, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = 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 + | +LL | fn needs_metasized<T: ?Sized + 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 + | +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 + | +LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:11: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 + | +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 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:11: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 + | +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 + | +LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:14:32 + | +LL | fn needs_metasized<T: ?Sized + 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 + | +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 + | +LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:11: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 + | +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 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_sized` + --> $DIR/impls.rs:11: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 + | +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 + | +LL | struct StructLastFieldUnsized { x: u32, y: Foo } + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:14:32 + | +LL | fn needs_metasized<T: ?Sized + MetaSized>() { } + | ^^^^^^^^^ required by this bound in `needs_metasized` + +error: aborting due to 26 previous errors + +For more information about this error, try `rustc --explain E0277`. From fc6870deecf0cc427ece93e44d8e1bc1727b1d3b Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 23:30:16 +0000 Subject: [PATCH 03/43] aux: add `{Meta,Pointee}Sized` to minicore Add `MetaSized` and `PointeeSized` to minicore so that fewer tests fail from missing language items. --- tests/auxiliary/minicore.rs | 8 +++++++- tests/ui/traits/const-traits/auxiliary/minicore.rs | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 03aa847650823..c3ea1801804a8 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -40,8 +40,14 @@ macro_rules! impl_marker_trait { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 08d7817548d7c..0a8a4bc097b82 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -18,8 +18,15 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} + #[lang = "copy"] pub trait Copy {} From e24137631c86545f4135a1955a7bbbfb32921f71 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 23 Jan 2025 11:25:12 +0000 Subject: [PATCH 04/43] tests: `{Meta,Pointee}Sized` in non-minicore tests As before, add `MetaSized` and `PointeeSized` traits to all of the non-minicore `no_core` tests so that they don't fail for lack of language items. --- tests/assembly/rust-abi-arg-attr.rs | 10 ++- tests/assembly/s390x-vector-abi.rs | 9 ++- tests/assembly/small_data_threshold.rs | 8 ++- .../item-collection/implicit-panic-call.rs | 8 ++- tests/codegen/abi-x86-sse.rs | 8 ++- .../codegen/emscripten-catch-unwind-js-eh.rs | 8 ++- .../emscripten-catch-unwind-wasm-eh.rs | 8 ++- tests/codegen/terminating-catchpad.rs | 8 ++- tests/codegen/unwind-abis/aapcs-unwind-abi.rs | 9 ++- .../unwind-abis/fastcall-unwind-abi.rs | 9 ++- .../codegen/unwind-abis/stdcall-unwind-abi.rs | 9 ++- .../codegen/unwind-abis/sysv64-unwind-abi.rs | 9 ++- .../unwind-abis/thiscall-unwind-abi.rs | 9 ++- .../unwind-abis/vectorcall-unwind-abi.rs | 9 ++- tests/codegen/unwind-abis/win64-unwind-abi.rs | 9 ++- tests/crashes/107362.rs | 14 +++-- tests/crashes/120033.rs | 6 +- .../mir-opt/inline/inline_instruction_set.rs | 8 ++- tests/run-make/amdgpu-kd/foo.rs | 8 ++- .../atomic-lock-free/atomic_lock_free.rs | 8 ++- .../avr-rjmp-offset/avr-rjmp-offsets.rs | 10 ++- .../min-global-align/min_global_align.rs | 8 ++- tests/run-make/simd-ffi/simd.rs | 8 ++- tests/run-make/target-specs/foo.rs | 8 ++- tests/ui/amdgpu-require-explicit-cpu.rs | 10 ++- tests/ui/codegen/mismatched-data-layouts.rs | 8 ++- tests/ui/debuginfo/dwarf-versions.rs | 8 ++- .../branch-protection-missing-pac-ret.rs | 8 ++- tests/ui/lang-items/issue-83471.rs | 10 ++- tests/ui/lang-items/issue-83471.stderr | 30 +++++++-- tests/ui/lang-items/issue-87573.rs | 8 ++- tests/ui/lang-items/issue-87573.stderr | 4 +- .../lang-item-generic-requirements.rs | 8 ++- .../lang-item-generic-requirements.stderr | 18 +++--- .../missing-copy-lang-item-issue-19660.rs | 8 ++- .../missing-copy-lang-item-issue-19660.stderr | 2 +- .../start_lang_item_args.argc.stderr | 2 +- .../start_lang_item_args.argv.stderr | 2 +- ...start_lang_item_args.argv_inner_ptr.stderr | 2 +- .../start_lang_item_args.main_args.stderr | 2 +- .../start_lang_item_args.main_ret.stderr | 2 +- .../start_lang_item_args.main_ty.stderr | 2 +- ...art_lang_item_args.missing_all_args.stderr | 2 +- .../start_lang_item_args.missing_ret.stderr | 2 +- ..._lang_item_args.missing_sigpipe_arg.stderr | 2 +- tests/ui/lang-items/start_lang_item_args.rs | 6 +- .../start_lang_item_args.sigpipe.stderr | 2 +- .../start_lang_item_args.start_ret.stderr | 2 +- .../start_lang_item_args.too_many_args.stderr | 2 +- .../start_lang_item_with_target_feature.rs | 9 ++- ...start_lang_item_with_target_feature.stderr | 2 +- .../panic-handler-requires-panic-info.rs | 8 ++- tests/ui/privacy/privacy1.rs | 10 ++- tests/ui/privacy/privacy1.stderr | 62 +++++++++---------- tests/ui/privacy/privacy4.rs | 4 +- tests/ui/privacy/privacy4.stderr | 4 +- .../warn-stack-protector-unsupported.rs | 9 ++- ...owed-softfloat-target-feature-attribute.rs | 8 ++- ...d-softfloat-target-feature-flag-disable.rs | 8 ++- tests/ui/target-feature/feature-hierarchy.rs | 10 ++- ...dden-hardfloat-target-feature-attribute.rs | 8 ++- ...-hardfloat-target-feature-attribute.stderr | 2 +- .../forbidden-hardfloat-target-feature-cfg.rs | 20 ++++++ ...oat-target-feature-flag-disable-implied.rs | 8 ++- ...dfloat-target-feature-flag-disable-neon.rs | 8 ++- ...n-hardfloat-target-feature-flag-disable.rs | 8 ++- ...forbidden-hardfloat-target-feature-flag.rs | 8 ++- .../forbidden-target-feature-attribute.rs | 8 ++- .../forbidden-target-feature-attribute.stderr | 2 +- .../forbidden-target-feature-cfg.rs | 8 ++- .../forbidden-target-feature-flag-disable.rs | 8 ++- .../forbidden-target-feature-flag.rs | 8 ++- ...arget-cpu-lacks-required-target-feature.rs | 8 ++- tests/ui/target-feature/tied-features-cli.rs | 10 ++- .../tied-features-no-implication-1.rs | 10 ++- .../tied-features-no-implication.pacg.stderr | 2 +- .../tied-features-no-implication.rs | 10 ++- 77 files changed, 494 insertions(+), 136 deletions(-) create mode 100644 tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs diff --git a/tests/assembly/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs index 5b5eeb29f0f41..4f3673ccfc3b9 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -13,12 +13,16 @@ #![crate_type = "lib"] #![no_std] #![no_core] - // FIXME: Migrate these code after PR #130693 is landed. -// vvvvv core + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/assembly/s390x-vector-abi.rs b/tests/assembly/s390x-vector-abi.rs index e159a3576850e..fcf42664034c6 100644 --- a/tests/assembly/s390x-vector-abi.rs +++ b/tests/assembly/s390x-vector-abi.rs @@ -15,12 +15,17 @@ #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] - // Cases where vector feature is disabled are rejected. // See tests/ui/simd-abi-checks-s390x.rs for test for them. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs index bed515915b85d..2abe8687d8b26 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -19,8 +19,14 @@ #![no_core] #![crate_type = "lib"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "drop_in_place"] fn drop_in_place<T>(_: *mut T) {} diff --git a/tests/codegen-units/item-collection/implicit-panic-call.rs b/tests/codegen-units/item-collection/implicit-panic-call.rs index b348b4acc2486..3f368bed88e59 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -30,8 +30,14 @@ fn panic_div_overflow() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs index 837bf6134b01c..21b5eff4f489b 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -17,7 +17,13 @@ #![crate_type = "lib"] #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +trait PointeeSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/codegen/emscripten-catch-unwind-js-eh.rs b/tests/codegen/emscripten-catch-unwind-js-eh.rs index 018ad5454fc23..1bffa8a3c0f56 100644 --- a/tests/codegen/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs @@ -9,8 +9,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs index 0fc9ae96720e4..6019d6bd30a21 100644 --- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs @@ -8,8 +8,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} #[lang = "copy"] diff --git a/tests/codegen/terminating-catchpad.rs b/tests/codegen/terminating-catchpad.rs index 17d8879630094..a2ec19871d1fc 100644 --- a/tests/codegen/terminating-catchpad.rs +++ b/tests/codegen/terminating-catchpad.rs @@ -15,8 +15,14 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} unsafe extern "C-unwind" { safe fn unwinds(); diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index 0d9c7757883f7..ecace722e0dbe 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `aapcs` and // `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 4c7b2856e2e45..7df46813ed1dd 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `fastcall` and // `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index ffc11d1faef8c..cc06ee125495a 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind` // extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index c869ca7e2b825..69bfaf80b4be6 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `sysv64` and // `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index 19b23ee47ba84..05f6b8b70e171 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `thiscall` and // `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index b420f67ca9b70..d001a16b32a1c 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items, abi_vectorcall)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `vectorcall` and // `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute. diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index 2697d3cbcd68e..257f00b54e4d8 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -2,8 +2,15 @@ //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] #![feature(no_core, lang_items)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `win64` and // `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We diff --git a/tests/crashes/107362.rs b/tests/crashes/107362.rs index 8d55d611eb133..71373508e2519 100644 --- a/tests/crashes/107362.rs +++ b/tests/crashes/107362.rs @@ -1,7 +1,9 @@ //@ known-bug: #107362 //@ compile-flags: -Cdebuginfo=2 +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] // added to keep parameters unconstrained -pub trait Functor +pub trait Functor: std::marker::PointeeSized { type With<T>: Functor; } @@ -18,20 +20,20 @@ impl<T> Functor for Vec<T> { pub struct Compose<F1, F2, T>(F1::With<F2::With<T>>) where - F1: Functor + ?Sized, - F2: Functor + ?Sized; + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized; impl<F1, F2, T> Functor for Compose<F1, F2, T> where - F1: Functor + ?Sized, - F2: Functor + ?Sized + F1: Functor + std::marker::PointeeSized, + F2: Functor + std::marker::PointeeSized, { type With<T2> = F1::With<F2::With<T2>> ; } pub enum Value<F> where - F: Functor + ?Sized, + F: Functor + std::marker::PointeeSized, { SignedInt(*mut F::With<i64>), Array(*mut Value<Compose<F, Vec<()>, ()>>), diff --git a/tests/crashes/120033.rs b/tests/crashes/120033.rs index f1502978dc511..7584f98ec9060 100644 --- a/tests/crashes/120033.rs +++ b/tests/crashes/120033.rs @@ -1,8 +1,10 @@ //@ known-bug: #120033 #![feature(non_lifetime_binders)] +#![allow(sized_hierarchy_migration)] +#![feature(sized_hierarchy)] // added to keep parameters unconstrained -pub trait Foo<T: ?Sized> { - type Bar<K: ?Sized>; +pub trait Foo<T: std::marker::PointeeSized> { + type Bar<K: std::marker::PointeeSized>; } pub struct Bar<T: ?AutoTrait> {} diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index 44faf3a4ed9ad..fe2aaffa2a09c 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -22,8 +22,14 @@ macro_rules! asm { }; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/amdgpu-kd/foo.rs b/tests/run-make/amdgpu-kd/foo.rs index a0d803ab81374..a097e9211a799 100644 --- a/tests/run-make/amdgpu-kd/foo.rs +++ b/tests/run-make/amdgpu-kd/foo.rs @@ -4,8 +4,14 @@ #![no_std] // This is needed because of #![no_core]: +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[no_mangle] extern "gpu-kernel" fn kernel() {} diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index 1f1116b9bfd17..1a83a5b8072be 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -6,8 +6,14 @@ extern "rust-intrinsic" { fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T; } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} #[lang = "freeze"] diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index 2f97fc1ed95ab..3b84d8aa71cc5 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -24,14 +24,20 @@ pub fn main() -> ! { // FIXME: replace with proper minicore once available (#130693) mod minicore { + #[lang = "pointee_sized"] + pub trait PointeeSized {} + + #[lang = "meta_sized"] + pub trait MetaSized: PointeeSized {} + #[lang = "sized"] - pub trait Sized {} + pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} impl Copy for u32 {} impl Copy for &u32 {} - impl<T: ?Sized> Copy for *mut T {} + impl<T: PointeeSized> Copy for *mut T {} pub mod ptr { #[inline] diff --git a/tests/run-make/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs index cd1ef8cb351ff..fd6f83570300a 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -9,8 +9,14 @@ pub static mut STATIC_MUT_BOOL: bool = true; const CONST_BOOL: bool = true; pub static CONST_BOOL_REF: &'static bool = &CONST_BOOL; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs index 9ea8eb8cf8831..1cd961ff87e7b 100644 --- a/tests/run-make/simd-ffi/simd.rs +++ b/tests/run-make/simd-ffi/simd.rs @@ -52,8 +52,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { unsafe { integer(a, b) } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/run-make/target-specs/foo.rs b/tests/run-make/target-specs/foo.rs index 22939e87912c1..aead76dff87c2 100644 --- a/tests/run-make/target-specs/foo.rs +++ b/tests/run-make/target-specs/foo.rs @@ -4,8 +4,14 @@ #[lang = "copy"] trait Copy {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "freeze"] auto trait Freeze {} diff --git a/tests/ui/amdgpu-require-explicit-cpu.rs b/tests/ui/amdgpu-require-explicit-cpu.rs index 46778a1094fab..cf48cc191c82c 100644 --- a/tests/ui/amdgpu-require-explicit-cpu.rs +++ b/tests/ui/amdgpu-require-explicit-cpu.rs @@ -11,7 +11,13 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 955f917ee3328..cf760c37d109a 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -10,5 +10,11 @@ #![feature(lang_items, no_core, auto_traits)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/debuginfo/dwarf-versions.rs b/tests/ui/debuginfo/dwarf-versions.rs index 806ade51a997f..e9831ff2c2ad9 100644 --- a/tests/ui/debuginfo/dwarf-versions.rs +++ b/tests/ui/debuginfo/dwarf-versions.rs @@ -32,7 +32,13 @@ #![no_core] #![no_std] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs index b4025080034ab..403395906248c 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs @@ -13,5 +13,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/lang-items/issue-83471.rs b/tests/ui/lang-items/issue-83471.rs index 6be345ac50765..f3ce9f25c1360 100644 --- a/tests/ui/lang-items/issue-83471.rs +++ b/tests/ui/lang-items/issue-83471.rs @@ -4,9 +4,17 @@ #![feature(no_core)] #![no_core] +#[lang = "pointee_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +//~^ ERROR: lang items are subject to change [E0658] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] //~^ ERROR: lang items are subject to change [E0658] -trait Sized {} +trait Sized: MetaSized {} #[lang = "fn"] //~^ ERROR: lang items are subject to change [E0658] diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 244b2efeaf1e0..e913c0bf10fd0 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found built-in attribute `export_name` - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ not a type @@ -7,6 +7,24 @@ LL | fn call(export_name); error[E0658]: lang items are subject to change --> $DIR/issue-83471.rs:7:1 | +LL | #[lang = "pointee_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` 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]: lang items are subject to change + --> $DIR/issue-83471.rs:11:1 + | +LL | #[lang = "meta_sized"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(lang_items)]` 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]: lang items are subject to change + --> $DIR/issue-83471.rs:15:1 + | LL | #[lang = "sized"] | ^^^^^^^^^^^^^^^^^ | @@ -14,7 +32,7 @@ LL | #[lang = "sized"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: lang items are subject to change - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -23,7 +41,7 @@ LL | #[lang = "fn"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: anonymous parameters are deprecated and will be removed in the next edition - --> $DIR/issue-83471.rs:15:13 + --> $DIR/issue-83471.rs:23:13 | LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` @@ -33,7 +51,7 @@ LL | fn call(export_name); = note: `#[warn(anonymous_parameters)]` on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument - --> $DIR/issue-83471.rs:11:1 + --> $DIR/issue-83471.rs:19:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -42,12 +60,12 @@ LL | trait Fn { | - this trait has 0 generic arguments error[E0425]: cannot find function `a` in this scope - --> $DIR/issue-83471.rs:21:5 + --> $DIR/issue-83471.rs:29:5 | LL | a() | ^ not found in this scope -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted Some errors have detailed explanations: E0425, E0573, E0658, E0718. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/lang-items/issue-87573.rs b/tests/ui/lang-items/issue-87573.rs index 7b805e8b0cdb6..97146df0ba766 100644 --- a/tests/ui/lang-items/issue-87573.rs +++ b/tests/ui/lang-items/issue-87573.rs @@ -7,8 +7,14 @@ pub static STATIC_BOOL: bool = true; +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/ui/lang-items/issue-87573.stderr b/tests/ui/lang-items/issue-87573.stderr index 7085bb8c339d4..07f4f5d8ac86f 100644 --- a/tests/ui/lang-items/issue-87573.stderr +++ b/tests/ui/lang-items/issue-87573.stderr @@ -1,5 +1,5 @@ error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/issue-87573.rs:20:1 + --> $DIR/issue-87573.rs:26:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn drop_fn() { | - this function has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/issue-87573.rs:26:1 + --> $DIR/issue-87573.rs:32:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index 0f982df61e8e7..e127f4baaa49c 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -4,8 +4,14 @@ #![feature(lang_items, no_core)] #![no_core] +#[lang = "pointee_sized"] +pub trait MyPointeeSized {} + +#[lang = "meta_sized"] +pub trait MyMetaSized: MyPointeeSized {} + #[lang = "sized"] -trait MySized {} +trait MySized: MyMetaSized {} #[lang = "add"] trait MyAdd<'a, T> {} diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index 3de67d6594035..aa67a9ca92143 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -1,5 +1,5 @@ error[E0718]: `add` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:10:1 + --> $DIR/lang-item-generic-requirements.rs:16:1 | LL | #[lang = "add"] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | trait MyAdd<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:14:1 + --> $DIR/lang-item-generic-requirements.rs:20:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | fn my_ptr_drop() {} | - this function has 0 generic arguments error[E0718]: `index` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:18:1 + --> $DIR/lang-item-generic-requirements.rs:24:1 | LL | #[lang = "index"] | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | trait MyIndex<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `phantom_data` lang item must be applied to a struct with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:22:1 + --> $DIR/lang-item-generic-requirements.rs:28:1 | LL | #[lang = "phantom_data"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` lang item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:28:1 + --> $DIR/lang-item-generic-requirements.rs:34:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:34:1 + --> $DIR/lang-item-generic-requirements.rs:40:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments error[E0392]: type parameter `T` is never used - --> $DIR/lang-item-generic-requirements.rs:24:22 + --> $DIR/lang-item-generic-requirements.rs:30:22 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -60,7 +60,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0392]: type parameter `U` is never used - --> $DIR/lang-item-generic-requirements.rs:24:25 + --> $DIR/lang-item-generic-requirements.rs:30:25 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -69,7 +69,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead error[E0369]: cannot add `{integer}` to `{integer}` - --> $DIR/lang-item-generic-requirements.rs:44:7 + --> $DIR/lang-item-generic-requirements.rs:50:7 | LL | r + a; | - ^ - {integer} diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs index 9b634ee8ee3e4..6e17023d4f96f 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs @@ -4,8 +4,14 @@ #![no_core] #![no_main] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized { } +trait Sized: MetaSized { } struct S; diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr index 3dc7716ecd2a6..79d912d5a8da5 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr @@ -1,5 +1,5 @@ error: requires `copy` lang_item - --> $DIR/missing-copy-lang-item-issue-19660.rs:14:5 + --> $DIR/missing-copy-lang-item-issue-19660.rs:20:5 | LL | argc | ^^^^ diff --git a/tests/ui/lang-items/start_lang_item_args.argc.stderr b/tests/ui/lang-items/start_lang_item_args.argc.stderr index cd7361255eb91..82fd374a1c5b1 100644 --- a/tests/ui/lang-items/start_lang_item_args.argc.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argc.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:75:38 + --> $DIR/start_lang_item_args.rs:79:38 | LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^ expected `isize`, found `i8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv.stderr b/tests/ui/lang-items/start_lang_item_args.argv.stderr index 1a5905ab8e602..6095f8fa53299 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:89:52 + --> $DIR/start_lang_item_args.rs:93:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize { | ^^ expected `*const *const u8`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr index c61ace3cd628e..2a295c8990b38 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:82:52 + --> $DIR/start_lang_item_args.rs:86:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^ expected `u8`, found `usize` diff --git a/tests/ui/lang-items/start_lang_item_args.main_args.stderr b/tests/ui/lang-items/start_lang_item_args.main_args.stderr index ef943d6b3dba1..027fd16d41040 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:61:1 + --> $DIR/start_lang_item_args.rs:65:1 | LL | fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr index 00395a05d33f7..0f295d350d1b9 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:68:20 + --> $DIR/start_lang_item_args.rs:72:20 | LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | - ^^^^^^^^^^^ expected type parameter `T`, found `u16` diff --git a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr index 193f25bab05b1..6e462c8b1a7c8 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:54:20 + --> $DIR/start_lang_item_args.rs:58:20 | LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^ expected fn pointer, found `u64` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr index 56b787d2ae38f..90fa5e0d575f1 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:15:1 + --> $DIR/start_lang_item_args.rs:19:1 | LL | fn start<T>() -> isize { | ^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr index 2672efe51c9aa..879917cc80067 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:29:83 + --> $DIR/start_lang_item_args.rs:33:83 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} | ^ expected `isize`, found `()` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr index 98814dcd24a7c..d756909d73542 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:22:1 + --> $DIR/start_lang_item_args.rs:26:1 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.rs b/tests/ui/lang-items/start_lang_item_args.rs index 5bb99e2adc88f..1da761545a8ff 100644 --- a/tests/ui/lang-items/start_lang_item_args.rs +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -8,7 +8,11 @@ #[lang = "copy"] pub trait Copy {} #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[cfg(missing_all_args)] #[lang = "start"] diff --git a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr index e0a8496dba99b..ba1dd4b4f793b 100644 --- a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr +++ b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:96:80 + --> $DIR/start_lang_item_args.rs:100:80 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize { | ^^^ expected `u8`, found `i64` diff --git a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr index 4437b0fdcfb18..a11867997d393 100644 --- a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:34:87 + --> $DIR/start_lang_item_args.rs:38:87 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 { | ^^ expected `isize`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr index 8570d96fc6219..ecccf8c74bc3d 100644 --- a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:41:1 + --> $DIR/start_lang_item_args.rs:45:1 | LL | / fn start<T>( LL | | diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.rs b/tests/ui/lang-items/start_lang_item_with_target_feature.rs index 18cd4c9704056..19036819d3d80 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.rs +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.rs @@ -6,8 +6,15 @@ #[lang = "copy"] pub trait Copy {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[lang = "start"] #[target_feature(enable = "avx2")] diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr index 6214e3f8bc79a..ce0b1d7557445 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr @@ -1,5 +1,5 @@ error: `start` lang item function is not allowed to have `#[target_feature]` - --> $DIR/start_lang_item_with_target_feature.rs:13:1 + --> $DIR/start_lang_item_with_target_feature.rs:20:1 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs index 0b8308ba753aa..618ac7d88ddf2 100644 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -11,5 +11,11 @@ fn panic() -> ! { loop {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 9436441ecc6a7..8ec2befcd0b34 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -1,8 +1,14 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang="sized"] -pub trait Sized {} +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index cb7b858e54dc8..2cbdbb3ff9513 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -1,54 +1,54 @@ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:132:18 + --> $DIR/privacy1.rs:138:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:141:18 + --> $DIR/privacy1.rs:147:18 | LL | use bar::baz; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:165:20 + --> $DIR/privacy1.rs:171:20 | LL | use self::foo::i::A; | ^ private module | note: the module `i` is defined here - --> $DIR/privacy1.rs:170:9 + --> $DIR/privacy1.rs:176:9 | LL | mod i { | ^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:104:16 + --> $DIR/privacy1.rs:110:16 | LL | ::bar::baz::A::foo(); | ^^^ - struct `A` is not publicly re-exported @@ -56,13 +56,13 @@ LL | ::bar::baz::A::foo(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:105:16 + --> $DIR/privacy1.rs:111:16 | LL | ::bar::baz::A::bar(); | ^^^ - struct `A` is not publicly re-exported @@ -70,13 +70,13 @@ LL | ::bar::baz::A::bar(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:107:16 + --> $DIR/privacy1.rs:113:16 | LL | ::bar::baz::A.foo2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -84,13 +84,13 @@ LL | ::bar::baz::A.foo2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:108:16 + --> $DIR/privacy1.rs:114:16 | LL | ::bar::baz::A.bar2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -98,13 +98,13 @@ LL | ::bar::baz::A.bar2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:112:16 + --> $DIR/privacy1.rs:118:16 | LL | ::bar::B::foo(); | ^ --- associated function `foo` is not publicly re-exported @@ -112,31 +112,31 @@ LL | ::bar::B::foo(); | private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:40:5 + --> $DIR/privacy1.rs:46:5 | LL | trait B { | ^^^^^^^ error[E0603]: function `epriv` is private - --> $DIR/privacy1.rs:118:20 + --> $DIR/privacy1.rs:124:20 | LL | ::bar::epriv(); | ^^^^^ private function | note: the function `epriv` is defined here - --> $DIR/privacy1.rs:65:9 + --> $DIR/privacy1.rs:71:9 | LL | fn epriv(); | ^^^^^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:127:16 + --> $DIR/privacy1.rs:133:16 | LL | ::bar::baz::foo(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -147,13 +147,13 @@ LL + bar::foo(); | error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:128:16 + --> $DIR/privacy1.rs:134:16 | LL | ::bar::baz::bar(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:50:5 + --> $DIR/privacy1.rs:56:5 | LL | mod baz { | ^^^^^^^ @@ -164,19 +164,19 @@ LL + bar::bar(); | error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:157:17 + --> $DIR/privacy1.rs:163:17 | LL | impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } | ^ private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:40:5 + --> $DIR/privacy1.rs:46:5 | LL | trait B { | ^^^^^^^ error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:77:23 + --> $DIR/privacy1.rs:83:23 | LL | fn bar() {} | -------- private associated function defined here @@ -185,7 +185,7 @@ LL | self::baz::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:95:13 + --> $DIR/privacy1.rs:101:13 | LL | fn bar() {} | -------- private associated function defined here @@ -194,7 +194,7 @@ LL | bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:102:19 + --> $DIR/privacy1.rs:108:19 | LL | fn bar() {} | -------- private associated function defined here @@ -203,7 +203,7 @@ LL | ::bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:105:24 + --> $DIR/privacy1.rs:111:24 | LL | fn bar() {} | -------- private associated function defined here @@ -212,7 +212,7 @@ LL | ::bar::baz::A::bar(); | ^^^ private associated function error[E0624]: method `bar2` is private - --> $DIR/privacy1.rs:108:23 + --> $DIR/privacy1.rs:114:23 | LL | fn bar2(&self) {} | -------------- private method defined here diff --git a/tests/ui/privacy/privacy4.rs b/tests/ui/privacy/privacy4.rs index 7341c7752bbf7..6091613271fdf 100644 --- a/tests/ui/privacy/privacy4.rs +++ b/tests/ui/privacy/privacy4.rs @@ -1,7 +1,9 @@ #![feature(lang_items, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized {} +#[lang = "sized"] pub trait Sized: MetaSized {} +#[lang = "meta_sized"] pub trait MetaSized: PointeeSized {} +#[lang = "pointee_sized"] pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} // Test to make sure that private items imported through globs remain private diff --git a/tests/ui/privacy/privacy4.stderr b/tests/ui/privacy/privacy4.stderr index 4aa3ae964c0ca..eeefd85645c7d 100644 --- a/tests/ui/privacy/privacy4.stderr +++ b/tests/ui/privacy/privacy4.stderr @@ -1,11 +1,11 @@ error[E0603]: module `glob` is private - --> $DIR/privacy4.rs:21:14 + --> $DIR/privacy4.rs:23:14 | LL | use bar::glob::gpriv; | ^^^^ private module | note: the module `glob` is defined here - --> $DIR/privacy4.rs:13:5 + --> $DIR/privacy4.rs:15:5 | LL | mod glob { | ^^^^^^^^ diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index 9205d4052ad48..5dc8968557b0f 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -11,8 +11,15 @@ #![no_std] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs index 8b60820cc9b68..0c90c573c5046 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items, x87_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "x87")] pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs index e34faf5a983c3..c53610c190518 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs @@ -5,5 +5,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 315ec983a19a5..ccf32a35f72e7 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -12,10 +12,18 @@ // Tests vetting "feature hierarchies" in the cases where we impose them. // Supporting minimal rust core code +#[lang = "pointee_sized"] +trait PointeeSized {} + +#[lang = "meta_sized"] +trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +trait Sized: MetaSized {} + #[lang = "copy"] trait Copy {} + impl Copy for bool {} #[stable(feature = "test", since = "1.0.0")] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs index 215e64979f736..e96e17a42121a 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "d")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr index bfe767e5ffb07..d9a57412195d1 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:10:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:16:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs new file mode 100644 index 0000000000000..2692cf802f2d4 --- /dev/null +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-cfg.rs @@ -0,0 +1,20 @@ +//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib +//@ needs-llvm-components: x86 +//@ check-pass +#![feature(no_core, lang_items)] +#![no_core] +#![allow(unexpected_cfgs)] + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this +// complains about the missing macro rather than showing the error... but that's good enough. +#[cfg(not(target_feature = "x87"))] +compile_error!("the x87 feature *should* be exposed in `cfg`"); diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs index 81f138b175f29..f1891d0c21268 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs @@ -9,5 +9,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs index 7242bcc85bfd1..4514c84df8f19 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs @@ -7,5 +7,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs index 7eebcf05dc0f4..00cf249524d9a 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs @@ -8,5 +8,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs index f277a309cd698..c7e7d1d0f131a 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag.rs @@ -8,5 +8,11 @@ #![feature(no_core, lang_items, riscv_target_feature)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index 6bb6f8aaffb6f..a59747ec80ffd 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -4,8 +4,14 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} #[target_feature(enable = "forced-atomics")] //~^ERROR: cannot be enabled with diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr index f8ea0c0e793fb..65814e8edcf61 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `forced-atomics` cannot be enabled with `#[target_feature]`: unsound because it changes the ABI of atomic operations - --> $DIR/forbidden-target-feature-attribute.rs:10:18 + --> $DIR/forbidden-target-feature-attribute.rs:16:18 | LL | #[target_feature(enable = "forced-atomics")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs index e848ffde018e2..c21eb63257a0f 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -6,8 +6,14 @@ #![no_core] #![allow(unexpected_cfgs)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} // The compile_error macro does not exist, so if the `cfg` evaluates to `true` this // complains about the missing macro rather than showing the error... but that's good enough. diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs index cf85c5212289c..b900e181ec89f 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -8,5 +8,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index 245841eb0395c..ed6438ad65c9b 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -8,5 +8,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs index 28d026c1a9a2d..5461747829e98 100644 --- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs +++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs @@ -8,5 +8,11 @@ #![feature(no_core, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index 17c13826ce9e6..f45bcae550430 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -14,7 +14,13 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} fn main() {} diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 0473ca319b8f0..35c884f8b19ea 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -8,8 +8,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // In this test, demonstrate that +paca and +pacg both result in the tied feature error if there // isn't something causing an error. diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr index 0e31dea24ea4d..47872eb874aac 100644 --- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr +++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `foo` is defined multiple times - --> $DIR/tied-features-no-implication.rs:28:1 + --> $DIR/tied-features-no-implication.rs:34:1 | LL | fn foo() {} | -------- previous definition of the value `foo` here diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index 157b50bb0d329..b7abc262c8a82 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -8,8 +8,14 @@ #![feature(no_core, lang_items)] #![no_core] -#[lang="sized"] -trait Sized {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} // Can't use `compile_error!` here without `core`/`std` but requiring these makes this test only // work if you have libcore built in the sysroot for `aarch64-unknown-linux-gnu`. Can't run this From d324866aa1d05d3821b18fdc2a925e54dc554410 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 10 Feb 2025 14:18:20 +0000 Subject: [PATCH 05/43] library/compiler: add `PointeeSized` bounds As core uses an extern type (`ptr::VTable`), the default `?Sized` to `MetaSized` migration isn't sufficient, and some code that previously accepted `VTable` needs relaxed to continue to accept extern types. Similarly, the compiler uses many extern types in `rustc_codegen_llvm` and in the `rustc_middle::ty::List` implementation (`OpaqueListContents`) some bounds must be relaxed to continue to accept these types. Unfortunately, due to the current inability to relax `Deref::Target`, some of the bounds in the standard library are forced to be stricter than they ideally would be. --- compiler/rustc_data_structures/src/aligned.rs | 3 +- compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_data_structures/src/marker.rs | 29 ++++---- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/codec.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 10 +-- compiler/rustc_serialize/src/lib.rs | 1 + compiler/rustc_serialize/src/serialize.rs | 6 +- compiler/rustc_smir/src/lib.rs | 1 + compiler/rustc_smir/src/rustc_smir/mod.rs | 3 +- library/core/src/clone.rs | 16 +++-- library/core/src/cmp.rs | 64 +++++++++++++---- library/core/src/convert/mod.rs | 11 +-- library/core/src/fmt/mod.rs | 36 +++++----- library/core/src/hash/mod.rs | 10 +-- library/core/src/intrinsics/mod.rs | 10 +-- library/core/src/marker.rs | 60 ++++++++-------- library/core/src/ops/deref.rs | 17 +++-- library/core/src/ops/unsize.rs | 69 +++++++++++++++---- library/core/src/ptr/const_ptr.rs | 12 ++-- library/core/src/ptr/metadata.rs | 38 +++++----- library/core/src/ptr/mod.rs | 21 +++--- library/core/src/ptr/mut_ptr.rs | 13 ++-- library/core/src/ptr/non_null.rs | 46 +++++++------ library/core/src/ptr/unique.rs | 34 +++++---- library/core/src/tuple.rs | 10 +-- 26 files changed, 316 insertions(+), 210 deletions(-) diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs index a636d09fcae23..bfc7556faf68c 100644 --- a/compiler/rustc_data_structures/src/aligned.rs +++ b/compiler/rustc_data_structures/src/aligned.rs @@ -1,3 +1,4 @@ +use std::marker::PointeeSized; use std::ptr::Alignment; /// Returns the ABI-required minimum alignment of a type in bytes. @@ -17,7 +18,7 @@ pub const fn align_of<T: ?Sized + Aligned>() -> Alignment { /// example `[T]` has alignment of `T`. /// /// [`align_of::<Self>()`]: align_of -pub unsafe trait Aligned { +pub unsafe trait Aligned: PointeeSized { /// Alignment of `Self`. const ALIGN: Alignment; } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 865424fd6bbdc..6ca9f78e1a14b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -32,6 +32,7 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] #![feature(test)] #![feature(thread_id_value)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 64c64bfa3c296..6702173e19de1 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -1,4 +1,5 @@ use std::alloc::Allocator; +use std::marker::PointeeSized; #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \ Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")] @@ -15,7 +16,7 @@ pub unsafe auto trait DynSend {} pub unsafe auto trait DynSync {} // Same with `Sync` and `Send`. -unsafe impl<T: DynSync + ?Sized> DynSend for &T {} +unsafe impl<T: DynSync + ?Sized + PointeeSized> DynSend for &T {} macro_rules! impls_dyn_send_neg { ($([$t1: ty $(where $($generics1: tt)*)?])*) => { @@ -27,9 +28,9 @@ macro_rules! impls_dyn_send_neg { impls_dyn_send_neg!( [std::env::Args] [std::env::ArgsOs] - [*const T where T: ?Sized] - [*mut T where T: ?Sized] - [std::ptr::NonNull<T> where T: ?Sized] + [*const T where T: ?Sized + PointeeSized] + [*mut T where T: ?Sized + PointeeSized] + [std::ptr::NonNull<T> where T: ?Sized + PointeeSized] [std::rc::Rc<T, A> where T: ?Sized, A: Allocator] [std::rc::Weak<T, A> where T: ?Sized, A: Allocator] [std::sync::MutexGuard<'_, T> where T: ?Sized] @@ -93,12 +94,12 @@ macro_rules! impls_dyn_sync_neg { impls_dyn_sync_neg!( [std::env::Args] [std::env::ArgsOs] - [*const T where T: ?Sized] - [*mut T where T: ?Sized] + [*const T where T: ?Sized + PointeeSized] + [*mut T where T: ?Sized + PointeeSized] [std::cell::Cell<T> where T: ?Sized] [std::cell::RefCell<T> where T: ?Sized] [std::cell::UnsafeCell<T> where T: ?Sized] - [std::ptr::NonNull<T> where T: ?Sized] + [std::ptr::NonNull<T> where T: ?Sized + PointeeSized] [std::rc::Rc<T, A> where T: ?Sized, A: Allocator] [std::rc::Weak<T, A> where T: ?Sized, A: Allocator] [std::cell::OnceCell<T> where T] @@ -161,10 +162,10 @@ impl_dyn_sync!( [thin_vec::ThinVec<T> where T: DynSync] ); -pub fn assert_dyn_sync<T: ?Sized + DynSync>() {} -pub fn assert_dyn_send<T: ?Sized + DynSend>() {} -pub fn assert_dyn_send_val<T: ?Sized + DynSend>(_t: &T) {} -pub fn assert_dyn_send_sync_val<T: ?Sized + DynSync + DynSend>(_t: &T) {} +pub fn assert_dyn_sync<T: ?Sized + PointeeSized + DynSync>() {} +pub fn assert_dyn_send<T: ?Sized + PointeeSized + DynSend>() {} +pub fn assert_dyn_send_val<T: ?Sized + PointeeSized + DynSend>(_t: &T) {} +pub fn assert_dyn_send_sync_val<T: ?Sized + PointeeSized + DynSync + DynSend>(_t: &T) {} #[derive(Copy, Clone)] pub struct FromDyn<T>(T); @@ -204,10 +205,10 @@ impl<T> std::ops::Deref for FromDyn<T> { // an instance of `DynSend` and `DynSync`, since the compiler cannot infer // it automatically in some cases. (e.g. Box<dyn Send / Sync>) #[derive(Copy, Clone)] -pub struct IntoDynSyncSend<T: ?Sized>(pub T); +pub struct IntoDynSyncSend<T: ?Sized + PointeeSized>(pub T); -unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {} -unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {} +unsafe impl<T: ?Sized + PointeeSized + Send> DynSend for IntoDynSyncSend<T> {} +unsafe impl<T: ?Sized + PointeeSized + Sync> DynSync for IntoDynSyncSend<T> {} impl<T> std::ops::Deref for IntoDynSyncSend<T> { type Target = T; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 1e6178144c921..a15d7b83f287f 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -56,6 +56,7 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] #![feature(trusted_len)] #![feature(try_blocks)] #![feature(try_trait_v2)] diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 74b34afe616b9..e2c54eb949f22 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -8,7 +8,7 @@ use std::hash::Hash; use std::intrinsics; -use std::marker::DiscriminantKind; +use std::marker::{DiscriminantKind, PointeeSized}; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashMap; @@ -96,7 +96,7 @@ impl<'tcx, E: TyEncoder<'tcx>> EncodableWithShorthand<'tcx, E> for ty::Predicate /// /// `Decodable` can still be implemented in cases where `Decodable` is required /// by a trait bound. -pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> { +pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>>: PointeeSized { fn decode(d: &mut D) -> &'tcx Self; } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 33095258a74b4..af5f84f3e9c98 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -8,7 +8,7 @@ use std::assert_matches::{assert_matches, debug_assert_matches}; use std::borrow::Borrow; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; +use std::marker::{PhantomData, PointeeSized}; use std::ops::{Bound, Deref}; use std::sync::{Arc, OnceLock}; use std::{fmt, iter, mem}; @@ -2425,17 +2425,17 @@ impl<'tcx> TyCtxt<'tcx> { // this type just holds a pointer to it, but it still effectively owns it. It // impls `Borrow` so that it can be looked up using the original // (non-arena-memory-owning) types. -struct InternedInSet<'tcx, T: ?Sized>(&'tcx T); +struct InternedInSet<'tcx, T: ?Sized + PointeeSized>(&'tcx T); -impl<'tcx, T: 'tcx + ?Sized> Clone for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Clone for InternedInSet<'tcx, T> { fn clone(&self) -> Self { InternedInSet(self.0) } } -impl<'tcx, T: 'tcx + ?Sized> Copy for InternedInSet<'tcx, T> {} +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> Copy for InternedInSet<'tcx, T> {} -impl<'tcx, T: 'tcx + ?Sized> IntoPointer for InternedInSet<'tcx, T> { +impl<'tcx, T: 'tcx + ?Sized + PointeeSized> IntoPointer for InternedInSet<'tcx, T> { fn into_pointer(&self) -> *const () { self.0 as *const _ as *const () } diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 34be35e36aceb..806d880b19c5a 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -14,6 +14,7 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] // tidy-alphabetical-end // Allows macros to refer to this crate as `::rustc_serialize`. diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 1eefd76f92b49..f4f59993f5112 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque}; use std::hash::{BuildHasher, Hash}; -use std::marker::PhantomData; +use std::marker::{PhantomData, PointeeSized}; use std::num::NonZero; use std::path; use std::rc::Rc; @@ -142,7 +142,7 @@ pub trait Decoder { /// `rustc_metadata::rmeta::Lazy`. /// * `TyEncodable` should be used for types that are only serialized in crate /// metadata or the incremental cache. This is most types in `rustc_middle`. -pub trait Encodable<S: Encoder> { +pub trait Encodable<S: Encoder>: PointeeSized { fn encode(&self, s: &mut S); } @@ -198,7 +198,7 @@ direct_serialize_impls! { char emit_char read_char } -impl<S: Encoder, T: ?Sized> Encodable<S> for &T +impl<S: Encoder, T: ?Sized + PointeeSized> Encodable<S> for &T where T: Encodable<S>, { diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index eaba14bbf30f5..ec9602aa1d501 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -16,6 +16,7 @@ )] #![doc(rust_logo)] #![feature(rustdoc_internals)] +#![feature(sized_hierarchy)] // tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index c5d33f090a05b..68ca925905a7e 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,6 +7,7 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. +use std::marker::PointeeSized; use std::ops::RangeInclusive; use rustc_hir::def::DefKind; @@ -157,7 +158,7 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { } /// Trait used to convert between an internal MIR type to a Stable MIR type. -pub trait Stable<'cx> { +pub trait Stable<'cx>: PointeeSized { /// The stable representation of the type implementing Stable. type T; /// Converts an object to the equivalent Stable MIR representation. diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index e0ac0bfc5289f..27fa9d05f0f0e 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,6 +36,8 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::marker::PointeeSized; + mod uninit; /// A common trait for the ability to explicitly duplicate an object. @@ -248,7 +250,7 @@ impl_use_cloned! { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsClone<T: Clone + ?Sized> { +pub struct AssertParamIsClone<T: Clone + ?Sized + PointeeSized> { _field: crate::marker::PhantomData<T>, } #[doc(hidden)] @@ -258,7 +260,7 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { reason = "deriving hack, should not be public", issue = "none" )] -pub struct AssertParamIsCopy<T: Copy + ?Sized> { +pub struct AssertParamIsCopy<T: Copy + ?Sized + PointeeSized> { _field: crate::marker::PhantomData<T>, } @@ -495,6 +497,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr { /// are implemented in `traits::SelectionContext::copy_clone_conditions()` /// in `rustc_trait_selection`. mod impls { + use crate::marker::PointeeSized; + macro_rules! impl_clone { ($($t:ty)*) => { $( @@ -525,7 +529,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for *const T { + impl<T: ?Sized + PointeeSized> Clone for *const T { #[inline(always)] fn clone(&self) -> Self { *self @@ -533,7 +537,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for *mut T { + impl<T: ?Sized + PointeeSized> Clone for *mut T { #[inline(always)] fn clone(&self) -> Self { *self @@ -542,7 +546,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Clone for &T { + impl<T: ?Sized + PointeeSized> Clone for &T { #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { @@ -552,5 +556,5 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> !Clone for &mut T {} + impl<T: ?Sized + PointeeSized> !Clone for &mut T {} } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 0b0dbf723b658..7328b73ab25a1 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,6 +29,7 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; use self::Ordering::*; +use crate::marker::PointeeSized; use crate::ops::ControlFlow; /// Trait for comparisons using the equality operator. @@ -246,6 +247,37 @@ use crate::ops::ControlFlow; append_const_msg )] #[rustc_diagnostic_item = "PartialEq"] +#[cfg(not(bootstrap))] // FIXME(sized_hierarchy): needs bootstrap updated +pub trait PartialEq<Rhs: ?Sized + PointeeSized = Self>: PointeeSized { + /// Tests for `self` and `other` values to be equal, and is used by `==`. + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "cmp_partialeq_eq"] + fn eq(&self, other: &Rhs) -> bool; + + /// Tests for `!=`. The default implementation is almost always sufficient, + /// and should not be overridden without very good reason. + #[inline] + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "cmp_partialeq_ne"] + fn ne(&self, other: &Rhs) -> bool { + !self.eq(other) + } +} + +#[allow(missing_docs)] +#[lang = "eq"] +#[stable(feature = "rust1", since = "1.0.0")] +#[doc(alias = "==")] +#[doc(alias = "!=")] +#[rustc_on_unimplemented( + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} == {Rhs}`", + append_const_msg +)] +#[rustc_diagnostic_item = "PartialEq"] +#[cfg(bootstrap)] // FIXME(sized_hierarchy): needs bootstrap updated pub trait PartialEq<Rhs: ?Sized = Self> { /// Tests for `self` and `other` values to be equal, and is used by `==`. #[must_use] @@ -332,7 +364,7 @@ pub macro PartialEq($item:item) { #[doc(alias = "!=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Eq"] -pub trait Eq: PartialEq<Self> { +pub trait Eq: PartialEq<Self> + PointeeSized { // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a // type implements `Eq` itself. The current deriving infrastructure means doing this assertion // without using a method on this trait is nearly impossible. @@ -361,7 +393,7 @@ pub macro Eq($item:item) { #[doc(hidden)] #[allow(missing_debug_implementations)] #[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")] -pub struct AssertParamIsEq<T: Eq + ?Sized> { +pub struct AssertParamIsEq<T: Eq + ?Sized + PointeeSized> { _field: crate::marker::PhantomData<T>, } @@ -954,7 +986,7 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -pub trait Ord: Eq + PartialOrd<Self> { +pub trait Ord: Eq + PartialOrd<Self> + PointeeSized { /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression @@ -1337,7 +1369,8 @@ pub macro Ord($item:item) { append_const_msg )] #[rustc_diagnostic_item = "PartialOrd"] -pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { +#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +pub trait PartialOrd<Rhs: ?Sized + PointeeSized = Self>: PartialEq<Rhs> + PointeeSized { /// This method returns an ordering between `self` and `other` values if one exists. /// /// # Examples @@ -1481,7 +1514,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { } } -fn default_chaining_impl<T: ?Sized, U: ?Sized>( +fn default_chaining_impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized>( lhs: &T, rhs: &U, p: impl FnOnce(Ordering) -> bool, @@ -1803,6 +1836,7 @@ where mod impls { use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::hint::unreachable_unchecked; + use crate::marker::PointeeSized; use crate::ops::ControlFlow::{self, Break, Continue}; macro_rules! partial_eq_impl { @@ -2019,7 +2053,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialEq<&B> for &A where A: PartialEq<B>, { @@ -2033,7 +2067,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialOrd<&B> for &A where A: PartialOrd<B>, { @@ -2059,7 +2093,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Ord for &A + impl<A: ?Sized + PointeeSized> Ord for &A where A: Ord, { @@ -2069,12 +2103,12 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Eq for &A where A: Eq {} + impl<A: ?Sized + PointeeSized> Eq for &A where A: Eq {} // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialEq<&mut B> for &mut A where A: PartialEq<B>, { @@ -2088,7 +2122,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialOrd<&mut B> for &mut A where A: PartialOrd<B>, { @@ -2114,7 +2148,7 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Ord for &mut A + impl<A: ?Sized + PointeeSized> Ord for &mut A where A: Ord, { @@ -2124,10 +2158,10 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized> Eq for &mut A where A: Eq {} + impl<A: ?Sized + PointeeSized> Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialEq<&mut B> for &A where A: PartialEq<B>, { @@ -2142,7 +2176,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A + impl<A: ?Sized + PointeeSized, B: ?Sized + PointeeSized> PartialEq<&B> for &mut A where A: PartialEq<B>, { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index e1b10e1074d27..ca823a31e89c4 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -38,6 +38,7 @@ use crate::error::Error; use crate::fmt; use crate::hash::{Hash, Hasher}; +use crate::marker::PointeeSized; mod num; @@ -215,7 +216,7 @@ pub const fn identity<T>(x: T) -> T { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AsRef"] -pub trait AsRef<T: ?Sized> { +pub trait AsRef<T: ?Sized + PointeeSized>: PointeeSized { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_ref(&self) -> &T; @@ -366,7 +367,7 @@ pub trait AsRef<T: ?Sized> { /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "AsMut"] -pub trait AsMut<T: ?Sized> { +pub trait AsMut<T: ?Sized + PointeeSized>: PointeeSized { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] fn as_mut(&mut self) -> &mut T; @@ -695,7 +696,7 @@ pub trait TryFrom<T>: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsRef<U> for &T +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> AsRef<U> for &T where T: AsRef<U>, { @@ -707,7 +708,7 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> AsRef<U> for &mut T where T: AsRef<U>, { @@ -727,7 +728,7 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> AsMut<U> for &mut T where T: AsMut<U>, { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 30fd2d7815f51..64baa591bdcb0 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -4,7 +4,7 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell}; use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; -use crate::marker::PhantomData; +use crate::marker::{PhantomData, PointeeSized}; use crate::num::fmt as numfmt; use crate::ops::Deref; use crate::{iter, mem, result, str}; @@ -898,7 +898,7 @@ impl Display for Arguments<'_> { #[doc(alias = "{:?}")] #[rustc_diagnostic_item = "Debug"] #[rustc_trivial_field_reads] -pub trait Debug { +pub trait Debug: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples @@ -1015,7 +1015,7 @@ pub use macros::Debug; #[doc(alias = "{}")] #[rustc_diagnostic_item = "Display"] #[stable(feature = "rust1", since = "1.0.0")] -pub trait Display { +pub trait Display: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples @@ -1091,7 +1091,7 @@ pub trait Display { /// assert_eq!(format!("l as octal is: {l:#06o}"), "l as octal is: 0o0011"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait Octal { +pub trait Octal: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1150,7 +1150,7 @@ pub trait Octal { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait Binary { +pub trait Binary: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1205,7 +1205,7 @@ pub trait Binary { /// assert_eq!(format!("l as hex is: {l:#010x}"), "l as hex is: 0x00000009"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait LowerHex { +pub trait LowerHex: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1260,7 +1260,7 @@ pub trait LowerHex { /// assert_eq!(format!("l as hex is: {l:#010X}"), "l as hex is: 0x7FFFFFFF"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait UpperHex { +pub trait UpperHex: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1319,7 +1319,7 @@ pub trait UpperHex { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Pointer"] -pub trait Pointer { +pub trait Pointer: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1370,7 +1370,7 @@ pub trait Pointer { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait LowerExp { +pub trait LowerExp: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -1421,7 +1421,7 @@ pub trait LowerExp { /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub trait UpperExp { +pub trait UpperExp: PointeeSized { #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; @@ -2694,11 +2694,11 @@ macro_rules! fmt_refs { ($($tr:ident),*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + $tr> $tr for &T { + impl<T: ?Sized + PointeeSized + $tr> $tr for &T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + $tr> $tr for &mut T { + impl<T: ?Sized + PointeeSized + $tr> $tr for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) } } )* @@ -2820,7 +2820,7 @@ impl Display for char { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for *const T { +impl<T: ?Sized + PointeeSized> Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { if <<T as core::ptr::Pointee>::Metadata as core::unit::IsUnit>::is_unit() { pointer_fmt_inner(self.expose_provenance(), f) @@ -2865,21 +2865,21 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for *mut T { +impl<T: ?Sized + PointeeSized> Pointer for *mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(*self as *const T), f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for &T { +impl<T: ?Sized + PointeeSized> Pointer for &T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(*self as *const T), f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Pointer for &mut T { +impl<T: ?Sized + PointeeSized> Pointer for &mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(&(&**self as *const T), f) } @@ -2888,13 +2888,13 @@ impl<T: ?Sized> Pointer for &mut T { // Implementation of Display/Debug for various core types #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Debug for *const T { +impl<T: ?Sized + PointeeSized> Debug for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Debug for *mut T { +impl<T: ?Sized + PointeeSized> Debug for *mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self, f) } diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index f7b874b26bb74..efda64791d403 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -183,7 +183,7 @@ mod sip; /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Hash"] -pub trait Hash { +pub trait Hash: marker::PointeeSized { /// Feeds this value into the given [`Hasher`]. /// /// # Examples @@ -941,7 +941,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + Hash> Hash for &T { + impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); @@ -949,7 +949,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized + Hash> Hash for &mut T { + impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &mut T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); @@ -957,7 +957,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Hash for *const T { + impl<T: ?Sized + marker::PointeeSized> Hash for *const T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); @@ -967,7 +967,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl<T: ?Sized> Hash for *mut T { + impl<T: ?Sized + marker::PointeeSized> Hash for *mut T { #[inline] fn hash<H: Hasher>(&self, state: &mut H) { let (address, metadata) = self.to_raw_parts(); diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 81e59a1f349ec..4cb42b8ff48af 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -64,7 +64,7 @@ )] #![allow(missing_docs)] -use crate::marker::{DiscriminantKind, Tuple}; +use crate::marker::{DiscriminantKind, PointeeSized, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; @@ -3615,10 +3615,10 @@ pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(data: pub trait AggregateRawPtr<D> { type Metadata: Copy; } -impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P { +impl<P: ?Sized + PointeeSized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P { type Metadata = <P as ptr::Pointee>::Metadata; } -impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P { +impl<P: ?Sized + PointeeSized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P { type Metadata = <P as ptr::Pointee>::Metadata; } @@ -3629,7 +3629,9 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(ptr: *const P) -> M; +pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized + PointeeSized, M>( + ptr: *const P, +) -> M; // Some functions are defined here because they accidentally got made // available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 6a9423cd4c40a..25dbd16e2a05f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -92,15 +92,15 @@ pub unsafe auto trait Send { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Send for *const T {} +impl<T: ?Sized + PointeeSized> !Send for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Send for *mut T {} +impl<T: ?Sized + PointeeSized> !Send for *mut T {} // Most instances arise automatically, but this instance is needed to link up `T: Sync` with // `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would // otherwise exist). #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Sync + ?Sized> Send for &T {} +unsafe impl<T: Sync + ?Sized + PointeeSized> Send for &T {} /// Types with a constant size known at compile time. /// @@ -231,7 +231,7 @@ impl<T: ?Sized> PointeeSized for T {} #[lang = "unsize"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Unsize<T: ?Sized> { +pub trait Unsize<T: ?Sized + PointeeSized>: PointeeSized { // Empty. } @@ -268,7 +268,7 @@ marker_impls! { (), {T, const N: usize} [T; N], {T} [T], - {T: ?Sized} &T, + {T: ?Sized + PointeeSized} &T, } /// Types whose values can be duplicated simply by copying bits. @@ -481,8 +481,8 @@ marker_impls! { isize, i8, i16, i32, i64, i128, f16, f32, f64, f128, bool, char, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, } @@ -491,7 +491,7 @@ impl Copy for ! {} /// Shared references can be copied, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Copy for &T {} +impl<T: ?Sized + PointeeSized> Copy for &T {} /// Marker trait for the types that are allowed in union fields and unsafe /// binder types. @@ -675,9 +675,9 @@ pub unsafe auto trait Sync { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Sync for *const T {} +impl<T: ?Sized + PointeeSized> !Sync for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> !Sync for *mut T {} +impl<T: ?Sized + PointeeSized> !Sync for *mut T {} /// Zero-sized type used to mark things that "act like" they own a `T`. /// @@ -814,57 +814,57 @@ impl<T: ?Sized> !Sync for *mut T {} /// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: ?Sized + PointeeSized>; #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Hash for PhantomData<T> { +impl<T: ?Sized + PointeeSized> Hash for PhantomData<T> { #[inline] fn hash<H: Hasher>(&self, _: &mut H) {} } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::PartialEq for PhantomData<T> { +impl<T: ?Sized + PointeeSized> cmp::PartialEq for PhantomData<T> { fn eq(&self, _other: &PhantomData<T>) -> bool { true } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::Eq for PhantomData<T> {} +impl<T: ?Sized + PointeeSized> cmp::Eq for PhantomData<T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::PartialOrd for PhantomData<T> { +impl<T: ?Sized + PointeeSized> cmp::PartialOrd for PhantomData<T> { fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<cmp::Ordering> { Option::Some(cmp::Ordering::Equal) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> cmp::Ord for PhantomData<T> { +impl<T: ?Sized + PointeeSized> cmp::Ord for PhantomData<T> { fn cmp(&self, _other: &PhantomData<T>) -> cmp::Ordering { cmp::Ordering::Equal } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Copy for PhantomData<T> {} +impl<T: ?Sized + PointeeSized> Copy for PhantomData<T> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Clone for PhantomData<T> { +impl<T: ?Sized + PointeeSized> Clone for PhantomData<T> { fn clone(&self) -> Self { Self } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Default for PhantomData<T> { +impl<T: ?Sized + PointeeSized> Default for PhantomData<T> { fn default() -> Self { Self } } #[unstable(feature = "structural_match", issue = "31434")] -impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {} +impl<T: ?Sized + PointeeSized> StructuralPartialEq for PhantomData<T> {} /// Compiler-internal trait used to indicate the type of enum discriminants. /// @@ -907,15 +907,15 @@ pub trait DiscriminantKind { pub unsafe auto trait Freeze {} #[unstable(feature = "freeze", issue = "121675")] -impl<T: ?Sized> !Freeze for UnsafeCell<T> {} +impl<T: ?Sized + PointeeSized> !Freeze for UnsafeCell<T> {} marker_impls! { #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for - {T: ?Sized} PhantomData<T>, - {T: ?Sized} *const T, - {T: ?Sized} *mut T, - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: ?Sized + PointeeSized} PhantomData<T>, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, + {T: ?Sized + PointeeSized} &T, + {T: ?Sized + PointeeSized} &mut T, } /// Types that do not require any pinning guarantees. @@ -1003,15 +1003,15 @@ impl !Unpin for PhantomPinned {} marker_impls! { #[stable(feature = "pin", since = "1.33.0")] Unpin for - {T: ?Sized} &T, - {T: ?Sized} &mut T, + {T: ?Sized + PointeeSized} &T, + {T: ?Sized + PointeeSized} &mut T, } marker_impls! { #[stable(feature = "pin_raw", since = "1.38.0")] Unpin for - {T: ?Sized} *const T, - {T: ?Sized} *mut T, + {T: ?Sized + PointeeSized} *const T, + {T: ?Sized + PointeeSized} *mut T, } /// A marker for types that can be dropped. diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index e74f5443ac2d8..f5fa5c4e0ef0c 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -1,3 +1,5 @@ +use crate::marker::PointeeSized; + /// Used for immutable dereferencing operations, like `*v`. /// /// In addition to being used for explicit dereferencing operations with the @@ -135,7 +137,7 @@ #[rustc_diagnostic_item = "Deref"] #[const_trait] #[rustc_const_unstable(feature = "const_deref", issue = "88955")] -pub trait Deref { +pub trait Deref: PointeeSized { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "deref_target"] @@ -267,7 +269,8 @@ impl<T: ?Sized> const Deref for &mut T { #[stable(feature = "rust1", since = "1.0.0")] #[const_trait] #[rustc_const_unstable(feature = "const_deref", issue = "88955")] -pub trait DerefMut: ~const Deref { +#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this +pub trait DerefMut: ~const Deref + PointeeSized { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "deref_mut_method"] @@ -293,7 +296,7 @@ impl<T: ?Sized> const DerefMut for &mut T { /// unchanged. #[unstable(feature = "deref_pure_trait", issue = "87121")] #[lang = "deref_pure"] -pub unsafe trait DerefPure {} +pub unsafe trait DerefPure: PointeeSized {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl<T: ?Sized> DerefPure for &T {} @@ -366,7 +369,7 @@ unsafe impl<T: ?Sized> DerefPure for &mut T {} /// ``` #[lang = "receiver"] #[unstable(feature = "arbitrary_self_types", issue = "44874")] -pub trait Receiver { +pub trait Receiver: PointeeSized { /// The target type on which the method may be called. #[rustc_diagnostic_item = "receiver_target"] #[lang = "receiver_target"] @@ -393,12 +396,12 @@ where #[lang = "legacy_receiver"] #[unstable(feature = "legacy_receiver_trait", issue = "none")] #[doc(hidden)] -pub trait LegacyReceiver { +pub trait LegacyReceiver: PointeeSized { // Empty. } #[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl<T: ?Sized> LegacyReceiver for &T {} +impl<T: ?Sized + PointeeSized> LegacyReceiver for &T {} #[unstable(feature = "legacy_receiver_trait", issue = "none")] -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: ?Sized + PointeeSized> LegacyReceiver for &mut T {} diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs index d2a07197f6f6a..2080b05d053fd 100644 --- a/library/core/src/ops/unsize.rs +++ b/library/core/src/ops/unsize.rs @@ -1,4 +1,4 @@ -use crate::marker::Unsize; +use crate::marker::{PointeeSized, Unsize}; /// Trait that indicates that this is a pointer or a wrapper for one, /// where unsizing can be performed on the pointee. @@ -33,40 +33,67 @@ use crate::marker::Unsize; /// [nomicon-coerce]: ../../nomicon/coercions.html #[unstable(feature = "coerce_unsized", issue = "18598")] #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> { +pub trait CoerceUnsized<T: ?Sized + PointeeSized> { // Empty. } // &mut T -> &mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<&'a mut U> + for &'a mut T +{ +} // &mut T -> &U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {} +impl<'a, 'b: 'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> + CoerceUnsized<&'a U> for &'b mut T +{ +} // &mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*mut U> + for &'a mut T +{ +} // &mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for &'a mut T +{ +} // &T -> &U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> + CoerceUnsized<&'a U> for &'b T +{ +} // &T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for &'a T +{ +} // *mut T -> *mut U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*mut U> + for *mut T +{ +} // *mut T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {} +impl<T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for *mut T +{ +} // *const T -> *const U #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} +impl<T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> CoerceUnsized<*const U> + for *const T +{ +} /// `DispatchFromDyn` is used in the implementation of dyn-compatibility[^1] checks (specifically /// allowing arbitrary self types), to guarantee that a method's receiver type can be dispatched on. @@ -122,13 +149,25 @@ pub trait DispatchFromDyn<T> { // &T -> &U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> DispatchFromDyn<&'a U> + for &'a T +{ +} // &mut T -> &mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> DispatchFromDyn<&'a mut U> + for &'a mut T +{ +} // *const T -> *const U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> DispatchFromDyn<*const U> + for *const T +{ +} // *mut T -> *mut U #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: ?Sized + PointeeSized + Unsize<U>, U: ?Sized + PointeeSized> DispatchFromDyn<*mut U> + for *mut T +{ +} diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 7d0839aff3f73..c2ca6dbc51c20 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -4,7 +4,7 @@ use crate::intrinsics::const_eval_select; use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; -impl<T: ?Sized> *const T { +impl<T: ?Sized + PointeeSized> *const T { /// Returns `true` if the pointer is null. /// /// Note that unsized types have many possible null pointers, as only the @@ -120,7 +120,7 @@ impl<T: ?Sized> *const T { #[inline] pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U where - U: ?Sized, + U: ?Sized + PointeeSized, { from_raw_parts::<U>(self as *const (), metadata(meta)) } @@ -1677,7 +1677,7 @@ impl<T, const N: usize> *const [T; N] { /// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialEq for *const T { +impl<T: ?Sized + PointeeSized> PartialEq for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*const T) -> bool { @@ -1687,11 +1687,11 @@ impl<T: ?Sized> PartialEq for *const T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Eq for *const T {} +impl<T: ?Sized + PointeeSized> Eq for *const T {} /// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Ord for *const T { +impl<T: ?Sized + PointeeSized> Ord for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*const T) -> Ordering { @@ -1707,7 +1707,7 @@ impl<T: ?Sized> Ord for *const T { /// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialOrd for *const T { +impl<T: ?Sized + PointeeSized> PartialOrd for *const T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*const T) -> Option<Ordering> { diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 9c5da306e27a7..c511830b73a98 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -3,7 +3,7 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::intrinsics::{aggregate_raw_ptr, ptr_metadata}; -use crate::marker::Freeze; +use crate::marker::{Freeze, PointeeSized}; use crate::ptr::NonNull; /// Provides the pointer metadata type of any pointed-to type. @@ -55,7 +55,7 @@ use crate::ptr::NonNull; #[lang = "pointee_trait"] #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] -pub trait Pointee { +pub trait Pointee: PointeeSized { /// The type for metadata in pointers and references to `Self`. #[lang = "metadata_type"] // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` @@ -81,7 +81,7 @@ pub trait Pointee { /// ``` #[unstable(feature = "ptr_metadata", issue = "81513")] // NOTE: don’t stabilize this before trait aliases are stable in the language? -pub trait Thin = Pointee<Metadata = ()>; +pub trait Thin = Pointee<Metadata = ()> + PointeeSized; /// Extracts the metadata component of a pointer. /// @@ -96,7 +96,7 @@ pub trait Thin = Pointee<Metadata = ()>; /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` #[inline] -pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata { +pub const fn metadata<T: ?Sized + PointeeSized>(ptr: *const T) -> <T as Pointee>::Metadata { ptr_metadata(ptr) } @@ -109,7 +109,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata { /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts<T: ?Sized>( +pub const fn from_raw_parts<T: ?Sized + PointeeSized>( data_pointer: *const impl Thin, metadata: <T as Pointee>::Metadata, ) -> *const T { @@ -122,7 +122,7 @@ pub const fn from_raw_parts<T: ?Sized>( /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] #[inline] -pub const fn from_raw_parts_mut<T: ?Sized>( +pub const fn from_raw_parts_mut<T: ?Sized + PointeeSized>( data_pointer: *mut impl Thin, metadata: <T as Pointee>::Metadata, ) -> *mut T { @@ -152,7 +152,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>( /// duplicated in multiple codegen units), and pointers to vtables of *different* types/traits can /// compare equal (since identical vtables can be deduplicated within a codegen unit). #[lang = "dyn_metadata"] -pub struct DynMetadata<Dyn: ?Sized> { +pub struct DynMetadata<Dyn: ?Sized + PointeeSized> { _vtable_ptr: NonNull<VTable>, _phantom: crate::marker::PhantomData<Dyn>, } @@ -165,7 +165,7 @@ unsafe extern "C" { type VTable; } -impl<Dyn: ?Sized> DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> DynMetadata<Dyn> { /// When `DynMetadata` appears as the metadata field of a wide pointer, the rustc_middle layout /// computation does magic and the resulting layout is *not* a `FieldsShape::Aggregate`, instead /// it is a `FieldsShape::Primitive`. This means that the same type can have different layout @@ -206,10 +206,10 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> { } } -unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {} -unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {} +unsafe impl<Dyn: ?Sized + PointeeSized> Send for DynMetadata<Dyn> {} +unsafe impl<Dyn: ?Sized + PointeeSized> Sync for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> fmt::Debug for DynMetadata<Dyn> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish() } @@ -217,27 +217,27 @@ impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> { // Manual impls needed to avoid `Dyn: $Trait` bounds. -impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {} +impl<Dyn: ?Sized + PointeeSized> Unpin for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {} +impl<Dyn: ?Sized + PointeeSized> Copy for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> Clone for DynMetadata<Dyn> { #[inline] fn clone(&self) -> Self { *self } } -impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {} +impl<Dyn: ?Sized + PointeeSized> Eq for DynMetadata<Dyn> {} -impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> PartialEq for DynMetadata<Dyn> { #[inline] fn eq(&self, other: &Self) -> bool { crate::ptr::eq::<VTable>(self.vtable_ptr(), other.vtable_ptr()) } } -impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> Ord for DynMetadata<Dyn> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> crate::cmp::Ordering { @@ -245,14 +245,14 @@ impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> { } } -impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> PartialOrd for DynMetadata<Dyn> { #[inline] fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> { Some(self.cmp(other)) } } -impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> { +impl<Dyn: ?Sized + PointeeSized> Hash for DynMetadata<Dyn> { #[inline] fn hash<H: Hasher>(&self, hasher: &mut H) { crate::ptr::hash::<VTable, _>(self.vtable_ptr(), hasher) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ea53da78d3bd2..1c0e80ddb6d35 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -396,7 +396,7 @@ use crate::cmp::Ordering; use crate::intrinsics::const_eval_select; -use crate::marker::FnPtr; +use crate::marker::{FnPtr, PointeeSized}; use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::{fmt, hash, intrinsics, ub_checks}; @@ -520,7 +520,7 @@ mod mut_ptr; #[lang = "drop_in_place"] #[allow(unconditional_recursion)] #[rustc_diagnostic_item = "ptr_drop_in_place"] -pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { +pub unsafe fn drop_in_place<T: ?Sized + PointeeSized>(to_drop: *mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. @@ -549,7 +549,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] #[rustc_diagnostic_item = "ptr_null"] -pub const fn null<T: ?Sized + Thin>() -> *const T { +pub const fn null<T: ?Sized + PointeeSized + Thin>() -> *const T { from_raw_parts(without_provenance::<()>(0), ()) } @@ -574,7 +574,7 @@ pub const fn null<T: ?Sized + Thin>() -> *const T { #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] #[rustc_diagnostic_item = "ptr_null_mut"] -pub const fn null_mut<T: ?Sized + Thin>() -> *mut T { +pub const fn null_mut<T: ?Sized + PointeeSized + Thin>() -> *mut T { from_raw_parts_mut(without_provenance_mut::<()>(0), ()) } @@ -792,7 +792,7 @@ pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T { #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_never_returns_null_ptr] #[rustc_diagnostic_item = "ptr_from_ref"] -pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { +pub const fn from_ref<T: ?Sized + PointeeSized>(r: &T) -> *const T { r } @@ -842,7 +842,7 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { #[stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_never_returns_null_ptr] -pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T { +pub const fn from_mut<T: ?Sized + PointeeSized>(r: &mut T) -> *mut T { r } @@ -2067,7 +2067,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize { #[must_use = "pointer comparison produces a value"] #[rustc_diagnostic_item = "ptr_eq"] #[allow(ambiguous_wide_pointer_comparisons)] // it's actually clear here -pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { +pub fn eq<T: ?Sized + PointeeSized>(a: *const T, b: *const T) -> bool { a == b } @@ -2091,7 +2091,10 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool { #[stable(feature = "ptr_addr_eq", since = "1.76.0")] #[inline(always)] #[must_use = "pointer comparison produces a value"] -pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool { +pub fn addr_eq<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized>( + p: *const T, + q: *const U, +) -> bool { (p as *const ()) == (q as *const ()) } @@ -2174,7 +2177,7 @@ pub fn fn_addr_eq<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool { /// assert_eq!(actual, expected); /// ``` #[stable(feature = "ptr_hash", since = "1.35.0")] -pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) { +pub fn hash<T: ?Sized + PointeeSized, S: hash::Hasher>(hashee: *const T, into: &mut S) { use crate::hash::Hash; hashee.hash(into); } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index b960a3d86bef0..f55657fd7a234 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1,10 +1,11 @@ use super::*; use crate::cmp::Ordering::{Equal, Greater, Less}; use crate::intrinsics::const_eval_select; +use crate::marker::PointeeSized; use crate::mem::{self, SizedTypeProperties}; use crate::slice::{self, SliceIndex}; -impl<T: ?Sized> *mut T { +impl<T: ?Sized + PointeeSized> *mut T { /// Returns `true` if the pointer is null. /// /// Note that unsized types have many possible null pointers, as only the @@ -101,7 +102,7 @@ impl<T: ?Sized> *mut T { #[inline] pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U where - U: ?Sized, + U: ?Sized + PointeeSized, { from_raw_parts_mut::<U>(self as *mut (), metadata(meta)) } @@ -2094,7 +2095,7 @@ impl<T, const N: usize> *mut [T; N] { /// Pointer equality is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialEq for *mut T { +impl<T: ?Sized + PointeeSized> PartialEq for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &*mut T) -> bool { @@ -2104,11 +2105,11 @@ impl<T: ?Sized> PartialEq for *mut T { /// Pointer equality is an equivalence relation. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Eq for *mut T {} +impl<T: ?Sized + PointeeSized> Eq for *mut T {} /// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> Ord for *mut T { +impl<T: ?Sized + PointeeSized> Ord for *mut T { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &*mut T) -> Ordering { @@ -2124,7 +2125,7 @@ impl<T: ?Sized> Ord for *mut T { /// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method. #[stable(feature = "rust1", since = "1.0.0")] -impl<T: ?Sized> PartialOrd for *mut T { +impl<T: ?Sized + PointeeSized> PartialOrd for *mut T { #[inline(always)] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> { diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c769ba673c61e..73117f051c6d7 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1,5 +1,5 @@ use crate::cmp::Ordering; -use crate::marker::Unsize; +use crate::marker::{PointeeSized, Unsize}; use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::num::NonZero; use crate::ops::{CoerceUnsized, DispatchFromDyn}; @@ -67,7 +67,7 @@ use crate::{fmt, hash, intrinsics, mem, ptr}; #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] #[rustc_diagnostic_item = "NonNull"] -pub struct NonNull<T: ?Sized> { +pub struct NonNull<T: ?Sized + PointeeSized> { // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to // this is banned by <https://github.com/rust-lang/compiler-team/issues/807>. pointer: *const T, @@ -76,12 +76,12 @@ pub struct NonNull<T: ?Sized> { /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> !Send for NonNull<T> {} +impl<T: ?Sized + PointeeSized> !Send for NonNull<T> {} /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // N.B., this impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> !Sync for NonNull<T> {} +impl<T: ?Sized + PointeeSized> !Sync for NonNull<T> {} impl<T: Sized> NonNull<T> { /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance]. @@ -189,7 +189,7 @@ impl<T: Sized> NonNull<T> { } } -impl<T: ?Sized> NonNull<T> { +impl<T: ?Sized + PointeeSized> NonNull<T> { /// Creates a new `NonNull`. /// /// # Safety @@ -1572,7 +1572,7 @@ impl<T> NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Clone for NonNull<T> { +impl<T: ?Sized + PointeeSized> Clone for NonNull<T> { #[inline(always)] fn clone(&self) -> Self { *self @@ -1580,39 +1580,45 @@ impl<T: ?Sized> Clone for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Copy for NonNull<T> {} +impl<T: ?Sized + PointeeSized> Copy for NonNull<T> {} #[unstable(feature = "coerce_unsized", issue = "18598")] -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where + T: Unsize<U> +{ +} #[unstable(feature = "dispatch_from_dyn", issue = "none")] -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where + T: Unsize<U> +{ +} #[stable(feature = "pin", since = "1.33.0")] -unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {} +unsafe impl<T: ?Sized + PointeeSized> PinCoerceUnsized for NonNull<T> {} #[unstable(feature = "pointer_like_trait", issue = "none")] impl<T> core::marker::PointerLike for NonNull<T> {} #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> fmt::Debug for NonNull<T> { +impl<T: ?Sized + PointeeSized> fmt::Debug for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> fmt::Pointer for NonNull<T> { +impl<T: ?Sized + PointeeSized> fmt::Pointer for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Eq for NonNull<T> {} +impl<T: ?Sized + PointeeSized> Eq for NonNull<T> {} #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> PartialEq for NonNull<T> { +impl<T: ?Sized + PointeeSized> PartialEq for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn eq(&self, other: &Self) -> bool { @@ -1621,7 +1627,7 @@ impl<T: ?Sized> PartialEq for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> Ord for NonNull<T> { +impl<T: ?Sized + PointeeSized> Ord for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn cmp(&self, other: &Self) -> Ordering { @@ -1630,7 +1636,7 @@ impl<T: ?Sized> Ord for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> PartialOrd for NonNull<T> { +impl<T: ?Sized + PointeeSized> PartialOrd for NonNull<T> { #[inline] #[allow(ambiguous_wide_pointer_comparisons)] fn partial_cmp(&self, other: &Self) -> Option<Ordering> { @@ -1639,7 +1645,7 @@ impl<T: ?Sized> PartialOrd for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> hash::Hash for NonNull<T> { +impl<T: ?Sized + PointeeSized> hash::Hash for NonNull<T> { #[inline] fn hash<H: hash::Hasher>(&self, state: &mut H) { self.as_ptr().hash(state) @@ -1647,7 +1653,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<Unique<T>> for NonNull<T> { +impl<T: ?Sized + PointeeSized> From<Unique<T>> for NonNull<T> { #[inline] fn from(unique: Unique<T>) -> Self { unique.as_non_null_ptr() @@ -1655,7 +1661,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> From<&mut T> for NonNull<T> { +impl<T: ?Sized + PointeeSized> From<&mut T> for NonNull<T> { /// Converts a `&mut T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. @@ -1666,7 +1672,7 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -impl<T: ?Sized> From<&T> for NonNull<T> { +impl<T: ?Sized + PointeeSized> From<&T> for NonNull<T> { /// Converts a `&T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 4810ebe01f9bb..10870a858e2e1 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -1,5 +1,5 @@ use crate::fmt; -use crate::marker::{PhantomData, Unsize}; +use crate::marker::{PhantomData, PointeeSized, Unsize}; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::pin::PinCoerceUnsized; use crate::ptr::NonNull; @@ -34,7 +34,7 @@ use crate::ptr::NonNull; #[repr(transparent)] // Lang item used experimentally by Miri to define the semantics of `Unique`. #[lang = "ptr_unique"] -pub struct Unique<T: ?Sized> { +pub struct Unique<T: ?Sized + PointeeSized> { pointer: NonNull<T>, // NOTE: this marker has no consequences for variance, but is necessary // for dropck to understand that we logically own a `T`. @@ -49,14 +49,14 @@ pub struct Unique<T: ?Sized> { /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. #[unstable(feature = "ptr_internals", issue = "none")] -unsafe impl<T: Send + ?Sized> Send for Unique<T> {} +unsafe impl<T: Send + ?Sized + PointeeSized> Send for Unique<T> {} /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. #[unstable(feature = "ptr_internals", issue = "none")] -unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {} +unsafe impl<T: Sync + ?Sized + PointeeSized> Sync for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] impl<T: Sized> Unique<T> { @@ -78,7 +78,7 @@ impl<T: Sized> Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Unique<T> { +impl<T: ?Sized + PointeeSized> Unique<T> { /// Creates a new `Unique`. /// /// # Safety @@ -151,7 +151,7 @@ impl<T: ?Sized> Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Clone for Unique<T> { +impl<T: ?Sized + PointeeSized> Clone for Unique<T> { #[inline] fn clone(&self) -> Self { *self @@ -159,33 +159,39 @@ impl<T: ?Sized> Clone for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> Copy for Unique<T> {} +impl<T: ?Sized + PointeeSized> Copy for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where + T: Unsize<U> +{ +} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: ?Sized + PointeeSized, U: ?Sized + PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where + T: Unsize<U> +{ +} #[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")] -unsafe impl<T: ?Sized> PinCoerceUnsized for Unique<T> {} +unsafe impl<T: ?Sized + PointeeSized> PinCoerceUnsized for Unique<T> {} #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> fmt::Debug for Unique<T> { +impl<T: ?Sized + PointeeSized> fmt::Debug for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> fmt::Pointer for Unique<T> { +impl<T: ?Sized + PointeeSized> fmt::Pointer for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<&mut T> for Unique<T> { +impl<T: ?Sized + PointeeSized> From<&mut T> for Unique<T> { /// Converts a `&mut T` to a `Unique<T>`. /// /// This conversion is infallible since references cannot be null. @@ -196,7 +202,7 @@ impl<T: ?Sized> From<&mut T> for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> From<NonNull<T>> for Unique<T> { +impl<T: ?Sized + PointeeSized> From<NonNull<T>> for Unique<T> { /// Converts a `NonNull<T>` to a `Unique<T>`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index d754bb9034300..f12241a8bfc16 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,7 +1,7 @@ // See core/src/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; -use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; +use crate::marker::{ConstParamTy_, PointeeSized, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{Break, Continue}; // Recursive macro for implementing n-ary tuple functions and operations @@ -25,7 +25,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: PartialEq),+> PartialEq for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?Sized + PointeeSized { #[inline] fn eq(&self, other: &($($T,)+)) -> bool { @@ -43,7 +43,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: Eq),+> Eq for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?Sized + PointeeSized {} } @@ -73,7 +73,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?Sized + PointeeSized { #[inline] fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> { @@ -103,7 +103,7 @@ macro_rules! tuple_impls { #[stable(feature = "rust1", since = "1.0.0")] impl<$($T: Ord),+> Ord for ($($T,)+) where - last_type!($($T,)+): ?Sized + last_type!($($T,)+): ?Sized + PointeeSized { #[inline] fn cmp(&self, other: &($($T,)+)) -> Ordering { From 3d5c9765a8c76c346f5bc80b570a71b4123e7b58 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 21:19:51 +0000 Subject: [PATCH 06/43] 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. --- .../src/collect/item_bounds.rs | 16 +- .../src/collect/predicates_of.rs | 30 +- .../src/hir_ty_lowering/bounds.rs | 273 ++++++++++++------ .../src/hir_ty_lowering/errors.rs | 46 ++- compiler/rustc_ty_utils/src/ty.rs | 2 +- library/core/src/marker.rs | 4 +- .../feature-gate-sized-hierarchy.rs | 4 +- .../feature-gate-sized-hierarchy.stderr | 6 +- tests/ui/sized-hierarchy/default-bound.rs | 49 ++++ tests/ui/sized-hierarchy/default-bound.stderr | 88 ++++++ .../ui/sized-hierarchy/default-supertrait.rs | 61 ++++ .../sized-hierarchy/default-supertrait.stderr | 125 ++++++++ .../sized-hierarchy/extern-type-behind-ptr.rs | 20 ++ tests/ui/sized-hierarchy/impls.rs | 14 +- tests/ui/sized-hierarchy/impls.stderr | 108 +++---- .../ui/sized-hierarchy/pointee-supertrait.rs | 28 ++ 16 files changed, 711 insertions(+), 163 deletions(-) create mode 100644 tests/ui/sized-hierarchy/default-bound.rs create mode 100644 tests/ui/sized-hierarchy/default-bound.stderr create mode 100644 tests/ui/sized-hierarchy/default-supertrait.rs create mode 100644 tests/ui/sized-hierarchy/default-supertrait.stderr create mode 100644 tests/ui/sized-hierarchy/extern-type-behind-ptr.rs create mode 100644 tests/ui/sized-hierarchy/pointee-supertrait.rs diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 6e07f0ff53c39..eeebf7eaeb0bc 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -44,7 +44,13 @@ fn associated_type_bounds<'tcx>( | PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + icx.lowerer().adjust_sizedness_params_and_assoc_types( + &mut bounds, + item_ty, + hir_bounds, + None, + span, + ); } // `ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} @@ -334,7 +340,13 @@ fn opaque_type_bounds<'tcx>( | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { // Associated types are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); + icx.lowerer().adjust_sizedness_params_and_assoc_types( + &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 4bd89861a9e5a..d1b65f5e091b7 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -162,10 +162,11 @@ 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); + ItemKind::Trait(is_auto, _, _, _, self_bounds, ..) => { + is_trait = Some((is_auto, self_bounds)); + } + ItemKind::TraitAlias(_, _, self_bounds) => { + is_trait = Some((IsAuto::No, self_bounds)); } _ => {} } @@ -177,7 +178,7 @@ 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((is_auto, self_bounds)) = is_trait { let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, @@ -186,6 +187,18 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::List::empty(), PredicateFilter::All, ); + + // Don't add default supertraits to auto traits as it is not permitted to explicitly + // relax it in the source code. + if is_auto == IsAuto::No { + icx.lowerer().adjust_sizedness_supertraits( + &mut bounds, + tcx.types.self_param, + self_bounds, + def_id, + ); + } + predicates.extend(bounds); } @@ -211,7 +224,7 @@ 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(); // Params are implicitly sized unless a `?Sized` bound is found - icx.lowerer().add_sized_bound( + icx.lowerer().adjust_sizedness_params_and_assoc_types( &mut bounds, param_ty, &[], @@ -269,6 +282,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, PredicateFilter::All, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, bound_pred.bounded_ty.span); predicates.extend(bounds); } @@ -625,6 +639,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let self_param_ty = tcx.types.self_param; let mut bounds = Vec::new(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, item.span); let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter); @@ -932,6 +947,7 @@ impl<'tcx> ItemCtxt<'tcx> { bound_vars, filter, ); + self.lowerer().adjust_sizedness_predicates(&mut bounds, predicate.bounded_ty.span); } bounds @@ -1011,6 +1027,7 @@ pub(super) fn const_conditions<'tcx>( bound_vars, PredicateFilter::ConstIfConst, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, bound_pred.bounded_ty.span); } _ => {} } @@ -1031,6 +1048,7 @@ pub(super) fn const_conditions<'tcx>( ty::List::empty(), PredicateFilter::ConstIfConst, ); + icx.lowerer().adjust_sizedness_predicates(&mut bounds, DUMMY_SP); } ty::ConstConditions { 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 f0dffd780bcc7..1600231ecff50 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -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::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{HirId, 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,104 +23,204 @@ 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 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, SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]>) { + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let mut sized = CollectedBound::default(); + + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let mut meta_sized = CollectedBound::default(); + + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + let mut pointee_sized = CollectedBound::default(); + + let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); + 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; + }; + + if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) { + unbounds.push(ptr); + } + + let collect_into = match ptr.trait_ref.path.res { + Res::Def(DefKind::Trait, did) if did == sized_did => &mut sized, + Res::Def(DefKind::Trait, did) if did == meta_sized_did => &mut meta_sized, + Res::Def(DefKind::Trait, did) if did == pointee_sized_did => &mut pointee_sized, + _ => continue, + }; + + 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, + } + } + }; + + 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); + } + } + } + + (CollectedSizednessBounds { sized, meta_sized, pointee_sized }, unbounds) +} + +/// 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)); +} + +/// Remove any bounds of `did`. +fn remove_lang_item_bound<'tcx>(bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, did: DefId) { + bounds.retain(|(clause, _)| { + clause.as_trait_clause().map_or(true, |clause| clause.skip_binder().def_id() != did) + }); +} + impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { - /// Add a `Sized` bound to the `bounds` if appropriate. + /// Remove `PointeeSized` predicates (sibling functions do the same for supertraits and params). /// - /// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`. - pub(crate) fn add_sized_bound( + // `PointeeSized` is a "fake bound" insofar as it is preferred that 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 adjust_sizedness_predicates( + &self, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, + span: Span, + ) { + let tcx = self.tcx(); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); + } + + /// Adds a `MetaSized` bound to `bounds` (of a trait definition) if there are no other sizedness + /// bounds. Also removes `PointeeSized` params - see doc comment on + /// `adjust_sizedness_predicates`. + pub(crate) fn adjust_sizedness_supertraits( &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>])>, - span: Span, + trait_did: LocalDefId, ) { let tcx = self.tcx(); - let sized_def_id = tcx.lang_items().sized_trait(); - let mut seen_negative_sized_bound = false; - let mut seen_positive_sized_bound = false; - - // Try to find an unbound in bounds. - let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); - 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; - }; - match ptr.modifiers.polarity { - hir::BoundPolarity::Maybe(_) => unbounds.push(ptr), - hir::BoundPolarity::Negative(_) => { - if let Some(sized_def_id) = sized_def_id - && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_negative_sized_bound = true; - } - } - hir::BoundPolarity::Positive => { - if let Some(sized_def_id) = sized_def_id - && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_positive_sized_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 span = tcx.def_span(trait_did); + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + + let trait_did = trait_did.to_def_id(); + if trait_did == pointee_sized_did { + // Never add a default supertrait to `PointeeSized`. + return; } - let mut seen_sized_unbound = false; - for unbound in unbounds { - if let Some(sized_def_id) = sized_def_id - && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) - { - seen_sized_unbound = true; - continue; - } - // There was a `?Trait` bound, but it was not `?Sized` - self.dcx().span_err( - unbound.span, - "relaxing a default bound only does something for `?Sized`; \ - all other traits are not bound by default", - ); + let (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span); + if !collected.any() && trait_did != pointee_sized_did { + // If there are no explicit sizedness bounds then add a default `MetaSized` supertrait. + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); } - if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound { - // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound; - // we don't need to do anything. - } else if let Some(sized_def_id) = sized_def_id { - // There was no `?Sized`, `!Sized` or explicit `Sized` bound; - // add `Sized` if it's available. - let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - bounds.insert(0, (trait_ref.upcast(tcx), span)); + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); + } + + /// Add a default `Sized` bound if there are no other sizedness bounds and rewrite `?Sized` + /// to `MetaSized`. Also removes `PointeeSized` params - see doc comment on + /// `adjust_sizedness_predicates`. + pub(crate) fn adjust_sizedness_params_and_assoc_types( + &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>])>, + span: Span, + ) { + let tcx = self.tcx(); + + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); + let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + + let (collected, unbounds) = + collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span); + self.check_and_report_invalid_unbounds_on_param(unbounds); + + 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) + add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + } else if !collected.any() { + // If there are no explicit sizedness bounds then add a default `Sized` bound. + add_trait_bound(tcx, bounds, self_ty, sized_did, span); } + + // See doc comment on `adjust_sizedness_predicates`. + remove_lang_item_bound(bounds, pointee_sized_did); } /// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any. @@ -423,6 +523,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { projection_ty.bound_vars(), predicate_filter, ); + self.adjust_sizedness_predicates(bounds, constraint.span); } PredicateFilter::SelfOnly | PredicateFilter::SelfTraitThatDefines(_) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 3b007c7719880..b4e93398142db 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -5,9 +5,9 @@ use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, ErrorGuaranteed, MultiSpan, listify, pluralize, struct_span_code_err, }; -use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem, PolyTraitRef}; use rustc_middle::bug; use rustc_middle::ty::fast_reject::{TreatParams, simplify_type}; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -32,6 +32,50 @@ 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, None); + + 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() { + 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) + { + continue; + } + + self.dcx().span_err( + unbound.span, + "relaxing a default bound only does something for `?Sized`; all other traits \ + are not bound by default", + ); + } + } + /// 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 complain_about_missing_type_params( diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 454e496e13f3c..04f1370629533 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -104,7 +104,7 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { /// Calculates the `Sized` constraint. /// /// In fact, 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 #[instrument(level = "debug", skip(tcx), ret)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 25dbd16e2a05f..c1f05d952eedf 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -173,7 +173,7 @@ pub trait MetaSized: PointeeSized { #[cfg(bootstrap)] #[unstable(feature = "sized_hierarchy", issue = "none")] -impl<T: ?Sized> MetaSized for T {} +impl<T: ?Sized + PointeeSized> MetaSized for T {} /// Types that may or may not have a size. #[unstable(feature = "sized_hierarchy", issue = "none")] @@ -193,7 +193,7 @@ pub trait PointeeSized { #[cfg(bootstrap)] #[unstable(feature = "sized_hierarchy", issue = "none")] -impl<T: ?Sized> PointeeSized for T {} +impl<T: ?Sized + PointeeSized> PointeeSized for T {} /// Types that can be "unsized" to a dynamically-sized type. /// diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs index 5e2a76ba254e8..33688c2e2ce03 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -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() { diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr index 8cbea3b6ba430..6a35fcfb0e8e5 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -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 diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs new file mode 100644 index 0000000000000..12b2eb2b5c1b4 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -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>(); +} diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr new file mode 100644 index 0000000000000..22f0fa29d3e23 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -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`. diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs new file mode 100644 index 0000000000000..b25acf9e6ea4f --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -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() { } diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr new file mode 100644 index 0000000000000..ca461a4317b42 --- /dev/null +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -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`. diff --git a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs new file mode 100644 index 0000000000000..70a84aabf2cfb --- /dev/null +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -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()); +} diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs index b05313dccae49..601d837043ef5 100644 --- a/tests/ui/sized-hierarchy/impls.rs +++ b/tests/ui/sized-hierarchy/impls.rs @@ -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>(); diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr index 5fffe47866350..02ccfebdc4416 100644 --- a/tests/ui/sized-hierarchy/impls.stderr +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -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 diff --git a/tests/ui/sized-hierarchy/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs new file mode 100644 index 0000000000000..4bf486890bf23 --- /dev/null +++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs @@ -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() { } From 108a02ca33c8036e9eb836350d181525154c7c44 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 22 Jan 2025 18:06:08 +0000 Subject: [PATCH 07/43] aux: add `{Meta,Pointee}Sized` bounds to minicore With `MetaSized` bounds replacing `?Sized` and being added as a supertrait, the same relaxations applied to the standard library must be applied to minicore. --- tests/auxiliary/minicore.rs | 30 +++++------ .../traits/const-traits/auxiliary/minicore.rs | 50 +++++++++---------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index c3ea1801804a8..052b29c5be04c 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -51,8 +51,8 @@ pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} #[lang = "copy"] pub trait Copy: Sized {} @@ -74,14 +74,14 @@ impl_marker_trait!( f16, f32, f64, f128, ] ); -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} impl<T: Copy, const N: usize> Copy for [T; N] {} #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; -impl<T: ?Sized> Copy for PhantomData<T> {} +pub struct PhantomData<T: PointeeSized>; +impl<T: PointeeSized> Copy for PhantomData<T> {} pub enum Option<T> { None, @@ -97,17 +97,17 @@ impl<T: Copy, E: Copy> Copy for Result<T, E> {} #[lang = "manually_drop"] #[repr(transparent)] -pub struct ManuallyDrop<T: ?Sized> { +pub struct ManuallyDrop<T: PointeeSized> { value: T, } -impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {} +impl<T: Copy + PointeeSized> Copy for ManuallyDrop<T> {} #[lang = "unsafe_cell"] #[repr(transparent)] -pub struct UnsafeCell<T: ?Sized> { +pub struct UnsafeCell<T: PointeeSized> { value: T, } -impl<T: ?Sized> !Freeze for UnsafeCell<T> {} +impl<T: PointeeSized> !Freeze for UnsafeCell<T> {} #[lang = "tuple_trait"] pub trait Tuple {} @@ -183,15 +183,15 @@ pub trait Fn<Args: Tuple>: FnMut<Args> { #[lang = "dispatch_from_dyn"] trait DispatchFromDyn<T> {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} #[lang = "unsize"] -trait Unsize<T: ?Sized> {} +trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> {} +pub trait CoerceUnsized<T: PointeeSized> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} #[lang = "drop"] trait Drop { diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 0a8a4bc097b82..073337b2ac6db 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -12,7 +12,7 @@ fundamental, marker_trait_attr, const_trait_impl, - const_destruct + const_destruct, )] #![allow(internal_features, incomplete_features)] #![no_std] @@ -32,7 +32,7 @@ pub trait Copy {} impl Copy for bool {} impl Copy for u8 {} -impl<T: ?Sized> Copy for &T {} +impl<T: PointeeSized> Copy for &T {} #[lang = "add"] #[const_trait] @@ -113,17 +113,17 @@ pub trait Tuple {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} #[lang = "receiver"] pub trait Receiver { #[lang = "receiver_target"] - type Target: ?Sized; + type Target: MetaSized; } -impl<T: Deref + ?Sized> Receiver for T { +impl<T: Deref + MetaSized> Receiver for T { type Target = <T as Deref>::Target; } @@ -169,15 +169,15 @@ fn panic_fmt() {} #[lang = "index"] #[const_trait] -pub trait Index<Idx: ?Sized> { - type Output: ?Sized; +pub trait Index<Idx: PointeeSized> { + type Output: MetaSized; fn index(&self, index: Idx) -> &Self::Output; } #[const_trait] -pub unsafe trait SliceIndex<T: ?Sized> { - type Output: ?Sized; +pub unsafe trait SliceIndex<T: PointeeSized> { + type Output: MetaSized; fn index(self, slice: &T) -> &Self::Output; } @@ -206,23 +206,23 @@ where } #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] -pub trait CoerceUnsized<T: ?Sized> {} +pub trait CoerceUnsized<T: PointeeSized> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} #[lang = "deref"] #[const_trait] pub trait Deref { #[lang = "deref_target"] - type Target: ?Sized; + type Target: MetaSized; fn deref(&self) -> &Self::Target; } -impl<T: ?Sized> const Deref for &T { +impl<T: MetaSized> const Deref for &T { type Target = T; fn deref(&self) -> &T { @@ -230,7 +230,7 @@ impl<T: ?Sized> const Deref for &T { } } -impl<T: ?Sized> const Deref for &mut T { +impl<T: MetaSized> const Deref for &mut T { type Target = T; fn deref(&self) -> &T { @@ -314,14 +314,14 @@ fn from_str(s: &str) -> Result<bool, ()> { #[lang = "eq"] #[const_trait] -pub trait PartialEq<Rhs: ?Sized = Self> { +pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } } -impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A +impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A where A: ~const PartialEq<B>, { @@ -364,7 +364,7 @@ impl<P> Pin<P> { } } -impl<'a, T: ?Sized> Pin<&'a T> { +impl<'a, T: PointeeSized> Pin<&'a T> { const fn get_ref(self) -> &'a T { self.pointer } @@ -379,7 +379,7 @@ impl<P: Deref> Pin<P> { } } -impl<'a, T: ?Sized> Pin<&'a mut T> { +impl<'a, T: PointeeSized> Pin<&'a mut T> { const unsafe fn get_unchecked_mut(self) -> &'a mut T { self.pointer } @@ -425,7 +425,7 @@ impl<T: Clone> Clone for RefCell<T> { } } -struct RefCell<T: ?Sized> { +struct RefCell<T: PointeeSized> { borrow: UnsafeCell<()>, value: UnsafeCell<T>, } @@ -434,7 +434,7 @@ impl<T> RefCell<T> { loop {} } } -impl<T: ?Sized> RefCell<T> { +impl<T: PointeeSized> RefCell<T> { fn borrow(&self) -> Ref<'_, T> { loop {} } @@ -442,16 +442,16 @@ impl<T: ?Sized> RefCell<T> { #[lang = "unsafe_cell"] #[repr(transparent)] -struct UnsafeCell<T: ?Sized> { +struct UnsafeCell<T: PointeeSized> { value: T, } -struct Ref<'b, T: ?Sized + 'b> { +struct Ref<'b, T: PointeeSized + 'b> { value: *const T, borrow: &'b UnsafeCell<()>, } -impl<T: ?Sized> Deref for Ref<'_, T> { +impl<T: MetaSized> Deref for Ref<'_, T> { type Target = T; #[inline] From 1e2ada1758e64be54c291ffd486e6ba71eaf867b Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 21:20:20 +0000 Subject: [PATCH 08/43] trait_sel: stash `{Meta,Pointee}Sized` errors `Sized` errors are currently stashed to improve diagnostics and this must happen with `{Meta,Pointee}Sized` too to maintain diagnostic output. --- .../src/error_reporting/traits/ambiguity.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 59c93db9c8fff..fa34a23a26fb6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -199,7 +199,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and don't add the obligations to // begin with in those cases. - if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) { + if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized) + || self.tcx.is_lang_item(trait_pred.def_id(), LangItem::MetaSized) + || self.tcx.is_lang_item(trait_pred.def_id(), LangItem::PointeeSized) + { match self.tainted_by_errors() { None => { let err = self.emit_inference_failure_err( From e984a3fc921ebbbeac3182e921f68904f32fe408 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 21:22:27 +0000 Subject: [PATCH 09/43] trait_sel: `MetaSized` bounds in dispatchable check Given the necessary additions of bounds to these traits and their impls in the standard library, it is necessary to add `MetaSized` bounds to the obligation which is proven as part of checking for dyn dispatchability. --- .../src/traits/dyn_compatibility.rs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 78a452439836f..b3ad7d101d883 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -7,8 +7,8 @@ use std::ops::ControlFlow; use rustc_errors::FatalError; -use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::{self as hir, LangItem}; use rustc_middle::query::Providers; use rustc_middle::ty::{ self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -541,11 +541,11 @@ fn receiver_for_self_ty<'tcx>( /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in /// a new check that `Trait` is dyn-compatible, creating a cycle. /// Instead, we emulate a placeholder by introducing a new type parameter `U` such that -/// `Self: Unsize<U>` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. +/// `Self: Unsize<U>` and `U: Trait + MetaSized`, and use `U` in place of `dyn Trait`. /// /// Written as a chalk-style query: /// ```ignore (not-rust) -/// forall (U: Trait + ?Sized) { +/// forall (U: Trait + MetaSized) { /// if (Self: Unsize<U>) { /// Receiver: DispatchFromDyn<Receiver[Self => U]> /// } @@ -565,9 +565,10 @@ fn receiver_is_dispatchable<'tcx>( ) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); - let traits = (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()); - let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else { - debug!("receiver_is_dispatchable: Missing Unsize or DispatchFromDyn traits"); + let (Some(unsize_did), Some(dispatch_from_dyn_did)) = + (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait()) + else { + debug!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits"); return false; }; @@ -581,7 +582,7 @@ fn receiver_is_dispatchable<'tcx>( receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id); // create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of - // its supertraits) added to caller bounds. `U: ?Sized` is already implied here. + // its supertraits) added to caller bounds. `U: MetaSized` is already implied here. let param_env = { let param_env = tcx.param_env(method.def_id); @@ -599,11 +600,18 @@ fn receiver_is_dispatchable<'tcx>( ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx) }; + let meta_sized_predicate = { + let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, None); + ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty]).upcast(tcx) + }; + normalize_param_env_or_error( tcx, - ty::ParamEnv::new(tcx.mk_clauses_from_iter( - param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]), - )), + ty::ParamEnv::new(tcx.mk_clauses_from_iter(param_env.caller_bounds().iter().chain([ + unsize_predicate, + meta_sized_predicate, + trait_predicate, + ]))), ObligationCause::dummy_with_span(tcx.def_span(method.def_id)), ) }; From bd21a9cd0b241b2b00926404ff06137f5b65d4dc Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 23 Jan 2025 18:31:28 +0000 Subject: [PATCH 10/43] trait_sel: sort `{Meta,Pointee}Sized` diagnostics last Like `Sized` diagnostics, sorting `MetaSized` and `PointeeSized` diagnostics last prevents earlier more useful diagnostics from being skipped because there has already been error tainting. --- .../src/error_reporting/traits/mod.rs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 98df09b6f7b01..6316620168f1a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -164,17 +164,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .collect(); - // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics - // with more relevant type information and hide redundant E0282 errors. - errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) - if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => - { - 1 + // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last. + // This lets us display diagnostics with more relevant type information and hide redundant + // E0282 errors. + errors.sort_by_key(|e| { + let maybe_sizedness_did = match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred.def_id()), + ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(pred)) => Some(pred.def_id()), + _ => None, + }; + + match e.obligation.predicate.kind().skip_binder() { + _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => 1, + _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => 2, + _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => 3, + ty::PredicateKind::Coerce(_) => 4, + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 5, + _ => 0, } - ty::PredicateKind::Coerce(_) => 2, - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, - _ => 0, }); for (index, error) in errors.iter().enumerate() { From 9b8d2e63f4ffd8532f5e25810ef6b55fe5d7fc30 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 00:28:42 +0000 Subject: [PATCH 11/43] trait_sel: print `{Meta,Pointee}Sized` impl headers When printing impl headers in a diagnostic, the compiler has to account for `?Sized` implying `MetaSized` and new `MetaSized` and `PointeeSized` bounds. --- .../src/error_reporting/traits/mod.rs | 62 ++++++++++++++----- .../auxiliary/pretty-print-dep.rs | 19 ++++++ .../auxiliary/pretty-print-no-feat-dep.rs | 7 +++ .../pretty-print-no-feat-dep-has-feat.rs | 26 ++++++++ .../pretty-print-no-feat-dep-has-feat.stderr | 42 +++++++++++++ .../sized-hierarchy/pretty-print-no-feat.rs | 19 ++++++ .../pretty-print-no-feat.stderr | 22 +++++++ tests/ui/sized-hierarchy/pretty-print.rs | 28 +++++++++ tests/ui/sized-hierarchy/pretty-print.stderr | 43 +++++++++++++ 9 files changed, 252 insertions(+), 16 deletions(-) create mode 100644 tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs create mode 100644 tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr create mode 100644 tests/ui/sized-hierarchy/pretty-print-no-feat.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print-no-feat.stderr create mode 100644 tests/ui/sized-hierarchy/pretty-print.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 6316620168f1a..cb8fe8c31d7cf 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, AmbigArg, LangItem}; +use rustc_hir::{self as hir, AmbigArg}; use rustc_infer::traits::{ DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, @@ -338,19 +338,26 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); let mut w = "impl".to_owned(); - let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); + #[derive(Debug, Default)] + struct SizednessFound { + sized: bool, + meta_sized: bool, + } - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxIndexSet::default(); - let sized_trait = tcx.lang_items().sized_trait(); + let mut types_with_sizedness_bounds = FxIndexMap::<_, SizednessFound>::default(); + + let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::<Vec<_>>(); if !arg_names.is_empty() { - types_without_default_bounds.extend(args.types()); w.push('<'); w.push_str(&arg_names.join(", ")); w.push('>'); + + for ty in args.types() { + // `PointeeSized` params might have no predicates. + types_with_sizedness_bounds.insert(ty, SizednessFound::default()); + } } write!( @@ -362,24 +369,47 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti ) .unwrap(); - // The predicates will contain default bounds like `T: Sized`. We need to - // remove these bounds, and add `T: ?Sized` to any untouched type parameters. let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = - Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); + let mut pretty_predicates = Vec::with_capacity(predicates.len()); + + let sized_trait = tcx.lang_items().sized_trait(); + let meta_sized_trait = tcx.lang_items().meta_sized_trait(); for (p, _) in predicates { - if let Some(poly_trait_ref) = p.as_trait_clause() { - if Some(poly_trait_ref.def_id()) == sized_trait { - // FIXME(#120456) - is `swap_remove` correct? - types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); + // Accumulate the sizedness bounds for each self ty. + if let Some(trait_clause) = p.as_trait_clause() { + let self_ty = trait_clause.self_ty().skip_binder(); + let sizedness_of = types_with_sizedness_bounds.entry(self_ty).or_default(); + if Some(trait_clause.def_id()) == sized_trait { + sizedness_of.sized = true; + continue; + } else if Some(trait_clause.def_id()) == meta_sized_trait { + sizedness_of.meta_sized = true; continue; } } + pretty_predicates.push(p.to_string()); } - pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); + for (ty, sizedness) in types_with_sizedness_bounds { + if !tcx.features().sized_hierarchy() { + if sizedness.sized { + // Maybe a default bound, don't write anything. + } else { + pretty_predicates.push(format!("{ty}: ?Sized")); + } + } else { + if sizedness.sized { + // Maybe a default bound, don't write anything. + pretty_predicates.push(format!("{ty}: Sized")); + } else if sizedness.meta_sized { + pretty_predicates.push(format!("{ty}: MetaSized")); + } else { + pretty_predicates.push(format!("{ty}: PointeeSized")); + } + } + } if !pretty_predicates.is_empty() { write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); diff --git a/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs new file mode 100644 index 0000000000000..a7d18d9036856 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs @@ -0,0 +1,19 @@ +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait SizedTr {} + +impl<T: Sized> SizedTr for T {} + +pub trait NegSizedTr {} + +impl<T: ?Sized> NegSizedTr for T {} + +pub trait MetaSizedTr {} + +impl<T: MetaSized> MetaSizedTr for T {} + +pub trait PointeeSizedTr: PointeeSized {} + +impl<T: PointeeSized> PointeeSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs b/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs new file mode 100644 index 0000000000000..3314b0f356f53 --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-no-feat-dep.rs @@ -0,0 +1,7 @@ +pub trait SizedTr {} + +impl<T: Sized> SizedTr for T {} + +pub trait NegSizedTr {} + +impl<T: ?Sized> NegSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs new file mode 100644 index 0000000000000..0412ff651cee6 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -0,0 +1,26 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, NegSizedTr, MetaSizedTr, PointeeSizedTr}; + +// Test that printing the sizedness trait bounds in the conflicting impl error without enabling +// `sized_hierarchy` will continue to print `?Sized`, even if the dependency is compiled with +// `sized_hierarchy`. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl<T: ?Sized> MetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl<T: ?Sized> PointeeSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr new file mode 100644 index 0000000000000..cb9bfd178f88d --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr @@ -0,0 +1,42 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:16:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:19:1 + | +LL | impl<T: ?Sized> NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + | +LL | impl<T: ?Sized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + | +LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: ?Sized; + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat.rs new file mode 100644 index 0000000000000..d5800be582805 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat.rs @@ -0,0 +1,19 @@ +//@ aux-build:pretty-print-no-feat-dep.rs +//@ compile-flags: --crate-type=lib + +extern crate pretty_print_no_feat_dep; +use pretty_print_no_feat_dep::{SizedTr, NegSizedTr}; + +// Test that printing the sizedness trait bounds in the conflicting impl error without enabling +// `sized_hierarchy` will continue to print `?Sized`. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr new file mode 100644 index 0000000000000..1d50f0145fe9a --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat.stderr @@ -0,0 +1,22 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat.rs:15:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat.rs:18:1 + | +LL | impl<T: ?Sized> NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_no_feat_dep`: + - impl<T> NegSizedTr for T + where T: ?Sized; + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs new file mode 100644 index 0000000000000..0908e76490ce7 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -0,0 +1,28 @@ +//@ aux-build:pretty-print-dep.rs +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +// Test that printing the sizedness trait bounds in the conflicting impl error with +// `sized_hierarchy` enabled prints all of the appropriate bounds. +// +// It isn't possible to write a test that matches the multiline note containing the important +// diagnostic output being tested - so check the stderr changes carefully! + +use std::marker::{MetaSized, PointeeSized}; + +extern crate pretty_print_dep; +use pretty_print_dep::{SizedTr, MetaSizedTr, PointeeSizedTr}; + +struct X<T>(T); + +impl<T: Sized> SizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` + +impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` + +impl<T: MetaSized> MetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` + +impl<T: PointeeSized> PointeeSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `PointeeSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print.stderr b/tests/ui/sized-hierarchy/pretty-print.stderr new file mode 100644 index 0000000000000..3602c804945bd --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.stderr @@ -0,0 +1,43 @@ +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:18:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T + where T: Sized; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:21:1 + | +LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:24:1 + | +LL | impl<T: MetaSized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:27:1 + | +LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: PointeeSized; + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0119`. From 8f46a4eaea64f73b441207f379875ba9437689dc Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 22:27:57 +0000 Subject: [PATCH 12/43] middle: print `{Meta,Pointee}Sized` in opaques When `sized_hierarchy` is enabled, rustc should print `MetaSized` or `PointeeSized` instead of `?Sized` in opaques. --- compiler/rustc_middle/src/ty/print/pretty.rs | 32 ++++++++++-- .../pretty-print-opaque-no-feat.rs | 13 +++++ .../pretty-print-opaque-no-feat.stderr | 12 +++++ .../ui/sized-hierarchy/pretty-print-opaque.rs | 45 +++++++++++++++++ .../pretty-print-opaque.stderr | 50 +++++++++++++++++++ 5 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr create mode 100644 tests/ui/sized-hierarchy/pretty-print-opaque.rs create mode 100644 tests/ui/sized-hierarchy/pretty-print-opaque.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3ef8ecc59e402..ae2960802aa81 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1062,16 +1062,20 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); + let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_sized_bound = false; let mut has_negative_sized_bound = false; - let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); + let mut has_meta_sized_bound = false; + let mut has_pointee_sized_bound = false; for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => { - // Don't print `+ Sized`, but rather `+ ?Sized` if absent. + // With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for + // `MetaSized`, and skip sizedness bounds to be added at the end. if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { match pred.polarity { ty::PredicatePolarity::Positive => { @@ -1080,6 +1084,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } ty::PredicatePolarity::Negative => has_negative_sized_bound = true, } + } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { + has_meta_sized_bound = true; + continue; + } else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) { + // Unexpected - `PointeeSized` is the absence of bounds. + has_pointee_sized_bound = true; + continue; } self.insert_trait_and_projection( @@ -1248,8 +1259,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { })?; } + let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); let add_sized = has_sized_bound && (first || has_negative_sized_bound); - let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound; + let add_maybe_sized = + has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy; + // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. + has_pointee_sized_bound = has_pointee_sized_bound + || (!has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound); if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; @@ -1258,6 +1274,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { write!(self, "?")?; } write!(self, "Sized")?; + } else if has_meta_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "MetaSized")?; + } else if has_pointee_sized_bound && using_sized_hierarchy { + if !first { + write!(self, " + ")?; + } + write!(self, "PointeeSized")?; } if !with_forced_trimmed_paths() { diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs new file mode 100644 index 0000000000000..955108a20744b --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --crate-type=lib + +pub trait Tr {} +impl Tr for u32 {} + +pub fn foo() -> Box<impl Tr + ?Sized> { + if true { + let x = foo(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + ?Sized` cannot be known + } + Box::new(1u32) +} diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr new file mode 100644 index 0000000000000..bbe19870937ee --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque-no-feat.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `impl Tr + ?Sized` cannot be known at compilation time + --> $DIR/pretty-print-opaque-no-feat.rs:9:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + ?Sized` + = note: required for the cast from `Box<impl Tr + ?Sized>` to `Box<dyn Tr>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs new file mode 100644 index 0000000000000..43946777e0635 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -0,0 +1,45 @@ +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +use std::marker::{MetaSized, PointeeSized}; + +pub trait Tr: PointeeSized {} +impl Tr for u32 {} + +pub fn sized() -> Box<impl Tr + Sized> { + if true { + let x = sized(); + let y: Box<dyn Tr> = x; + } + Box::new(1u32) +} + +pub fn neg_sized() -> Box<impl Tr + ?Sized> { + if true { + let x = neg_sized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn metasized() -> Box<impl Tr + MetaSized> { + if true { + let x = metasized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known + } + Box::new(1u32) +} + +pub fn pointeesized() -> Box<impl Tr + PointeeSized> { +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + if true { + let x = pointeesized(); +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known + } + Box::new(1u32) +} + diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr new file mode 100644 index 0000000000000..523f6e7dd83ff --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -0,0 +1,50 @@ +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:35:26 + | +LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:20:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:29:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` + = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:38:17 + | +LL | let x = pointeesized(); + | ^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:40:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + PointeeSized` + = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. From 9685048cd27ad6413833ccde5717627e232c7638 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 22 Jan 2025 18:07:04 +0000 Subject: [PATCH 13/43] tests: `PointeeSized` bounds with extern types These tests necessarily need to change now that `?Sized` is not sufficient to accept extern types and `PointeeSized` is now necessary. In addition, the `size_of_val`/`align_of_val` test can now be changed to expect an error. --- tests/codegen/dst-offset.rs | 5 ++- ...st-size_of_val-align_of_val-extern-type.rs | 6 ++- ...ize_of_val-align_of_val-extern-type.stderr | 26 +++++++++---- .../ui/extern/extern-type-diag-not-similar.rs | 7 +++- .../extern-type-diag-not-similar.stderr | 6 +-- .../extern/extern-types-manual-sync-send.rs | 8 ++-- tests/ui/extern/extern-types-not-sync-send.rs | 8 ++-- .../extern/extern-types-not-sync-send.stderr | 16 ++++---- tests/ui/extern/extern-types-pointer-cast.rs | 5 ++- tests/ui/extern/extern-types-size_of_val.rs | 16 +++----- .../ui/extern/extern-types-size_of_val.stderr | 39 +++++++++++++++++++ tests/ui/extern/extern-types-thin-pointer.rs | 7 ++-- tests/ui/extern/extern-types-trait-impl.rs | 9 +++-- tests/ui/offset-of/offset-of-dst-field.rs | 5 ++- tests/ui/offset-of/offset-of-dst-field.stderr | 20 +++++----- tests/ui/symbol-names/foreign-types.rs | 5 ++- tests/ui/symbol-names/foreign-types.stderr | 6 +-- 17 files changed, 128 insertions(+), 66 deletions(-) create mode 100644 tests/ui/extern/extern-types-size_of_val.stderr diff --git a/tests/codegen/dst-offset.rs b/tests/codegen/dst-offset.rs index 7177a960432a6..2cf5fa9fac6ab 100644 --- a/tests/codegen/dst-offset.rs +++ b/tests/codegen/dst-offset.rs @@ -3,8 +3,9 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 #![crate_type = "lib"] -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::ptr::addr_of; // Hack to get the correct type for usize @@ -12,7 +13,7 @@ use std::ptr::addr_of; #[no_mangle] pub fn helper(_: usize) {} -struct Dst<T: ?Sized> { +struct Dst<T: PointeeSized> { x: u32, y: u8, z: T, diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs index 598904d3c4453..1dac8f8c62b40 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -7,7 +7,9 @@ extern "C" { type Opaque; } -const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR constant -const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; //~ ERROR constant +const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; +//~^ ERROR the size for values of type `Opaque` cannot be known +const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; +//~^ ERROR the size for values of type `Opaque` cannot be known fn main() {} diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index 4c0252123a4d3..ea55399f618b1 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -1,15 +1,27 @@ -error[E0080]: evaluation of constant value failed - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | | + | required by a bound introduced by this call + | + = help: the trait `MetaSized` is not implemented for `Opaque` +note: required by a bound in `std::intrinsics::size_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL -error[E0080]: evaluation of constant value failed - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:32 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:49 | LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout + | ---------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | | + | required by a bound introduced by this call + | + = help: the trait `MetaSized` is not implemented for `Opaque` +note: required by a bound in `std::intrinsics::min_align_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/extern-type-diag-not-similar.rs b/tests/ui/extern/extern-type-diag-not-similar.rs index cd3eec9f1f7b8..21a2a20a64451 100644 --- a/tests/ui/extern/extern-type-diag-not-similar.rs +++ b/tests/ui/extern/extern-type-diag-not-similar.rs @@ -3,7 +3,10 @@ // Two extern types shouldn't really be considered similar just // because they are both extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; + extern "C" { type ShouldNotBeMentioned; } @@ -14,7 +17,7 @@ extern "C" { unsafe impl Send for ShouldNotBeMentioned {} -fn assert_send<T: Send + ?Sized>() {} +fn assert_send<T: Send + PointeeSized>() {} fn main() { assert_send::<Foo>() diff --git a/tests/ui/extern/extern-type-diag-not-similar.stderr b/tests/ui/extern/extern-type-diag-not-similar.stderr index 3547f9b3ff613..f85ff1eead64b 100644 --- a/tests/ui/extern/extern-type-diag-not-similar.stderr +++ b/tests/ui/extern/extern-type-diag-not-similar.stderr @@ -1,14 +1,14 @@ error[E0277]: `Foo` cannot be sent between threads safely - --> $DIR/extern-type-diag-not-similar.rs:20:19 + --> $DIR/extern-type-diag-not-similar.rs:23:19 | LL | assert_send::<Foo>() | ^^^ `Foo` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Foo` note: required by a bound in `assert_send` - --> $DIR/extern-type-diag-not-similar.rs:17:19 + --> $DIR/extern-type-diag-not-similar.rs:20:19 | -LL | fn assert_send<T: Send + ?Sized>() {} +LL | fn assert_send<T: Send + PointeeSized>() {} | ^^^^ required by this bound in `assert_send` error: aborting due to 1 previous error diff --git a/tests/ui/extern/extern-types-manual-sync-send.rs b/tests/ui/extern/extern-types-manual-sync-send.rs index 2df0cd4c923c1..b273dcea7228f 100644 --- a/tests/ui/extern/extern-types-manual-sync-send.rs +++ b/tests/ui/extern/extern-types-manual-sync-send.rs @@ -1,7 +1,9 @@ //@ run-pass // Test that unsafe impl for Sync/Send can be provided for extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; extern "C" { type A; @@ -10,8 +12,8 @@ extern "C" { unsafe impl Sync for A {} unsafe impl Send for A {} -fn assert_sync<T: ?Sized + Sync>() {} -fn assert_send<T: ?Sized + Send>() {} +fn assert_sync<T: PointeeSized + Sync>() {} +fn assert_send<T: PointeeSized + Send>() {} fn main() { assert_sync::<A>(); diff --git a/tests/ui/extern/extern-types-not-sync-send.rs b/tests/ui/extern/extern-types-not-sync-send.rs index ba82caced7a4e..3cac1aabea99e 100644 --- a/tests/ui/extern/extern-types-not-sync-send.rs +++ b/tests/ui/extern/extern-types-not-sync-send.rs @@ -1,13 +1,15 @@ // Make sure extern types are !Sync and !Send. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] + +use std::marker::PointeeSized; extern "C" { type A; } -fn assert_sync<T: ?Sized + Sync>() {} -fn assert_send<T: ?Sized + Send>() {} +fn assert_sync<T: PointeeSized + Sync>() {} +fn assert_send<T: PointeeSized + Send>() {} fn main() { assert_sync::<A>(); diff --git a/tests/ui/extern/extern-types-not-sync-send.stderr b/tests/ui/extern/extern-types-not-sync-send.stderr index 7865ddeda34f5..56bdd5be7cff3 100644 --- a/tests/ui/extern/extern-types-not-sync-send.stderr +++ b/tests/ui/extern/extern-types-not-sync-send.stderr @@ -1,28 +1,28 @@ error[E0277]: `A` cannot be shared between threads safely - --> $DIR/extern-types-not-sync-send.rs:13:19 + --> $DIR/extern-types-not-sync-send.rs:15:19 | LL | assert_sync::<A>(); | ^ `A` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `A` note: required by a bound in `assert_sync` - --> $DIR/extern-types-not-sync-send.rs:9:28 + --> $DIR/extern-types-not-sync-send.rs:11:34 | -LL | fn assert_sync<T: ?Sized + Sync>() {} - | ^^^^ required by this bound in `assert_sync` +LL | fn assert_sync<T: PointeeSized + Sync>() {} + | ^^^^ required by this bound in `assert_sync` error[E0277]: `A` cannot be sent between threads safely - --> $DIR/extern-types-not-sync-send.rs:16:19 + --> $DIR/extern-types-not-sync-send.rs:18:19 | LL | assert_send::<A>(); | ^ `A` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `A` note: required by a bound in `assert_send` - --> $DIR/extern-types-not-sync-send.rs:10:28 + --> $DIR/extern-types-not-sync-send.rs:12:34 | -LL | fn assert_send<T: ?Sized + Send>() {} - | ^^^^ required by this bound in `assert_send` +LL | fn assert_send<T: PointeeSized + Send>() {} + | ^^^^ required by this bound in `assert_send` error: aborting due to 2 previous errors diff --git a/tests/ui/extern/extern-types-pointer-cast.rs b/tests/ui/extern/extern-types-pointer-cast.rs index 78dbee77b9c4b..080ed91a632a6 100644 --- a/tests/ui/extern/extern-types-pointer-cast.rs +++ b/tests/ui/extern/extern-types-pointer-cast.rs @@ -2,7 +2,8 @@ #![allow(dead_code)] // Test that pointers to extern types can be cast from/to usize, // despite being !Sized. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; extern "C" { type A; @@ -13,7 +14,7 @@ struct Foo { tail: A, } -struct Bar<T: ?Sized> { +struct Bar<T: PointeeSized> { x: u8, tail: T, } diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index 399a5828ff3b2..3ff51b9b6b0df 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,8 +1,4 @@ -//@ run-fail -//@ check-run-results -//@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" -//@ revisions: size align +//@ check-fail #![feature(extern_types)] use std::mem::{align_of_val, size_of_val}; @@ -14,10 +10,8 @@ extern "C" { fn main() { let x: &A = unsafe { &*(1usize as *const A) }; - // These don't have a dynamic size, so this should panic. - if cfg!(size) { - assert_eq!(size_of_val(x), 0); - } else { - assert_eq!(align_of_val(x), 1); - } + size_of_val(x); + //~^ ERROR the size for values of type `A` cannot be known + align_of_val(x); + //~^ ERROR the size for values of type `A` cannot be known } diff --git a/tests/ui/extern/extern-types-size_of_val.stderr b/tests/ui/extern/extern-types-size_of_val.stderr new file mode 100644 index 0000000000000..040dc0d1f6756 --- /dev/null +++ b/tests/ui/extern/extern-types-size_of_val.stderr @@ -0,0 +1,39 @@ +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-size_of_val.rs:13:17 + | +LL | size_of_val(x); + | ----------- ^ the trait `MetaSized` is not implemented for `A` + | | + | required by a bound introduced by this call + | + = note: the trait bound `A: MetaSized` is not satisfied +note: required by a bound in `std::mem::size_of_val` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | size_of_val(&x); + | + +LL | size_of_val(&mut x); + | ++++ + +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-size_of_val.rs:15:18 + | +LL | align_of_val(x); + | ------------ ^ the trait `MetaSized` is not implemented for `A` + | | + | required by a bound introduced by this call + | + = note: the trait bound `A: MetaSized` is not satisfied +note: required by a bound in `align_of_val` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: consider borrowing here + | +LL | align_of_val(&x); + | + +LL | align_of_val(&mut x); + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/extern/extern-types-thin-pointer.rs b/tests/ui/extern/extern-types-thin-pointer.rs index 8e5911228b2e4..15777d456c264 100644 --- a/tests/ui/extern/extern-types-thin-pointer.rs +++ b/tests/ui/extern/extern-types-thin-pointer.rs @@ -2,8 +2,9 @@ #![allow(dead_code)] // Test that pointers and references to extern types are thin, ie they have the same size and // alignment as a pointer to (). -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::{align_of, size_of}; extern "C" { @@ -15,12 +16,12 @@ struct Foo { tail: A, } -struct Bar<T: ?Sized> { +struct Bar<T: PointeeSized> { x: u8, tail: T, } -fn assert_thin<T: ?Sized>() { +fn assert_thin<T: PointeeSized>() { assert_eq!(size_of::<*const T>(), size_of::<*const ()>()); assert_eq!(align_of::<*const T>(), align_of::<*const ()>()); diff --git a/tests/ui/extern/extern-types-trait-impl.rs b/tests/ui/extern/extern-types-trait-impl.rs index 44300b1051412..07cb1efa80130 100644 --- a/tests/ui/extern/extern-types-trait-impl.rs +++ b/tests/ui/extern/extern-types-trait-impl.rs @@ -1,13 +1,14 @@ //@ run-pass #![allow(dead_code)] // Test that traits can be implemented for extern types. -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; extern "C" { type A; } -trait Foo { +trait Foo: PointeeSized { fn foo(&self) {} } @@ -15,9 +16,9 @@ impl Foo for A { fn foo(&self) {} } -fn assert_foo<T: ?Sized + Foo>() {} +fn assert_foo<T: PointeeSized + Foo>() {} -fn use_foo<T: ?Sized + Foo>(x: &dyn Foo) { +fn use_foo<T: PointeeSized + Foo>(x: &dyn Foo) { x.foo(); } diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 2e0bdb151e180..575a66fe302ce 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,5 +1,6 @@ -#![feature(extern_types)] +#![feature(extern_types, sized_hierarchy)] +use std::marker::PointeeSized; use std::mem::offset_of; struct Alpha { @@ -26,7 +27,7 @@ struct Gamma { z: Extern, } -struct Delta<T: ?Sized> { +struct Delta<T: PointeeSized> { x: u8, y: u16, z: T, diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 714bf7a0266c6..0953e86e222e4 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:36:5 + --> $DIR/offset-of-dst-field.rs:37:5 | LL | offset_of!(Alpha, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,7 +8,7 @@ LL | offset_of!(Alpha, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:37:5 + --> $DIR/offset-of-dst-field.rs:38:5 | LL | offset_of!(Beta, z); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -17,7 +17,7 @@ LL | offset_of!(Beta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:38:5 + --> $DIR/offset-of-dst-field.rs:39:5 | LL | offset_of!(Gamma, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -26,7 +26,7 @@ LL | offset_of!(Gamma, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:40:5 + --> $DIR/offset-of-dst-field.rs:41:5 | LL | offset_of!((u8, dyn Trait), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -35,7 +35,7 @@ LL | offset_of!((u8, dyn Trait), 1); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:45:5 + --> $DIR/offset-of-dst-field.rs:46:5 | LL | offset_of!(Delta<Extern>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -44,7 +44,7 @@ LL | offset_of!(Delta<Extern>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:46:5 + --> $DIR/offset-of-dst-field.rs:47:5 | LL | offset_of!(Delta<dyn Trait>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,21 +53,21 @@ LL | offset_of!(Delta<dyn Trait>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:44:5 + --> $DIR/offset-of-dst-field.rs:45:5 | LL | offset_of!(Delta<Alpha>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `Alpha` - --> $DIR/offset-of-dst-field.rs:5:8 + --> $DIR/offset-of-dst-field.rs:6:8 | LL | struct Alpha { | ^^^^^ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:50:5 + --> $DIR/offset-of-dst-field.rs:51:5 | LL | fn generic_with_maybe_sized<T: ?Sized>() -> usize { | - this type parameter needs to be `Sized` @@ -82,7 +82,7 @@ LL + fn generic_with_maybe_sized<T>() -> usize { | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:54:16 + --> $DIR/offset-of-dst-field.rs:55:16 | LL | offset_of!(([u8], u8), 1); | ^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/symbol-names/foreign-types.rs b/tests/ui/symbol-names/foreign-types.rs index 2a9aadfcb83b5..b863e8c17594e 100644 --- a/tests/ui/symbol-names/foreign-types.rs +++ b/tests/ui/symbol-names/foreign-types.rs @@ -2,13 +2,16 @@ //@ compile-flags: -C symbol-mangling-version=v0 #![feature(extern_types)] +#![feature(sized_hierarchy)] #![feature(rustc_attrs)] +use std::marker::PointeeSized; + extern "C" { type ForeignType; } -struct Check<T: ?Sized>(T); +struct Check<T: PointeeSized>(T); #[rustc_symbol_name] //~^ ERROR symbol-name(_RMCs diff --git a/tests/ui/symbol-names/foreign-types.stderr b/tests/ui/symbol-names/foreign-types.stderr index 6304499148526..4640ceae81167 100644 --- a/tests/ui/symbol-names/foreign-types.stderr +++ b/tests/ui/symbol-names/foreign-types.stderr @@ -1,17 +1,17 @@ error: symbol-name(_RMCsCRATE_HASH_13foreign_typesINtB<REF>_5CheckNtB<REF>_11ForeignTypeE) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(<foreign_types[fcdd87e190ad88e3]::Check<foreign_types[fcdd87e190ad88e3]::ForeignType>>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(<foreign_types::Check<foreign_types::ForeignType>>) - --> $DIR/foreign-types.rs:13:1 + --> $DIR/foreign-types.rs:16:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ From 831bb160175906e55827f86ca65d103e1e043970 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 22 Jan 2025 18:10:22 +0000 Subject: [PATCH 14/43] tests: use `PointeeSized` to re-unconstrain params These tests expected entirely unconstrained parameters and their `?Sized` bounds are no longer sufficient to achieve that. --- tests/ui/traits/resolve-impl-before-constrain-check.rs | 5 ++++- tests/ui/traits/resolve-impl-before-constrain-check.stderr | 4 ++-- .../unconstrained-projection-normalization-2.current.stderr | 4 ++-- .../unconstrained-projection-normalization-2.next.stderr | 4 ++-- tests/ui/traits/unconstrained-projection-normalization-2.rs | 4 +++- .../unconstrained-projection-normalization.current.stderr | 4 ++-- .../unconstrained-projection-normalization.next.stderr | 4 ++-- tests/ui/traits/unconstrained-projection-normalization.rs | 4 +++- 8 files changed, 20 insertions(+), 13 deletions(-) diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 87f9c241e402b..cdcc2fa9fe5e6 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -1,12 +1,15 @@ // Need a different module so we try to build the mir for `test` // before analyzing `mod foo`. +#![feature(sized_hierarchy)] mod foo { + use std::marker::PointeeSized; + pub trait Callable { fn call(); } - impl<V: ?Sized> Callable for () { + impl<V: PointeeSized> Callable for () { //~^ ERROR the type parameter `V` is not constrained by the impl trait, self type, or predicates fn call() {} } diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e8e569ba625ee..b1e8ed11d6e8e 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/resolve-impl-before-constrain-check.rs:9:10 + --> $DIR/resolve-impl-before-constrain-check.rs:12:10 | -LL | impl<V: ?Sized> Callable for () { +LL | impl<V: PointeeSized> Callable for () { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 2bb389c6ec161..4e90bb4bebab6 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:14:6 + --> $DIR/unconstrained-projection-normalization-2.rs:16:6 | -LL | impl<T: ?Sized> Every for Thing { +LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 2bb389c6ec161..4e90bb4bebab6 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:14:6 + --> $DIR/unconstrained-projection-normalization-2.rs:16:6 | -LL | impl<T: ?Sized> Every for Thing { +LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.rs b/tests/ui/traits/unconstrained-projection-normalization-2.rs index 6b584c436c606..bbbe4b90299e3 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.rs +++ b/tests/ui/traits/unconstrained-projection-normalization-2.rs @@ -5,13 +5,15 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] +use std::marker::PointeeSized; struct Thing; pub trait Every { type Assoc; } -impl<T: ?Sized> Every for Thing { +impl<T: PointeeSized> Every for Thing { //~^ ERROR the type parameter `T` is not constrained type Assoc = T; } diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index 991f0e8ba666e..044704e54dbde 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:13:6 + --> $DIR/unconstrained-projection-normalization.rs:15:6 | -LL | impl<T: ?Sized> Every for Thing { +LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index 991f0e8ba666e..044704e54dbde 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -1,7 +1,7 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:13:6 + --> $DIR/unconstrained-projection-normalization.rs:15:6 | -LL | impl<T: ?Sized> Every for Thing { +LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter error: aborting due to 1 previous error diff --git a/tests/ui/traits/unconstrained-projection-normalization.rs b/tests/ui/traits/unconstrained-projection-normalization.rs index fa4ab7fec4c2f..c231b1aa224c0 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.rs +++ b/tests/ui/traits/unconstrained-projection-normalization.rs @@ -4,13 +4,15 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![feature(sized_hierarchy)] +use std::marker::PointeeSized; struct Thing; pub trait Every { type Assoc; } -impl<T: ?Sized> Every for Thing { +impl<T: PointeeSized> Every for Thing { //~^ ERROR the type parameter `T` is not constrained type Assoc = T; } From 360a62eddb61499ce7b028203f8cc245ef55c283 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 12 Feb 2025 20:43:19 +0000 Subject: [PATCH 15/43] tests: unconstrain params in `non_lifetime_binders` It seems like generics from `non_lifetime_binders` don't have any default bounds like normal generics, so all of the `?Sized` relaxations need to be further relaxed with `PointeeSized` for this test to be the equivalent of before. --- tests/ui/traits/non_lifetime_binders/basic.rs | 7 +++++-- tests/ui/traits/non_lifetime_binders/basic.stderr | 2 +- tests/ui/traits/non_lifetime_binders/on-rpit.rs | 7 +++++-- .../ui/traits/non_lifetime_binders/on-rpit.stderr | 2 +- .../supertrait-dyn-compatibility.rs | 9 ++++++--- .../supertrait-dyn-compatibility.stderr | 14 +++++++------- ...placeholders-in-query-response-2.current.stderr | 2 +- ...ng-placeholders-in-query-response-2.next.stderr | 2 +- .../unifying-placeholders-in-query-response-2.rs | 13 ++++++++----- ...g-placeholders-in-query-response.current.stderr | 2 +- ...ying-placeholders-in-query-response.next.stderr | 2 +- .../unifying-placeholders-in-query-response.rs | 9 ++++++--- 12 files changed, 43 insertions(+), 28 deletions(-) diff --git a/tests/ui/traits/non_lifetime_binders/basic.rs b/tests/ui/traits/non_lifetime_binders/basic.rs index 533891bf830d2..09c0244ec9540 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.rs +++ b/tests/ui/traits/non_lifetime_binders/basic.rs @@ -1,12 +1,15 @@ //@ check-pass // Basic test that show's we can successfully typeck a `for<T>` where clause. +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait {} +use std::marker::PointeeSized; -impl<T: ?Sized> Trait for T {} +trait Trait: PointeeSized {} + +impl<T: PointeeSized> Trait for T {} fn foo() where diff --git a/tests/ui/traits/non_lifetime_binders/basic.stderr b/tests/ui/traits/non_lifetime_binders/basic.stderr index 0fd16c5d0ee04..9f2df2238d15f 100644 --- a/tests/ui/traits/non_lifetime_binders/basic.stderr +++ b/tests/ui/traits/non_lifetime_binders/basic.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:4:12 + --> $DIR/basic.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 4d1cacb189083..1364f63a37336 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -1,11 +1,14 @@ //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Trait<T: ?Sized> {} +use std::marker::PointeeSized; -impl<T: ?Sized> Trait<T> for i32 {} +trait Trait<T: PointeeSized> {} + +impl<T: PointeeSized> Trait<T> for i32 {} fn produce() -> impl for<T> Trait<T> { 16 diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr index 34c56068c5cc5..c8396c3854844 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-rpit.rs:3:12 + --> $DIR/on-rpit.rs:4:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs index 28785ae3dea14..462724c73ee70 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs @@ -1,19 +1,22 @@ +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete +use std::marker::PointeeSized; + trait Foo: for<T> Bar<T> {} -trait Bar<T: ?Sized> { +trait Bar<T: PointeeSized>: PointeeSized { fn method(&self) {} } -fn needs_bar(x: &(impl Bar<i32> + ?Sized)) { +fn needs_bar(x: &(impl Bar<i32> + PointeeSized)) { x.method(); } impl Foo for () {} -impl<T: ?Sized> Bar<T> for () {} +impl<T: PointeeSized> Bar<T> for () {} fn main() { let x: &dyn Foo = &(); diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr index 43b69d0b50e48..57f16b3dfd62a 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-dyn-compatibility.rs:1:12 + --> $DIR/supertrait-dyn-compatibility.rs:2:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,14 +8,14 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:19:23 + --> $DIR/supertrait-dyn-compatibility.rs:22:23 | LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:7:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -25,14 +25,14 @@ LL | trait Foo: for<T> Bar<T> {} = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:19:12 + --> $DIR/supertrait-dyn-compatibility.rs:22:12 | LL | let x: &dyn Foo = &(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:7:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -41,14 +41,14 @@ LL | trait Foo: for<T> Bar<T> {} = help: only type `()` implements `Foo`; consider using it directly instead. error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:22:5 + --> $DIR/supertrait-dyn-compatibility.rs:25:5 | LL | needs_bar(x); | ^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:4:12 + --> $DIR/supertrait-dyn-compatibility.rs:7:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr index 3e5854ea1c85e..6551253d2e9e8 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr index 3e5854ea1c85e..6551253d2e9e8 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs index 2066887ea5966..d900bd429e6ec 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs @@ -3,19 +3,22 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -trait Id { - type Output: ?Sized; +use std::marker::PointeeSized; + +trait Id: PointeeSized { + type Output: PointeeSized; } -impl<T: ?Sized> Id for T { +impl<T: PointeeSized> Id for T { type Output = T; } -trait Everyone {} -impl<T: ?Sized> Everyone for T {} +trait Everyone: PointeeSized {} +impl<T: PointeeSized> Everyone for T {} fn hello() where for<T> <T as Id>::Output: Everyone {} diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr index 0224e5763e0b4..fecdc860f8e7d 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr index 0224e5763e0b4..fecdc860f8e7d 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:6:12 + --> $DIR/unifying-placeholders-in-query-response.rs:7:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs index 5334118e9ac7d..04e34531f4d78 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs @@ -3,15 +3,18 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete -pub trait Foo<T: ?Sized> { - type Bar<K: ?Sized>: ?Sized; +use std::marker::PointeeSized; + +pub trait Foo<T: PointeeSized> { + type Bar<K: PointeeSized>: PointeeSized; } impl Foo<usize> for () { - type Bar<K: ?Sized> = K; + type Bar<K: PointeeSized> = K; } pub fn f<T1, T2>(a: T1, b: T2) From 6efc4e1b1231f5abd6e4819ec74725abe695c7bf Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Feb 2025 15:54:25 +0000 Subject: [PATCH 16/43] tests: bless remaining tests These tests just need blessing, they don't have any interesting behaviour changes. Some of these tests have new errors because `LegacyReceiver` cannot be proven to be implemented now that it is also testing for `MetaSized` - but this is just a consequence of the other errors in the test. --- tests/incremental/hashes/trait_defs.rs | 6 +++--- tests/ui/attributes/dump-preds.stderr | 3 ++- .../unused-type-param-suggestion.rs | 2 ++ .../unused-type-param-suggestion.stderr | 13 ++++++------ .../layout/unconstrained-param-ice-137308.rs | 6 ++++-- .../unconstrained-param-ice-137308.stderr | 6 +++--- tests/ui/nll/issue-50716.rs | 3 +-- tests/ui/nll/issue-50716.stderr | 20 +++++++++++++++++-- tests/ui/recursion/issue-83150.rs | 2 +- tests/ui/recursion/issue-83150.stderr | 2 +- tests/ui/traits/cache-reached-depth-ice.rs | 5 +++-- .../ui/traits/cache-reached-depth-ice.stderr | 6 +++--- .../normalize/normalize-param-env-2.stderr | 14 ++++++++++++- .../normalize-param-env-4.next.stderr | 14 ++++++++++++- 14 files changed, 74 insertions(+), 28 deletions(-) diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index cb8716d90b07f..7b2185954b860 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -30,7 +30,7 @@ trait TraitVisibility { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail6")] pub trait TraitVisibility { } @@ -43,7 +43,7 @@ trait TraitUnsafety { } #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] unsafe trait TraitUnsafety { } @@ -57,7 +57,7 @@ trait TraitAddMethod { #[cfg(not(any(cfail1,cfail4)))] #[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids", cfg="cfail5")] +#[rustc_clean(except="opt_hir_owner_nodes,associated_item_def_ids,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] pub trait TraitAddMethod { fn method(); diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index 7db2abc5ffe6d..e63b51a47406a 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -4,6 +4,7 @@ error: rustc_dump_predicates LL | trait Trait<T>: Iterator<Item: Copy> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } @@ -16,6 +17,7 @@ error: rustc_dump_predicates LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } @@ -35,7 +37,6 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } - = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::PointeeSized>, polarity:Positive), bound_vars: [] } error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index fb0ccb4fdcd72..b7f8eb45083e1 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -1,4 +1,5 @@ #![crate_type="lib"] +#![feature(sized_hierarchy)] struct S<N>; //~^ ERROR type parameter `N` is never used @@ -25,3 +26,4 @@ type C<N: Sized> = (); type D<N: ?Sized> = (); //~^ ERROR type parameter `N` is never used //~| HELP consider removing `N` +//~| HELP if you intended `N` to be a const parameter diff --git a/tests/ui/const-generics/unused-type-param-suggestion.stderr b/tests/ui/const-generics/unused-type-param-suggestion.stderr index 67b704d8bc725..7963465bfa0fe 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:3:10 + --> $DIR/unused-type-param-suggestion.rs:4:10 | LL | struct S<N>; | ^ unused type parameter @@ -8,7 +8,7 @@ LL | struct S<N>; = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:9:10 + --> $DIR/unused-type-param-suggestion.rs:10:10 | LL | struct T<N: Copy>; | ^ unused type parameter @@ -16,7 +16,7 @@ LL | struct T<N: Copy>; = help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData` error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:13:8 + --> $DIR/unused-type-param-suggestion.rs:14:8 | LL | type A<N> = (); | ^ unused type parameter @@ -25,7 +25,7 @@ LL | type A<N> = (); = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:19:8 + --> $DIR/unused-type-param-suggestion.rs:20:8 | LL | type B<N: Copy> = (); | ^ unused type parameter @@ -33,7 +33,7 @@ LL | type B<N: Copy> = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:22:8 + --> $DIR/unused-type-param-suggestion.rs:23:8 | LL | type C<N: Sized> = (); | ^ unused type parameter @@ -41,12 +41,13 @@ LL | type C<N: Sized> = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:25:8 + --> $DIR/unused-type-param-suggestion.rs:26:8 | LL | type D<N: ?Sized> = (); | ^ unused type parameter | = help: consider removing `N` or referring to it in the body of the type alias + = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error: aborting due to 6 previous errors diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index c9b1e0a4b9ec3..928784a4f0566 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -3,14 +3,16 @@ //! This used to ICE in layout computation, because `<u8 as A>::B` fails to normalize //! due to the unconstrained param on the impl. -#![feature(rustc_attrs)] +#![feature(rustc_attrs, sized_hierarchy)] #![crate_type = "lib"] +use std::marker::PointeeSized; + trait A { const B: usize; } -impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained +impl<C: PointeeSized> A for u8 { //~ ERROR: the type parameter `C` is not constrained const B: usize = 42; } diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 615c131eb9045..3746e3e829f14 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -1,11 +1,11 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-param-ice-137308.rs:13:6 + --> $DIR/unconstrained-param-ice-137308.rs:15:6 | -LL | impl<C: ?Sized> A for u8 { +LL | impl<C: PointeeSized> A for u8 { | ^ unconstrained type parameter error: the type has an unknown layout - --> $DIR/unconstrained-param-ice-137308.rs:18:1 + --> $DIR/unconstrained-param-ice-137308.rs:20:1 | LL | struct S([u8; <u8 as A>::B]); | ^^^^^^^^ diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index c2fc345fa2ba2..c24d41e94e878 100644 --- a/tests/ui/nll/issue-50716.rs +++ b/tests/ui/nll/issue-50716.rs @@ -1,4 +1,3 @@ -// // Regression test for the issue #50716: NLL ignores lifetimes bounds // derived from `Sized` requirements @@ -6,7 +5,7 @@ trait A { type X: ?Sized; } -fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) +fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR mismatched types where for<'b> &'b T: A, <&'static T as A>::X: Sized diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index a09e76705156e..edd7fd765dade 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -1,5 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/issue-50716.rs:8:27 + | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch + | + = note: expected trait `<<&'a T as A>::X as MetaSized>` + found trait `<<&'static T as A>::X as MetaSized>` +note: the lifetime `'a` as defined here... + --> $DIR/issue-50716.rs:8:8 + | +LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) + | ^^ + = note: ...does not necessarily outlive the static lifetime + error: lifetime may not live long enough - --> $DIR/issue-50716.rs:14:14 + --> $DIR/issue-50716.rs:13:14 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) | -- lifetime `'a` defined here @@ -7,5 +22,6 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) LL | let _x = *s; | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index b720c168187b8..5b8161f7d0a9b 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` +//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: MetaSized` //@ build-fail //@ compile-flags: -Copt-level=0 diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 600922f1e57a7..7e603ba3f6e0e 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -10,7 +10,7 @@ LL | func(&mut iter.map(|x| x + 1)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` +error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: MetaSized` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) = note: required for `&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` diff --git a/tests/ui/traits/cache-reached-depth-ice.rs b/tests/ui/traits/cache-reached-depth-ice.rs index 8c2391113d719..bc62adf4842d3 100644 --- a/tests/ui/traits/cache-reached-depth-ice.rs +++ b/tests/ui/traits/cache-reached-depth-ice.rs @@ -1,4 +1,5 @@ -#![feature(rustc_attrs)] +#![feature(rustc_attrs, sized_hierarchy)] +use std::marker::PointeeSized; // Test for a particular corner case where the evaluation // cache can get out of date. The problem here is that @@ -37,7 +38,7 @@ struct C { } #[rustc_evaluate_where_clauses] -fn test<X: ?Sized + Send>() {} +fn test<X: PointeeSized + Send>() {} fn main() { test::<A>(); diff --git a/tests/ui/traits/cache-reached-depth-ice.stderr b/tests/ui/traits/cache-reached-depth-ice.stderr index e84ebc91ae169..fd76dc92dfbd7 100644 --- a/tests/ui/traits/cache-reached-depth-ice.stderr +++ b/tests/ui/traits/cache-reached-depth-ice.stderr @@ -1,8 +1,8 @@ error: evaluate(Binder { value: TraitPredicate(<A as std::marker::Send>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) - --> $DIR/cache-reached-depth-ice.rs:43:5 + --> $DIR/cache-reached-depth-ice.rs:44:5 | -LL | fn test<X: ?Sized + Send>() {} - | ---- predicate +LL | fn test<X: PointeeSized + Send>() {} + | ---- predicate ... LL | test::<A>(); | ^^^^^^^^^ 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 74a0a90885da5..8fb3104d2d96b 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,6 +19,18 @@ 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> { + | ^^^^^^^^^^ 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 | @@ -46,6 +58,6 @@ LL | where LL | Self::Assoc: A<T>, | ^^^^ required by this bound in `A::f` -error: aborting due to 5 previous errors +error: aborting due to 6 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 e91a48f62aec3..f92b2eaa6391e 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,6 +4,18 @@ 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 { + | ^^^^^^^^^^^ required by this bound in `Trait` + error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed` --> $DIR/normalize-param-env-4.rs:19:26 | @@ -22,6 +34,6 @@ note: required by a bound in `impls_trait` LL | fn impls_trait<T: Trait>() {} | ^^^^^ required by this bound in `impls_trait` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0275`. From cba7c2c8c691b30743eba8919fea054c861a0cd1 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 13 Feb 2025 17:47:49 +0000 Subject: [PATCH 17/43] feature/passes: add `rustc_non_const_sized` While there are no non-`const Sized` types in the language, this testing attribute will make it possible to force this for testing purposes. --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++++ compiler/rustc_passes/messages.ftl | 4 ++++ compiler/rustc_passes/src/check_attr.rs | 16 ++++++++++++++++ compiler/rustc_passes/src/errors.rs | 7 +++++++ compiler/rustc_span/src/symbol.rs | 1 + 5 files changed, 32 insertions(+) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fd936458f1115..81bbed617e9d8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1036,6 +1036,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes, "#[rustc_force_inline] forces a free function to be inlined" ), + rustc_attr!( + rustc_non_const_sized, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, + "#[rustc_non_const_sized] forces a type to not implement `const {Meta,Pointee,}Sized` for testing" + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 06398dd4f725b..54d0c773a844e 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -688,6 +688,10 @@ passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct .label = not a struct +passes_rustc_non_const_sized = + attribute should be applied to a struct or enum + .label = not a struct or enum + passes_rustc_pub_transparent = attribute should be applied to `#[repr(transparent)]` types .label = not a `#[repr(transparent)]` type diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9238c73cdb113..aa3b8badcce56 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -218,6 +218,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) } + [sym::rustc_non_const_sized, ..] => { + self.check_rustc_non_const_sized(span, target) + } [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target), [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target), @@ -2615,6 +2618,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + /// `#[rustc_non_const_sized]` is a testing attribute for forcing a type to only be `Sized`, + /// not `const Sized` (which almost all types implement) - it should only be applied to structs + /// or enums. This isn't equivalent to `!const Sized` or anything like that, it just means that + /// there isn't a `impl const Sized for T`, only `impl Sized for T` in the compiler. + fn check_rustc_non_const_sized(&self, span: Span, target: Target) { + match target { + Target::Struct | Target::Enum => (), + _ => { + self.dcx().emit_err(errors::RustcNonConstSized { attr_span: span }); + } + } + } + /// Checks if `#[autodiff]` is applied to an item other than a function item. fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) { debug!("check_autodiff"); diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index a72f40cd843a7..a344b1c2ec0a3 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -690,6 +690,13 @@ pub(crate) struct RustcForceInline { pub span: Span, } +#[derive(Diagnostic)] +#[diag(passes_rustc_non_const_sized)] +pub(crate) struct RustcNonConstSized { + #[primary_span] + pub attr_span: Span, +} + #[derive(Diagnostic)] #[diag(passes_rustc_force_inline_coro)] pub(crate) struct RustcForceInlineCoro { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 996e276c3a185..b7d83a0d874f0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1804,6 +1804,7 @@ symbols! { rustc_never_returns_null_ptr, rustc_never_type_options, rustc_no_mir_inline, + rustc_non_const_sized, rustc_nonnull_optimization_guaranteed, rustc_nounwind, rustc_object_lifetime_default, From 7cef03d6ba7611846a5a6ee78373f119e94b5e63 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 13 Feb 2025 17:48:34 +0000 Subject: [PATCH 18/43] library/trait_sel: make `{Meta,}Sized` const Makes `{Meta,}Sized` into const traits and implements them in the trait solvers so everything is `Sized` except ADTs with the `rustc_non_const_sized` attribute. --- compiler/rustc_middle/src/ty/adt.rs | 17 +++++ compiler/rustc_middle/src/ty/flags.rs | 6 +- .../src/solve/assembly/structural_traits.rs | 33 +++++++- .../src/solve/effect_goals.rs | 26 ++++++- .../src/traits/effects.rs | 42 +++++++++- compiler/rustc_type_ir/src/flags.rs | 3 + compiler/rustc_type_ir/src/visit.rs | 5 ++ library/core/src/marker.rs | 4 + tests/ui/sized-hierarchy/constness.rs | 38 ++++++++++ tests/ui/sized-hierarchy/constness.stderr | 76 +++++++++++++++++++ ...utually-exclusive-trait-bound-modifiers.rs | 2 +- 11 files changed, 243 insertions(+), 9 deletions(-) create mode 100644 tests/ui/sized-hierarchy/constness.rs create mode 100644 tests/ui/sized-hierarchy/constness.stderr diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 9ec1752d0b0d7..399a152d3b110 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -53,6 +53,13 @@ bitflags::bitflags! { const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. const IS_UNSAFE_CELL = 1 << 9; + /// Indicates whether the type is annotated with `#[rustc_non_const_sized]`. + /// + /// Necessary to know when to add a type flag since `TyCtxt` isn't available and the + /// presence of the attribute cannot be checked. + /// FIXME(sized-hierarchy): Consider removing this when scalable vectors are implemented + /// and `def.repr.scalable` can be checked. + const HAS_NON_CONST_SIZEDNESS = 1 << 10; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -288,6 +295,10 @@ impl AdtDefData { flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } + if tcx.has_attr(did, sym::rustc_non_const_sized) { + flags = flags | AdtFlags::HAS_NON_CONST_SIZEDNESS; + } + flags |= match kind { AdtKind::Enum => AdtFlags::IS_ENUM, AdtKind::Union => AdtFlags::IS_UNION, @@ -354,6 +365,12 @@ impl<'tcx> AdtDef<'tcx> { self.is_variant_list_non_exhaustive() && !self.did().is_local() } + /// Returns `true` if this type only has non-const implementations of sizedness traits. + #[inline] + pub fn has_non_const_sizedness(self) -> bool { + self.flags().contains(AdtFlags::HAS_NON_CONST_SIZEDNESS) + } + /// Returns the kind of the ADT. #[inline] pub fn adt_kind(self) -> AdtKind { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index b0c442d28f0a0..3070a18f06f93 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -129,7 +129,11 @@ impl FlagComputation { } }, - &ty::Adt(_, args) => { + &ty::Adt(def, args) => { + if def.has_non_const_sizedness() { + self.add_flags(TypeFlags::HAS_NON_CONST_SIZEDNESS); + } + self.add_args(args); } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index e32d86d0ce001..b40031704fe10 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -8,7 +8,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{ self as ty, Interner, Movability, Mutability, TypeFoldable, TypeFolder, TypeSuperFoldable, - Upcast as _, elaborate, + TypeVisitableExt as _, Upcast as _, elaborate, }; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; @@ -189,6 +189,37 @@ where } } +/// Returns the trait refs which need to hold for `self_ty`, with a given `sizedness` trait, to be +/// `const` - can return `Err(NoSolution)` if the given `self_ty` cannot be const. +/// +/// This only checks the conditions for constness, not the conditions for the given `sizedness` +/// trait to be implemented (see the trait goal for that), as these are orthogonal. This means that +/// the effect predicate can succeed while the trait predicate can fail - this is unintuitive but +/// allows this function to be much simpler. +// NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver. +#[instrument(level = "trace", skip(cx), ret)] +pub(in crate::solve) fn const_conditions_for_sizedness<I: Interner>( + cx: I, + self_ty: I::Ty, + sizedness: SizedTraitKind, +) -> Result<Vec<ty::TraitRef<I>>, NoSolution> { + // The specific degree of sizedness is orthogonal to whether a type implements any given + // sizedness trait const-ly or not. + if self_ty.has_non_const_sizedness() { + return Err(NoSolution); + } + + match sizedness { + SizedTraitKind::Sized => { + let meta_sized_def_id = cx.require_lang_item(TraitSolverLangItem::MetaSized); + let meta_sized_trait_ref = ty::TraitRef::new(cx, meta_sized_def_id, [self_ty]); + Ok(vec![meta_sized_trait_ref]) + } + SizedTraitKind::MetaSized => Ok(vec![]), + SizedTraitKind::PointeeSized => unreachable!("`PointeeSized` is not const"), + } +} + #[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<D, I>( ecx: &EvalCtxt<'_, D>, diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index b8666a1def3d7..1638f970937f3 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -200,11 +200,29 @@ where } fn consider_builtin_sizedness_candidates( - _ecx: &mut EvalCtxt<'_, D>, - _goal: Goal<I, Self>, - _sizedness: SizedTraitKind, + ecx: &mut EvalCtxt<'_, D>, + goal: Goal<I, Self>, + sizedness: SizedTraitKind, ) -> Result<Candidate<I>, NoSolution> { - unreachable!("Sized/MetaSized/PointeeSized is never const") + let cx = ecx.cx(); + + let self_ty = goal.predicate.self_ty(); + let const_conditions = + structural_traits::const_conditions_for_sizedness(cx, self_ty, sizedness)?; + + ecx.probe_builtin_trait_candidate(BuiltinImplSource::Trivial).enter(|ecx| { + ecx.add_goals( + GoalSource::AliasBoundConstCondition, + const_conditions.into_iter().map(|trait_ref| { + goal.with( + cx, + ty::Binder::dummy(trait_ref) + .to_host_effect_clause(cx, goal.predicate.constness), + ) + }), + ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } fn consider_builtin_copy_clone_candidate( diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 3c127416cbf7c..627eb2eb77760 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -5,9 +5,9 @@ use rustc_infer::traits::{ }; use rustc_middle::span_bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, TypingMode}; +use rustc_middle::ty::{self, TypeVisitableExt, TypingMode}; use rustc_type_ir::elaborate::elaborate; -use rustc_type_ir::solve::NoSolution; +use rustc_type_ir::solve::{NoSolution, SizedTraitKind}; use thin_vec::{ThinVec, thin_vec}; use super::SelectionContext; @@ -242,10 +242,48 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>( ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> { match selcx.tcx().as_lang_item(obligation.predicate.def_id()) { Some(LangItem::Destruct) => evaluate_host_effect_for_destruct_goal(selcx, obligation), + Some(LangItem::Sized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::Sized) + } + Some(LangItem::MetaSized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::MetaSized) + } + Some(LangItem::PointeeSized) => { + evaluate_host_effect_for_sizedness_goal(selcx, obligation, SizedTraitKind::PointeeSized) + } _ => Err(EvaluationFailure::NoSolution), } } +// NOTE: Keep this in sync with `const_conditions_for_sizedness` in the new solver. +fn evaluate_host_effect_for_sizedness_goal<'tcx>( + selcx: &mut SelectionContext<'_, 'tcx>, + obligation: &HostEffectObligation<'tcx>, + sizedness: SizedTraitKind, +) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> { + let tcx = selcx.tcx(); + let self_ty = obligation.predicate.self_ty(); + + if self_ty.has_non_const_sizedness() { + return Err(EvaluationFailure::NoSolution); + } + + match sizedness { + SizedTraitKind::Sized => { + let meta_sized_def_id = tcx.require_lang_item(LangItem::MetaSized, None); + let meta_sized_trait_ref = ty::TraitRef::new(tcx, meta_sized_def_id, [self_ty]); + let meta_sized_obligation = obligation.with( + tcx, + ty::Binder::dummy(meta_sized_trait_ref) + .to_host_effect_clause(tcx, obligation.predicate.constness), + ); + Ok(thin_vec![meta_sized_obligation]) + } + SizedTraitKind::MetaSized => Ok(thin_vec![]), + SizedTraitKind::PointeeSized => unreachable!("`PointeeSized` is not const"), + } +} + // NOTE: Keep this in sync with `const_conditions_for_destruct` in the new solver. fn evaluate_host_effect_for_destruct_goal<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6a2498242feeb..0673f969fe271 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -126,5 +126,8 @@ bitflags::bitflags! { /// Does this have any binders with bound vars (e.g. that need to be anonymized)? const HAS_BINDER_VARS = 1 << 23; + + /// Does this type only have non-const implementations of sizedness traits? + const HAS_NON_CONST_SIZEDNESS = 1 << 24; } } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 2285e0e75de04..d8d81257ab615 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -342,6 +342,11 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> { self.has_type_flags(TypeFlags::HAS_BOUND_VARS) } + /// Returns `true` if this type only has non-const implementations of sizedness traits. + fn has_non_const_sizedness(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_NON_CONST_SIZEDNESS) + } + /// Indicates whether this value still has parameters/placeholders/inference variables /// which could be replaced later, in a way that would change the results of `impl` /// specialization. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c1f05d952eedf..3a6b953cf2a98 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -151,6 +151,8 @@ unsafe impl<T: Sync + ?Sized + PointeeSized> Send for &T {} #[rustc_deny_explicit_impl] #[rustc_do_not_implement_via_object] #[rustc_coinductive] +#[cfg_attr(not(bootstrap), const_trait)] +#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "sized_hierarchy", issue = "none"))] pub trait Sized: MetaSized { // Empty. } @@ -167,6 +169,8 @@ pub trait Sized: MetaSized { #[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] #[rustc_do_not_implement_via_object] #[rustc_coinductive] +#[cfg_attr(not(bootstrap), const_trait)] +#[cfg_attr(not(bootstrap), rustc_const_unstable(feature = "sized_hierarchy", issue = "none"))] pub trait MetaSized: PointeeSized { // Empty } diff --git a/tests/ui/sized-hierarchy/constness.rs b/tests/ui/sized-hierarchy/constness.rs new file mode 100644 index 0000000000000..05694852d9eef --- /dev/null +++ b/tests/ui/sized-hierarchy/constness.rs @@ -0,0 +1,38 @@ +//@ compile-flags: -Zunstable-options +//@ edition: future +#![allow(internal_features)] +#![feature(rustc_attrs, const_trait_impl, sized_hierarchy)] + +#[rustc_non_const_sized] +struct NotConstSized; + +#[rustc_non_const_sized] +struct NotConstMetaSized([u8]); + +impl NotConstMetaSized { + fn new() -> &'static Self { unimplemented!() } +} + +const fn size_of<T: ~const Sized>() { unimplemented!() } +const fn size_of_val<T: ~const MetaSized>(_t: &T) { unimplemented!() } + +fn main() { + let _ = const { size_of::<NotConstSized>() }; +//~^ ERROR the trait bound `NotConstSized: const Sized` is not satisfied + let _ = size_of::<NotConstSized>(); + + let _ = const { size_of::<NotConstMetaSized>() }; +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + let _ = size_of::<NotConstMetaSized>(); +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + let v = NotConstSized; + let _ = const { size_of_val(&v) }; +//~^ ERROR attempt to use a non-constant value in a constant + let _ = size_of_val(&v); + + let v = NotConstMetaSized::new(); + let _ = const { size_of_val(v) }; +//~^ ERROR attempt to use a non-constant value in a constant + let _ = size_of_val(v); +} diff --git a/tests/ui/sized-hierarchy/constness.stderr b/tests/ui/sized-hierarchy/constness.stderr new file mode 100644 index 0000000000000..9234380e9a46a --- /dev/null +++ b/tests/ui/sized-hierarchy/constness.stderr @@ -0,0 +1,76 @@ +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/constness.rs:30:34 + | +LL | let _ = const { size_of_val(&v) }; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - let v = NotConstSized; +LL + const v: /* Type */ = NotConstSized; + | + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/constness.rs:35:33 + | +LL | let _ = const { size_of_val(v) }; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL - let v = NotConstSized; +LL + const v: /* Type */ = NotConstSized; + | + +error[E0277]: the trait bound `NotConstSized: const Sized` is not satisfied + --> $DIR/constness.rs:20:31 + | +LL | let _ = const { size_of::<NotConstSized>() }; + | ^^^^^^^^^^^^^ + | +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of<T: ~const Sized>() { unimplemented!() } + | ^^^^^^ required by this bound in `size_of` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/constness.rs:24:31 + | +LL | let _ = const { size_of::<NotConstMetaSized>() }; + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `NotConstMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `NotConstMetaSized` + --> $DIR/constness.rs:10:8 + | +LL | struct NotConstMetaSized([u8]); + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of<T: ~const Sized>() { unimplemented!() } + | ^^^^^^^^^^^^ required by this bound in `size_of` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/constness.rs:26:23 + | +LL | let _ = size_of::<NotConstMetaSized>(); + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `NotConstMetaSized`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `NotConstMetaSized` + --> $DIR/constness.rs:10:8 + | +LL | struct NotConstMetaSized([u8]); + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `size_of` + --> $DIR/constness.rs:16:21 + | +LL | const fn size_of<T: ~const Sized>() { unimplemented!() } + | ^^^^^^^^^^^^ required by this bound in `size_of` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0435. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs index aaab8e819a39c..e9dcad1026761 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, sized_hierarchy)] const fn maybe_const_maybe<T: ~const ?Sized>() {} //~^ ERROR `~const` trait not allowed with `?` trait polarity modifier From 47f7ea3786c82548e745c80db85ac56422eed386 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 23:36:05 +0000 Subject: [PATCH 19/43] aux: add `const {Meta,}Sized` to minicore Now that `MetaSized` and `Sized` are const traits, this must be reflected in minicore. --- tests/auxiliary/minicore.rs | 3 +++ tests/ui/traits/const-traits/auxiliary/minicore.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 052b29c5be04c..a5c13354774cf 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -26,6 +26,7 @@ f16, f128, asm_experimental_arch, + const_trait_impl, unboxed_closures )] #![allow(unused, improper_ctypes_definitions, internal_features)] @@ -44,9 +45,11 @@ macro_rules! impl_marker_trait { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] diff --git a/tests/ui/traits/const-traits/auxiliary/minicore.rs b/tests/ui/traits/const-traits/auxiliary/minicore.rs index 073337b2ac6db..37a48da789387 100644 --- a/tests/ui/traits/const-traits/auxiliary/minicore.rs +++ b/tests/ui/traits/const-traits/auxiliary/minicore.rs @@ -22,9 +22,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] From d489f351fe981a8739ef914a8fd7b3d11e32a2a5 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 23:36:31 +0000 Subject: [PATCH 20/43] tests: `const {Meta,}Sized` in non-minicore Now that `MetaSized` and `Sized` are const traits, this must be reflected in tests without minicore which define these language items. --- tests/assembly/rust-abi-arg-attr.rs | 4 +- tests/assembly/s390x-vector-abi.rs | 4 +- tests/assembly/small_data_threshold.rs | 4 +- .../item-collection/implicit-panic-call.rs | 4 +- tests/codegen/abi-x86-sse.rs | 4 +- .../codegen/emscripten-catch-unwind-js-eh.rs | 4 +- .../emscripten-catch-unwind-wasm-eh.rs | 4 +- tests/codegen/terminating-catchpad.rs | 4 +- tests/codegen/unwind-abis/aapcs-unwind-abi.rs | 4 +- .../unwind-abis/fastcall-unwind-abi.rs | 4 +- .../codegen/unwind-abis/stdcall-unwind-abi.rs | 4 +- .../codegen/unwind-abis/sysv64-unwind-abi.rs | 4 +- .../unwind-abis/thiscall-unwind-abi.rs | 4 +- .../unwind-abis/vectorcall-unwind-abi.rs | 4 +- tests/codegen/unwind-abis/win64-unwind-abi.rs | 4 +- .../mir-opt/inline/inline_instruction_set.rs | 4 +- tests/run-make/amdgpu-kd/foo.rs | 3 + .../atomic-lock-free/atomic_lock_free.rs | 4 +- .../avr-rjmp-offset/avr-rjmp-offsets.rs | 3 + .../min-global-align/min_global_align.rs | 4 +- tests/run-make/simd-ffi/simd.rs | 4 +- tests/run-make/target-specs/foo.rs | 4 +- tests/ui/amdgpu-require-explicit-cpu.rs | 4 +- tests/ui/codegen/mismatched-data-layouts.rs | 4 +- tests/ui/debuginfo/dwarf-versions.rs | 4 +- .../branch-protection-missing-pac-ret.rs | 4 +- tests/ui/lang-items/issue-83471.rs | 4 +- tests/ui/lang-items/issue-83471.stderr | 12 ++-- tests/ui/lang-items/issue-87573.rs | 4 +- tests/ui/lang-items/issue-87573.stderr | 4 +- .../lang-item-generic-requirements.rs | 4 +- .../lang-item-generic-requirements.stderr | 18 +++--- .../missing-copy-lang-item-issue-19660.rs | 4 +- .../missing-copy-lang-item-issue-19660.stderr | 2 +- .../start_lang_item_args.argc.stderr | 2 +- .../start_lang_item_args.argv.stderr | 2 +- ...start_lang_item_args.argv_inner_ptr.stderr | 2 +- .../start_lang_item_args.main_args.stderr | 2 +- .../start_lang_item_args.main_ret.stderr | 2 +- .../start_lang_item_args.main_ty.stderr | 2 +- ...art_lang_item_args.missing_all_args.stderr | 2 +- .../start_lang_item_args.missing_ret.stderr | 2 +- ..._lang_item_args.missing_sigpipe_arg.stderr | 2 +- tests/ui/lang-items/start_lang_item_args.rs | 4 +- .../start_lang_item_args.sigpipe.stderr | 2 +- .../start_lang_item_args.start_ret.stderr | 2 +- .../start_lang_item_args.too_many_args.stderr | 2 +- .../start_lang_item_with_target_feature.rs | 3 + ...start_lang_item_with_target_feature.stderr | 2 +- .../panic-handler-requires-panic-info.rs | 4 +- tests/ui/privacy/privacy1.rs | 4 +- tests/ui/privacy/privacy1.stderr | 62 +++++++++---------- tests/ui/privacy/privacy4.rs | 6 +- .../warn-stack-protector-unsupported.rs | 4 +- ...owed-softfloat-target-feature-attribute.rs | 4 +- ...d-softfloat-target-feature-flag-disable.rs | 4 +- tests/ui/target-feature/feature-hierarchy.rs | 4 +- ...dden-hardfloat-target-feature-attribute.rs | 4 +- ...-hardfloat-target-feature-attribute.stderr | 2 +- ...oat-target-feature-flag-disable-implied.rs | 4 +- ...dfloat-target-feature-flag-disable-neon.rs | 4 +- ...n-hardfloat-target-feature-flag-disable.rs | 4 +- .../forbidden-target-feature-attribute.rs | 4 +- .../forbidden-target-feature-attribute.stderr | 2 +- .../forbidden-target-feature-cfg.rs | 4 +- .../forbidden-target-feature-flag-disable.rs | 4 +- .../forbidden-target-feature-flag.rs | 4 +- ...arget-cpu-lacks-required-target-feature.rs | 4 +- tests/ui/target-feature/tied-features-cli.rs | 4 +- .../tied-features-no-implication-1.rs | 4 +- .../tied-features-no-implication.pacg.stderr | 2 +- .../tied-features-no-implication.rs | 4 +- 72 files changed, 218 insertions(+), 115 deletions(-) diff --git a/tests/assembly/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs index 4f3673ccfc3b9..5a5ed1f442368 100644 --- a/tests/assembly/rust-abi-arg-attr.rs +++ b/tests/assembly/rust-abi-arg-attr.rs @@ -9,7 +9,7 @@ //@ [loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@ [loongarch64] needs-llvm-components: loongarch -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] @@ -19,9 +19,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/assembly/s390x-vector-abi.rs b/tests/assembly/s390x-vector-abi.rs index fcf42664034c6..7e176b17648ee 100644 --- a/tests/assembly/s390x-vector-abi.rs +++ b/tests/assembly/s390x-vector-abi.rs @@ -11,7 +11,7 @@ //@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector //@[z13_no_vector] needs-llvm-components: systemz -#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![feature(no_core, lang_items, repr_simd, s390x_target_feature, const_trait_impl)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types)] @@ -22,9 +22,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} diff --git a/tests/assembly/small_data_threshold.rs b/tests/assembly/small_data_threshold.rs index 2abe8687d8b26..cd5afcbab39be 100644 --- a/tests/assembly/small_data_threshold.rs +++ b/tests/assembly/small_data_threshold.rs @@ -14,7 +14,7 @@ //@ [M68K] compile-flags: --target=m68k-unknown-linux-gnu //@ [M68K] needs-llvm-components: m68k -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_std] #![no_core] #![crate_type = "lib"] @@ -23,9 +23,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "drop_in_place"] diff --git a/tests/codegen-units/item-collection/implicit-panic-call.rs b/tests/codegen-units/item-collection/implicit-panic-call.rs index 3f368bed88e59..4c1c792d87b1a 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -3,7 +3,7 @@ // rust-lang/rust#90405 // Ensure implicit panic calls are collected -#![feature(lang_items)] +#![feature(lang_items, const_trait_impl)] #![feature(no_core)] #![crate_type = "lib"] #![no_core] @@ -34,9 +34,11 @@ fn panic_div_overflow() -> ! { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs index 21b5eff4f489b..4ea66ece09167 100644 --- a/tests/codegen/abi-x86-sse.rs +++ b/tests/codegen/abi-x86-sse.rs @@ -12,14 +12,16 @@ //@[x86-32-nosse] compile-flags: --target i586-unknown-linux-gnu //@[x86-32-nosse] needs-llvm-components: x86 -#![feature(no_core, lang_items, rustc_attrs, repr_simd)] +#![feature(no_core, lang_items, const_trait_impl, rustc_attrs, repr_simd)] #![no_core] #![crate_type = "lib"] #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[lang = "meta_sized"] +#[const_trait] trait MetaSized: PointeeSized {} #[lang = "pointee_sized"] diff --git a/tests/codegen/emscripten-catch-unwind-js-eh.rs b/tests/codegen/emscripten-catch-unwind-js-eh.rs index 1bffa8a3c0f56..909444fbe16d1 100644 --- a/tests/codegen/emscripten-catch-unwind-js-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-js-eh.rs @@ -4,7 +4,7 @@ // Emscripten has its own unique implementation of catch_unwind (in `codegen_emcc_try`), // make sure it generates something reasonable. -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] @@ -13,9 +13,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} diff --git a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs index 6019d6bd30a21..2f787a7456ae4 100644 --- a/tests/codegen/emscripten-catch-unwind-wasm-eh.rs +++ b/tests/codegen/emscripten-catch-unwind-wasm-eh.rs @@ -3,7 +3,7 @@ // Emscripten catch_unwind using wasm exceptions -#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(no_core, lang_items, intrinsics, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] @@ -12,9 +12,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "freeze"] trait Freeze {} diff --git a/tests/codegen/terminating-catchpad.rs b/tests/codegen/terminating-catchpad.rs index a2ec19871d1fc..76fa7cd444734 100644 --- a/tests/codegen/terminating-catchpad.rs +++ b/tests/codegen/terminating-catchpad.rs @@ -10,7 +10,7 @@ // - `catchpad ... [ptr null]` on Wasm (otherwise LLVM gets confused) // - `catchpad ... [ptr null, i32 64, ptr null]` on Windows (otherwise we catch SEH exceptions) -#![feature(no_core, lang_items, rustc_attrs)] +#![feature(no_core, lang_items, rustc_attrs, const_trait_impl)] #![crate_type = "lib"] #![no_std] #![no_core] @@ -19,9 +19,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} unsafe extern "C-unwind" { diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs index ecace722e0dbe..44f50aecf3858 100644 --- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs +++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: arm //@ compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `aapcs` and diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs index 7df46813ed1dd..2ef9b89c75e11 100644 --- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `fastcall` and diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs index cc06ee125495a..ce416e1ea4f0a 100644 --- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `stdcall` and `stdcall-unwind` diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs index 69bfaf80b4be6..32044df962206 100644 --- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `sysv64` and diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs index 05f6b8b70e171..54d404cad1c62 100644 --- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `thiscall` and diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs index d001a16b32a1c..e446fa26770d4 100644 --- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs +++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items, abi_vectorcall)] +#![feature(no_core, lang_items, abi_vectorcall, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `vectorcall` and diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs index 257f00b54e4d8..bb77ac4c96639 100644 --- a/tests/codegen/unwind-abis/win64-unwind-abi.rs +++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs @@ -1,15 +1,17 @@ //@ needs-llvm-components: x86 //@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes #![no_core] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Test that `nounwind` attributes are correctly applied to exported `win64` and diff --git a/tests/mir-opt/inline/inline_instruction_set.rs b/tests/mir-opt/inline/inline_instruction_set.rs index fe2aaffa2a09c..e8fa01c5b4cfb 100644 --- a/tests/mir-opt/inline/inline_instruction_set.rs +++ b/tests/mir-opt/inline/inline_instruction_set.rs @@ -7,7 +7,7 @@ #![crate_type = "lib"] #![feature(rustc_attrs)] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![feature(isa_attribute)] #![no_core] @@ -26,9 +26,11 @@ macro_rules! asm { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/amdgpu-kd/foo.rs b/tests/run-make/amdgpu-kd/foo.rs index a097e9211a799..f87f69390cd38 100644 --- a/tests/run-make/amdgpu-kd/foo.rs +++ b/tests/run-make/amdgpu-kd/foo.rs @@ -1,5 +1,6 @@ #![allow(internal_features)] #![feature(no_core, lang_items, abi_gpu_kernel)] +#![feature(const_trait_impl)] #![no_core] #![no_std] @@ -8,9 +9,11 @@ trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[no_mangle] diff --git a/tests/run-make/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs index 1a83a5b8072be..be02af89b0771 100644 --- a/tests/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/tests/run-make/atomic-lock-free/atomic_lock_free.rs @@ -1,4 +1,4 @@ -#![feature(no_core, intrinsics, lang_items)] +#![feature(no_core, intrinsics, lang_items, const_trait_impl)] #![crate_type = "rlib"] #![no_core] @@ -10,9 +10,11 @@ extern "rust-intrinsic" { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] trait Copy {} diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index 3b84d8aa71cc5..a9c92a85f039e 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -3,6 +3,7 @@ //! The function [`delay()`] is removed, as it is not necessary to trigger the //! wrong behavior and would require some additional lang items. #![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![no_main] #![allow(internal_features)] @@ -28,9 +29,11 @@ mod minicore { pub trait PointeeSized {} #[lang = "meta_sized"] + #[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] + #[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/run-make/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs index fd6f83570300a..cda3c058d141d 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -1,4 +1,4 @@ -#![feature(no_core, lang_items, freeze_impls)] +#![feature(no_core, lang_items, freeze_impls, const_trait_impl)] #![crate_type = "rlib"] #![no_core] @@ -13,9 +13,11 @@ pub static CONST_BOOL_REF: &'static bool = &CONST_BOOL; pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs index 1cd961ff87e7b..d9ef4ec45e339 100644 --- a/tests/run-make/simd-ffi/simd.rs +++ b/tests/run-make/simd-ffi/simd.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] // we can compile to a variety of platforms, because we don't need // cross-compiled standard libraries. -#![feature(no_core, auto_traits)] +#![feature(no_core, auto_traits, const_trait_impl)] #![no_core] #![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)] @@ -56,9 +56,11 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/run-make/target-specs/foo.rs b/tests/run-make/target-specs/foo.rs index aead76dff87c2..945e6dfed5088 100644 --- a/tests/run-make/target-specs/foo.rs +++ b/tests/run-make/target-specs/foo.rs @@ -1,4 +1,4 @@ -#![feature(lang_items, no_core, auto_traits)] +#![feature(lang_items, no_core, auto_traits, const_trait_impl)] #![no_core] #[lang = "copy"] @@ -8,9 +8,11 @@ trait Copy {} pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[lang = "freeze"] diff --git a/tests/ui/amdgpu-require-explicit-cpu.rs b/tests/ui/amdgpu-require-explicit-cpu.rs index cf48cc191c82c..b3e7fd305f520 100644 --- a/tests/ui/amdgpu-require-explicit-cpu.rs +++ b/tests/ui/amdgpu-require-explicit-cpu.rs @@ -8,16 +8,18 @@ //@[cpu] compile-flags: -Ctarget-cpu=gfx900 //@[cpu] build-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index cf760c37d109a..2b94fd9027f35 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -7,14 +7,16 @@ //@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" //@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" -#![feature(lang_items, no_core, auto_traits)] +#![feature(lang_items, no_core, auto_traits, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/debuginfo/dwarf-versions.rs b/tests/ui/debuginfo/dwarf-versions.rs index e9831ff2c2ad9..a58227522f328 100644 --- a/tests/ui/debuginfo/dwarf-versions.rs +++ b/tests/ui/debuginfo/dwarf-versions.rs @@ -27,7 +27,7 @@ //@ compile-flags: -g --target x86_64-unknown-linux-gnu --crate-type cdylib //@ needs-llvm-components: x86 -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![no_std] @@ -36,9 +36,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} pub fn foo() {} diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs index 403395906248c..0d1c00e4e3582 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs @@ -10,14 +10,16 @@ //@ [BADTARGET] needs-llvm-components: x86 #![crate_type = "lib"] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/lang-items/issue-83471.rs b/tests/ui/lang-items/issue-83471.rs index f3ce9f25c1360..5e7554b3e64e0 100644 --- a/tests/ui/lang-items/issue-83471.rs +++ b/tests/ui/lang-items/issue-83471.rs @@ -1,7 +1,7 @@ // Regression test for the ICE reported in issue #83471. #![crate_type="lib"] -#![feature(no_core)] +#![feature(no_core, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] @@ -10,10 +10,12 @@ pub trait PointeeSized {} #[lang = "meta_sized"] //~^ ERROR: lang items are subject to change [E0658] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] //~^ ERROR: lang items are subject to change [E0658] +#[const_trait] trait Sized: MetaSized {} #[lang = "fn"] diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index e913c0bf10fd0..ef5f77369434b 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -1,5 +1,5 @@ error[E0573]: expected type, found built-in attribute `export_name` - --> $DIR/issue-83471.rs:23:13 + --> $DIR/issue-83471.rs:25:13 | LL | fn call(export_name); | ^^^^^^^^^^^ not a type @@ -23,7 +23,7 @@ LL | #[lang = "meta_sized"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: lang items are subject to change - --> $DIR/issue-83471.rs:15:1 + --> $DIR/issue-83471.rs:16:1 | LL | #[lang = "sized"] | ^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | #[lang = "sized"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: lang items are subject to change - --> $DIR/issue-83471.rs:19:1 + --> $DIR/issue-83471.rs:21:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | #[lang = "fn"] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: anonymous parameters are deprecated and will be removed in the next edition - --> $DIR/issue-83471.rs:23:13 + --> $DIR/issue-83471.rs:25:13 | LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` @@ -51,7 +51,7 @@ LL | fn call(export_name); = note: `#[warn(anonymous_parameters)]` on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument - --> $DIR/issue-83471.rs:19:1 + --> $DIR/issue-83471.rs:21:1 | LL | #[lang = "fn"] | ^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | trait Fn { | - this trait has 0 generic arguments error[E0425]: cannot find function `a` in this scope - --> $DIR/issue-83471.rs:29:5 + --> $DIR/issue-83471.rs:31:5 | LL | a() | ^ not found in this scope diff --git a/tests/ui/lang-items/issue-87573.rs b/tests/ui/lang-items/issue-87573.rs index 97146df0ba766..6d5a5435ab965 100644 --- a/tests/ui/lang-items/issue-87573.rs +++ b/tests/ui/lang-items/issue-87573.rs @@ -1,7 +1,7 @@ // Regression test for #87573, ensures that duplicate lang items or invalid generics // for lang items doesn't cause ICE. -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![crate_type = "lib"] @@ -11,9 +11,11 @@ pub static STATIC_BOOL: bool = true; pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/ui/lang-items/issue-87573.stderr b/tests/ui/lang-items/issue-87573.stderr index 07f4f5d8ac86f..3a7e3c9bdc53c 100644 --- a/tests/ui/lang-items/issue-87573.stderr +++ b/tests/ui/lang-items/issue-87573.stderr @@ -1,5 +1,5 @@ error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/issue-87573.rs:26:1 + --> $DIR/issue-87573.rs:28:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | fn drop_fn() { | - this function has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/issue-87573.rs:32:1 + --> $DIR/issue-87573.rs:34:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs index e127f4baaa49c..1bb3e282c319c 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.rs +++ b/tests/ui/lang-items/lang-item-generic-requirements.rs @@ -1,16 +1,18 @@ // Checks that declaring a lang item with the wrong number of generic arguments errors rather than // crashing (issue #83474, #83893, #87573, part of #9307, #79559). -#![feature(lang_items, no_core)] +#![feature(lang_items, no_core, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait MyPointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MyMetaSized: MyPointeeSized {} #[lang = "sized"] +#[const_trait] trait MySized: MyMetaSized {} #[lang = "add"] diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr index aa67a9ca92143..9062289a49cfc 100644 --- a/tests/ui/lang-items/lang-item-generic-requirements.stderr +++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr @@ -1,5 +1,5 @@ error[E0718]: `add` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:16:1 + --> $DIR/lang-item-generic-requirements.rs:18:1 | LL | #[lang = "add"] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | trait MyAdd<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `drop_in_place` lang item must be applied to a function with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:20:1 + --> $DIR/lang-item-generic-requirements.rs:22:1 | LL | #[lang = "drop_in_place"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | fn my_ptr_drop() {} | - this function has 0 generic arguments error[E0718]: `index` lang item must be applied to a trait with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:24:1 + --> $DIR/lang-item-generic-requirements.rs:26:1 | LL | #[lang = "index"] | ^^^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | trait MyIndex<'a, T> {} | ------- this trait has 2 generic arguments error[E0718]: `phantom_data` lang item must be applied to a struct with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:28:1 + --> $DIR/lang-item-generic-requirements.rs:30:1 | LL | #[lang = "phantom_data"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>; | ------ this struct has 2 generic arguments error[E0718]: `owned_box` lang item must be applied to a struct with at least 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:34:1 + --> $DIR/lang-item-generic-requirements.rs:36:1 | LL | #[lang = "owned_box"] | ^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | struct Foo; | - this struct has 0 generic arguments error[E0718]: `start` lang item must be applied to a function with 1 generic argument - --> $DIR/lang-item-generic-requirements.rs:40:1 + --> $DIR/lang-item-generic-requirements.rs:42:1 | LL | #[lang = "start"] | ^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize { | - this function has 0 generic arguments error[E0392]: type parameter `T` is never used - --> $DIR/lang-item-generic-requirements.rs:30:22 + --> $DIR/lang-item-generic-requirements.rs:32:22 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -60,7 +60,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead error[E0392]: type parameter `U` is never used - --> $DIR/lang-item-generic-requirements.rs:30:25 + --> $DIR/lang-item-generic-requirements.rs:32:25 | LL | struct MyPhantomData<T, U>; | ^ unused type parameter @@ -69,7 +69,7 @@ LL | struct MyPhantomData<T, U>; = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead error[E0369]: cannot add `{integer}` to `{integer}` - --> $DIR/lang-item-generic-requirements.rs:50:7 + --> $DIR/lang-item-generic-requirements.rs:52:7 | LL | r + a; | - ^ - {integer} diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs index 6e17023d4f96f..76ed8a79e698a 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs @@ -1,6 +1,6 @@ //@ error-pattern: requires `copy` lang_item -#![feature(lang_items, no_core)] +#![feature(lang_items, no_core, const_trait_impl)] #![no_core] #![no_main] @@ -8,9 +8,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized { } struct S; diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr index 79d912d5a8da5..26701e7a66ad1 100644 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr +++ b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr @@ -1,5 +1,5 @@ error: requires `copy` lang_item - --> $DIR/missing-copy-lang-item-issue-19660.rs:20:5 + --> $DIR/missing-copy-lang-item-issue-19660.rs:22:5 | LL | argc | ^^^^ diff --git a/tests/ui/lang-items/start_lang_item_args.argc.stderr b/tests/ui/lang-items/start_lang_item_args.argc.stderr index 82fd374a1c5b1..e02c50921ba94 100644 --- a/tests/ui/lang-items/start_lang_item_args.argc.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argc.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:79:38 + --> $DIR/start_lang_item_args.rs:81:38 | LL | fn start<T>(_main: fn() -> T, _argc: i8, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^ expected `isize`, found `i8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv.stderr b/tests/ui/lang-items/start_lang_item_args.argv.stderr index 6095f8fa53299..1ba43af06f7b4 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:93:52 + --> $DIR/start_lang_item_args.rs:95:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: u8, _sigpipe: u8) -> isize { | ^^ expected `*const *const u8`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr index 2a295c8990b38..5c868ea7d02fa 100644 --- a/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr +++ b/tests/ui/lang-items/start_lang_item_args.argv_inner_ptr.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:86:52 + --> $DIR/start_lang_item_args.rs:88:52 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const usize, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^ expected `u8`, found `usize` diff --git a/tests/ui/lang-items/start_lang_item_args.main_args.stderr b/tests/ui/lang-items/start_lang_item_args.main_args.stderr index 027fd16d41040..3c5ccfb31e2c7 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:65:1 + --> $DIR/start_lang_item_args.rs:67:1 | LL | fn start<T>(_main: fn(i32) -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr index 0f295d350d1b9..082a07026601d 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:72:20 + --> $DIR/start_lang_item_args.rs:74:20 | LL | fn start<T>(_main: fn() -> u16, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | - ^^^^^^^^^^^ expected type parameter `T`, found `u16` diff --git a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr index 6e462c8b1a7c8..32896ed12dbfc 100644 --- a/tests/ui/lang-items/start_lang_item_args.main_ty.stderr +++ b/tests/ui/lang-items/start_lang_item_args.main_ty.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:58:20 + --> $DIR/start_lang_item_args.rs:60:20 | LL | fn start<T>(_main: u64, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { | ^^^ expected fn pointer, found `u64` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr index 90fa5e0d575f1..a5850a156bb4b 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_all_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:19:1 + --> $DIR/start_lang_item_args.rs:21:1 | LL | fn start<T>() -> isize { | ^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr index 879917cc80067..9eeead57ca2b4 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:33:83 + --> $DIR/start_lang_item_args.rs:35:83 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {} | ^ expected `isize`, found `()` diff --git a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr index d756909d73542..cd97d7160bc5c 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_sigpipe_arg.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:26:1 + --> $DIR/start_lang_item_args.rs:28:1 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters diff --git a/tests/ui/lang-items/start_lang_item_args.rs b/tests/ui/lang-items/start_lang_item_args.rs index 1da761545a8ff..64298ba09e30d 100644 --- a/tests/ui/lang-items/start_lang_item_args.rs +++ b/tests/ui/lang-items/start_lang_item_args.rs @@ -2,14 +2,16 @@ //@ revisions: missing_all_args missing_sigpipe_arg missing_ret start_ret too_many_args //@ revisions: main_ty main_args main_ret argc argv_inner_ptr argv sigpipe -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] #[lang = "copy"] pub trait Copy {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "pointee_sized"] pub trait PointeeSized {} diff --git a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr index ba1dd4b4f793b..fd33c64992bfd 100644 --- a/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr +++ b/tests/ui/lang-items/start_lang_item_args.sigpipe.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:100:80 + --> $DIR/start_lang_item_args.rs:102:80 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: i64) -> isize { | ^^^ expected `u8`, found `i64` diff --git a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr index a11867997d393..05958ec9921eb 100644 --- a/tests/ui/lang-items/start_lang_item_args.start_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.start_ret.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:38:87 + --> $DIR/start_lang_item_args.rs:40:87 | LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> u8 { | ^^ expected `isize`, found `u8` diff --git a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr index ecccf8c74bc3d..8a216a526e663 100644 --- a/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr +++ b/tests/ui/lang-items/start_lang_item_args.too_many_args.stderr @@ -1,5 +1,5 @@ error[E0308]: lang item `start` function has wrong type - --> $DIR/start_lang_item_args.rs:45:1 + --> $DIR/start_lang_item_args.rs:47:1 | LL | / fn start<T>( LL | | diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.rs b/tests/ui/lang-items/start_lang_item_with_target_feature.rs index 19036819d3d80..46256697eb3b4 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.rs +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.rs @@ -2,6 +2,7 @@ //@ check-fail #![feature(lang_items, no_core)] +#![feature(const_trait_impl)] #![no_core] #[lang = "copy"] @@ -11,9 +12,11 @@ pub trait Copy {} pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "start"] diff --git a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr index ce0b1d7557445..92d2e2409e38c 100644 --- a/tests/ui/lang-items/start_lang_item_with_target_feature.stderr +++ b/tests/ui/lang-items/start_lang_item_with_target_feature.stderr @@ -1,5 +1,5 @@ error: `start` lang item function is not allowed to have `#[target_feature]` - --> $DIR/start_lang_item_with_target_feature.rs:20:1 + --> $DIR/start_lang_item_with_target_feature.rs:23:1 | LL | #[target_feature(enable = "avx2")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs index 618ac7d88ddf2..c9414b2764203 100644 --- a/tests/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/tests/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -1,7 +1,7 @@ //@ compile-flags:-C panic=abort #![feature(lang_items)] -#![feature(no_core)] +#![feature(no_core, const_trait_impl)] #![no_core] #![no_main] @@ -15,7 +15,9 @@ fn panic() -> ! { pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 8ec2befcd0b34..8c4d457a5f4c7 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -1,10 +1,12 @@ -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "pointee_sized"] diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 2cbdbb3ff9513..39159e6e8517c 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -1,54 +1,54 @@ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:138:18 + --> $DIR/privacy1.rs:140:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:138:18 + --> $DIR/privacy1.rs:140:18 | LL | use bar::baz::{foo, bar}; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:147:18 + --> $DIR/privacy1.rs:149:18 | LL | use bar::baz; | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `i` is private - --> $DIR/privacy1.rs:171:20 + --> $DIR/privacy1.rs:173:20 | LL | use self::foo::i::A; | ^ private module | note: the module `i` is defined here - --> $DIR/privacy1.rs:176:9 + --> $DIR/privacy1.rs:178:9 | LL | mod i { | ^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:110:16 + --> $DIR/privacy1.rs:112:16 | LL | ::bar::baz::A::foo(); | ^^^ - struct `A` is not publicly re-exported @@ -56,13 +56,13 @@ LL | ::bar::baz::A::foo(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:111:16 + --> $DIR/privacy1.rs:113:16 | LL | ::bar::baz::A::bar(); | ^^^ - struct `A` is not publicly re-exported @@ -70,13 +70,13 @@ LL | ::bar::baz::A::bar(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:113:16 + --> $DIR/privacy1.rs:115:16 | LL | ::bar::baz::A.foo2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -84,13 +84,13 @@ LL | ::bar::baz::A.foo2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:114:16 + --> $DIR/privacy1.rs:116:16 | LL | ::bar::baz::A.bar2(); | ^^^ - unit struct `A` is not publicly re-exported @@ -98,13 +98,13 @@ LL | ::bar::baz::A.bar2(); | private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:118:16 + --> $DIR/privacy1.rs:120:16 | LL | ::bar::B::foo(); | ^ --- associated function `foo` is not publicly re-exported @@ -112,31 +112,31 @@ LL | ::bar::B::foo(); | private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:46:5 + --> $DIR/privacy1.rs:48:5 | LL | trait B { | ^^^^^^^ error[E0603]: function `epriv` is private - --> $DIR/privacy1.rs:124:20 + --> $DIR/privacy1.rs:126:20 | LL | ::bar::epriv(); | ^^^^^ private function | note: the function `epriv` is defined here - --> $DIR/privacy1.rs:71:9 + --> $DIR/privacy1.rs:73:9 | LL | fn epriv(); | ^^^^^^^^^^^ error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:133:16 + --> $DIR/privacy1.rs:135:16 | LL | ::bar::baz::foo(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ @@ -147,13 +147,13 @@ LL + bar::foo(); | error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:134:16 + --> $DIR/privacy1.rs:136:16 | LL | ::bar::baz::bar(); | ^^^ private module | note: the module `baz` is defined here - --> $DIR/privacy1.rs:56:5 + --> $DIR/privacy1.rs:58:5 | LL | mod baz { | ^^^^^^^ @@ -164,19 +164,19 @@ LL + bar::bar(); | error[E0603]: trait `B` is private - --> $DIR/privacy1.rs:163:17 + --> $DIR/privacy1.rs:165:17 | LL | impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } | ^ private trait | note: the trait `B` is defined here - --> $DIR/privacy1.rs:46:5 + --> $DIR/privacy1.rs:48:5 | LL | trait B { | ^^^^^^^ error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:83:23 + --> $DIR/privacy1.rs:85:23 | LL | fn bar() {} | -------- private associated function defined here @@ -185,7 +185,7 @@ LL | self::baz::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:101:13 + --> $DIR/privacy1.rs:103:13 | LL | fn bar() {} | -------- private associated function defined here @@ -194,7 +194,7 @@ LL | bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:108:19 + --> $DIR/privacy1.rs:110:19 | LL | fn bar() {} | -------- private associated function defined here @@ -203,7 +203,7 @@ LL | ::bar::A::bar(); | ^^^ private associated function error[E0624]: associated function `bar` is private - --> $DIR/privacy1.rs:111:24 + --> $DIR/privacy1.rs:113:24 | LL | fn bar() {} | -------- private associated function defined here @@ -212,7 +212,7 @@ LL | ::bar::baz::A::bar(); | ^^^ private associated function error[E0624]: method `bar2` is private - --> $DIR/privacy1.rs:114:23 + --> $DIR/privacy1.rs:116:23 | LL | fn bar2(&self) {} | -------------- private method defined here diff --git a/tests/ui/privacy/privacy4.rs b/tests/ui/privacy/privacy4.rs index 6091613271fdf..4573227f9c3b6 100644 --- a/tests/ui/privacy/privacy4.rs +++ b/tests/ui/privacy/privacy4.rs @@ -1,8 +1,8 @@ -#![feature(lang_items, no_core)] +#![feature(lang_items, const_trait_impl, no_core)] #![no_core] // makes debugging this test *a lot* easier (during resolve) -#[lang = "sized"] pub trait Sized: MetaSized {} -#[lang = "meta_sized"] pub trait MetaSized: PointeeSized {} +#[lang = "sized"] #[const_trait] pub trait Sized: MetaSized {} +#[lang = "meta_sized"] #[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang="copy"] pub trait Copy {} diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index 5dc8968557b0f..bdfacf7e9bf65 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -7,7 +7,7 @@ //@ [basic] compile-flags: -Z stack-protector=basic #![crate_type = "lib"] -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_std] #![no_core] @@ -15,9 +15,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs index 0c90c573c5046..eac6590c5eb7e 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-attribute.rs @@ -1,16 +1,18 @@ //@ compile-flags: --target=x86_64-unknown-none --crate-type=lib //@ needs-llvm-components: x86 //@ build-pass -#![feature(no_core, lang_items, x87_target_feature)] +#![feature(no_core, lang_items, x87_target_feature, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[target_feature(enable = "x87")] diff --git a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs index c53610c190518..b54055b1d6996 100644 --- a/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/allowed-softfloat-target-feature-flag-disable.rs @@ -2,14 +2,16 @@ //@ needs-llvm-components: x86 //@ compile-flags: -Ctarget-feature=-x87 //@ build-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index ccf32a35f72e7..3b6d3695c1228 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -6,7 +6,7 @@ //@ build-pass #![no_core] #![crate_type = "rlib"] -#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api)] +#![feature(intrinsics, rustc_attrs, no_core, lang_items, staged_api, const_trait_impl)] #![stable(feature = "test", since = "1.0.0")] // Tests vetting "feature hierarchies" in the cases where we impose them. @@ -16,9 +16,11 @@ trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] trait Sized: MetaSized {} #[lang = "copy"] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs index e96e17a42121a..45ecf83924e64 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.rs @@ -1,16 +1,18 @@ //! Ensure ABI-incompatible features cannot be enabled via `#[target_feature]`. //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv -#![feature(no_core, lang_items, riscv_target_feature)] +#![feature(no_core, lang_items, riscv_target_feature, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[target_feature(enable = "d")] diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr index d9a57412195d1..4c2ef450c3915 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `d` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI - --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:16:18 + --> $DIR/forbidden-hardfloat-target-feature-attribute.rs:18:18 | LL | #[target_feature(enable = "d")] | ^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs index f1891d0c21268..757bdc7f0a1b2 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-implied.rs @@ -6,14 +6,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs index 4514c84df8f19..0ec96559d7859 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable-neon.rs @@ -4,14 +4,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs index 00cf249524d9a..06cf7b4c41d84 100644 --- a/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-hardfloat-target-feature-flag-disable.rs @@ -5,14 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: must be enabled to ensure that the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.rs b/tests/ui/target-feature/forbidden-target-feature-attribute.rs index a59747ec80ffd..62e2da63a3dbd 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.rs +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.rs @@ -1,16 +1,18 @@ //! Ensure "forbidden" target features cannot be enabled via `#[target_feature]`. //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} #[target_feature(enable = "forced-atomics")] diff --git a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr index 65814e8edcf61..bcce824f5ef5c 100644 --- a/tests/ui/target-feature/forbidden-target-feature-attribute.stderr +++ b/tests/ui/target-feature/forbidden-target-feature-attribute.stderr @@ -1,5 +1,5 @@ error: target feature `forced-atomics` cannot be enabled with `#[target_feature]`: unsound because it changes the ABI of atomic operations - --> $DIR/forbidden-target-feature-attribute.rs:16:18 + --> $DIR/forbidden-target-feature-attribute.rs:18:18 | LL | #[target_feature(enable = "forced-atomics")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/forbidden-target-feature-cfg.rs b/tests/ui/target-feature/forbidden-target-feature-cfg.rs index c21eb63257a0f..bb54e81c6287f 100644 --- a/tests/ui/target-feature/forbidden-target-feature-cfg.rs +++ b/tests/ui/target-feature/forbidden-target-feature-cfg.rs @@ -2,7 +2,7 @@ //@ compile-flags: --target=riscv32e-unknown-none-elf --crate-type=lib //@ needs-llvm-components: riscv //@ check-pass -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #![allow(unexpected_cfgs)] @@ -10,9 +10,11 @@ pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // The compile_error macro does not exist, so if the `cfg` evaluates to `true` this diff --git a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs index b900e181ec89f..fdeb8fa11c978 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag-disable.rs @@ -5,14 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: unsound because it changes the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/forbidden-target-feature-flag.rs b/tests/ui/target-feature/forbidden-target-feature-flag.rs index ed6438ad65c9b..ed6c4e6175b3b 100644 --- a/tests/ui/target-feature/forbidden-target-feature-flag.rs +++ b/tests/ui/target-feature/forbidden-target-feature-flag.rs @@ -5,14 +5,16 @@ // For now this is just a warning. //@ build-pass //@error-pattern: unsound because it changes the ABI -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs index 5461747829e98..232b2e6235f32 100644 --- a/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs +++ b/tests/ui/target-feature/target-cpu-lacks-required-target-feature.rs @@ -5,14 +5,16 @@ //@ build-pass //@error-pattern: must be enabled -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} diff --git a/tests/ui/target-feature/tied-features-cli.rs b/tests/ui/target-feature/tied-features-cli.rs index f45bcae550430..5212b9b6b0757 100644 --- a/tests/ui/target-feature/tied-features-cli.rs +++ b/tests/ui/target-feature/tied-features-cli.rs @@ -11,16 +11,18 @@ //@ [three] compile-flags: -C target-feature=+paca,+pacg,-paca //@ [four] build-pass //@ [four] compile-flags: -C target-feature=-paca,+pacg -C target-feature=+paca -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} fn main() {} diff --git a/tests/ui/target-feature/tied-features-no-implication-1.rs b/tests/ui/target-feature/tied-features-no-implication-1.rs index 35c884f8b19ea..4f048c5354aea 100644 --- a/tests/ui/target-feature/tied-features-no-implication-1.rs +++ b/tests/ui/target-feature/tied-features-no-implication-1.rs @@ -5,16 +5,18 @@ //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together //@[pacg] compile-flags: -Ctarget-feature=+pacg //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // In this test, demonstrate that +paca and +pacg both result in the tied feature error if there diff --git a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr index 47872eb874aac..6eda0729b6b0a 100644 --- a/tests/ui/target-feature/tied-features-no-implication.pacg.stderr +++ b/tests/ui/target-feature/tied-features-no-implication.pacg.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `foo` is defined multiple times - --> $DIR/tied-features-no-implication.rs:34:1 + --> $DIR/tied-features-no-implication.rs:36:1 | LL | fn foo() {} | -------- previous definition of the value `foo` here diff --git a/tests/ui/target-feature/tied-features-no-implication.rs b/tests/ui/target-feature/tied-features-no-implication.rs index b7abc262c8a82..443f677974c05 100644 --- a/tests/ui/target-feature/tied-features-no-implication.rs +++ b/tests/ui/target-feature/tied-features-no-implication.rs @@ -5,16 +5,18 @@ //@[paca] error-pattern: the target features paca, pacg must all be either enabled or disabled together //@[pacg] compile-flags: -Ctarget-feature=+pacg //@[pacg] error-pattern: the name `foo` is defined multiple times -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, const_trait_impl)] #![no_core] #[lang = "pointee_sized"] pub trait PointeeSized {} #[lang = "meta_sized"] +#[const_trait] pub trait MetaSized: PointeeSized {} #[lang = "sized"] +#[const_trait] pub trait Sized: MetaSized {} // Can't use `compile_error!` here without `core`/`std` but requiring these makes this test only From 9b31f280c7583b048a13834fbcad794118d8f315 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 14:03:48 +0000 Subject: [PATCH 21/43] hir_analysis: change `{Meta,}Sized` bounds to const With const sizedness traits, the correct migration is from `Sized` to `const Sized` and from `?Sized` to `const MetaSized`. --- .../src/hir_ty_lowering/bounds.rs | 47 ++++++++++++++----- .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 3 +- ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 11 +---- tests/ui/sized-hierarchy/const-bound.rs | 14 ++++++ tests/ui/where-clauses/ignore-err-clauses.rs | 1 - .../where-clauses/ignore-err-clauses.stderr | 13 ++--- 6 files changed, 53 insertions(+), 36 deletions(-) create mode 100644 tests/ui/sized-hierarchy/const-bound.rs 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 1600231ecff50..741204a3ea990 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -113,8 +113,8 @@ fn collect_sizedness_bounds<'tcx>( (CollectedSizednessBounds { sized, meta_sized, pointee_sized }, unbounds) } -/// Add a trait bound for `did`. -fn add_trait_bound<'tcx>( +/// Add a trait predicate for `did`. +fn add_trait_predicate<'tcx>( tcx: TyCtxt<'tcx>, bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, @@ -127,6 +127,23 @@ fn add_trait_bound<'tcx>( bounds.insert(0, (trait_ref.upcast(tcx), span)); } +/// Add a host effect predicate for `did`. +fn add_host_effect_predicate<'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]); + let clause = ty::ClauseKind::HostEffect(ty::HostEffectPredicate { + trait_ref, + constness: ty::BoundConstness::Const, + }) + .upcast(tcx); + bounds.insert(1, (clause, span)); +} + /// Remove any bounds of `did`. fn remove_lang_item_bound<'tcx>(bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, did: DefId) { bounds.retain(|(clause, _)| { @@ -153,8 +170,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { remove_lang_item_bound(bounds, pointee_sized_did); } - /// Adds a `MetaSized` bound to `bounds` (of a trait definition) if there are no other sizedness - /// bounds. Also removes `PointeeSized` params - see doc comment on + /// Adds a `const MetaSized` bound to `bounds` (of a trait definition) if there are no other + /// sizedness bounds. Also removes `PointeeSized` params - see doc comment on /// `adjust_sizedness_predicates`. pub(crate) fn adjust_sizedness_supertraits( &self, @@ -177,16 +194,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span); if !collected.any() && trait_did != pointee_sized_did { - // If there are no explicit sizedness bounds then add a default `MetaSized` supertrait. - add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + // If there are no explicit sizedness bounds then add a default `const MetaSized` + // supertrait. + add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); + add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); } // See doc comment on `adjust_sizedness_predicates`. remove_lang_item_bound(bounds, pointee_sized_did); } - /// Add a default `Sized` bound if there are no other sizedness bounds and rewrite `?Sized` - /// to `MetaSized`. Also removes `PointeeSized` params - see doc comment on + /// Add a default `const Sized` bound if there are no other sizedness bounds and rewrite + /// `?Sized` to `MetaSized`. Also removes `PointeeSized` params - see doc comment on /// `adjust_sizedness_predicates`. pub(crate) fn adjust_sizedness_params_and_assoc_types( &self, @@ -211,12 +230,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && !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) - add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span); + // `?Sized` is equivalent to `const MetaSized` (but only add the bound if there aren't + // any other explicit ones) + add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); + add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); } else if !collected.any() { - // If there are no explicit sizedness bounds then add a default `Sized` bound. - add_trait_bound(tcx, bounds, self_ty, sized_did, span); + // If there are no explicit sizedness bounds then add a default `const Sized` bound. + add_trait_predicate(tcx, bounds, self_ty, sized_did, span); + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span); } // See doc comment on `adjust_sizedness_predicates`. diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index a718eb23bed59..40546efa40b9c 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -12,8 +12,7 @@ fn take( K = { () } >, ) {} -//~^^^^^^ ERROR implementation of `Project` is not general enough -//~^^^^ ERROR higher-ranked subtype error +//~^^^ ERROR higher-ranked subtype error //~| ERROR higher-ranked subtype error trait Project { type Out; } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 967814c9c3d9d..f77f37f101eef 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -12,14 +12,5 @@ LL | K = { () } | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:9:4 - | -LL | fn take( - | ^^^^ implementation of `Project` is not general enough - | - = note: `Project` would have to be implemented for the type `for<'a> fn(&'a str) -> &'a str` - = note: ...but `Project` is actually implemented for the type `fn(&'0 str) -> &'0 str`, for some specific lifetime `'0` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/sized-hierarchy/const-bound.rs b/tests/ui/sized-hierarchy/const-bound.rs new file mode 100644 index 0000000000000..f9f1fd2ce938a --- /dev/null +++ b/tests/ui/sized-hierarchy/const-bound.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(const_trait_impl)] + +// This test can fail because of the implicit const bounds/supertraits. + +pub struct Bar; + +#[const_trait] +pub trait Foo {} + +impl const Foo for Bar {} + +pub const fn bar<T: ~const Foo>() {} diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs index 428ebf4b40836..c76f0e1a8b2b5 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.rs +++ b/tests/ui/where-clauses/ignore-err-clauses.rs @@ -1,7 +1,6 @@ use std::ops::Add; fn dbl<T>(x: T) -> <T as Add>::Output -//~^ ERROR type annotations needed where T: Copy + Add, UUU: Copy, diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr index fbf1b99334f42..4cf553da4c5fc 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.stderr +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -1,16 +1,9 @@ error[E0412]: cannot find type `UUU` in this scope - --> $DIR/ignore-err-clauses.rs:7:5 + --> $DIR/ignore-err-clauses.rs:6:5 | LL | UUU: Copy, | ^^^ not found in this scope -error[E0282]: type annotations needed - --> $DIR/ignore-err-clauses.rs:3:14 - | -LL | fn dbl<T>(x: T) -> <T as Add>::Output - | ^ cannot infer type for type parameter `T` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0282, E0412. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0412`. From 438bb7c51b5a5447ac473788dbe40c2ec326bf8b Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 14:05:01 +0000 Subject: [PATCH 22/43] hir_analysis: specialisation w/ host effect preds There are some uses of `min_specialization` in the standard library which now see `HostEffectPredicate` - this shouldn't prevent specialization for the sizedness marker traits that are now const. --- .../src/impl_wf_check/min_specialization.rs | 11 ++++--- tests/ui/sized-hierarchy/specialisation.rs | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/ui/sized-hierarchy/specialisation.rs diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index af1107b499f4e..bcd76f732ffb1 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -436,9 +436,10 @@ fn check_specialization_on<'tcx>( // Global predicates are either always true or always false, so we // are fine to specialize on. _ if clause.is_global() => Ok(()), - // We allow specializing on explicitly marked traits with no associated + // We allow specializing on explicitly marked traits (and host effects) with no associated // items. - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) + | ty::ClauseKind::HostEffect(ty::HostEffectPredicate { trait_ref, constness: _ }) => { if matches!( trait_specialization_kind(tcx, clause), Some(TraitSpecializationKind::Marker) @@ -487,7 +488,8 @@ fn trait_specialization_kind<'tcx>( clause: ty::Clause<'tcx>, ) -> Option<TraitSpecializationKind> { match clause.kind().skip_binder() { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) + | ty::ClauseKind::HostEffect(ty::HostEffectPredicate { trait_ref, constness: _ }) => { Some(tcx.trait_def(trait_ref.def_id).specialization_kind) } ty::ClauseKind::RegionOutlives(_) @@ -495,7 +497,6 @@ fn trait_specialization_kind<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(..) - | ty::ClauseKind::HostEffect(..) => None, + | ty::ClauseKind::ConstEvaluatable(..) => None, } } diff --git a/tests/ui/sized-hierarchy/specialisation.rs b/tests/ui/sized-hierarchy/specialisation.rs new file mode 100644 index 0000000000000..8a18eee9674b6 --- /dev/null +++ b/tests/ui/sized-hierarchy/specialisation.rs @@ -0,0 +1,32 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![no_std] +#![allow(internal_features)] +#![feature(rustc_attrs, min_specialization)] + +// Confirm that specialisation w/ sizedness host effect predicates works. + +pub trait Iterator { + type Item; +} + +#[rustc_unsafe_specialization_marker] +pub trait MoreSpecificThanIterator: Iterator {} + +pub trait Tr { + fn foo(); +} + +impl<A, Iter> Tr for Iter + where + Iter: Iterator<Item = A>, +{ + default fn foo() {} +} + +impl<A, Iter> Tr for Iter + where + Iter: MoreSpecificThanIterator<Item = A>, +{ + fn foo() {} +} From d1ebdf06fff5087c75d05e1d938f9d6ffbc41b67 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 14:05:44 +0000 Subject: [PATCH 23/43] next_trait_solver: merge trivial builtin impls Some of the host effect predicates end up with `TraitGoalProvenVia::ParamEnv` combined with `CandidateSource::BuiltinImpl` and are discarded as a consequence. This commit special-cases `BuiltinImplSource::Trivial` to avoid this - that might not be precisely the correct fix but it is unclear what that would be. Without this, the following tests fail: - tests/ui/associated-type-bounds/cant-see-copy-bound-from-child-rigid.rs#next - tests/ui/associated-types/defaults-suitability.rs#next - tests/ui/associated-types/defaults-unsound-62211-1.rs#next - tests/ui/associated-types/defaults-unsound-62211-2.rs#next - tests/ui/associated-types/imply-relevant-nested-item-bounds.rs#next - tests/ui/associated-types/imply-relevant-nested-item-bounds-2.rs#next - tests/ui/associated-types/issue-63593.rs#next - tests/ui/associated-types/issue-54108.rs#next - tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs#next - tests/ui/async-await/async-closures/is-not-fn.rs#next - tests/ui/async-await/async-closures/is-fn.rs#next - tests/ui/async-await/async-closures/once.rs#next - tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs#next - tests/ui/async-await/async-fn/higher-ranked-async-fn.rs#next - tests/ui/async-await/async-fn/project.rs#next - tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs#next - tests/ui/async-await/send-bound-async-closure.rs#next - tests/ui/borrowck/implied-bound-from-impl-header.rs#next - tests/ui/borrowck/implied-bound-from-normalized-arg.rs#next - tests/ui/borrowck/issue-103095.rs#next - tests/ui/closures/deduce-signature/deduce-from-opaque-type-after-norm.rs#next - tests/ui/closures/deduce-signature/infer-higher-ranked-signature.rs#next - tests/ui/closures/deduce-signature/infer-signature-from-impl.rs#next - tests/ui/closures/deduce-signature/obligation-with-leaking-placeholders.rs#next - tests/ui/closures/deduce-signature/supertrait-signature-inference-issue-23012.rs#next - tests/ui/closures/supertrait-hint-references-assoc-ty.rs#next - tests/ui/coherence/coherence-overlap-negate-use-feature-gate.rs - tests/ui/coherence/occurs-check/opaques.rs#next - tests/ui/coherence/occurs-check/associated-type.rs#next - tests/ui/coherence/orphan-check-alias.rs#next - tests/ui/coherence/orphan-check-projections-nested.rs#next - tests/ui/coherence/orphan-check-projections-not-covering-ambiguity.rs#next - tests/ui/coherence/orphan-check-projections-not-covering.rs#next - tests/ui/coroutine/gen_block_iterate.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/nested.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/simple.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs#next - tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs#next - tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs#next - tests/ui/generic-associated-types/assume-gat-normalization-for-nested-goals.rs#next - tests/ui/generic-associated-types/issue-74816.rs#next - tests/ui/generic-associated-types/issue-74824.rs#next - tests/ui/generic-associated-types/issue-91883.rs#next - tests/ui/generic-associated-types/rigid-hr-projection-issue-93340.rs#next - tests/ui/generic-const-items/const-trait-impl.rs - tests/ui/higher-ranked/builtin-closure-like-bounds.rs#next - tests/ui/higher-ranked/closure-bound-codegen-ice.rs#next - tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs#next - tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs#next - tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs#next - tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs#next - tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs#next - tests/ui/higher-ranked/leak-check/leak-check-in-selection-4-hr-nested.rs#next - tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs#next - tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs#next - tests/ui/higher-ranked/trait-bounds/future.rs#next - tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs#next - tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs#next - tests/ui/impl-trait/auto-trait-selection-freeze.rs#next - tests/ui/impl-trait/auto-trait-selection.rs#next - tests/ui/impl-trait/call_method_on_inherent_impl.rs#next - tests/ui/impl-trait/call_method_ambiguous.rs#next - tests/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs#next - tests/ui/impl-trait/hidden-type-is-opaque-2.rs#next - tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs - tests/ui/impl-trait/in-trait/default-body-with-rpit.rs#next - tests/ui/impl-trait/in-trait/dyn-compatibility-sized.rs#next - tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs#next - tests/ui/impl-trait/in-trait/refine-normalize.rs#next - tests/ui/impl-trait/issue-103181-1.rs#next - tests/ui/impl-trait/method-resolution2.rs#next - tests/ui/impl-trait/recursive-bound-eval.rs#next - tests/ui/impl-trait/unsized_coercion.rs#next - tests/ui/issues/issue-15734.rs#next - tests/ui/methods/fulfillment-disqualifies-method.rs#next - tests/ui/methods/leak-check-disquality.rs#next - tests/ui/nll/check-normalized-sig-for-wf.rs#next - tests/ui/panics/abort-on-panic.rs#next - tests/ui/specialization/source-impl-requires-constraining-predicates.rs#next - tests/ui/specialization/source-impl-requires-constraining-predicates-ambig.rs#next - tests/ui/specialization/specialization-default-items-drop-coherence.rs#next - tests/ui/traits/const-traits/assoc-type-const-bound-usage-0.rs#next - tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs#next - tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs#next - tests/ui/traits/const-traits/assoc-type.rs#next - tests/ui/traits/const-traits/call-const-in-tilde-const.rs - tests/ui/traits/const-traits/call-generic-method-dup-bound.rs - tests/ui/traits/const-traits/call-generic-method-nonconst.rs - tests/ui/traits/const-traits/const-bound-in-host.rs - tests/ui/traits/const-traits/const-bound-on-not-const-associated-fn.rs - tests/ui/traits/const-traits/const-cond-for-rpitit.rs - tests/ui/traits/const-traits/const-drop-fail.rs#new_precise - tests/ui/traits/const-traits/const-drop-fail.rs#new_stock - tests/ui/traits/const-traits/const-drop.rs#precise - tests/ui/traits/const-traits/const-drop.rs#stock - tests/ui/traits/const-traits/const-in-closure.rs - tests/ui/traits/const-traits/const-opaque.rs#no - tests/ui/traits/const-traits/const-impl-trait.rs - tests/ui/traits/const-traits/const-opaque.rs#yes - tests/ui/traits/const-traits/dont-ice-on-const-pred-for-bounds.rs - tests/ui/traits/const-traits/infer-fallback.rs - tests/ui/traits/const-traits/issue-92230-wf-super-trait-env.rs - tests/ui/traits/const-traits/item-bound-entailment-fails.rs - tests/ui/traits/const-traits/item-bound-entailment.rs - tests/ui/traits/const-traits/minicore-drop-without-feature-gate.rs#no - tests/ui/traits/const-traits/minicore-deref-fail.rs - tests/ui/traits/const-traits/minicore-const-fn-early-bound.rs - tests/ui/traits/const-traits/minicore-drop-fail.rs - tests/ui/traits/const-traits/minicore-drop-without-feature-gate.rs#yes - tests/ui/traits/const-traits/minicore-fn-fail.rs - tests/ui/traits/const-traits/minicore-works.rs - tests/ui/traits/const-traits/predicate-entailment-passes.rs - tests/ui/traits/const-traits/predicate-entailment-fails.rs - tests/ui/traits/const-traits/super-traits-fail-2.rs#nn - tests/ui/traits/const-traits/super-traits-fail-2.rs#ny - tests/ui/traits/const-traits/staged-api.rs - tests/ui/traits/const-traits/super-traits-fail-3.rs#nnn - tests/ui/traits/const-traits/super-traits-fail-2.rs#yn - tests/ui/traits/const-traits/super-traits-fail-2.rs#yy - tests/ui/traits/const-traits/super-traits-fail-3.rs#nny - tests/ui/traits/const-traits/super-traits-fail-3.rs#nyy - tests/ui/traits/const-traits/super-traits-fail-3.rs#nyn - tests/ui/traits/const-traits/super-traits-fail-3.rs#yyy - tests/ui/traits/const-traits/super-traits-fail-3.rs#ynn - tests/ui/traits/const-traits/super-traits-fail-3.rs#yyn - tests/ui/traits/const-traits/super-traits-fail-3.rs#yny - tests/ui/traits/const-traits/super-traits.rs - tests/ui/traits/const-traits/tilde-const-assoc-fn-in-trait-impl.rs - tests/ui/traits/const-traits/tilde-const-inherent-assoc-const-fn.rs - tests/ui/traits/const-traits/tilde-const-in-struct-args.rs - tests/ui/traits/const-traits/trait-where-clause-self-referential.rs - tests/ui/traits/const-traits/trait-where-clause-const.rs - tests/ui/traits/const-traits/unsatisfied-const-trait-bound.rs - tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs - tests/ui/traits/negative-impls/negative-impl-normalizes-to.rs#next - tests/ui/traits/next-solver/alias-bound-preference.rs#next - tests/ui/traits/next-solver/alias-relate/alias_eq_cant_be_furthur_normalized.rs - tests/ui/traits/next-solver/alias-eq-in-canonical-response.rs - tests/ui/traits/next-solver/alias-bound-unsound.rs - tests/ui/traits/next-solver/alias-relate/alias_eq_simple.rs - tests/ui/traits/next-solver/alias-relate/opaque-hidden-ty-is-rigid-alias.rs - tests/ui/traits/next-solver/alias-sub.rs - tests/ui/traits/next-solver/alias-relate/deeply-nested-no-hang.rs - tests/ui/traits/next-solver/assembly/ambig-projection-self-is-ambig.rs - tests/ui/traits/next-solver/assembly/assemble-normalizing-self-ty-impl-ambiguity.rs - tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-1.rs - tests/ui/traits/next-solver/async.rs#fail - tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-2.rs - tests/ui/traits/next-solver/async.rs#pass - tests/ui/traits/next-solver/assembly/param-env-alias-bound-conflict.rs - tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs#pass - tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.rs - tests/ui/traits/next-solver/auto-with-drop_tracking_mir.rs#fail - tests/ui/traits/next-solver/canonical/effect-var.rs - tests/ui/traits/next-solver/canonical/int-var-eq-in-response.rs - tests/ui/traits/next-solver/builtin-fn-must-return-sized.rs - tests/ui/traits/next-solver/closure-inference-guidance.rs - tests/ui/traits/next-solver/closure-signature-inference-2.rs - tests/ui/traits/next-solver/closure-signature-inference-hr-ambig-alias-naming-self.rs#next - tests/ui/traits/next-solver/coerce-ambig-alias-to-rigid-alias.rs - tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs - tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-1.rs - tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs - tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-2.rs - tests/ui/traits/next-solver/const-param-placeholder.rs#pass - tests/ui/traits/next-solver/const-param-placeholder.rs#fail - tests/ui/traits/next-solver/constrain-alias-goals-in-unsize.rs - tests/ui/traits/next-solver/coroutine.rs#pass - tests/ui/traits/next-solver/coroutine.rs#fail - tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.rs - tests/ui/traits/next-solver/cycles/double-cycle-inductive-coinductive.rs - tests/ui/traits/next-solver/cycles/inductive-cycle-but-err.rs - tests/ui/traits/next-solver/cycles/inductive-cycle-but-ok.rs - tests/ui/traits/next-solver/cycles/inductive-fixpoint-hang.rs - tests/ui/traits/next-solver/cycles/leak-check-coinductive-cycle.rs - tests/ui/traits/next-solver/cycles/inductive-not-on-stack.rs - tests/ui/traits/next-solver/cycles/mixed-cycles-1.rs - tests/ui/traits/next-solver/cycles/mixed-cycles-2.rs - tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs - tests/ui/traits/next-solver/cycles/provisional-result-done.rs - tests/ui/traits/next-solver/cycles/cycle-modulo-ambig-aliases.rs - tests/ui/traits/next-solver/destruct.rs - tests/ui/traits/next-solver/diagnostics/alias_relate_error_uses_structurally_normalize.rs - tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs - tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs - tests/ui/traits/next-solver/diagnostics/point-at-failing-nested.rs - tests/ui/traits/next-solver/diagnostics/projection-trait-ref.rs - tests/ui/traits/next-solver/diagnostics/dont-pick-fnptr-bound-as-leaf.rs#next - tests/ui/traits/next-solver/dont-loop-fulfill-on-region-constraints.rs - tests/ui/traits/next-solver/elaborate-item-bounds.rs - tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs - tests/ui/traits/next-solver/dyn-incompatibility.rs - tests/ui/traits/next-solver/fn-trait-closure.rs - tests/ui/traits/next-solver/fn-trait.rs - tests/ui/traits/next-solver/generalize/bivariant-alias.rs#next - tests/ui/traits/next-solver/generalize/equating-projection-cyclically.rs - tests/ui/traits/next-solver/generalize/hr-alias-non-hr-alias-self-ty-1.rs#next - tests/ui/traits/next-solver/generalize/hr-alias-universe-lowering-ambiguity.rs - tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs#next - tests/ui/traits/next-solver/generalize/instantiate-canonical-occurs-check-failure.rs - tests/ui/traits/next-solver/generalize/hr-alias-non-hr-alias-self-ty-2.rs#next - tests/ui/traits/next-solver/higher-ranked-dyn-bounds.rs - tests/ui/traits/next-solver/issue-118950-root-region.rs - tests/ui/traits/next-solver/iter-filter-projection.rs - tests/ui/traits/next-solver/lazy-nested-obligations-2.rs - tests/ui/traits/next-solver/lazy-nested-obligations-3.rs - tests/ui/traits/next-solver/nested-obligations-with-bound-vars-gat.rs - tests/ui/traits/next-solver/nested-alias-bound.rs - tests/ui/traits/next-solver/method/path_lookup_wf_constraints.rs - tests/ui/traits/next-solver/non-wf-ret.rs - tests/ui/traits/next-solver/normalization-shadowing/alias-bound-shadowed-by-env.rs - tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-1.rs - tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-3.rs - tests/ui/traits/next-solver/normalization-shadowing/discard-impls-shadowed-by-env-2.rs#next - tests/ui/traits/next-solver/normalization-shadowing/param-env-impl-conflict.rs - tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.rs - tests/ui/traits/next-solver/normalization-shadowing/param-candidate-shadows-project.rs - tests/ui/traits/next-solver/normalize-in-implied_outlives_bounds.rs - tests/ui/traits/next-solver/normalize/normalize-param-env-3.rs - tests/ui/traits/next-solver/normalize/normalize-param-env-1.rs - tests/ui/traits/next-solver/normalize/normalize-async-closure-in-trait.rs - tests/ui/traits/next-solver/normalize/normalize-param-env-2.rs - tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs#next - tests/ui/traits/next-solver/normalize/normalize-rcvr-for-inherent.rs - tests/ui/traits/next-solver/normalize/normalize-path-for-method.rs - tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs#hrtb - tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs#normalize_obligation - tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs#normalize_param_env - tests/ui/traits/next-solver/normalize/normalize-type-outlives-in-param-env.rs - tests/ui/traits/next-solver/normalize/ambig-goal-infer-in-type-oulives.rs - tests/ui/traits/next-solver/normalize/param-env-trait-candidate-2.rs - tests/ui/traits/next-solver/normalize/two-projection-param-candidates-are-ambiguous.rs - tests/ui/traits/next-solver/opaques/dont-remap-tait-substs.rs - tests/ui/traits/next-solver/opaques/select-alias-bound-as-param.rs - tests/ui/traits/next-solver/opportunistic-region-resolve.rs - tests/ui/traits/next-solver/opaques/no-define-in-wf-check.rs#next - tests/ui/traits/next-solver/overflow/exponential-trait-goals.rs - tests/ui/traits/next-solver/normalize/param-env-trait-candidate-1.rs - tests/ui/traits/next-solver/overflow/global-cache.rs - tests/ui/traits/next-solver/overflow/nalgebra-hang.rs#next - tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs - tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs - tests/ui/traits/next-solver/pointee.rs - tests/ui/traits/next-solver/pointer-like.rs - tests/ui/traits/next-solver/prefer-candidate-no-constraints.rs - tests/ui/traits/next-solver/prefer-param-env-on-ambiguity.rs - tests/ui/traits/next-solver/projection-discr-kind.rs - tests/ui/traits/next-solver/specialization-unconstrained.rs - tests/ui/traits/next-solver/specialization-transmute.rs - tests/ui/traits/next-solver/typeck/guide-ctors.rs - tests/ui/traits/next-solver/try-example.rs - tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs - tests/ui/traits/next-solver/typeck/resolve-before-checking-builtin-ptr.rs - tests/ui/traits/next-solver/typeck/resolve-before-checking-never.rs - tests/ui/traits/next-solver/typeck/structurally-resolve-in-probe_adt.rs - tests/ui/traits/next-solver/typeck/resolve-expectations.rs - tests/ui/traits/next-solver/winnow-specializing-impls.rs - tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs#next - tests/ui/traits/normalize-supertrait.rs#next - tests/ui/traits/pointee-normalize-equate.rs#next - tests/ui/traits/reservation-impl/non-lattice-ok.rs#next - tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs#next - tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs#next - tests/ui/traits/trait-upcasting/normalization.rs#next - tests/ui/traits/trait-upcasting/prefer-lower-candidates.rs#next - tests/ui/traits/winnowing/global-non-global-env-1.rs#next - tests/ui/traits/winnowing/global-non-global-env-3.rs#next - tests/ui/traits/winnowing/global-non-global-env-2.rs#next - tests/ui/traits/winnowing/global-non-global-env-4.rs#next - tests/ui/transmutability/primitives/bool.rs#next - tests/ui/transmutability/primitives/unit.rs#next - tests/ui/type-alias-impl-trait/assoc-type-const.rs#next - tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs#next - tests/ui/type-alias-impl-trait/issue-78450.rs#next - tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs#next - tests/ui/type-alias-impl-trait/method_resolution3.rs#next - tests/ui/type-alias-impl-trait/method_resolution4.rs#next - tests/ui/type-alias-impl-trait/nested_inference_failure.rs#next - tests/ui/type-alias-impl-trait/normalize-hidden-types.rs#next - tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs#next - tests/ui/typeck/bad-index-due-to-nested.rs#next - tests/ui/typeck/issue-116864.rs - tests/ui/unsized/issue-75899.rs#next - tests/ui/transmutability/primitives/numbers.rs#next - tests/ui/wf/wf-in-where-clause-static.rs#next --- compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 388965270ba65..ebbb63756f301 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -821,7 +821,10 @@ where .filter(|c| { matches!( c.source, - CandidateSource::AliasBound | CandidateSource::ParamEnv(_) + CandidateSource::AliasBound + | CandidateSource::ParamEnv(_) + // Allow trivial for `const Sized` + | CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial) ) }) .map(|c| c.result) From 8467e8b3589d05ecfa6804faaac25ef795927ed4 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 15:05:17 +0000 Subject: [PATCH 24/43] trait_sel: re-order host effect evaluations When evaluating a host effect predicate on an opaque in `addr2line`, running `evaluate_host_effect_from_bounds` first would create an opaque type which wouldn't be removed from opaque type storage and that would cause a delayed bug - creating a small reproduction of this has been tricky but if `builtin_impls` checking is moved below `evaluate_host_effect_from_item_bounds` then it will trigger. The correct fix is probably to work out why the opaque type is created and then not used, but this was particularly tricky. Given that this root cause wasn't identified, writing a test case proved difficult. --- compiler/rustc_trait_selection/src/traits/effects.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 627eb2eb77760..88378c72315f0 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -38,19 +38,25 @@ pub fn evaluate_host_effect_obligation<'tcx>( return Err(EvaluationFailure::Ambiguous); } - match evaluate_host_effect_from_bounds(selcx, obligation) { + // FIXME: during implementation of `#![feature(sized_hierarchy)]`, when evaluating a host + // effect predicate on an opaque in addr2line, running `evaluate_host_effect_from_bounds` first + // would create an opaque type which wouldn't be removed from opaque type storage and that + // would cause a delayed bug - creating a small reproduction of this has been tricky but if + // `builtin_impls` checking is moved below `evaluate_host_effect_from_item_bounds` then it will + // trigger. + match evaluate_host_effect_from_builtin_impls(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} } - match evaluate_host_effect_from_item_bounds(selcx, obligation) { + match evaluate_host_effect_from_bounds(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} } - match evaluate_host_effect_from_builtin_impls(selcx, obligation) { + match evaluate_host_effect_from_item_bounds(selcx, obligation) { Ok(result) => return Ok(result), Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous), Err(EvaluationFailure::NoSolution) => {} From 2b147f2c9b42d93a8403cf2cff1c562e61e1feae Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 16:36:00 +0000 Subject: [PATCH 25/43] trait_sel: `const {Meta,}Sized` in impl headers Now that sizedness traits have been made const, pretty printing of impl headers should print the constness of the sizedness trait. --- compiler/rustc_middle/src/ty/predicate.rs | 9 ++++++ .../src/error_reporting/traits/mod.rs | 21 +++++++++++-- .../auxiliary/pretty-print-dep.rs | 10 +++++- .../pretty-print-no-feat-dep-has-feat.rs | 10 +++++- .../pretty-print-no-feat-dep-has-feat.stderr | 29 ++++++++++++++--- tests/ui/sized-hierarchy/pretty-print.rs | 10 ++++-- tests/ui/sized-hierarchy/pretty-print.stderr | 31 +++++++++++++++---- 7 files changed, 103 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 02e316dfc3db7..99ab13819396b 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -208,6 +208,15 @@ impl<'tcx> Clause<'tcx> { } } + pub fn as_host_effect_clause(self) -> Option<ty::Binder<'tcx, HostEffectPredicate<'tcx>>> { + let clause = self.kind(); + if let ty::ClauseKind::HostEffect(host_effect_clause) = clause.skip_binder() { + Some(clause.rebind(host_effect_clause)) + } else { + None + } + } + pub fn as_projection_clause(self) -> Option<ty::Binder<'tcx, ProjectionPredicate<'tcx>>> { let clause = self.kind(); if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index cb8fe8c31d7cf..b9e6ae7dd61e8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -340,7 +340,9 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti #[derive(Debug, Default)] struct SizednessFound { + const_sized: bool, sized: bool, + const_meta_sized: bool, meta_sized: bool, } @@ -389,20 +391,35 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti } } + if let Some(host_effect_clause) = p.as_host_effect_clause() { + let self_ty = host_effect_clause.self_ty().skip_binder(); + let sizedness_of = types_with_sizedness_bounds.entry(self_ty).or_default(); + if Some(host_effect_clause.def_id()) == sized_trait { + sizedness_of.const_sized = true; + continue; + } else if Some(host_effect_clause.def_id()) == meta_sized_trait { + sizedness_of.const_meta_sized = true; + continue; + } + } + pretty_predicates.push(p.to_string()); } for (ty, sizedness) in types_with_sizedness_bounds { if !tcx.features().sized_hierarchy() { - if sizedness.sized { + if sizedness.const_sized || sizedness.sized { // Maybe a default bound, don't write anything. } else { pretty_predicates.push(format!("{ty}: ?Sized")); } } else { - if sizedness.sized { + if sizedness.const_sized { // Maybe a default bound, don't write anything. + } else if sizedness.sized { pretty_predicates.push(format!("{ty}: Sized")); + } else if sizedness.const_meta_sized { + pretty_predicates.push(format!("{ty}: const MetaSized")); } else if sizedness.meta_sized { pretty_predicates.push(format!("{ty}: MetaSized")); } else { diff --git a/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs index a7d18d9036856..eecd353214844 100644 --- a/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs +++ b/tests/ui/sized-hierarchy/auxiliary/pretty-print-dep.rs @@ -1,7 +1,11 @@ -#![feature(sized_hierarchy)] +#![feature(const_trait_impl, sized_hierarchy)] use std::marker::{MetaSized, PointeeSized}; +pub trait ConstSizedTr {} + +impl<T: const Sized> ConstSizedTr for T {} + pub trait SizedTr {} impl<T: Sized> SizedTr for T {} @@ -10,6 +14,10 @@ pub trait NegSizedTr {} impl<T: ?Sized> NegSizedTr for T {} +pub trait ConstMetaSizedTr {} + +impl<T: const MetaSized> ConstMetaSizedTr for T {} + pub trait MetaSizedTr {} impl<T: MetaSized> MetaSizedTr for T {} diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs index 0412ff651cee6..998aa5597c9fc 100644 --- a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -2,7 +2,9 @@ //@ compile-flags: --crate-type=lib extern crate pretty_print_dep; -use pretty_print_dep::{SizedTr, NegSizedTr, MetaSizedTr, PointeeSizedTr}; +use pretty_print_dep::{ + ConstSizedTr, SizedTr, NegSizedTr, ConstMetaSizedTr, MetaSizedTr, PointeeSizedTr +}; // Test that printing the sizedness trait bounds in the conflicting impl error without enabling // `sized_hierarchy` will continue to print `?Sized`, even if the dependency is compiled with @@ -13,12 +15,18 @@ use pretty_print_dep::{SizedTr, NegSizedTr, MetaSizedTr, PointeeSizedTr}; struct X<T>(T); +impl<T: Sized> ConstSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `ConstSizedTr` for type `X<_>` + impl<T: Sized> SizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` impl<T: ?Sized> NegSizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` +impl<T: ?Sized> ConstMetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + impl<T: ?Sized> MetaSizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr index cb9bfd178f88d..756876542117a 100644 --- a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr @@ -1,5 +1,14 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:18:1 + | +LL | impl<T: Sized> ConstSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstSizedTr for T; + error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:16:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:21:1 | LL | impl<T: Sized> SizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +17,7 @@ LL | impl<T: Sized> SizedTr for X<T> {} - impl<T> SizedTr for T; error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:19:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:24:1 | LL | impl<T: ?Sized> NegSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,8 +26,18 @@ LL | impl<T: ?Sized> NegSizedTr for X<T> {} - impl<T> NegSizedTr for T where T: ?Sized; +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:27:1 + | +LL | impl<T: ?Sized> ConstMetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstMetaSizedTr for T + where T: ?Sized; + error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:30:1 | LL | impl<T: ?Sized> MetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +47,7 @@ LL | impl<T: ?Sized> MetaSizedTr for X<T> {} where T: ?Sized; error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:33:1 | LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,6 +56,6 @@ LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} - impl<T> PointeeSizedTr for T where T: ?Sized; -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs index 0908e76490ce7..68fb6b13455ef 100644 --- a/tests/ui/sized-hierarchy/pretty-print.rs +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -1,6 +1,6 @@ //@ aux-build:pretty-print-dep.rs //@ compile-flags: --crate-type=lib -#![feature(sized_hierarchy)] +#![feature(const_trait_impl, sized_hierarchy)] // Test that printing the sizedness trait bounds in the conflicting impl error with // `sized_hierarchy` enabled prints all of the appropriate bounds. @@ -11,16 +11,22 @@ use std::marker::{MetaSized, PointeeSized}; extern crate pretty_print_dep; -use pretty_print_dep::{SizedTr, MetaSizedTr, PointeeSizedTr}; +use pretty_print_dep::{ConstSizedTr, SizedTr, ConstMetaSizedTr, MetaSizedTr, PointeeSizedTr}; struct X<T>(T); +impl<T: const Sized> ConstSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `ConstSizedTr` for type `X<_>` + impl<T: Sized> SizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `SizedTr` for type `X<_>` impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `NegSizedTr` for type `X<_>` +impl<T: const MetaSized> ConstMetaSizedTr for X<T> {} +//~^ ERROR conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + impl<T: MetaSized> MetaSizedTr for X<T> {} //~^ ERROR conflicting implementations of trait `MetaSizedTr` for type `X<_>` diff --git a/tests/ui/sized-hierarchy/pretty-print.stderr b/tests/ui/sized-hierarchy/pretty-print.stderr index 3602c804945bd..84f942ddf05c2 100644 --- a/tests/ui/sized-hierarchy/pretty-print.stderr +++ b/tests/ui/sized-hierarchy/pretty-print.stderr @@ -1,6 +1,15 @@ -error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` --> $DIR/pretty-print.rs:18:1 | +LL | impl<T: const Sized> ConstSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:21:1 + | LL | impl<T: Sized> SizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -9,17 +18,27 @@ LL | impl<T: Sized> SizedTr for X<T> {} where T: Sized; error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:21:1 + --> $DIR/pretty-print.rs:24:1 | LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `pretty_print_dep`: - impl<T> NegSizedTr for T - where T: MetaSized; + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:27:1 + | +LL | impl<T: const MetaSized> ConstMetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstMetaSizedTr for T + where T: const MetaSized; error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:24:1 + --> $DIR/pretty-print.rs:30:1 | LL | impl<T: MetaSized> MetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +48,7 @@ LL | impl<T: MetaSized> MetaSizedTr for X<T> {} where T: MetaSized; error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:27:1 + --> $DIR/pretty-print.rs:33:1 | LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,6 +57,6 @@ LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} - impl<T> PointeeSizedTr for T where T: PointeeSized; -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0119`. From c16f159c61bc3197a15a5e1eca6e179bcd123e4d Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 22:56:22 +0000 Subject: [PATCH 26/43] middle: `const {Meta,Pointee}Sized` in opaques These traits are now const and that needs to be reflected in their printing in opaques. --- compiler/rustc_middle/src/ty/print/pretty.rs | 44 ++++++++++++------- .../ui/sized-hierarchy/pretty-print-opaque.rs | 22 ++++++++-- .../pretty-print-opaque.stderr | 27 ++++++++---- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index ae2960802aa81..53319ad7200e2 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1064,10 +1064,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut fn_traits = FxIndexMap::default(); let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); - let mut has_sized_bound = false; - let mut has_negative_sized_bound = false; - let mut has_meta_sized_bound = false; - let mut has_pointee_sized_bound = false; + let mut has_sized_pred = false; + let mut has_const_sized_pred = false; + let mut has_negative_sized_pred = false; + let mut has_meta_sized_pred = false; + let mut has_const_meta_sized_pred = false; + let mut has_pointee_sized_pred = false; for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) { let bound_predicate = predicate.kind(); @@ -1079,17 +1081,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { match pred.polarity { ty::PredicatePolarity::Positive => { - has_sized_bound = true; + has_sized_pred = true; continue; } - ty::PredicatePolarity::Negative => has_negative_sized_bound = true, + ty::PredicatePolarity::Negative => has_negative_sized_pred = true, } } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { - has_meta_sized_bound = true; + has_meta_sized_pred = true; continue; } else if tcx.is_lang_item(pred.def_id(), LangItem::PointeeSized) { // Unexpected - `PointeeSized` is the absence of bounds. - has_pointee_sized_bound = true; + has_pointee_sized_pred = true; continue; } @@ -1117,6 +1119,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ClauseKind::TypeOutlives(outlives) => { lifetimes.push(outlives.1); } + ty::ClauseKind::HostEffect(pred) => { + if tcx.is_lang_item(pred.def_id(), LangItem::Sized) { + has_const_sized_pred = true; + } else if tcx.is_lang_item(pred.def_id(), LangItem::MetaSized) { + has_const_meta_sized_pred = true; + } + } _ => {} } } @@ -1125,7 +1134,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let mut first = true; // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait - let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound; + let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_pred; for ((bound_args_and_self_ty, is_async), entry) in fn_traits { write!(self, "{}", if first { "" } else { " + " })?; @@ -1260,26 +1269,31 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } let using_sized_hierarchy = self.tcx().features().sized_hierarchy(); - let add_sized = has_sized_bound && (first || has_negative_sized_bound); + let add_sized = has_sized_pred && (first || has_negative_sized_pred); let add_maybe_sized = - has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy; + has_meta_sized_pred && !has_negative_sized_pred && !using_sized_hierarchy; // Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds. - has_pointee_sized_bound = has_pointee_sized_bound - || (!has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound); + has_pointee_sized_pred = has_pointee_sized_pred + || (!has_sized_pred && !has_meta_sized_pred && !has_negative_sized_pred); if add_sized || add_maybe_sized { if !first { write!(self, " + ")?; } if add_maybe_sized { write!(self, "?")?; + } else if has_const_sized_pred && using_sized_hierarchy { + write!(self, "const ")?; } write!(self, "Sized")?; - } else if has_meta_sized_bound && using_sized_hierarchy { + } else if has_meta_sized_pred && using_sized_hierarchy { if !first { write!(self, " + ")?; } + if has_const_meta_sized_pred && using_sized_hierarchy { + write!(self, "const ")?; + } write!(self, "MetaSized")?; - } else if has_pointee_sized_bound && using_sized_hierarchy { + } else if has_pointee_sized_pred && using_sized_hierarchy { if !first { write!(self, " + ")?; } diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs index 43946777e0635..b21cee1357add 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.rs +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -1,5 +1,5 @@ //@ compile-flags: --crate-type=lib -#![feature(sized_hierarchy)] +#![feature(const_trait_impl, sized_hierarchy)] use std::marker::{MetaSized, PointeeSized}; @@ -14,11 +14,19 @@ pub fn sized() -> Box<impl Tr + Sized> { Box::new(1u32) } +pub fn const_sized() -> Box<impl Tr + const Sized> { + if true { + let x = const_sized(); + let y: Box<dyn Tr> = x; + } + Box::new(1u32) +} + pub fn neg_sized() -> Box<impl Tr + ?Sized> { if true { let x = neg_sized(); let y: Box<dyn Tr> = x; -//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known +//~^ ERROR: the size for values of type `impl Tr + const MetaSized` cannot be known } Box::new(1u32) } @@ -32,6 +40,15 @@ pub fn metasized() -> Box<impl Tr + MetaSized> { Box::new(1u32) } +pub fn const_metasized() -> Box<impl Tr + const MetaSized> { + if true { + let x = const_metasized(); + let y: Box<dyn Tr> = x; +//~^ ERROR: the size for values of type `impl Tr + const MetaSized` cannot be known + } + Box::new(1u32) +} + pub fn pointeesized() -> Box<impl Tr + PointeeSized> { //~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known if true { @@ -42,4 +59,3 @@ pub fn pointeesized() -> Box<impl Tr + PointeeSized> { } Box::new(1u32) } - diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr index 523f6e7dd83ff..541e018261bde 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known - --> $DIR/pretty-print-opaque.rs:35:26 + --> $DIR/pretty-print-opaque.rs:52:26 | LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size @@ -8,17 +8,17 @@ LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:20:30 +error[E0277]: the size for values of type `impl Tr + const MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:28:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time | - = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` - = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` + = help: the trait `Sized` is not implemented for `impl Tr + const MetaSized` + = note: required for the cast from `Box<impl Tr + const MetaSized>` to `Box<dyn Tr>` error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:29:30 + --> $DIR/pretty-print-opaque.rs:37:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time @@ -26,8 +26,17 @@ LL | let y: Box<dyn Tr> = x; = help: the trait `Sized` is not implemented for `impl Tr + MetaSized` = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` +error[E0277]: the size for values of type `impl Tr + const MetaSized` cannot be known at compilation time + --> $DIR/pretty-print-opaque.rs:46:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Tr + const MetaSized` + = note: required for the cast from `Box<impl Tr + const MetaSized>` to `Box<dyn Tr>` + error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known - --> $DIR/pretty-print-opaque.rs:38:17 + --> $DIR/pretty-print-opaque.rs:55:17 | LL | let x = pointeesized(); | ^^^^^^^^^^^^^^ doesn't have a known size @@ -37,7 +46,7 @@ note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:40:30 + --> $DIR/pretty-print-opaque.rs:57:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time @@ -45,6 +54,6 @@ LL | let y: Box<dyn Tr> = x; = help: the trait `Sized` is not implemented for `impl Tr + PointeeSized` = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. From 38442642c6fa4d62563c01c70a3cd37afd85b64c Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 20 Feb 2025 16:58:12 +0000 Subject: [PATCH 27/43] trait_sel: remove intercrate mode assertion This causes a bunch of tests to fail and everything appears to work without it: - tests/ui/coherence/orphan-check-opaque-types-not-covering.rs - tests/ui/coherence/orphan-check-projections-covering.rs - tests/ui/coherence/orphan-check-projections-unsat-bounds.rs#classic - tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs - tests/ui/coherence/orphan-check-weak-aliases-covering.rs#classic - tests/ui/specialization/issue-43037.rs#negative - tests/ui/specialization/issue-43037.rs#current - tests/ui/type-alias-impl-trait/coherence.rs#classic --- compiler/rustc_trait_selection/src/traits/effects.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 88378c72315f0..54679a7dbb55e 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -3,9 +3,8 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::traits::{ ImplDerivedHostCause, ImplSource, Obligation, ObligationCauseCode, PredicateObligation, }; -use rustc_middle::span_bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; -use rustc_middle::ty::{self, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, TypeVisitableExt}; use rustc_type_ir::elaborate::elaborate; use rustc_type_ir::solve::{NoSolution, SizedTraitKind}; use thin_vec::{ThinVec, thin_vec}; @@ -24,13 +23,6 @@ pub fn evaluate_host_effect_obligation<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &HostEffectObligation<'tcx>, ) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> { - if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) { - span_bug!( - obligation.cause.span, - "should not select host obligation in old solver in intercrate mode" - ); - } - let ref obligation = selcx.infcx.resolve_vars_if_possible(obligation.clone()); // Force ambiguity for infer self ty. From 0ca95663384e618b4f2a7b7b77e8606565277245 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 21:57:43 +0000 Subject: [PATCH 28/43] tests: bless remaining tests These tests just need blessing, they don't have any interesting behaviour changes. --- tests/ui/attributes/dump-preds.stderr | 6 +++ .../incompleteness-unstable-result.rs | 38 +++++++++++-------- ...incompleteness-unstable-result.with.stderr | 17 +++++---- ...ompleteness-unstable-result.without.stderr | 17 +++++---- .../next-solver/issue-118950-root-region.rs | 1 + .../issue-118950-root-region.stderr | 14 ++++++- .../normalize/normalize-param-env-2.stderr | 14 ++++++- .../normalize-param-env-4.next.stderr | 14 ++++++- 8 files changed, 89 insertions(+), 32 deletions(-) diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index e63b51a47406a..a84b91e309c7f 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -5,9 +5,11 @@ LL | trait Trait<T>: Iterator<Item: Copy> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <Self as std::marker::MetaSized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <T as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<std::string::String as std::convert::From<T>>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as Trait<T>>, polarity:Positive), bound_vars: [] } @@ -18,12 +20,15 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: Binder { value: TraitPredicate(<Self as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <Self as std::marker::MetaSized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as std::iter::Iterator>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as std::iter::Iterator>::Item as std::marker::Copy>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<T as std::marker::Sized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <T as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<std::string::String as std::convert::From<T>>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<Self as Trait<T>>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<P as std::marker::Sized>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <P as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<P as std::cmp::Eq>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<()> as std::marker::Copy>, polarity:Positive), bound_vars: [] } @@ -35,6 +40,7 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> | = note: Binder { value: ProjectionPredicate(AliasTerm { args: [Alias(Projection, AliasTy { args: [Self/#0, T/#1, P/#2], def_id: DefId(..), .. })], def_id: DefId(..), .. }, Term::Ty(())), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] } + = note: Binder { value: HostEffectPredicate { trait_ref: <<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index 920f8add50795..e2389bd02e80a 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -1,6 +1,7 @@ //@ revisions: with without //@ compile-flags: -Znext-solver -#![feature(rustc_attrs)] +#![feature(rustc_attrs, sized_hierarchy)] +use std::marker::PointeeSized; // This test is incredibly subtle. At its core the goal is to get a coinductive cycle, // which, depending on its root goal, either holds or errors. We achieve this by getting @@ -17,20 +18,20 @@ // test for that. #[rustc_coinductive] -trait Trait<T: ?Sized, V: ?Sized, D: ?Sized> {} -struct A<T: ?Sized>(*const T); -struct B<T: ?Sized>(*const T); +trait Trait<T: PointeeSized, V: PointeeSized, D: PointeeSized>: PointeeSized {} +struct A<T: PointeeSized>(*const T); +struct B<T: PointeeSized>(*const T); -trait IncompleteGuidance<T: ?Sized, V: ?Sized> {} -impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, u8> for T {} -impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i8> for T {} -impl<T: ?Sized, U: ?Sized + 'static> IncompleteGuidance<U, i16> for T {} +trait IncompleteGuidance<T: PointeeSized, V: PointeeSized>: PointeeSized {} +impl<T: PointeeSized, U: PointeeSized + 'static> IncompleteGuidance<U, u8> for T {} +impl<T: PointeeSized, U: PointeeSized + 'static> IncompleteGuidance<U, i8> for T {} +impl<T: PointeeSized, U: PointeeSized + 'static> IncompleteGuidance<U, i16> for T {} -trait ImplGuidance<T: ?Sized, V: ?Sized> {} -impl<T: ?Sized> ImplGuidance<u32, u8> for T {} -impl<T: ?Sized> ImplGuidance<i32, i8> for T {} +trait ImplGuidance<T: PointeeSized, V: PointeeSized>: PointeeSized {} +impl<T: PointeeSized> ImplGuidance<u32, u8> for T {} +impl<T: PointeeSized> ImplGuidance<i32, i8> for T {} -impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T> +impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for A<T> where T: IncompleteGuidance<U, V>, A<T>: Trait<U, D, V>, @@ -39,17 +40,24 @@ where { } -trait ToU8<T: ?Sized> {} +trait ToU8<T: PointeeSized>: PointeeSized {} impl ToU8<u8> for () {} -impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for B<T> +impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for B<T> where T: ImplGuidance<U, V>, A<T>: Trait<U, V, D>, { } -fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {} +fn impls_trait<T, U, V, D>() +where + T: PointeeSized + Trait<U, V, D>, + U: PointeeSized, + V: PointeeSized, + D: PointeeSized +{ +} fn with_bound<X>() where diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr index 9114bcadac0c0..c796663b13f0b 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr @@ -1,25 +1,28 @@ error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:73:19 | LL | impls_trait::<A<X>, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>` | = help: the trait `Trait<U, V, D>` is implemented for `A<T>` note: required for `A<X>` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:34:74 | -LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T> - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for A<T> + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A<T>: Trait<U, D, V>, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A<X>` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:55:23 | -LL | fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait<T, U, V, D>() + | ----------- required by a bound in this function +LL | where +LL | T: PointeeSized + Trait<U, V, D>, + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr index 9114bcadac0c0..c796663b13f0b 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr @@ -1,25 +1,28 @@ error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:65:19 + --> $DIR/incompleteness-unstable-result.rs:73:19 | LL | impls_trait::<A<X>, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>` | = help: the trait `Trait<U, V, D>` is implemented for `A<T>` note: required for `A<X>` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:33:50 + --> $DIR/incompleteness-unstable-result.rs:34:74 | -LL | impl<T: ?Sized, U: ?Sized, V: ?Sized, D: ?Sized> Trait<U, V, D> for A<T> - | ^^^^^^^^^^^^^^ ^^^^ +LL | impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for A<T> + | ^^^^^^^^^^^^^^ ^^^^ ... LL | A<T>: Trait<U, D, V>, | -------------- unsatisfied trait bound introduced here = note: 8 redundant requirements hidden = note: required for `A<X>` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:52:28 + --> $DIR/incompleteness-unstable-result.rs:55:23 | -LL | fn impls_trait<T: ?Sized + Trait<U, V, D>, U: ?Sized, V: ?Sized, D: ?Sized>() {} - | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` +LL | fn impls_trait<T, U, V, D>() + | ----------- required by a bound in this function +LL | where +LL | T: PointeeSized + Trait<U, V, D>, + | ^^^^^^^^^^^^^^ required by this bound in `impls_trait` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 8fe53d6773b95..fa3b8e9d8c9ca 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -19,5 +19,6 @@ impl<T> Overlap<T> for T {} impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} //~^ ERROR cannot find type `Missing` in this scope //~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied +//~| ERROR the trait bound `{type error}: const MetaSized` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index d2a58e95629a4..50cc145471c55 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -37,7 +37,19 @@ help: consider further restricting type parameter `T` with trait `Overlap` LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {} | ++++++++++++++++++++++++++++++++++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error[E0277]: the trait bound `{type error}: const MetaSized` is not satisfied + --> $DIR/issue-118950-root-region.rs:19:64 + | +LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} + | ^^^^^^^^^^ + | +note: required by a bound in `Overlap` + --> $DIR/issue-118950-root-region.rs:12:1 + | +LL | trait Overlap<T> {} + | ^^^^^^^^^^^^^^^^ required by this bound in `Overlap` + +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0412. For more information about an error, try `rustc --explain E0277`. 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 8fb3104d2d96b..be8bc846c048a 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 @@ -31,6 +31,18 @@ note: required by a bound in `A` LL | trait A<T> { | ^^^^^^^^^^ required by this bound in `A` +error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: const 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> { + | ^^^^^^^^^^ 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 | @@ -58,6 +70,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 7 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 f92b2eaa6391e..bb46d53165266 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 @@ -16,6 +16,18 @@ note: required by a bound in `Trait` LL | trait Trait { | ^^^^^^^^^^^ required by this bound in `Trait` +error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: const 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 { + | ^^^^^^^^^^^ required by this bound in `Trait` + error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed` --> $DIR/normalize-param-env-4.rs:19:26 | @@ -34,6 +46,6 @@ note: required by a bound in `impls_trait` LL | fn impls_trait<T: Trait>() {} | ^^^^^ required by this bound in `impls_trait` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0275`. From be51f99745ddc9e79abd11df8a2c1e3d000199a8 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 12 Feb 2025 06:38:33 +0000 Subject: [PATCH 29/43] library: add `{Pointee,Meta}Sized` to next prelude Its strange to have to import sizedness traits, so add them to the prelude in the next edition. --- library/core/src/prelude/mod.rs | 4 +++ .../sized-hierarchy/extern-type-behind-ptr.rs | 2 +- tests/ui/sized-hierarchy/prelude.e2024.stderr | 25 +++++++++++++++++++ tests/ui/sized-hierarchy/prelude.rs | 13 ++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/ui/sized-hierarchy/prelude.e2024.stderr create mode 100644 tests/ui/sized-hierarchy/prelude.rs diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs index 8d867a269a21a..2405995e97b49 100644 --- a/library/core/src/prelude/mod.rs +++ b/library/core/src/prelude/mod.rs @@ -92,4 +92,8 @@ pub mod rust_future { #[stable(feature = "prelude_2024", since = "1.85.0")] #[doc(no_inline)] pub use crate::future::{Future, IntoFuture}; + + #[unstable(feature = "prelude_next", issue = "none")] + #[doc(no_inline)] + pub use crate::marker::{MetaSized, PointeeSized}; } diff --git a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs index 70a84aabf2cfb..9cb6f267743b4 100644 --- a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -1,7 +1,7 @@ //@ check-pass #![feature(extern_types, sized_hierarchy)] -use std::marker::{MetaSized, PointeeSized}; +use std::marker::PointeeSized; pub fn hash<T: PointeeSized>(_: *const T) { unimplemented!(); diff --git a/tests/ui/sized-hierarchy/prelude.e2024.stderr b/tests/ui/sized-hierarchy/prelude.e2024.stderr new file mode 100644 index 0000000000000..80e6b236b664f --- /dev/null +++ b/tests/ui/sized-hierarchy/prelude.e2024.stderr @@ -0,0 +1,25 @@ +error[E0405]: cannot find trait `MetaSized` in this scope + --> $DIR/prelude.rs:10:21 + | +LL | pub fn metasized<T: MetaSized>() {} + | ^^^^^^^^^ not found in this scope + | +help: consider importing this trait + | +LL + use std::marker::MetaSized; + | + +error[E0405]: cannot find trait `PointeeSized` in this scope + --> $DIR/prelude.rs:12:24 + | +LL | pub fn pointeesized<T: PointeeSized>() {} + | ^^^^^^^^^^^^ not found in this scope + | +help: consider importing this trait + | +LL + use std::marker::PointeeSized; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/sized-hierarchy/prelude.rs b/tests/ui/sized-hierarchy/prelude.rs new file mode 100644 index 0000000000000..c78a11b6ae312 --- /dev/null +++ b/tests/ui/sized-hierarchy/prelude.rs @@ -0,0 +1,13 @@ +//@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[e2024] check-fail +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future +//@[future] check-pass +#![feature(sized_hierarchy)] + +pub fn metasized<T: MetaSized>() {} +//[e2024]~^ ERROR cannot find trait `MetaSized` in this scope +pub fn pointeesized<T: PointeeSized>() {} +//[e2024]~^ ERROR cannot find trait `PointeeSized` in this scope From d6ac69752cebfdbf4c15ce08b68241d4f048009b Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Thu, 27 Feb 2025 22:26:10 +0000 Subject: [PATCH 30/43] hir_analysis: edition migration Implement the edition migration required by these changes - `?Sized` becoming `const MetaSized`, `Sized` becoming `const Sized` and a `const MetaSized` supertrait. --- compiler/rustc_data_structures/src/lib.rs | 1 + .../src/collect/item_bounds.rs | 2 + .../src/collect/predicates_of.rs | 1 + .../src/hir_ty_lowering/bounds.rs | 67 ++++++++--- .../src/hir_ty_lowering/errors.rs | 106 +++++++++++++++++- compiler/rustc_lint_defs/src/builtin.rs | 39 +++++++ compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_serialize/src/lib.rs | 1 + compiler/rustc_smir/src/lib.rs | 1 + .../unused-type-param-suggestion.rs | 1 + .../unused-type-param-suggestion.stderr | 12 +- .../feature-gate-sized-hierarchy.rs | 1 + .../feature-gate-sized-hierarchy.stderr | 12 +- .../layout/unconstrained-param-ice-137308.rs | 1 + .../unconstrained-param-ice-137308.stderr | 4 +- tests/ui/offset-of/offset-of-dst-field.rs | 1 + tests/ui/offset-of/offset-of-dst-field.stderr | 20 ++-- .../auxiliary/migration-no-feat-dep.rs | 6 + tests/ui/sized-hierarchy/default-bound.rs | 7 +- tests/ui/sized-hierarchy/default-bound.stderr | 24 ++-- .../ui/sized-hierarchy/default-supertrait.rs | 1 + .../sized-hierarchy/default-supertrait.stderr | 30 ++--- .../sized-hierarchy/extern-type-behind-ptr.rs | 1 + tests/ui/sized-hierarchy/impls.rs | 4 +- tests/ui/sized-hierarchy/impls.stderr | 92 +++++++-------- tests/ui/sized-hierarchy/migration-no-feat.rs | 48 ++++++++ tests/ui/sized-hierarchy/migration.fixed | 71 ++++++++++++ tests/ui/sized-hierarchy/migration.rs | 71 ++++++++++++ tests/ui/sized-hierarchy/migration.stderr | 99 ++++++++++++++++ .../ui/sized-hierarchy/pointee-supertrait.rs | 1 + tests/ui/sized-hierarchy/prelude.e2024.stderr | 4 +- tests/ui/sized-hierarchy/prelude.rs | 1 + ...y-print-no-feat-dep-has-feat.e2024.stderr} | 12 +- ...y-print-no-feat-dep-has-feat.future.stderr | 61 ++++++++++ .../pretty-print-no-feat-dep-has-feat.rs | 4 + .../ui/sized-hierarchy/pretty-print-opaque.rs | 1 + .../pretty-print-opaque.stderr | 12 +- ...print.stderr => pretty-print.e2024.stderr} | 15 ++- .../pretty-print.future.stderr | 61 ++++++++++ tests/ui/sized-hierarchy/pretty-print.rs | 5 + ...utually-exclusive-trait-bound-modifiers.rs | 1 + ...lly-exclusive-trait-bound-modifiers.stderr | 12 +- .../traits/issue-85360-eval-obligation-ice.rs | 2 + .../issue-85360-eval-obligation-ice.stderr | 22 +++- .../incompleteness-unstable-result.rs | 1 + ...incompleteness-unstable-result.with.stderr | 6 +- ...ompleteness-unstable-result.without.stderr | 6 +- .../ui/traits/non_lifetime_binders/on-rpit.rs | 1 + .../non_lifetime_binders/on-rpit.stderr | 2 +- .../supertrait-dyn-compatibility.rs | 1 + .../supertrait-dyn-compatibility.stderr | 14 +-- ...holders-in-query-response-2.current.stderr | 2 +- ...aceholders-in-query-response-2.next.stderr | 2 +- ...ifying-placeholders-in-query-response-2.rs | 1 + ...ceholders-in-query-response.current.stderr | 2 +- ...placeholders-in-query-response.next.stderr | 2 +- ...unifying-placeholders-in-query-response.rs | 1 + .../resolve-impl-before-constrain-check.rs | 1 + ...resolve-impl-before-constrain-check.stderr | 2 +- ...-projection-normalization-2.current.stderr | 2 +- ...ned-projection-normalization-2.next.stderr | 2 +- ...nconstrained-projection-normalization-2.rs | 1 + ...ed-projection-normalization.current.stderr | 2 +- ...ained-projection-normalization.next.stderr | 2 +- .../unconstrained-projection-normalization.rs | 1 + 65 files changed, 821 insertions(+), 172 deletions(-) create mode 100644 tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs create mode 100644 tests/ui/sized-hierarchy/migration-no-feat.rs create mode 100644 tests/ui/sized-hierarchy/migration.fixed create mode 100644 tests/ui/sized-hierarchy/migration.rs create mode 100644 tests/ui/sized-hierarchy/migration.stderr rename tests/ui/sized-hierarchy/{pretty-print-no-feat-dep-has-feat.stderr => pretty-print-no-feat-dep-has-feat.e2024.stderr} (86%) create mode 100644 tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr rename tests/ui/sized-hierarchy/{pretty-print.stderr => pretty-print.e2024.stderr} (88%) create mode 100644 tests/ui/sized-hierarchy/pretty-print.future.stderr diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 6ca9f78e1a14b..a442652362adf 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,6 +10,7 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![deny(unsafe_op_in_unsafe_fn)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index eeebf7eaeb0bc..ce32dc037f752 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -50,6 +50,7 @@ fn associated_type_bounds<'tcx>( hir_bounds, None, span, + assoc_item_def_id, ); } // `ConstIfConst` is only interested in `~const` bounds. @@ -346,6 +347,7 @@ fn opaque_type_bounds<'tcx>( hir_bounds, None, span, + opaque_def_id, ); } //`ConstIfConst` is only interested in `~const` bounds. diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d1b65f5e091b7..4417d98fbe353 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -230,6 +230,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen &[], Some((param.def_id, hir_generics.predicates)), param.span, + def_id, ); trace!(?bounds); predicates.extend(bounds); 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 741204a3ea990..bfd6488ffad3c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -25,18 +25,19 @@ use crate::hir_ty_lowering::{ #[derive(Debug, Default)] struct CollectedBound { + constness: bool, /// `Trait` - positive: bool, + positive: Option<Span>, /// `?Trait` - maybe: bool, + maybe: Option<Span>, /// `!Trait` - negative: bool, + negative: Option<Span>, } impl CollectedBound { /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered. fn any(&self) -> bool { - self.positive || self.maybe || self.negative + self.positive.is_some() || self.maybe.is_some() || self.negative.is_some() } } @@ -84,6 +85,11 @@ fn collect_sizedness_bounds<'tcx>( unbounds.push(ptr); } + let has_constness = matches!( + ptr.modifiers.constness, + hir::BoundConstness::Always(_) | hir::BoundConstness::Maybe(_) + ); + let collect_into = match ptr.trait_ref.path.res { Res::Def(DefKind::Trait, did) if did == sized_did => &mut sized, Res::Def(DefKind::Trait, did) if did == meta_sized_did => &mut meta_sized, @@ -91,10 +97,11 @@ fn collect_sizedness_bounds<'tcx>( _ => continue, }; + collect_into.constness = has_constness; 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, + hir::BoundPolarity::Maybe(_) => collect_into.maybe = Some(hir_bound.span()), + hir::BoundPolarity::Negative(_) => collect_into.negative = Some(hir_bound.span()), + hir::BoundPolarity::Positive => collect_into.positive = Some(hir_bound.span()), } } }; @@ -183,9 +190,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let span = tcx.def_span(trait_did); + let sized_did = tcx.require_lang_item(LangItem::Sized, Some(span)); let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, Some(span)); let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, Some(span)); + let trait_hir_id = tcx.local_def_id_to_hir_id(trait_did); let trait_did = trait_did.to_def_id(); if trait_did == pointee_sized_did { // Never add a default supertrait to `PointeeSized`. @@ -193,11 +202,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let (collected, _unbounds) = collect_sizedness_bounds(tcx, hir_bounds, None, span); - if !collected.any() && trait_did != pointee_sized_did { - // If there are no explicit sizedness bounds then add a default `const MetaSized` - // supertrait. + if !collected.any() && !tcx.sess.edition().at_least_edition_future() { + // Emit migration lint when the feature is enabled. + self.emit_implicit_const_meta_sized_supertrait_lint(trait_hir_id, span); + + // If it is not Edition Future and there are no explicit sizedness bounds then add a + // default `const MetaSized` supertrait. add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); + } else if let Some(bound_span) = collected.sized.positive + && !collected.sized.constness + && !tcx.sess.edition().at_least_edition_future() + { + // Emit migration lint when the feature is enabled. + self.emit_sized_to_const_sized_lint(trait_hir_id, bound_span); + + // If it is not Edition Future then `Sized` is equivalent to writing `const Sized`. + add_trait_predicate(tcx, bounds, self_ty, sized_did, bound_span); + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, bound_span); } // See doc comment on `adjust_sizedness_predicates`. @@ -214,6 +236,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_bounds: &'tcx [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, + trait_did: LocalDefId, ) { let tcx = self.tcx(); @@ -223,10 +246,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let (collected, unbounds) = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span); - self.check_and_report_invalid_unbounds_on_param(unbounds); + let trait_hir_id = tcx.local_def_id_to_hir_id(trait_did); + self.check_and_report_invalid_unbounds_on_param(trait_hir_id, unbounds); - if (collected.sized.maybe || collected.sized.negative) - && !collected.sized.positive + if (collected.sized.maybe.is_some() || collected.sized.negative.is_some()) + && !collected.sized.positive.is_some() && !collected.meta_sized.any() && !collected.pointee_sized.any() { @@ -234,10 +258,25 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // any other explicit ones) add_trait_predicate(tcx, bounds, self_ty, meta_sized_did, span); add_host_effect_predicate(tcx, bounds, self_ty, meta_sized_did, span); + } else if let Some(bound_span) = collected.sized.positive + && !collected.sized.constness + && !tcx.sess.edition().at_least_edition_future() + { + // Emit migration lint when the feature is enabled. + self.emit_sized_to_const_sized_lint(trait_hir_id, bound_span); + + // Replace `Sized` with `const Sized`. + add_trait_predicate(tcx, bounds, self_ty, sized_did, bound_span); + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, bound_span); } else if !collected.any() { // If there are no explicit sizedness bounds then add a default `const Sized` bound. add_trait_predicate(tcx, bounds, self_ty, sized_did, span); - add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span); + + if !tcx.sess.edition().at_least_edition_future() { + self.emit_default_sized_to_const_sized_lint(trait_hir_id, span); + + add_host_effect_predicate(tcx, bounds, self_ty, sized_did, span); + } } // See doc comment on `adjust_sizedness_predicates`. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index b4e93398142db..402e776fc8aff 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -7,7 +7,7 @@ use rustc_errors::{ }; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, LangItem, PolyTraitRef}; +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 _}; @@ -15,6 +15,7 @@ use rustc_middle::ty::{ self, AdtDef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, suggest_constraining_type_param, }; +use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -32,9 +33,10 @@ 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. + /// Check for multiple relaxed default bounds and relaxed bounds. pub(crate) fn check_and_report_invalid_unbounds_on_param( &self, + trait_hir_id: HirId, unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>, ) { let tcx = self.tcx(); @@ -62,12 +64,35 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } for unbound in unbounds { - if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res - && (did == sized_did) - { + let is_sized = matches!( + unbound.trait_ref.path.res, + Res::Def(DefKind::Trait, did) if did == sized_did + ); + if is_sized && !tcx.features().sized_hierarchy() { continue; } + if tcx.features().sized_hierarchy() && is_sized { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + unbound.span, + |lint| { + lint.primary_message( + "`?Sized` bound relaxations are being migrated to `const MetaSized`", + ); + lint.span_suggestion( + unbound.span, + "replace `?Sized` with `const MetaSized`", + "const MetaSized", + Applicability::MachineApplicable, + ); + }, + ); + return; + } + + // There was a `?Trait` bound, but it was not `?Sized`. self.dcx().span_err( unbound.span, "relaxing a default bound only does something for `?Sized`; all other traits \ @@ -76,6 +101,77 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// Emit lint adding a `const MetaSized` supertrait as part of sized hierarchy migration. + pub(crate) fn emit_implicit_const_meta_sized_supertrait_lint( + &self, + trait_hir_id: HirId, + span: Span, + ) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message( + "a `const MetaSized` supertrait is required to maintain backwards \ + compatibility", + ); + lint.span_suggestion( + span.shrink_to_hi(), + "add an explicit `const MetaSized` supertrait", + ": const MetaSized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + + /// Emit lint changing `Sized` bounds to `const MetaSized` bounds as part of sized hierarchy + /// migration. + pub(crate) fn emit_sized_to_const_sized_lint(&self, trait_hir_id: HirId, span: Span) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message("`Sized` bounds are being migrated to `const Sized`"); + lint.span_suggestion( + span, + "replace `Sized` with `const Sized`", + "const Sized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + + /// Emit lint adding `const MetaSized` bound as part of sized hierarchy migration. + pub(crate) fn emit_default_sized_to_const_sized_lint(&self, trait_hir_id: HirId, span: Span) { + let tcx = self.tcx(); + if tcx.features().sized_hierarchy() { + tcx.node_span_lint( + lint::builtin::SIZED_HIERARCHY_MIGRATION, + trait_hir_id, + span, + |lint| { + lint.primary_message("default bounds are being migrated to `const Sized`"); + lint.span_suggestion( + span.shrink_to_hi(), + "add `const Sized`", + ": const Sized", + Applicability::MachineApplicable, + ); + }, + ); + } + } + /// 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 complain_about_missing_type_params( diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 592c934997c01..6c05a29c50ea5 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -97,6 +97,7 @@ declare_lint_pass! { SELF_CONSTRUCTOR_FROM_OUTER_ITEM, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SINGLE_USE_LIFETIMES, + SIZED_HIERARCHY_MIGRATION, SOFT_UNSTABLE, STABLE_FEATURES, SUPERTRAIT_ITEM_SHADOWING_DEFINITION, @@ -5125,3 +5126,41 @@ declare_lint! { reference: "issue #116558 <https://github.com/rust-lang/rust/issues/116558>", }; } + +declare_lint! { + /// The `sized_hierarchy_migration` lint detects uses of the `Sized` trait which must be + /// migrated with the introduction of a hierarchy of sizedness traits. + /// + /// ### Example + /// ```rust,edition_2024,compile_fail + /// #![feature(sized_hierarchy)] + /// #![deny(sized_hierarchy_migration)] + /// + /// pub fn foo<T: ?Sized>() {} + /// + /// pub trait Foo {} + /// + /// pub fn bar<T>() {} + /// + /// pub fn qux<T: Sized>() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// In order to preserve backwards compatibility when a hierarchy of sizedness traits is + /// introduced, various migrations are necessary: + /// + /// - `Sized` becomes `const Sized` + /// - `?Sized` becomes `const MetaSized` + /// - Traits have a `const MetaSized` supertrait + /// + /// See [RFC #3729](https://github.com/rust-lang/rfcs/pull/3729) for more details. + pub SIZED_HIERARCHY_MIGRATION, + Warn, + "new sized traits are being introduced which require migration to maintain backwards compat", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::EditionFuture), + reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html>", + }; +} diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index a15d7b83f287f..a6dd411608b1e 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,6 +30,7 @@ #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 806d880b19c5a..eef0dbdf20229 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -3,6 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::internal)] +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![cfg_attr(test, feature(test))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index ec9602aa1d501..e844fe16697a6 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,6 +10,7 @@ #![allow(internal_features)] #![allow(rustc::usage_of_ty_tykind)] #![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141 +#![cfg_attr(not(bootstrap), allow(sized_hierarchy_migration))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) diff --git a/tests/ui/const-generics/unused-type-param-suggestion.rs b/tests/ui/const-generics/unused-type-param-suggestion.rs index b7f8eb45083e1..8e6715ac3c7e5 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.rs +++ b/tests/ui/const-generics/unused-type-param-suggestion.rs @@ -1,4 +1,5 @@ #![crate_type="lib"] +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] struct S<N>; diff --git a/tests/ui/const-generics/unused-type-param-suggestion.stderr b/tests/ui/const-generics/unused-type-param-suggestion.stderr index 7963465bfa0fe..fa12eb35feff0 100644 --- a/tests/ui/const-generics/unused-type-param-suggestion.stderr +++ b/tests/ui/const-generics/unused-type-param-suggestion.stderr @@ -1,5 +1,5 @@ error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:4:10 + --> $DIR/unused-type-param-suggestion.rs:5:10 | LL | struct S<N>; | ^ unused type parameter @@ -8,7 +8,7 @@ LL | struct S<N>; = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0392]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:10:10 + --> $DIR/unused-type-param-suggestion.rs:11:10 | LL | struct T<N: Copy>; | ^ unused type parameter @@ -16,7 +16,7 @@ LL | struct T<N: Copy>; = help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData` error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:14:8 + --> $DIR/unused-type-param-suggestion.rs:15:8 | LL | type A<N> = (); | ^ unused type parameter @@ -25,7 +25,7 @@ LL | type A<N> = (); = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:20:8 + --> $DIR/unused-type-param-suggestion.rs:21:8 | LL | type B<N: Copy> = (); | ^ unused type parameter @@ -33,7 +33,7 @@ LL | type B<N: Copy> = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:23:8 + --> $DIR/unused-type-param-suggestion.rs:24:8 | LL | type C<N: Sized> = (); | ^ unused type parameter @@ -41,7 +41,7 @@ LL | type C<N: Sized> = (); = help: consider removing `N` or referring to it in the body of the type alias error[E0091]: type parameter `N` is never used - --> $DIR/unused-type-param-suggestion.rs:26:8 + --> $DIR/unused-type-param-suggestion.rs:27:8 | LL | type D<N: ?Sized> = (); | ^ unused type parameter diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs index 33688c2e2ce03..363a70f736dd6 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.rs @@ -1,3 +1,4 @@ +#![allow(sized_hierarchy_migration)] #![feature(extern_types)] #![feature(sized_hierarchy)] diff --git a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr index 6a35fcfb0e8e5..f1cbf2047adba 100644 --- a/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr +++ b/tests/ui/feature-gates/feature-gate-sized-hierarchy.stderr @@ -1,38 +1,38 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/feature-gate-sized-hierarchy.rs:17:19 + --> $DIR/feature-gate-sized-hierarchy.rs:18: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/feature-gate-sized-hierarchy.rs:8:19 + --> $DIR/feature-gate-sized-hierarchy.rs:9: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/feature-gate-sized-hierarchy.rs:25:23 + --> $DIR/feature-gate-sized-hierarchy.rs:26: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/feature-gate-sized-hierarchy.rs:7:23 + --> $DIR/feature-gate-sized-hierarchy.rs:8:23 | 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 + --> $DIR/feature-gate-sized-hierarchy.rs:28: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/feature-gate-sized-hierarchy.rs:8:19 + --> $DIR/feature-gate-sized-hierarchy.rs:9:19 | LL | fn needs_sized<T: Sized>() {} | ^^^^^ required by this bound in `needs_sized` diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index 928784a4f0566..91ea0c49dc028 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -3,6 +3,7 @@ //! This used to ICE in layout computation, because `<u8 as A>::B` fails to normalize //! due to the unconstrained param on the impl. +#![allow(sized_hierarchy_migration)] #![feature(rustc_attrs, sized_hierarchy)] #![crate_type = "lib"] diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 3746e3e829f14..7e9005c5501d3 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -1,11 +1,11 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-param-ice-137308.rs:15:6 + --> $DIR/unconstrained-param-ice-137308.rs:16:6 | LL | impl<C: PointeeSized> A for u8 { | ^ unconstrained type parameter error: the type has an unknown layout - --> $DIR/unconstrained-param-ice-137308.rs:20:1 + --> $DIR/unconstrained-param-ice-137308.rs:21:1 | LL | struct S([u8; <u8 as A>::B]); | ^^^^^^^^ diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 575a66fe302ce..f9eb0dde13920 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -1,3 +1,4 @@ +#![allow(sized_hierarchy_migration)] #![feature(extern_types, sized_hierarchy)] use std::marker::PointeeSized; diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index 0953e86e222e4..f86d1b0657e47 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:37:5 + --> $DIR/offset-of-dst-field.rs:38:5 | LL | offset_of!(Alpha, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -8,7 +8,7 @@ LL | offset_of!(Alpha, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:38:5 + --> $DIR/offset-of-dst-field.rs:39:5 | LL | offset_of!(Beta, z); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -17,7 +17,7 @@ LL | offset_of!(Beta, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:39:5 + --> $DIR/offset-of-dst-field.rs:40:5 | LL | offset_of!(Gamma, z); | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -26,7 +26,7 @@ LL | offset_of!(Gamma, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:41:5 + --> $DIR/offset-of-dst-field.rs:42:5 | LL | offset_of!((u8, dyn Trait), 1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -35,7 +35,7 @@ LL | offset_of!((u8, dyn Trait), 1); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `Extern` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:46:5 + --> $DIR/offset-of-dst-field.rs:47:5 | LL | offset_of!(Delta<Extern>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -44,7 +44,7 @@ LL | offset_of!(Delta<Extern>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:47:5 + --> $DIR/offset-of-dst-field.rs:48:5 | LL | offset_of!(Delta<dyn Trait>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -53,21 +53,21 @@ LL | offset_of!(Delta<dyn Trait>, z); = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:45:5 + --> $DIR/offset-of-dst-field.rs:46:5 | LL | offset_of!(Delta<Alpha>, z); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Alpha`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `Alpha` - --> $DIR/offset-of-dst-field.rs:6:8 + --> $DIR/offset-of-dst-field.rs:7:8 | LL | struct Alpha { | ^^^^^ = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:51:5 + --> $DIR/offset-of-dst-field.rs:52:5 | LL | fn generic_with_maybe_sized<T: ?Sized>() -> usize { | - this type parameter needs to be `Sized` @@ -82,7 +82,7 @@ LL + fn generic_with_maybe_sized<T>() -> usize { | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/offset-of-dst-field.rs:55:16 + --> $DIR/offset-of-dst-field.rs:56:16 | LL | offset_of!(([u8], u8), 1); | ^^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs b/tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs new file mode 100644 index 0000000000000..198d903ad414f --- /dev/null +++ b/tests/ui/sized-hierarchy/auxiliary/migration-no-feat-dep.rs @@ -0,0 +1,6 @@ +//@ compile-flags: -Zunstable-options +//@ edition: future +#![feature(const_trait_impl, sized_hierarchy)] + +pub fn needs_const_sized<T: const Sized>() { unimplemented!() } +pub fn needs_const_metasized<T: const MetaSized>() { unimplemented!() } diff --git a/tests/ui/sized-hierarchy/default-bound.rs b/tests/ui/sized-hierarchy/default-bound.rs index 12b2eb2b5c1b4..9e01f995ce8ff 100644 --- a/tests/ui/sized-hierarchy/default-bound.rs +++ b/tests/ui/sized-hierarchy/default-bound.rs @@ -1,4 +1,7 @@ //@ check-fail +//@ compile-flags: -Zunstable-options +//@ edition: future +#![allow(sized_hierarchy_migration)] #![feature(extern_types, sized_hierarchy)] use std::marker::{MetaSized, PointeeSized}; @@ -14,13 +17,13 @@ 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 +//~^ ERROR relaxing a default bound only does something for `?Sized` 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 +//~^ ERROR relaxing a default bound only does something for `?Sized` fn main() { diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr index 22f0fa29d3e23..510109a2d5770 100644 --- a/tests/ui/sized-hierarchy/default-bound.stderr +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -1,24 +1,24 @@ error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/default-bound.rs:16:21 + --> $DIR/default-bound.rs:19: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 + --> $DIR/default-bound.rs:25: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 + --> $DIR/default-bound.rs:32: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 + --> $DIR/default-bound.rs:9:9 | LL | fn bare<T>() {} | ^ required by the implicit `Sized` requirement on this type parameter in `bare` @@ -28,27 +28,27 @@ 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 + --> $DIR/default-bound.rs:34: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 + --> $DIR/default-bound.rs:12: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 + --> $DIR/default-bound.rs:45: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 + --> $DIR/default-bound.rs:9:9 | LL | fn bare<T>() {} | ^ required by the implicit `Sized` requirement on this type parameter in `bare` @@ -58,27 +58,27 @@ 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 + --> $DIR/default-bound.rs:47: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 + --> $DIR/default-bound.rs:12: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 + --> $DIR/default-bound.rs:49: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 + --> $DIR/default-bound.rs:17:17 | LL | fn metasized<T: MetaSized>() {} | ^^^^^^^^^ required by this bound in `metasized` diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs index b25acf9e6ea4f..e545431bb9cc3 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.rs +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -1,4 +1,5 @@ //@ check-fail +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] use std::marker::{MetaSized, PointeeSized}; diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index ca461a4317b42..8fcd58a56f990 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -1,5 +1,5 @@ error[E0658]: `?Trait` is not permitted in supertraits - --> $DIR/default-supertrait.rs:8:17 + --> $DIR/default-supertrait.rs:9:17 | LL | trait NegSized: ?Sized { } | ^^^^^^ @@ -9,7 +9,7 @@ LL | trait NegSized: ?Sized { } = 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 + --> $DIR/default-supertrait.rs:14:21 | LL | trait NegMetaSized: ?MetaSized { } | ^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | trait NegMetaSized: ?MetaSized { } = 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 + --> $DIR/default-supertrait.rs:20:24 | LL | trait NegPointeeSized: ?PointeeSized { } | ^^^^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | trait NegPointeeSized: ?PointeeSized { } = 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 + --> $DIR/default-supertrait.rs:53: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 + --> $DIR/default-supertrait.rs:23:1 | LL | trait Bare {} | ^^^^^^^^^^ required by this bound in `Bare` @@ -45,7 +45,7 @@ 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 + --> $DIR/default-supertrait.rs:36:22 | LL | fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() { | - this type parameter needs to be `Sized` @@ -53,13 +53,13 @@ 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 + --> $DIR/default-supertrait.rs:25: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 + --> $DIR/default-supertrait.rs:44:22 | LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() { | - this type parameter needs to be `Sized` @@ -67,19 +67,19 @@ 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 + --> $DIR/default-supertrait.rs:25: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 + --> $DIR/default-supertrait.rs:46: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 + --> $DIR/default-supertrait.rs:26:26 | LL | fn requires_metasized<T: MetaSized>() {} | ^^^^^^^^^ required by this bound in `requires_metasized` @@ -89,7 +89,7 @@ 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:54:22 + --> $DIR/default-supertrait.rs:55:22 | LL | fn with_bare_trait<T: PointeeSized + Bare>() { | - this type parameter needs to be `Sized` @@ -98,19 +98,19 @@ 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 + --> $DIR/default-supertrait.rs:25: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 + --> $DIR/default-supertrait.rs:57: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 + --> $DIR/default-supertrait.rs:26:26 | LL | fn requires_metasized<T: MetaSized>() {} | ^^^^^^^^^ required by this bound in `requires_metasized` diff --git a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs index 9cb6f267743b4..3bf11c85bee07 100644 --- a/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs +++ b/tests/ui/sized-hierarchy/extern-type-behind-ptr.rs @@ -1,4 +1,5 @@ //@ check-pass +#![allow(sized_hierarchy_migration)] #![feature(extern_types, sized_hierarchy)] use std::marker::PointeeSized; diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs index 601d837043ef5..fad1b27b789c1 100644 --- a/tests/ui/sized-hierarchy/impls.rs +++ b/tests/ui/sized-hierarchy/impls.rs @@ -1,7 +1,9 @@ //@ check-fail -//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ edition: future #![allow(incomplete_features, internal_features)] +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] #![feature(coroutines, dyn_star, extern_types, f16, never_type, unsized_fn_params)] diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr index 02ccfebdc4416..6856daaeb9201 100644 --- a/tests/ui/sized-hierarchy/impls.stderr +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/impls.rs:239:42 + --> $DIR/impls.rs:241: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:247:40 + --> $DIR/impls.rs:249: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:283:44 + --> $DIR/impls.rs:285: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:290:42 + --> $DIR/impls.rs:292: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:297:52 + --> $DIR/impls.rs:299: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:304:50 + --> $DIR/impls.rs:306: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:160:19 + --> $DIR/impls.rs:162: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:13:19 + --> $DIR/impls.rs:15: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:166:19 + --> $DIR/impls.rs:168: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:13:19 + --> $DIR/impls.rs:15: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:172:19 + --> $DIR/impls.rs:174: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:13:19 + --> $DIR/impls.rs:15: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:181:19 + --> $DIR/impls.rs:183: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:13:19 + --> $DIR/impls.rs:15: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:183:23 + --> $DIR/impls.rs:185: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:16:23 + --> $DIR/impls.rs:18:23 | 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:198:19 + --> $DIR/impls.rs:200: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:200:23 + --> $DIR/impls.rs:202: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:202:26 + --> $DIR/impls.rs:204: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:206:19 + --> $DIR/impls.rs:208: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:208:23 + --> $DIR/impls.rs:210: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:210:26 + --> $DIR/impls.rs:212: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:214:19 + --> $DIR/impls.rs:216: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:13:19 + --> $DIR/impls.rs:15: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:220:19 + --> $DIR/impls.rs:222: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:13:19 + --> $DIR/impls.rs:15: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:222:23 + --> $DIR/impls.rs:224:23 | LL | needs_metasized::<(u32, Foo)>(); | ^^^^^^^^^^ doesn't have a known size @@ -262,115 +262,115 @@ 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:16:23 + --> $DIR/impls.rs:18:23 | 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:241:19 + --> $DIR/impls.rs:243: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:239:12 + --> $DIR/impls.rs:241:12 | LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } | ^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_sized` - --> $DIR/impls.rs:13:19 + --> $DIR/impls.rs:15: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:249:19 + --> $DIR/impls.rs:251: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:247:12 + --> $DIR/impls.rs:249:12 | LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_sized` - --> $DIR/impls.rs:13:19 + --> $DIR/impls.rs:15: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:251:23 + --> $DIR/impls.rs:253: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:247:12 + --> $DIR/impls.rs:249:12 | LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_metasized` - --> $DIR/impls.rs:16:23 + --> $DIR/impls.rs:18:23 | 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:257:19 + --> $DIR/impls.rs:259: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:256:12 + --> $DIR/impls.rs:258:12 | LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } | ^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_sized` - --> $DIR/impls.rs:13:19 + --> $DIR/impls.rs:15: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:264:19 + --> $DIR/impls.rs:266: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:263:12 + --> $DIR/impls.rs:265:12 | LL | struct StructLastFieldUnsized { x: u32, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_sized` - --> $DIR/impls.rs:13:19 + --> $DIR/impls.rs:15: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:266:23 + --> $DIR/impls.rs:268: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:263:12 + --> $DIR/impls.rs:265:12 | LL | struct StructLastFieldUnsized { x: u32, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `needs_metasized` - --> $DIR/impls.rs:16:23 + --> $DIR/impls.rs:18:23 | LL | fn needs_metasized<T: MetaSized>() { } | ^^^^^^^^^ required by this bound in `needs_metasized` diff --git a/tests/ui/sized-hierarchy/migration-no-feat.rs b/tests/ui/sized-hierarchy/migration-no-feat.rs new file mode 100644 index 0000000000000..3683622284759 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration-no-feat.rs @@ -0,0 +1,48 @@ +//@ aux-build:migration-no-feat-dep.rs +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ edition: 2024 + +#![feature(const_trait_impl)] + +extern crate migration_no_feat_dep; +use migration_no_feat_dep::{needs_const_metasized, needs_const_sized}; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds without the `sized_hierarchy` +// feature work as expected with a migrated crate. + +pub fn relaxed_bound_migration<T: ?Sized>() { + needs_const_metasized::<T>() +} + + +pub fn default_sized_to_const_sized<T>() { + needs_const_sized::<T>() +} + +pub fn sized_to_const_sized<T: Sized>() { + needs_const_sized::<T>() +} + + +pub trait ImplicitSupertrait { + fn check() { + needs_const_metasized::<Self>() + } +} + +pub trait SizedToConstSized: Sized { + fn check() { + needs_const_sized::<Self>() + } +} + +pub trait AssocType { + type Foo: Sized; + type Bar: ?Sized; + + fn check() { + needs_const_sized::<Self::Foo>(); + needs_const_metasized::<Self::Bar>(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.fixed b/tests/ui/sized-hierarchy/migration.fixed new file mode 100644 index 0000000000000..f2b62276cebf4 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.fixed @@ -0,0 +1,71 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib +//@ edition: 2024 +//@ run-rustfix + +#![deny(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::MetaSized; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds trigger edition migration lints. + +pub fn needs_const_sized<T: const Sized>() { unimplemented!() } +pub fn needs_const_metasized<T: const MetaSized>() { unimplemented!() } + + +pub fn relaxed_bound_migration<T: const MetaSized>() { +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_metasized::<T>() +} + + +pub fn default_sized_to_const_sized<T: const Sized>() { +//~^ ERROR default bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::<T>() +} + +pub fn sized_to_const_sized<T: const Sized>() { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::<T>() +} + + +pub trait ImplicitSupertrait: const MetaSized { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_metasized::<Self>() + } +} + +pub trait SizedToConstSized: const Sized { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_sized::<Self>() + } +} + +pub trait AssocType: const MetaSized { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Foo: const Sized; +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Bar: const MetaSized; +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + + fn check() { + needs_const_sized::<Self::Foo>(); + needs_const_metasized::<Self::Bar>(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.rs b/tests/ui/sized-hierarchy/migration.rs new file mode 100644 index 0000000000000..3ab0acceace95 --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.rs @@ -0,0 +1,71 @@ +//@ check-fail +//@ compile-flags: --crate-type=lib +//@ edition: 2024 +//@ run-rustfix + +#![deny(sized_hierarchy_migration)] +#![feature(const_trait_impl, sized_hierarchy)] + +use std::marker::MetaSized; + +// Test that use of `?Sized`, `Sized` or default supertrait/bounds trigger edition migration lints. + +pub fn needs_const_sized<T: const Sized>() { unimplemented!() } +pub fn needs_const_metasized<T: const MetaSized>() { unimplemented!() } + + +pub fn relaxed_bound_migration<T: ?Sized>() { +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_metasized::<T>() +} + + +pub fn default_sized_to_const_sized<T>() { +//~^ ERROR default bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::<T>() +} + +pub fn sized_to_const_sized<T: Sized>() { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + needs_const_sized::<T>() +} + + +pub trait ImplicitSupertrait { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_metasized::<Self>() + } +} + +pub trait SizedToConstSized: Sized { +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + fn check() { + needs_const_sized::<Self>() + } +} + +pub trait AssocType { +//~^ ERROR a `const MetaSized` supertrait is required to maintain backwards compatibility +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Foo: Sized; +//~^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `Sized` bounds are being migrated to `const Sized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + type Bar: ?Sized; +//~^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future +//~^^^ ERROR `?Sized` bound relaxations are being migrated to `const MetaSized` +//~| WARN this is accepted in the current edition (Rust 2024) but is a hard error in Rust future + + fn check() { + needs_const_sized::<Self::Foo>(); + needs_const_metasized::<Self::Bar>(); + } +} diff --git a/tests/ui/sized-hierarchy/migration.stderr b/tests/ui/sized-hierarchy/migration.stderr new file mode 100644 index 0000000000000..b35f871246bfe --- /dev/null +++ b/tests/ui/sized-hierarchy/migration.stderr @@ -0,0 +1,99 @@ +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:17:35 + | +LL | pub fn relaxed_bound_migration<T: ?Sized>() { + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> +note: the lint level is defined here + --> $DIR/migration.rs:6:9 + | +LL | #![deny(sized_hierarchy_migration)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: default bounds are being migrated to `const Sized` + --> $DIR/migration.rs:24:37 + | +LL | pub fn default_sized_to_const_sized<T>() { + | ^- help: add `const Sized`: `: const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:30:32 + | +LL | pub fn sized_to_const_sized<T: Sized>() { + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: a `const MetaSized` supertrait is required to maintain backwards compatibility + --> $DIR/migration.rs:37:1 + | +LL | pub trait ImplicitSupertrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: add an explicit `const MetaSized` supertrait: `: const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:45:30 + | +LL | pub trait SizedToConstSized: Sized { + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: a `const MetaSized` supertrait is required to maintain backwards compatibility + --> $DIR/migration.rs:53:1 + | +LL | pub trait AssocType { + | ^^^^^^^^^^^^^^^^^^^- help: add an explicit `const MetaSized` supertrait: `: const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:56:15 + | +LL | type Foo: Sized; + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: `Sized` bounds are being migrated to `const Sized` + --> $DIR/migration.rs:56:15 + | +LL | type Foo: Sized; + | ^^^^^ help: replace `Sized` with `const Sized`: `const Sized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:61:15 + | +LL | type Bar: ?Sized; + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + +error: `?Sized` bound relaxations are being migrated to `const MetaSized` + --> $DIR/migration.rs:61:15 + | +LL | type Bar: ?Sized; + | ^^^^^^ help: replace `?Sized` with `const MetaSized`: `const MetaSized` + | + = warning: this is accepted in the current edition (Rust 2024) but is a hard error in Rust future! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-future/sized-hierarchy.html> + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + diff --git a/tests/ui/sized-hierarchy/pointee-supertrait.rs b/tests/ui/sized-hierarchy/pointee-supertrait.rs index 4bf486890bf23..b4f07baa1f998 100644 --- a/tests/ui/sized-hierarchy/pointee-supertrait.rs +++ b/tests/ui/sized-hierarchy/pointee-supertrait.rs @@ -1,4 +1,5 @@ //@ check-pass +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] // This is a reduction of some code in `library/core/src/cmp.rs` that would ICE if a default diff --git a/tests/ui/sized-hierarchy/prelude.e2024.stderr b/tests/ui/sized-hierarchy/prelude.e2024.stderr index 80e6b236b664f..e405456a59f30 100644 --- a/tests/ui/sized-hierarchy/prelude.e2024.stderr +++ b/tests/ui/sized-hierarchy/prelude.e2024.stderr @@ -1,5 +1,5 @@ error[E0405]: cannot find trait `MetaSized` in this scope - --> $DIR/prelude.rs:10:21 + --> $DIR/prelude.rs:11:21 | LL | pub fn metasized<T: MetaSized>() {} | ^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL + use std::marker::MetaSized; | error[E0405]: cannot find trait `PointeeSized` in this scope - --> $DIR/prelude.rs:12:24 + --> $DIR/prelude.rs:13:24 | LL | pub fn pointeesized<T: PointeeSized>() {} | ^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/sized-hierarchy/prelude.rs b/tests/ui/sized-hierarchy/prelude.rs index c78a11b6ae312..e9084135af90e 100644 --- a/tests/ui/sized-hierarchy/prelude.rs +++ b/tests/ui/sized-hierarchy/prelude.rs @@ -5,6 +5,7 @@ //@[future] compile-flags: -Zunstable-options //@[future] edition: future //@[future] check-pass +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] pub fn metasized<T: MetaSized>() {} diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr similarity index 86% rename from tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr rename to tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr index 756876542117a..e805e15961975 100644 --- a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.e2024.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:18:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 | LL | impl<T: Sized> ConstSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | impl<T: Sized> ConstSizedTr for X<T> {} - impl<T> ConstSizedTr for T; error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:21:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 | LL | impl<T: Sized> SizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | impl<T: Sized> SizedTr for X<T> {} - impl<T> SizedTr for T; error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:24:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:28:1 | LL | impl<T: ?Sized> NegSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | impl<T: ?Sized> NegSizedTr for X<T> {} where T: ?Sized; error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:27:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:31:1 | LL | impl<T: ?Sized> ConstMetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | impl<T: ?Sized> ConstMetaSizedTr for X<T> {} where T: ?Sized; error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:30:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:34:1 | LL | impl<T: ?Sized> MetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | impl<T: ?Sized> MetaSizedTr for X<T> {} where T: ?Sized; error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` - --> $DIR/pretty-print-no-feat-dep-has-feat.rs:33:1 + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:37:1 | LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr new file mode 100644 index 0000000000000..e805e15961975 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.future.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:22:1 + | +LL | impl<T: Sized> ConstSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:25:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:28:1 + | +LL | impl<T: ?Sized> NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:31:1 + | +LL | impl<T: ?Sized> ConstMetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstMetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:34:1 + | +LL | impl<T: ?Sized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print-no-feat-dep-has-feat.rs:37:1 + | +LL | impl<T: ?Sized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: ?Sized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs index 998aa5597c9fc..f69104fcee7c2 100644 --- a/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs +++ b/tests/ui/sized-hierarchy/pretty-print-no-feat-dep-has-feat.rs @@ -1,5 +1,9 @@ //@ aux-build:pretty-print-dep.rs //@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future extern crate pretty_print_dep; use pretty_print_dep::{ diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs index b21cee1357add..43bda5c7a0b25 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.rs +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -1,4 +1,5 @@ //@ compile-flags: --crate-type=lib +#![allow(sized_hierarchy_migration)] #![feature(const_trait_impl, sized_hierarchy)] use std::marker::{MetaSized, PointeeSized}; diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr index 541e018261bde..38880898007f7 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known - --> $DIR/pretty-print-opaque.rs:52:26 + --> $DIR/pretty-print-opaque.rs:53:26 | LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size @@ -9,7 +9,7 @@ note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL error[E0277]: the size for values of type `impl Tr + const MetaSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:28:30 + --> $DIR/pretty-print-opaque.rs:29:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time @@ -18,7 +18,7 @@ LL | let y: Box<dyn Tr> = x; = note: required for the cast from `Box<impl Tr + const MetaSized>` to `Box<dyn Tr>` error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:37:30 + --> $DIR/pretty-print-opaque.rs:38:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time @@ -27,7 +27,7 @@ LL | let y: Box<dyn Tr> = x; = note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>` error[E0277]: the size for values of type `impl Tr + const MetaSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:46:30 + --> $DIR/pretty-print-opaque.rs:47:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time @@ -36,7 +36,7 @@ LL | let y: Box<dyn Tr> = x; = note: required for the cast from `Box<impl Tr + const MetaSized>` to `Box<dyn Tr>` error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known - --> $DIR/pretty-print-opaque.rs:55:17 + --> $DIR/pretty-print-opaque.rs:56:17 | LL | let x = pointeesized(); | ^^^^^^^^^^^^^^ doesn't have a known size @@ -46,7 +46,7 @@ note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time - --> $DIR/pretty-print-opaque.rs:57:30 + --> $DIR/pretty-print-opaque.rs:58:30 | LL | let y: Box<dyn Tr> = x; | ^ doesn't have a size known at compile-time diff --git a/tests/ui/sized-hierarchy/pretty-print.stderr b/tests/ui/sized-hierarchy/pretty-print.e2024.stderr similarity index 88% rename from tests/ui/sized-hierarchy/pretty-print.stderr rename to tests/ui/sized-hierarchy/pretty-print.e2024.stderr index 84f942ddf05c2..7d851188214f4 100644 --- a/tests/ui/sized-hierarchy/pretty-print.stderr +++ b/tests/ui/sized-hierarchy/pretty-print.e2024.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:18:1 + --> $DIR/pretty-print.rs:23:1 | LL | impl<T: const Sized> ConstSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,17 +8,16 @@ LL | impl<T: const Sized> ConstSizedTr for X<T> {} - impl<T> ConstSizedTr for T; error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:21:1 + --> $DIR/pretty-print.rs:26:1 | LL | impl<T: Sized> SizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `pretty_print_dep`: - - impl<T> SizedTr for T - where T: Sized; + - impl<T> SizedTr for T; error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:24:1 + --> $DIR/pretty-print.rs:29:1 | LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +27,7 @@ LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} where T: const MetaSized; error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:27:1 + --> $DIR/pretty-print.rs:32:1 | LL | impl<T: const MetaSized> ConstMetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +37,7 @@ LL | impl<T: const MetaSized> ConstMetaSizedTr for X<T> {} where T: const MetaSized; error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:30:1 + --> $DIR/pretty-print.rs:35:1 | LL | impl<T: MetaSized> MetaSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,7 +47,7 @@ LL | impl<T: MetaSized> MetaSizedTr for X<T> {} where T: MetaSized; error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` - --> $DIR/pretty-print.rs:33:1 + --> $DIR/pretty-print.rs:38:1 | LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/sized-hierarchy/pretty-print.future.stderr b/tests/ui/sized-hierarchy/pretty-print.future.stderr new file mode 100644 index 0000000000000..7d851188214f4 --- /dev/null +++ b/tests/ui/sized-hierarchy/pretty-print.future.stderr @@ -0,0 +1,61 @@ +error[E0119]: conflicting implementations of trait `ConstSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:23:1 + | +LL | impl<T: const Sized> ConstSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstSizedTr for T; + +error[E0119]: conflicting implementations of trait `SizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:26:1 + | +LL | impl<T: Sized> SizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> SizedTr for T; + +error[E0119]: conflicting implementations of trait `NegSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:29:1 + | +LL | impl<T: ?Sized> pretty_print_dep::NegSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> NegSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `ConstMetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:32:1 + | +LL | impl<T: const MetaSized> ConstMetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> ConstMetaSizedTr for T + where T: const MetaSized; + +error[E0119]: conflicting implementations of trait `MetaSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:35:1 + | +LL | impl<T: MetaSized> MetaSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> MetaSizedTr for T + where T: MetaSized; + +error[E0119]: conflicting implementations of trait `PointeeSizedTr` for type `X<_>` + --> $DIR/pretty-print.rs:38:1 + | +LL | impl<T: PointeeSized> PointeeSizedTr for X<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `pretty_print_dep`: + - impl<T> PointeeSizedTr for T + where T: PointeeSized; + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/sized-hierarchy/pretty-print.rs b/tests/ui/sized-hierarchy/pretty-print.rs index 68fb6b13455ef..091a731ac769a 100644 --- a/tests/ui/sized-hierarchy/pretty-print.rs +++ b/tests/ui/sized-hierarchy/pretty-print.rs @@ -1,5 +1,10 @@ //@ aux-build:pretty-print-dep.rs //@ compile-flags: --crate-type=lib +//@ revisions: e2024 future +//@[e2024] edition: 2024 +//@[future] compile-flags: -Zunstable-options +//@[future] edition: future +#![allow(sized_hierarchy_migration)] #![feature(const_trait_impl, sized_hierarchy)] // Test that printing the sizedness trait bounds in the conflicting impl error with diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs index e9dcad1026761..a8d178b949e8e 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.rs @@ -1,3 +1,4 @@ +#![allow(sized_hierarchy_migration)] #![feature(const_trait_impl, sized_hierarchy)] const fn maybe_const_maybe<T: ~const ?Sized>() {} diff --git a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr index 18e4d160f5f46..cf02ddcc1325f 100644 --- a/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr +++ b/tests/ui/traits/const-traits/mutually-exclusive-trait-bound-modifiers.stderr @@ -1,5 +1,5 @@ error: `~const` trait not allowed with `?` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:38 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:4:38 | LL | const fn maybe_const_maybe<T: ~const ?Sized>() {} | ------ ^ @@ -7,7 +7,7 @@ LL | const fn maybe_const_maybe<T: ~const ?Sized>() {} | there is not a well-defined meaning for a `~const ?` trait error: `const` trait not allowed with `?` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:7:25 | LL | fn const_maybe<T: const ?Sized>() {} | ----- ^ @@ -15,7 +15,7 @@ LL | fn const_maybe<T: const ?Sized>() {} | there is not a well-defined meaning for a `const ?` trait error: `~const` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:10:41 | LL | const fn maybe_const_negative<T: ~const !Trait>() {} | ------ ^ @@ -23,7 +23,7 @@ LL | const fn maybe_const_negative<T: ~const !Trait>() {} | there is not a well-defined meaning for a `~const !` trait error: `const` trait not allowed with `!` trait polarity modifier - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:14:28 | LL | fn const_negative<T: const !Trait>() {} | ----- ^ @@ -31,13 +31,13 @@ LL | fn const_negative<T: const !Trait>() {} | there is not a well-defined meaning for a `const !` trait error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:41 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:10:41 | LL | const fn maybe_const_negative<T: ~const !Trait>() {} | ^ error: negative bounds are not supported - --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28 + --> $DIR/mutually-exclusive-trait-bound-modifiers.rs:14:28 | LL | fn const_negative<T: const !Trait>() {} | ^ diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.rs b/tests/ui/traits/issue-85360-eval-obligation-ice.rs index 931879a672262..bef84dabe70e9 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.rs +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.rs @@ -8,9 +8,11 @@ use core::marker::PhantomData; fn main() { test::<MaskedStorage<GenericComp<Pos>>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(<MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOk) + //~^^ ERROR evaluate(Binder { value: HostEffectPredicate { trait_ref: <MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) test::<MaskedStorage<GenericComp2<Pos>>>(make()); //~^ ERROR evaluate(Binder { value: TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) + //~^^ ERROR evaluate(Binder { value: HostEffectPredicate { trait_ref: <MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) } #[rustc_evaluate_where_clauses] diff --git a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr index d2b00a45a4f15..fee397ae36fd3 100644 --- a/tests/ui/traits/issue-85360-eval-obligation-ice.stderr +++ b/tests/ui/traits/issue-85360-eval-obligation-ice.stderr @@ -7,8 +7,26 @@ LL | test::<MaskedStorage<GenericComp<Pos>>>(make()); LL | fn test<T: Sized>(_: T) {} | ----- predicate +error: evaluate(Binder { value: HostEffectPredicate { trait_ref: <MaskedStorage<GenericComp<Pos>> as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) + --> $DIR/issue-85360-eval-obligation-ice.rs:9:5 + | +LL | test::<MaskedStorage<GenericComp<Pos>>>(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn test<T: Sized>(_: T) {} + | ----- predicate + error: evaluate(Binder { value: TraitPredicate(<MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, polarity:Positive), bound_vars: [] }) = Ok(EvaluatedToOkModuloRegions) - --> $DIR/issue-85360-eval-obligation-ice.rs:12:5 + --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 + | +LL | test::<MaskedStorage<GenericComp2<Pos>>>(make()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn test<T: Sized>(_: T) {} + | ----- predicate + +error: evaluate(Binder { value: HostEffectPredicate { trait_ref: <MaskedStorage<GenericComp2<Pos>> as std::marker::Sized>, constness: Const }, bound_vars: [] }) = Ok(EvaluatedToOk) + --> $DIR/issue-85360-eval-obligation-ice.rs:13:5 | LL | test::<MaskedStorage<GenericComp2<Pos>>>(make()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,5 +34,5 @@ LL | test::<MaskedStorage<GenericComp2<Pos>>>(make()); LL | fn test<T: Sized>(_: T) {} | ----- predicate -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs index e2389bd02e80a..2f454cfb062d9 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.rs @@ -1,5 +1,6 @@ //@ revisions: with without //@ compile-flags: -Znext-solver +#![allow(sized_hierarchy_migration)] #![feature(rustc_attrs, sized_hierarchy)] use std::marker::PointeeSized; diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr index c796663b13f0b..0eaa7d805e72c 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.with.stderr @@ -1,12 +1,12 @@ error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:73:19 + --> $DIR/incompleteness-unstable-result.rs:74:19 | LL | impls_trait::<A<X>, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>` | = help: the trait `Trait<U, V, D>` is implemented for `A<T>` note: required for `A<X>` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:34:74 + --> $DIR/incompleteness-unstable-result.rs:35:74 | LL | impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for A<T> | ^^^^^^^^^^^^^^ ^^^^ @@ -16,7 +16,7 @@ LL | A<T>: Trait<U, D, V>, = note: 8 redundant requirements hidden = note: required for `A<X>` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:55:23 + --> $DIR/incompleteness-unstable-result.rs:56:23 | LL | fn impls_trait<T, U, V, D>() | ----------- required by a bound in this function diff --git a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr index c796663b13f0b..0eaa7d805e72c 100644 --- a/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr +++ b/tests/ui/traits/next-solver/cycles/coinduction/incompleteness-unstable-result.without.stderr @@ -1,12 +1,12 @@ error[E0277]: the trait bound `A<X>: Trait<_, _, _>` is not satisfied - --> $DIR/incompleteness-unstable-result.rs:73:19 + --> $DIR/incompleteness-unstable-result.rs:74:19 | LL | impls_trait::<A<X>, _, _, _>(); | ^^^^ the trait `Trait<_, _, _>` is not implemented for `A<X>` | = help: the trait `Trait<U, V, D>` is implemented for `A<T>` note: required for `A<X>` to implement `Trait<_, _, _>` - --> $DIR/incompleteness-unstable-result.rs:34:74 + --> $DIR/incompleteness-unstable-result.rs:35:74 | LL | impl<T: PointeeSized, U: PointeeSized, V: PointeeSized, D: PointeeSized> Trait<U, V, D> for A<T> | ^^^^^^^^^^^^^^ ^^^^ @@ -16,7 +16,7 @@ LL | A<T>: Trait<U, D, V>, = note: 8 redundant requirements hidden = note: required for `A<X>` to implement `Trait<_, _, _>` note: required by a bound in `impls_trait` - --> $DIR/incompleteness-unstable-result.rs:55:23 + --> $DIR/incompleteness-unstable-result.rs:56:23 | LL | fn impls_trait<T, U, V, D>() | ----------- required by a bound in this function diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs index 1364f63a37336..41c89dfdb7827 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.rs +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs @@ -1,5 +1,6 @@ //@ check-pass +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr index c8396c3854844..2d5f382c184cf 100644 --- a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr +++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/on-rpit.rs:4:12 + --> $DIR/on-rpit.rs:5:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs index 462724c73ee70..5a47f1dcb5908 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.rs @@ -1,3 +1,4 @@ +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr index 57f16b3dfd62a..eb24fcf5f98df 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-dyn-compatibility.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-dyn-compatibility.rs:2:12 + --> $DIR/supertrait-dyn-compatibility.rs:3:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ @@ -8,14 +8,14 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:22:23 + --> $DIR/supertrait-dyn-compatibility.rs:23:23 | LL | let x: &dyn Foo = &(); | ^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:7:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -25,14 +25,14 @@ LL | trait Foo: for<T> Bar<T> {} = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:22:12 + --> $DIR/supertrait-dyn-compatibility.rs:23:12 | LL | let x: &dyn Foo = &(); | ^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:7:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables @@ -41,14 +41,14 @@ LL | trait Foo: for<T> Bar<T> {} = help: only type `()` implements `Foo`; consider using it directly instead. error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/supertrait-dyn-compatibility.rs:25:5 + --> $DIR/supertrait-dyn-compatibility.rs:26:5 | LL | needs_bar(x); | ^^^^^^^^^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/supertrait-dyn-compatibility.rs:7:12 + --> $DIR/supertrait-dyn-compatibility.rs:8:12 | LL | trait Foo: for<T> Bar<T> {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr index 6551253d2e9e8..4e929937054fe 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:8:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr index 6551253d2e9e8..4e929937054fe 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response-2.rs:7:12 + --> $DIR/unifying-placeholders-in-query-response-2.rs:8:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs index d900bd429e6ec..6b91e1052e504 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response-2.rs @@ -3,6 +3,7 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr index fecdc860f8e7d..586a76dcf3167 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.current.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:7:12 + --> $DIR/unifying-placeholders-in-query-response.rs:8:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr index fecdc860f8e7d..586a76dcf3167 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.next.stderr @@ -1,5 +1,5 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unifying-placeholders-in-query-response.rs:7:12 + --> $DIR/unifying-placeholders-in-query-response.rs:8:12 | LL | #![feature(non_lifetime_binders)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs index 04e34531f4d78..b6763b252d31c 100644 --- a/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs +++ b/tests/ui/traits/non_lifetime_binders/unifying-placeholders-in-query-response.rs @@ -3,6 +3,7 @@ //@[next] compile-flags: -Znext-solver //@ check-pass +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] #![feature(non_lifetime_binders)] //~^ WARN the feature `non_lifetime_binders` is incomplete diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index cdcc2fa9fe5e6..3cf5ca2d7772a 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -1,5 +1,6 @@ // Need a different module so we try to build the mir for `test` // before analyzing `mod foo`. +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] mod foo { diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index b1e8ed11d6e8e..7f4342410a06a 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -1,5 +1,5 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/resolve-impl-before-constrain-check.rs:12:10 + --> $DIR/resolve-impl-before-constrain-check.rs:13:10 | LL | impl<V: PointeeSized> Callable for () { | ^ unconstrained type parameter diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr index 4e90bb4bebab6..251adc85c80c1 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.current.stderr @@ -1,5 +1,5 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:16:6 + --> $DIR/unconstrained-projection-normalization-2.rs:17:6 | LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr index 4e90bb4bebab6..251adc85c80c1 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization-2.next.stderr @@ -1,5 +1,5 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization-2.rs:16:6 + --> $DIR/unconstrained-projection-normalization-2.rs:17:6 | LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter diff --git a/tests/ui/traits/unconstrained-projection-normalization-2.rs b/tests/ui/traits/unconstrained-projection-normalization-2.rs index bbbe4b90299e3..112c2e29b3e25 100644 --- a/tests/ui/traits/unconstrained-projection-normalization-2.rs +++ b/tests/ui/traits/unconstrained-projection-normalization-2.rs @@ -5,6 +5,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] use std::marker::PointeeSized; diff --git a/tests/ui/traits/unconstrained-projection-normalization.current.stderr b/tests/ui/traits/unconstrained-projection-normalization.current.stderr index 044704e54dbde..434327976af10 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.current.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.current.stderr @@ -1,5 +1,5 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:15:6 + --> $DIR/unconstrained-projection-normalization.rs:16:6 | LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter diff --git a/tests/ui/traits/unconstrained-projection-normalization.next.stderr b/tests/ui/traits/unconstrained-projection-normalization.next.stderr index 044704e54dbde..434327976af10 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.next.stderr +++ b/tests/ui/traits/unconstrained-projection-normalization.next.stderr @@ -1,5 +1,5 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-projection-normalization.rs:15:6 + --> $DIR/unconstrained-projection-normalization.rs:16:6 | LL | impl<T: PointeeSized> Every for Thing { | ^ unconstrained type parameter diff --git a/tests/ui/traits/unconstrained-projection-normalization.rs b/tests/ui/traits/unconstrained-projection-normalization.rs index c231b1aa224c0..55fad7c14f5b7 100644 --- a/tests/ui/traits/unconstrained-projection-normalization.rs +++ b/tests/ui/traits/unconstrained-projection-normalization.rs @@ -4,6 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +#![allow(sized_hierarchy_migration)] #![feature(sized_hierarchy)] use std::marker::PointeeSized; From 7c259f59f40ef6983b5f68a72ed0cc43adf40527 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Sun, 2 Mar 2025 23:30:44 +0000 Subject: [PATCH 31/43] lint-docs: add future edition group This should have been included in rust-lang/rust#137606. --- src/tools/lint-docs/src/groups.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs index 78d4f87ed0de6..a1e37eb08d7f4 100644 --- a/src/tools/lint-docs/src/groups.rs +++ b/src/tools/lint-docs/src/groups.rs @@ -17,6 +17,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[ ("rust-2018-compatibility", "Lints used to transition code from the 2015 edition to 2018"), ("rust-2021-compatibility", "Lints used to transition code from the 2018 edition to 2021"), ("rust-2024-compatibility", "Lints used to transition code from the 2021 edition to 2024"), + ( + "edition-future-compatibility", + "Lints used to transition code from the 2024 edition to the future edition", + ), ( "refining-impl-trait", "Detects refinement of `impl Trait` return types by trait implementations", From 8bfeaf0f78ef74a329627772131a91b3f4757448 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Sun, 2 Mar 2025 23:32:43 +0000 Subject: [PATCH 32/43] tests: move `crashes/79409.rs` to ui suite This test no longer crashes the compiler as `Box` no longer accepts `PointeeSized`-types. It eventually could, but not because of `Deref::Target` currently, so this doesn't fail anymore and there wasn't an obvious to add new types to make it continue to fail because `Deref` is special. --- tests/crashes/79409.rs | 16 ----- .../ui/extern/extern-types-unsizing-79409.rs | 21 +++++++ .../extern/extern-types-unsizing-79409.stderr | 60 +++++++++++++++++++ 3 files changed, 81 insertions(+), 16 deletions(-) delete mode 100644 tests/crashes/79409.rs create mode 100644 tests/ui/extern/extern-types-unsizing-79409.rs create mode 100644 tests/ui/extern/extern-types-unsizing-79409.stderr diff --git a/tests/crashes/79409.rs b/tests/crashes/79409.rs deleted file mode 100644 index 98b5f60633627..0000000000000 --- a/tests/crashes/79409.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #79409 - -#![feature(extern_types)] -#![feature(unsized_locals)] - -extern { - type Device; -} - -unsafe fn make_device() -> Box<Device> { - Box::from_raw(0 as *mut _) -} - -fn main() { - let d: Device = unsafe { *make_device() }; -} diff --git a/tests/ui/extern/extern-types-unsizing-79409.rs b/tests/ui/extern/extern-types-unsizing-79409.rs new file mode 100644 index 0000000000000..b53e205bee5dd --- /dev/null +++ b/tests/ui/extern/extern-types-unsizing-79409.rs @@ -0,0 +1,21 @@ +#![feature(extern_types)] +#![feature(unsized_locals)] +//~^ WARN the feature `unsized_locals` is incomplete + +// Regression test for #79409 + +extern "C" { + type Device; +} + +unsafe fn make_device() -> Box<Device> { +//~^ ERROR the size for values of type `Device` cannot be known + Box::from_raw(0 as *mut _) +//~^ ERROR the size for values of type `Device` cannot be known +//~| ERROR the size for values of type `Device` cannot be known +} + +fn main() { + let d: Device = unsafe { *make_device() }; +//~^ ERROR the size for values of type `Device` cannot be known +} diff --git a/tests/ui/extern/extern-types-unsizing-79409.stderr b/tests/ui/extern/extern-types-unsizing-79409.stderr new file mode 100644 index 0000000000000..afc8ccf607b7e --- /dev/null +++ b/tests/ui/extern/extern-types-unsizing-79409.stderr @@ -0,0 +1,60 @@ +warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/extern-types-unsizing-79409.rs:2:12 + | +LL | #![feature(unsized_locals)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/extern-types-unsizing-79409.rs:11:28 + | +LL | unsafe fn make_device() -> Box<Device> { + | ^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/extern-types-unsizing-79409.rs:13:19 + | +LL | Box::from_raw(0 as *mut _) + | ------------- ^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Device` + | | + | required by a bound introduced by this call + | + = note: the trait bound `Device: MetaSized` is not satisfied +note: required by a bound in `Box::<T>::from_raw` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +help: consider borrowing here + | +LL | Box::from_raw(&0 as *mut _) + | + +LL | Box::from_raw(&mut 0 as *mut _) + | ++++ + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/extern-types-unsizing-79409.rs:13:5 + | +LL | Box::from_raw(0 as *mut _) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error[E0277]: the size for values of type `Device` cannot be known + --> $DIR/extern-types-unsizing-79409.rs:19:31 + | +LL | let d: Device = unsafe { *make_device() }; + | ^^^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `Device` +note: required by a bound in `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From e037480a4a937dd5649be90d32f316118b54ee14 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Sun, 2 Mar 2025 23:34:49 +0000 Subject: [PATCH 33/43] rustdoc: update `no_core` tests w/ new traits Some rustdoc tests are `no_core` and need to have `MetaSized` and `PointeeSized` added to them. One or two tests used extern types and needed further relaxations to work as before. --- tests/rustdoc-json/impls/auto.rs | 15 ++++++++++++--- tests/rustdoc-json/primitives/primitive_impls.rs | 11 ++++++++++- .../custom_code_classes_in_docs-warning3.rs | 11 ++++++++++- .../custom_code_classes_in_docs-warning3.stderr | 4 ++-- tests/rustdoc-ui/target-feature-stability.rs | 11 ++++++++++- tests/rustdoc/cfg_doc_reexport.rs | 11 ++++++++++- tests/rustdoc/cross-crate-primitive-doc.rs | 11 ++++++++++- tests/rustdoc/file-creation-111249.rs | 14 +++++++++++++- tests/rustdoc/foreigntype.rs | 2 +- tests/rustdoc/intra-doc/auxiliary/my-core.rs | 11 ++++++++++- tests/rustdoc/intra-doc/extern-type.rs | 4 ++-- tests/rustdoc/intra-doc/no-doc-primitive.rs | 11 ++++++++++- tests/rustdoc/intra-doc/prim-methods-local.rs | 11 ++++++++++- tests/rustdoc/intra-doc/prim-self.rs | 11 ++++++++++- .../doc-notable_trait_box_is_not_an_iterator.rs | 11 ++++++++++- .../reexport-trait-from-hidden-111064-2.rs | 13 +++++++++++-- tests/rustdoc/safe-intrinsic.rs | 11 ++++++++++- 17 files changed, 151 insertions(+), 22 deletions(-) diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index f94f7338480bb..5cfb21da0d1d2 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -1,8 +1,17 @@ #![feature(no_core, auto_traits, lang_items, arbitrary_self_types)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} @@ -15,8 +24,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 0]" -//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 1]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[22, 0]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[24, 1]" // FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91 // is "$.index[?(@.inner.impl.is_synthetic==true)].span" null pub struct Foo; diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index a1f0ebd11b636..90f1f0415c220 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -1,4 +1,5 @@ #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![no_core] @@ -6,8 +7,16 @@ //@ set impl_i32 = "$.index[?(@.docs=='Only core can do this')].id" +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} /// Only core can do this impl i32 { diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs index 18ac37280c0ef..d6c5c4bcdf6b3 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.rs @@ -3,10 +3,19 @@ #![deny(warnings)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} /// ```{class="} /// main; diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index cc13cc0fe531b..4e90fe59212f8 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -1,5 +1,5 @@ error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:20:1 | LL | / /// ```{class="} LL | | /// main; @@ -17,7 +17,7 @@ LL | #![deny(warnings)] = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unclosed quote string `"` - --> $DIR/custom_code_classes_in_docs-warning3.rs:11:1 + --> $DIR/custom_code_classes_in_docs-warning3.rs:20:1 | LL | / /// ```{class="} LL | | /// main; diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs index 17fa3ccfe3e89..1886d653ce4bb 100644 --- a/tests/rustdoc-ui/target-feature-stability.rs +++ b/tests/rustdoc-ui/target-feature-stability.rs @@ -12,10 +12,19 @@ #![crate_type = "lib"] #![feature(no_core, lang_items)] #![feature(arm_target_feature)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} // `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`. #[target_feature(enable = "fp-armv8")] diff --git a/tests/rustdoc/cfg_doc_reexport.rs b/tests/rustdoc/cfg_doc_reexport.rs index 44ec366328413..5da4b87adca0f 100644 --- a/tests/rustdoc/cfg_doc_reexport.rs +++ b/tests/rustdoc/cfg_doc_reexport.rs @@ -1,11 +1,20 @@ #![feature(doc_cfg)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![crate_name = "foo"] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} //@ has 'foo/index.html' //@ has - '//dt/*[@class="stab portability"]' 'foobar' diff --git a/tests/rustdoc/cross-crate-primitive-doc.rs b/tests/rustdoc/cross-crate-primitive-doc.rs index 0ffde5b0f2d80..5a02776b24681 100644 --- a/tests/rustdoc/cross-crate-primitive-doc.rs +++ b/tests/rustdoc/cross-crate-primitive-doc.rs @@ -3,10 +3,19 @@ //@ only-linux #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} extern crate primitive_doc; diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc/file-creation-111249.rs index a6522d682f191..bd0e12dde1088 100644 --- a/tests/rustdoc/file-creation-111249.rs +++ b/tests/rustdoc/file-creation-111249.rs @@ -1,10 +1,22 @@ // https://github.com/rust-lang/rust/issues/111249 #![crate_name = "foo"] #![feature(no_core)] +#![feature(const_trait_impl, lang_items)] #![no_core] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +#[const_trait] +pub trait Sized: MetaSized {} + //@ files "foo" "['all.html', 'visible', 'index.html', 'sidebar-items.js', 'hidden', \ -// 'struct.Bar.html']" +// 'struct.Bar.html', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/visible" "['trait.Foo.html', 'index.html', 'sidebar-items.js']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" diff --git a/tests/rustdoc/foreigntype.rs b/tests/rustdoc/foreigntype.rs index bee3d8e65097a..66371e8c827cf 100644 --- a/tests/rustdoc/foreigntype.rs +++ b/tests/rustdoc/foreigntype.rs @@ -10,7 +10,7 @@ impl ExtType { pub fn do_something(&self) {} } -pub trait Trait {} +pub trait Trait: std::marker::PointeeSized {} //@ has foreigntype/trait.Trait.html '//a[@class="foreigntype"]' 'ExtType' impl Trait for ExtType {} diff --git a/tests/rustdoc/intra-doc/auxiliary/my-core.rs b/tests/rustdoc/intra-doc/auxiliary/my-core.rs index c050929db9682..7a79c6dcc1a48 100644 --- a/tests/rustdoc/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc/intra-doc/auxiliary/my-core.rs @@ -1,4 +1,5 @@ #![feature(no_core, lang_items, rustdoc_internals, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type="rlib"] @@ -13,8 +14,16 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/extern-type.rs b/tests/rustdoc/intra-doc/extern-type.rs index 198ac8e43e088..41a678d52cd0b 100644 --- a/tests/rustdoc/intra-doc/extern-type.rs +++ b/tests/rustdoc/intra-doc/extern-type.rs @@ -4,11 +4,11 @@ extern { pub type ExternType; } -pub trait T { +pub trait T: std::marker::PointeeSized { fn test(&self) {} } -pub trait G<N> { +pub trait G<N>: std::marker::PointeeSized { fn g(&self, n: N) {} } diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc/intra-doc/no-doc-primitive.rs index 79825643b98ce..63a26e847addc 100644 --- a/tests/rustdoc/intra-doc/no-doc-primitive.rs +++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs @@ -2,6 +2,7 @@ #![deny(rustdoc::broken_intra_doc_links)] #![feature(no_core, lang_items, rustc_attrs)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type = "rlib"] @@ -10,8 +11,16 @@ //@ has no_doc_primitive/index.html //! A [`char`] and its [`char::len_utf8`]. +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} impl char { pub fn len_utf8(self) -> usize { diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc/intra-doc/prim-methods-local.rs index a9e71c58be359..93a9967383e5a 100644 --- a/tests/rustdoc/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc/intra-doc/prim-methods-local.rs @@ -1,5 +1,6 @@ #![deny(rustdoc::broken_intra_doc_links)] #![feature(no_core, lang_items, rustc_attrs, rustdoc_internals)] +#![feature(const_trait_impl)] #![no_core] #![rustc_coherence_is_core] #![crate_type = "rlib"] @@ -19,8 +20,16 @@ impl char { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "clone"] pub trait Clone: Sized {} diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc/intra-doc/prim-self.rs index d5bfd570d547d..062d74513e1e4 100644 --- a/tests/rustdoc/intra-doc/prim-self.rs +++ b/tests/rustdoc/intra-doc/prim-self.rs @@ -5,6 +5,7 @@ #![feature(no_core)] #![feature(rustdoc_internals)] #![feature(inherent_associated_types)] +#![feature(const_trait_impl)] #![feature(lang_items)] #![no_core] @@ -37,5 +38,13 @@ impl S { pub fn f() {} } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs index dcdcbfb7ec157..bf125050970ff 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs +++ b/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs @@ -1,4 +1,5 @@ #![feature(doc_notable_trait)] +#![feature(const_trait_impl)] #![feature(lang_items)] #![feature(no_core)] #![no_core] @@ -11,8 +12,16 @@ impl<T> Box<T> { } } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[doc(notable_trait)] pub trait FakeIterator {} diff --git a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs index 61060b3ff7c74..67bc38ffa7d59 100644 --- a/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs +++ b/tests/rustdoc/reexport-trait-from-hidden-111064-2.rs @@ -1,13 +1,22 @@ // Regression test for <https://github.com/rust-lang/rust/issues/111064>. #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} //@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \ -// 'visible']" +// 'visible', 'trait.Sized.html', 'trait.MetaSized.html', 'trait.PointeeSized.html']" //@ files "foo/hidden" "['inner']" //@ files "foo/hidden/inner" "['trait.Foo.html']" //@ files "foo/visible" "['index.html', 'sidebar-items.js', 'trait.Foo.html']" diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs index 0d2ee89415d4a..00e5f281441db 100644 --- a/tests/rustdoc/safe-intrinsic.rs +++ b/tests/rustdoc/safe-intrinsic.rs @@ -1,12 +1,21 @@ #![feature(intrinsics)] #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![feature(rustc_attrs)] #![no_core] #![crate_name = "foo"] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} //@ has 'foo/fn.abort.html' //@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !' From d4f64472ed8addca9288e40d50c8a50fcac36e94 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Sun, 2 Mar 2025 23:36:00 +0000 Subject: [PATCH 34/43] rustdoc: skip `MetaSized` bounds These should never be shown to users at the moment. --- src/librustdoc/clean/inline.rs | 9 ++++++++- src/librustdoc/clean/mod.rs | 19 ++++++++++++++++++- src/librustdoc/clean/simplify.rs | 12 +++++++++--- src/librustdoc/clean/types.rs | 10 +++++++++- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e973b89b2375b..e1cff4e5a676b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -273,7 +273,14 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean let predicates = cx.tcx.predicates_of(did); let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); let generics = filter_non_trait_generics(did, generics); - let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); + let (generics, mut supertrait_bounds) = separate_supertrait_bounds(generics); + + supertrait_bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + clean::Trait { def_id: did, generics, items: trait_items, bounds: supertrait_bounds } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de6dc088176ff..4cdc9a587cffd 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,9 +39,9 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; -use rustc_hir::PredicateOrigin; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; +use rustc_hir::{LangItem, PredicateOrigin}; use rustc_hir_analysis::hir_ty_lowering::FeedConstTy; use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty}; use rustc_middle::metadata::Reexport; @@ -900,6 +900,10 @@ fn clean_ty_generics<'tcx>( if b.is_sized_bound(cx) { has_sized = true; false + } else if b.is_meta_sized_bound(cx) { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + false } else { true } @@ -1499,6 +1503,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo } _ => true, }); + + bounds.retain(|b| { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + !b.is_meta_sized_bound(cx) + }); + // Our Sized/?Sized bound didn't get handled when creating the generics // because we didn't actually get our whole set of bounds until just now // (some of them may have come from the trait). If we do have a sized @@ -2333,6 +2344,12 @@ fn clean_middle_opaque_bounds<'tcx>( _ => return None, }; + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + if cx.tcx.is_lang_item(trait_ref.def_id(), LangItem::MetaSized) { + return None; + } + if let Some(sized) = cx.tcx.lang_items().sized_trait() && trait_ref.def_id() == sized { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 41943b94d1e21..e09505a6851b1 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -138,11 +138,17 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi // don't actually know the set of associated types right here so that // should be handled when cleaning associated types. generics.where_predicates.retain(|pred| { - if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred - && bounds.iter().any(|b| b.is_sized_bound(cx)) - { + let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred else { + return true; + }; + + if bounds.iter().any(|b| b.is_sized_bound(cx)) { sized_params.insert(*param); false + } else if bounds.iter().any(|b| b.is_meta_sized_bound(cx)) { + // FIXME(sized-hierarchy): Always skip `MetaSized` bounds so that only `?Sized` + // is shown and none of the new sizedness traits leak into documentation. + false } else { true } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5f80aded9d0b4..3f805d8392371 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1290,11 +1290,19 @@ impl GenericBound { } pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool { + self.is_bounded_by_lang_item(cx, LangItem::Sized) + } + + pub(crate) fn is_meta_sized_bound(&self, cx: &DocContext<'_>) -> bool { + self.is_bounded_by_lang_item(cx, LangItem::MetaSized) + } + + fn is_bounded_by_lang_item(&self, cx: &DocContext<'_>, lang_item: LangItem) -> bool { if let GenericBound::TraitBound( PolyTrait { ref trait_, .. }, rustc_hir::TraitBoundModifiers::NONE, ) = *self - && Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() + && cx.tcx.is_lang_item(trait_.def_id(), lang_item) { return true; } From d417f0c6eaa3a20f85d259f7c53557dfe18a4f5e Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Mar 2025 02:39:21 +0000 Subject: [PATCH 35/43] clippy: update `no_core` tests w/ new traits One clippy test is `no_core` and needs to have `MetaSized` and `PointeeSized` added to it. --- src/tools/clippy/tests/ui/def_id_nocore.rs | 11 ++++++++++- src/tools/clippy/tests/ui/def_id_nocore.stderr | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs index 03f5ca31f5f07..c710f29d40656 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -1,14 +1,23 @@ //@ignore-target: apple #![feature(no_core, lang_items)] +#![feature(const_trait_impl)] #![no_core] #![allow(clippy::missing_safety_doc)] #[link(name = "c")] extern "C" {} +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "copy"] pub trait Copy {} #[lang = "freeze"] diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index 2718217313ff9..c25196f3da10c 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -1,5 +1,5 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutable reference - --> tests/ui/def_id_nocore.rs:27:19 + --> tests/ui/def_id_nocore.rs:36:19 | LL | pub fn as_ref(self) -> &'static str { | ^^^^ From 9bd53a5f56ed719c35fc741623fb12d670aefaf3 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Mar 2025 02:39:56 +0000 Subject: [PATCH 36/43] clippy: add `MetaSized` conditions Existing lints that had special-casing for `Sized` predicates ought to have these same special cases applied to `MetaSized` predicates. --- .../clippy/clippy_lints/src/methods/unnecessary_to_owned.rs | 2 ++ .../clippy_lints/src/needless_borrows_for_generic_args.rs | 2 ++ src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 62ba3012643ce..f8eb1601e3c0f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -389,9 +389,11 @@ fn check_other_call_arg<'tcx>( && let (input, n_refs) = peel_middle_ty_refs(*input) && let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input) && let Some(sized_def_id) = cx.tcx.lang_items().sized_trait() + && let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait() && let [trait_predicate] = trait_predicates .iter() .filter(|trait_predicate| trait_predicate.def_id() != sized_def_id) + .filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id) .collect::<Vec<_>>()[..] && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index f686cc912ddb0..5d4366396299d 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -174,6 +174,7 @@ fn needless_borrow_count<'tcx>( ) -> usize { let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait(); let sized_trait_def_id = cx.tcx.lang_items().sized_trait(); + let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait(); let drop_trait_def_id = cx.tcx.lang_items().drop_trait(); let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder(); @@ -209,6 +210,7 @@ fn needless_borrow_count<'tcx>( .all(|trait_def_id| { Some(trait_def_id) == destruct_trait_def_id || Some(trait_def_id) == sized_trait_def_id + || Some(trait_def_id) == meta_sized_trait_def_id || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id) }) { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 55ca875edcee6..44f6b3ff8b8c7 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -116,13 +116,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ]; let sized_trait = need!(cx.tcx.lang_items().sized_trait()); + let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait()); let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. match pred.kind().no_bound_vars() { - Some(ty::ClauseKind::Trait(pred)) if pred.def_id() != sized_trait => Some(pred), + Some(ty::ClauseKind::Trait(pred)) + if pred.def_id() != sized_trait && pred.def_id() != meta_sized_trait + => Some(pred), _ => None, } }) From efd23fc27368cc4db8b1fbf4992ac89af369fb56 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Mar 2025 01:41:13 +0000 Subject: [PATCH 37/43] bootstrap: address lint failures Unexpected Clippy lint triggering is fixed in previous commits but is necessary for `cfg(bootstrap)`. --- src/bootstrap/src/core/build_steps/tool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index cd57e06ae04a3..3bde8c1facdab 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -557,7 +557,7 @@ impl ErrorIndex { let compiler = builder.compiler_for(builder.top_stage, host, host); let mut cmd = command(builder.ensure(ErrorIndex { compiler }).tool_path); let mut dylib_paths = builder.rustc_lib_paths(compiler); - dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, compiler.host))); + dylib_paths.push(builder.sysroot_target_libdir(compiler, compiler.host)); add_dylib_path(dylib_paths, &mut cmd); cmd } From 705bcb92240f836a71cda21f5c27911d46eaf1fb Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Mar 2025 03:23:13 +0000 Subject: [PATCH 38/43] miri: fix build It's unclear why this change in miri is necessary. --- src/tools/miri/src/shims/native_lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index 0258a76c3e703..690f668637d6c 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -5,7 +5,7 @@ use libffi::high::call as ffi; use libffi::low::CodePtr; use rustc_abi::{BackendRepr, HasDataLayout, Size}; use rustc_middle::mir::interpret::Pointer; -use rustc_middle::ty::{self as ty, IntTy, UintTy}; +use rustc_middle::ty::{self as ty, inherent::SliceLike, IntTy, UintTy}; use rustc_span::Symbol; use crate::*; From 6e94c238b76006a8272fe36ee4e043799aa7b1df Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 3 Mar 2025 03:23:29 +0000 Subject: [PATCH 39/43] miri: bless tests These error messages include lines of the standard library which have changed and so need updated. --- .../tests/fail/stacked_borrows/drop_in_place_retag.stderr | 4 ++-- .../miri/tests/fail/unaligned_pointers/drop_in_place.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr index eebedf842ef5e..c8c9ff2f1e459 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub unsafe fn drop_in_place<T: ?Sized + PointeeSized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location | this error occurs as part of retag at ALLOC[0x0..0x1] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr index 75efa5ff806ce..20f39da6b4de0 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | -LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) +LL | pub unsafe fn drop_in_place<T: ?Sized + PointeeSized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information From 6211524fb98ea17f59dc84adc474b3f9a312bfe4 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 5 Mar 2025 04:29:41 +0000 Subject: [PATCH 40/43] passes: propagate unstability for traits Unstability is propagated when staged API is not used and `-Zforce-unstable-if-unmarked` is, but this only happened for const functions not const traits, which ends up being an issue for some of the minicore tests of codegen backends when introducing the sizedness traits. --- compiler/rustc_passes/src/stability.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 9e55914f8f2f7..83e8257f62bcf 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -155,7 +155,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { if let Some(stab) = self.parent_stab { if inherit_deprecation.yes() && stab.is_unstable() { self.index.stab_map.insert(def_id, stab); - if fn_sig.is_some_and(|s| s.header.is_const()) { + let is_const = fn_sig.is_some_and(|s| s.header.is_const()) + || (self.tcx.def_kind(def_id) == DefKind::Trait + && self.tcx.is_const_trait(def_id.to_def_id())); + if is_const { self.index.const_stab_map.insert( def_id, ConstStability::unmarked(const_stability_indirect, stab), From 86f4f6ca4067256dc45148b2aa5ffb9d0bbad4b7 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Wed, 5 Mar 2025 04:31:12 +0000 Subject: [PATCH 41/43] cranelift/gcc: add sizedness traits to minicore As in many previous commits, adding the new traits and constness to the minicore. --- .../example/mini_core.rs | 71 +++++++++++-------- .../rustc_codegen_gcc/example/mini_core.rs | 70 ++++++++++-------- 2 files changed, 79 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 6e345b2a6fdf0..7e8a1800341b2 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -9,13 +9,22 @@ transparent_unions, auto_traits, freeze_impls, - thread_local + thread_local, + const_trait_impl )] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -24,35 +33,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized<T> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn<T> {} // &T -> &U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: MetaSized + Unsize<U>, U: MetaSized> DispatchFromDyn<Box<U>> for Box<T> {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} -impl<T: ?Sized> LegacyReceiver for Box<T> {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} +impl<T: MetaSized> LegacyReceiver for Box<T> {} #[lang = "copy"] pub trait Copy {} @@ -74,9 +83,9 @@ impl Copy for isize {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} impl<T: Copy> Copy for Option<T> {} #[lang = "sync"] @@ -94,17 +103,17 @@ unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} unsafe impl Sync for f32 {} -unsafe impl<'a, T: ?Sized> Sync for &'a T {} +unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl<T: Sync, const N: usize> Sync for [T; N] {} #[lang = "freeze"] unsafe auto trait Freeze {} -unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} -unsafe impl<T: ?Sized> Freeze for *const T {} -unsafe impl<T: ?Sized> Freeze for *mut T {} -unsafe impl<T: ?Sized> Freeze for &T {} -unsafe impl<T: ?Sized> Freeze for &mut T {} +unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {} +unsafe impl<T: PointeeSized> Freeze for *const T {} +unsafe impl<T: PointeeSized> Freeze for *mut T {} +unsafe impl<T: PointeeSized> Freeze for &T {} +unsafe impl<T: PointeeSized> Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -443,7 +452,7 @@ pub enum Option<T> { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: PointeeSized>; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -546,18 +555,18 @@ pub trait Deref { #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull<T: ?Sized>(pub *const T); +pub struct NonNull<T: PointeeSized>(pub *const T); -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -pub struct Unique<T: ?Sized> { +pub struct Unique<T: PointeeSized> { pub pointer: NonNull<T>, pub _marker: PhantomData<T>, } -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} #[lang = "global_alloc_ty"] pub struct Global; diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 5544aee9eaf16..e2c2218ed2e44 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -1,7 +1,7 @@ #![feature( no_core, lang_items, intrinsics, unboxed_closures, extern_types, decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls, - thread_local + thread_local, const_trait_impl )] #![no_core] #![allow(dead_code, internal_features, ambiguous_wide_pointer_comparisons)] @@ -11,8 +11,16 @@ unsafe extern "C" fn _Unwind_Resume() { intrinsics::unreachable(); } +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +#[const_trait] +pub trait MetaSized: PointeeSized {} + #[lang = "sized"] -pub trait Sized {} +#[const_trait] +pub trait Sized: MetaSized {} #[lang = "destruct"] pub trait Destruct {} @@ -21,35 +29,35 @@ pub trait Destruct {} pub trait Tuple {} #[lang = "unsize"] -pub trait Unsize<T: ?Sized> {} +pub trait Unsize<T: PointeeSized>: PointeeSized {} #[lang = "coerce_unsized"] pub trait CoerceUnsized<T> {} -impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} -impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} +impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {} #[lang = "dispatch_from_dyn"] pub trait DispatchFromDyn<T> {} // &T -> &U -impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {} // &mut T -> &mut U -impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {} +impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {} // *const T -> *const U -impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {} // *mut T -> *mut U -impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} -impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {} +impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {} +impl<T: MetaSized + Unsize<U>, U: MetaSized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {} #[lang = "legacy_receiver"] pub trait LegacyReceiver {} -impl<T: ?Sized> LegacyReceiver for &T {} -impl<T: ?Sized> LegacyReceiver for &mut T {} -impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {} +impl<T: PointeeSized> LegacyReceiver for &T {} +impl<T: PointeeSized> LegacyReceiver for &mut T {} +impl<T: MetaSized> LegacyReceiver for Box<T> {} #[lang = "copy"] pub trait Copy {} @@ -70,9 +78,9 @@ impl Copy for isize {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for char {} -impl<'a, T: ?Sized> Copy for &'a T {} -impl<T: ?Sized> Copy for *const T {} -impl<T: ?Sized> Copy for *mut T {} +impl<'a, T: PointeeSized> Copy for &'a T {} +impl<T: PointeeSized> Copy for *const T {} +impl<T: PointeeSized> Copy for *mut T {} #[lang = "sync"] pub unsafe trait Sync {} @@ -88,17 +96,17 @@ unsafe impl Sync for i16 {} unsafe impl Sync for i32 {} unsafe impl Sync for isize {} unsafe impl Sync for char {} -unsafe impl<'a, T: ?Sized> Sync for &'a T {} +unsafe impl<'a, T: PointeeSized> Sync for &'a T {} unsafe impl Sync for [u8; 16] {} #[lang = "freeze"] unsafe auto trait Freeze {} -unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} -unsafe impl<T: ?Sized> Freeze for *const T {} -unsafe impl<T: ?Sized> Freeze for *mut T {} -unsafe impl<T: ?Sized> Freeze for &T {} -unsafe impl<T: ?Sized> Freeze for &mut T {} +unsafe impl<T: PointeeSized> Freeze for PhantomData<T> {} +unsafe impl<T: PointeeSized> Freeze for *const T {} +unsafe impl<T: PointeeSized> Freeze for *mut T {} +unsafe impl<T: PointeeSized> Freeze for &T {} +unsafe impl<T: PointeeSized> Freeze for &mut T {} #[lang = "structural_peq"] pub trait StructuralPartialEq {} @@ -403,7 +411,7 @@ pub enum Option<T> { pub use Option::*; #[lang = "phantom_data"] -pub struct PhantomData<T: ?Sized>; +pub struct PhantomData<T: PointeeSized>; #[lang = "fn_once"] #[rustc_paren_sugar] @@ -520,18 +528,18 @@ impl Allocator for Global {} #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] -pub struct NonNull<T: ?Sized>(pub *const T); +pub struct NonNull<T: PointeeSized>(pub *const T); -impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {} -pub struct Unique<T: ?Sized> { +pub struct Unique<T: PointeeSized> { pub pointer: NonNull<T>, pub _marker: PhantomData<T>, } -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} -impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {} +impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {} #[lang = "owned_box"] pub struct Box<T: ?Sized, A: Allocator = Global>(Unique<T>, A); From 576655a8ed4dc7adf6312c7748f6c200bcdaafaf Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Mon, 17 Mar 2025 10:24:56 +0000 Subject: [PATCH 42/43] wip: trait_sel: skip elaboration of sizedness supertrait As a performance optimization, skip elaborating the supertraits of `Sized`, and if a `MetaSized` obligation is being checked, then look for a `Sized` predicate in the parameter environment. This makes the `ParamEnv` smaller which should improve compiler performance as it avoids all the iteration over the larger `ParamEnv`. --- .../src/solve/effect_goals.rs | 29 ++++++-- .../src/solve/trait_goals.rs | 31 ++++++--- .../src/traits/coherence.rs | 16 +++++ .../src/traits/select/candidate_assembly.rs | 31 ++++++++- .../src/traits/select/confirmation.rs | 13 +++- .../src/traits/select/mod.rs | 15 ++++- .../rustc_trait_selection/src/traits/util.rs | 67 +++++++++++++++++++ compiler/rustc_type_ir/src/elaborate.rs | 52 ++++++++++++-- tests/ui/attributes/dump-preds.stderr | 1 - tests/ui/extern/extern-types-unsized.rs | 2 + tests/ui/extern/extern-types-unsized.stderr | 30 ++++++++- tests/ui/nll/issue-50716.rs | 2 +- tests/ui/nll/issue-50716.stderr | 18 +---- tests/ui/sized-hierarchy/impls.rs | 1 + tests/ui/sized-hierarchy/impls.stderr | 60 ++++++++++------- .../ui/sized-hierarchy/pretty-print-opaque.rs | 1 + .../pretty-print-opaque.stderr | 11 ++- .../next-solver/issue-118950-root-region.rs | 1 - .../issue-118950-root-region.stderr | 14 +--- 19 files changed, 310 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 1638f970937f3..69accf964d085 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -45,7 +45,9 @@ where then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>, ) -> Result<Candidate<I>, NoSolution> { if let Some(host_clause) = assumption.as_host_effect_clause() { - if host_clause.def_id() == goal.predicate.def_id() + let goal_did = goal.predicate.def_id(); + let host_clause_did = host_clause.def_id(); + if host_clause_did == goal_did && host_clause.constness().satisfies(goal.predicate.constness) { if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( @@ -55,7 +57,7 @@ where return Err(NoSolution); } - ecx.probe_trait_candidate(source).enter(|ecx| { + return ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause); ecx.eq( goal.param_env, @@ -63,13 +65,26 @@ where assumption_trait_pred.trait_ref, )?; then(ecx) - }) - } else { - Err(NoSolution) + }); + } + + // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so + // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds + // are syntactic sugar for a lack of bounds so don't need this. + if ecx.cx().is_lang_item(goal_did, TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(host_clause_did, TraitSolverLangItem::Sized) + && { + let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty()); + let found_self_ty = + ecx.resolve_vars_if_possible(host_clause.self_ty().skip_binder()); + expected_self_ty == found_self_ty + } + { + return ecx.probe_trait_candidate(source).enter(then); } - } else { - Err(NoSolution) } + + Err(NoSolution) } /// Register additional assumptions for aliases corresponding to `~const` item bounds. diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 3894631df6791..b2baebd19b1f6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -132,9 +132,9 @@ where then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>, ) -> Result<Candidate<I>, NoSolution> { if let Some(trait_clause) = assumption.as_trait_clause() { - if trait_clause.def_id() == goal.predicate.def_id() - && trait_clause.polarity() == goal.predicate.polarity - { + let goal_did = goal.predicate.def_id(); + let trait_clause_did = trait_clause.def_id(); + if trait_clause_did == goal_did && trait_clause.polarity() == goal.predicate.polarity { if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, trait_clause.skip_binder().trait_ref.args, @@ -142,7 +142,7 @@ where return Err(NoSolution); } - ecx.probe_trait_candidate(source).enter(|ecx| { + return ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause); ecx.eq( goal.param_env, @@ -150,13 +150,26 @@ where assumption_trait_pred.trait_ref, )?; then(ecx) - }) - } else { - Err(NoSolution) + }); + } + + // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so + // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds + // are syntactic sugar for a lack of bounds so don't need this. + if ecx.cx().is_lang_item(goal_did, TraitSolverLangItem::MetaSized) + && ecx.cx().is_lang_item(trait_clause_did, TraitSolverLangItem::Sized) + && { + let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty()); + let found_self_ty = + ecx.resolve_vars_if_possible(trait_clause.self_ty().skip_binder()); + expected_self_ty == found_self_ty + } + { + return ecx.probe_trait_candidate(source).enter(then); } - } else { - Err(NoSolution) } + + Err(NoSolution) } fn consider_auto_trait_candidate( diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index bcc247ba53c2b..124a7d154da90 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -8,6 +8,7 @@ use std::fmt::Debug; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{Diag, EmissionGuarantee}; +use rustc_hir::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; @@ -582,6 +583,21 @@ fn try_prove_negated_where_clause<'tcx>( return false; }; + let maybe_meta_sized_self_ty = clause + .as_trait_clause() + .filter(|c| root_infcx.tcx.is_lang_item(c.def_id(), LangItem::MetaSized)) + .map(|c| c.self_ty()); + if let Some(meta_sized_self_ty) = maybe_meta_sized_self_ty + && util::sizedness_elab_opt_fast_path_from_paramenv( + root_infcx, + meta_sized_self_ty, + param_env, + ) + .is_some() + { + return false; + } + // N.B. We don't need to use intercrate mode here because we're trying to prove // the *existence* of a negative goal, not the non-existence of a positive goal. // Without this, we over-eagerly register coherence ambiguity candidates when diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 922f7562d2a08..aea81a4d3b956 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -16,7 +16,7 @@ use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode}; use rustc_middle::{bug, span_bug}; -use rustc_type_ir::{Interner, elaborate}; +use rustc_type_ir::{Binder, Interner, elaborate}; use tracing::{debug, instrument, trace}; use super::SelectionCandidate::*; @@ -188,8 +188,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut distinct_normalized_bounds = FxHashSet::default(); let _ = self.for_each_item_bound::<!>( placeholder_trait_predicate.self_ty(), - |selcx, bound, idx| { - let Some(bound) = bound.as_trait_clause() else { + |selcx, clause, idx| { + let Some(bound) = clause.as_trait_clause() else { return ControlFlow::Continue(()); }; if bound.polarity() != placeholder_trait_predicate.polarity { @@ -197,6 +197,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } selcx.infcx.probe(|_| { + if selcx + .tcx() + .is_lang_item(placeholder_trait_predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_clauses( + selcx.infcx, + Binder::dummy(placeholder_trait_predicate.self_ty()), + [clause], + ) + .is_some() + { + candidates.vec.push(ProjectionCandidate(idx)); + return; + } + // We checked the polarity already match selcx.match_normalize_trait_ref( obligation, @@ -235,6 +249,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!(?stack.obligation); + if self.tcx().is_lang_item(stack.obligation.predicate.def_id(), LangItem::MetaSized) + && let Some(bound) = util::sizedness_elab_opt_fast_path_from_paramenv( + self.infcx, + stack.obligation.self_ty(), + stack.obligation.param_env, + ) + { + candidates.vec.push(ParamCandidate(bound)); + return Ok(()); + } + let bounds = stack .obligation .param_env diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 6f61dc9a6f28c..2cbf17f3af84c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -18,7 +18,7 @@ use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; -use rustc_type_ir::elaborate; +use rustc_type_ir::{Binder, elaborate}; use thin_vec::thin_vec; use tracing::{debug, instrument}; @@ -189,6 +189,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut obligations, ); + if tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_traitrefs( + self.infcx, + obligation.predicate.self_ty(), + [Binder::dummy(candidate)], + ) + .is_some() + { + return Ok(obligations); + } + obligations.extend( self.infcx .at(&obligation.cause, obligation.param_env) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index ab146022ba646..a9bb24a862c7b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -31,8 +31,9 @@ use rustc_middle::ty::{ TypingMode, Upcast, }; use rustc_span::{Symbol, sym}; -use rustc_type_ir::elaborate; use rustc_type_ir::solve::SizedTraitKind; +use rustc_type_ir::{Binder, elaborate}; +use thin_vec::thin_vec; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -2641,6 +2642,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> { HigherRankedType, poly_trait_ref, ); + + if self.tcx().is_lang_item(predicate.def_id(), LangItem::MetaSized) + && util::sizedness_elab_opt_fast_path_from_traitrefs( + self.infcx, + Binder::dummy(predicate.self_ty()), + [Binder::dummy(trait_ref)], + ) + .is_some() + { + return Ok(thin_vec![]); + } + self.infcx .at(&obligation.cause, obligation.param_env) .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 15f5cf916a48b..c7ceefe2491ae 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::Span; +use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::{InferCtxtLike, Interner, Upcast}; use smallvec::{SmallVec, smallvec}; use tracing::debug; @@ -504,3 +506,68 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { } } } + +/// To improve performance, Sizedness traits are not elaborated and so special-casing is required +/// in the trait solver to find a `Sized` candidate for a `MetaSized` predicate. This is a helper +/// function for that special-casing, intended to be used when the obligation to be proven has been +/// confirmed to be `MetaSized`, and checking whether the `param_env` contains `Sized` for the same +/// `self_ty` is all that remains to be done. +// Ideally this would be re-used by the next solver, but there is no `InferCtxtLike` implementor. +pub(crate) fn sizedness_elab_opt_fast_path_from_paramenv<Infcx, I>( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder<I, I::Ty>, + param_env: I::ParamEnv, +) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitPredicate<I>>> +where + I: Interner, + Infcx: InferCtxtLike<Interner = I>, +{ + #[allow(rustc::usage_of_type_ir_inherent)] + use rustc_type_ir::inherent::*; + sizedness_elab_opt_fast_path_from_clauses(infcx, self_ty, param_env.caller_bounds().iter()) +} + +/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of clauses instead +/// of a parameter environment. +pub(crate) fn sizedness_elab_opt_fast_path_from_clauses<Infcx, I, Trs>( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder<I, I::Ty>, + clauses: Trs, +) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitPredicate<I>>> +where + I: Interner, + Infcx: InferCtxtLike<Interner = I>, + Trs: IntoIterator<Item = I::Clause>, +{ + #[allow(rustc::usage_of_type_ir_inherent)] + use rustc_type_ir::inherent::*; + sizedness_elab_opt_fast_path_from_traitrefs( + infcx, + self_ty, + clauses + .into_iter() + .filter_map(|p| p.as_trait_clause()) + .map(|c| c.map_bound(|c| c.trait_ref)), + ) + .map(|f| f.map_bound(|f| f.upcast(infcx.cx()))) +} + +/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of trait refs instead +/// of a parameter environment. +pub(crate) fn sizedness_elab_opt_fast_path_from_traitrefs<Infcx, I, TraitRefs>( + infcx: &Infcx, + self_ty: rustc_type_ir::Binder<I, I::Ty>, + trait_refs: TraitRefs, +) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitRef<I>>> +where + I: Interner, + Infcx: InferCtxtLike<Interner = I>, + TraitRefs: IntoIterator<Item = rustc_type_ir::Binder<I, rustc_type_ir::TraitRef<I>>>, +{ + trait_refs.into_iter().find(|c| { + let expected_self_ty = infcx.resolve_vars_if_possible(self_ty); + let found_self_ty = infcx.resolve_vars_if_possible(c.self_ty()); + expected_self_ty == found_self_ty + && infcx.cx().is_lang_item(c.def_id(), TraitSolverLangItem::Sized) + }) +} diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index b11bcff1d8bbb..f417b5ee82e8d 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -4,6 +4,7 @@ use smallvec::smallvec; use crate::data_structures::HashSet; use crate::inherent::*; +use crate::lang_items::TraitSolverLangItem; use crate::outlives::{Component, push_outlives_components}; use crate::{self as ty, Interner, Upcast as _}; @@ -79,20 +80,57 @@ pub fn elaborate<I: Interner, O: Elaboratable<I>>( ) -> Elaborator<I, O> { let mut elaborator = Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All }; - elaborator.extend_deduped(obligations); + elaborator.extend_deduped(None, obligations); elaborator } impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { - fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) { + /// Adds `obligations` to the stack. `current_clause` is the clause which was elaborated to + /// produce these obligations. + fn extend_deduped( + &mut self, + current_clause: Option<I::Clause>, + obligations: impl IntoIterator<Item = O>, + ) { // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some // cases. One common case is when people define // `trait Sized: Sized { }` rather than `trait Sized { }`. self.stack.extend( - obligations.into_iter().filter(|o| { - self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind())) - }), + obligations + .into_iter() + .filter(|o| self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind()))) + .filter(|o| { + let Some(current_clause) = current_clause else { + return true; + }; + let Some(next_clause) = o.predicate().as_clause() else { + return true; + }; + + let current_did = match current_clause.kind().skip_binder() { + ty::ClauseKind::Trait(data) => data.def_id(), + ty::ClauseKind::HostEffect(data) => data.def_id(), + _ => return true, + }; + let next_did = match next_clause.kind().skip_binder() { + ty::ClauseKind::Trait(data) => data.def_id(), + ty::ClauseKind::HostEffect(data) => data.def_id(), + _ => return true, + }; + + // PERF(sized-hierarchy): To avoid iterating over sizedness supertraits in + // parameter environments, as an optimisation, sizedness supertraits aren't + // elaborated, so check if a `Sized` obligation is being elaborated to a + // `MetaSized` obligation and emit it. Candidate assembly and confirmation + // are modified to check for the `Sized` subtrait when a `MetaSized` obligation + // is present. + if self.cx.is_lang_item(current_did, TraitSolverLangItem::Sized) { + !self.cx.is_lang_item(next_did, TraitSolverLangItem::MetaSized) + } else { + true + } + }), ); } @@ -132,12 +170,14 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { // Get predicates implied by the trait, or only super predicates if we only care about self predicates. match self.mode { Filter::All => self.extend_deduped( + Some(clause), cx.explicit_implied_predicates_of(data.def_id()) .iter_identity() .enumerate() .map(map_to_child_clause), ), Filter::OnlySelf => self.extend_deduped( + Some(clause), cx.explicit_super_predicates_of(data.def_id()) .iter_identity() .enumerate() @@ -147,6 +187,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { } // `T: ~const Trait` implies `T: ~const Supertrait`. ty::ClauseKind::HostEffect(data) => self.extend_deduped( + Some(clause), cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| { elaboratable.child( trait_ref @@ -177,6 +218,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> { let mut components = smallvec![]; push_outlives_components(cx, ty_max, &mut components); self.extend_deduped( + Some(clause), components .into_iter() .filter_map(|component| elaborate_component_to_clause(cx, component, r_min)) diff --git a/tests/ui/attributes/dump-preds.stderr b/tests/ui/attributes/dump-preds.stderr index a84b91e309c7f..742847e7d04ab 100644 --- a/tests/ui/attributes/dump-preds.stderr +++ b/tests/ui/attributes/dump-preds.stderr @@ -42,7 +42,6 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()> = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] } = note: Binder { value: HostEffectPredicate { trait_ref: <<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, constness: Const }, bound_vars: [] } = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] } - = note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] } error: aborting due to 3 previous errors diff --git a/tests/ui/extern/extern-types-unsized.rs b/tests/ui/extern/extern-types-unsized.rs index 94a222a7e7e01..46cdc24e08328 100644 --- a/tests/ui/extern/extern-types-unsized.rs +++ b/tests/ui/extern/extern-types-unsized.rs @@ -27,7 +27,9 @@ fn main() { assert_sized::<Bar<A>>(); //~^ ERROR the size for values of type + //~| ERROR the size for values of type assert_sized::<Bar<Bar<A>>>(); //~^ ERROR the size for values of type + //~| ERROR the size for values of type } diff --git a/tests/ui/extern/extern-types-unsized.stderr b/tests/ui/extern/extern-types-unsized.stderr index a587d4dda55c8..43dd9800d6d30 100644 --- a/tests/ui/extern/extern-types-unsized.stderr +++ b/tests/ui/extern/extern-types-unsized.stderr @@ -59,8 +59,21 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-unsized.rs:28:20 + | +LL | assert_sized::<Bar<A>>(); + | ^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `A` +note: required by a bound in `Bar` + --> $DIR/extern-types-unsized.rs:14:12 + | +LL | struct Bar<T: ?Sized> { + | ^ required by this bound in `Bar` + error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/extern-types-unsized.rs:31:20 + --> $DIR/extern-types-unsized.rs:32:20 | LL | assert_sized::<Bar<Bar<A>>>(); | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction LL | fn assert_sized<T: ?Sized>() {} | ++++++++ -error: aborting due to 4 previous errors +error[E0277]: the size for values of type `A` cannot be known + --> $DIR/extern-types-unsized.rs:32:20 + | +LL | assert_sized::<Bar<Bar<A>>>(); + | ^^^^^^^^^^^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `A` +note: required by a bound in `Bar` + --> $DIR/extern-types-unsized.rs:14:12 + | +LL | struct Bar<T: ?Sized> { + | ^ required by this bound in `Bar` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/nll/issue-50716.rs b/tests/ui/nll/issue-50716.rs index c24d41e94e878..96168ebeaa165 100644 --- a/tests/ui/nll/issue-50716.rs +++ b/tests/ui/nll/issue-50716.rs @@ -5,7 +5,7 @@ trait A { type X: ?Sized; } -fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR mismatched types +fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) where for<'b> &'b T: A, <&'static T as A>::X: Sized diff --git a/tests/ui/nll/issue-50716.stderr b/tests/ui/nll/issue-50716.stderr index edd7fd765dade..536f88085ded3 100644 --- a/tests/ui/nll/issue-50716.stderr +++ b/tests/ui/nll/issue-50716.stderr @@ -1,18 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-50716.rs:8:27 - | -LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch - | - = note: expected trait `<<&'a T as A>::X as MetaSized>` - found trait `<<&'static T as A>::X as MetaSized>` -note: the lifetime `'a` as defined here... - --> $DIR/issue-50716.rs:8:8 - | -LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | ^^ - = note: ...does not necessarily outlive the static lifetime - error: lifetime may not live long enough --> $DIR/issue-50716.rs:13:14 | @@ -22,6 +7,5 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) LL | let _x = *s; | ^^ proving this value is `Sized` requires that `'a` must outlive `'static` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/sized-hierarchy/impls.rs b/tests/ui/sized-hierarchy/impls.rs index fad1b27b789c1..1ad87c5163056 100644 --- a/tests/ui/sized-hierarchy/impls.rs +++ b/tests/ui/sized-hierarchy/impls.rs @@ -209,6 +209,7 @@ fn main() { //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time needs_metasized::<(Foo, Foo)>(); //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time + //~| ERROR the size for values of type `main::Foo` cannot be known needs_pointeesized::<(Foo, Foo)>(); //~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr index 6856daaeb9201..720987757544f 100644 --- a/tests/ui/sized-hierarchy/impls.stderr +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/impls.rs:241:42 + --> $DIR/impls.rs:242: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:249:40 + --> $DIR/impls.rs:250: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:285:44 + --> $DIR/impls.rs:286: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:292:42 + --> $DIR/impls.rs:293: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:299:52 + --> $DIR/impls.rs:300: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:306:50 + --> $DIR/impls.rs:307:50 | LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } } | ^^^ doesn't have a size known at compile-time @@ -216,8 +216,22 @@ LL | needs_metasized::<(Foo, Foo)>(); = help: the trait `Sized` is not implemented for `main::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 + --> $DIR/impls.rs:210:23 + | +LL | needs_metasized::<(Foo, Foo)>(); + | ^^^^^^^^^^ doesn't have a known size + | + = help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = note: required because it appears within the type `(main::Foo, main::Foo)` +note: required by a bound in `needs_metasized` + --> $DIR/impls.rs:18:23 + | +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/impls.rs:212:26 + --> $DIR/impls.rs:213:26 | LL | needs_pointeesized::<(Foo, Foo)>(); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -226,7 +240,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:216:19 + --> $DIR/impls.rs:217:19 | LL | needs_sized::<(u32, [u8])>(); | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -240,7 +254,7 @@ 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:222:19 + --> $DIR/impls.rs:223:19 | LL | needs_sized::<(u32, Foo)>(); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -254,7 +268,7 @@ 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:224:23 + --> $DIR/impls.rs:225:23 | LL | needs_metasized::<(u32, Foo)>(); | ^^^^^^^^^^ doesn't have a known size @@ -268,14 +282,14 @@ 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:243:19 + --> $DIR/impls.rs:244: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:241:12 + --> $DIR/impls.rs:242:12 | LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -286,14 +300,14 @@ 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:251:19 + --> $DIR/impls.rs:252: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:249:12 + --> $DIR/impls.rs:250:12 | LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -304,14 +318,14 @@ 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:253:23 + --> $DIR/impls.rs:254: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:249:12 + --> $DIR/impls.rs:250:12 | LL | struct StructAllFieldsUnsized { x: Foo, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -322,14 +336,14 @@ 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:259:19 + --> $DIR/impls.rs:260: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:258:12 + --> $DIR/impls.rs:259:12 | LL | struct StructLastFieldMetaSized { x: u32, y: [u8] } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -340,14 +354,14 @@ 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:266:19 + --> $DIR/impls.rs:267: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:265:12 + --> $DIR/impls.rs:266:12 | LL | struct StructLastFieldUnsized { x: u32, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -358,14 +372,14 @@ 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:268:23 + --> $DIR/impls.rs:269: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:265:12 + --> $DIR/impls.rs:266:12 | LL | struct StructLastFieldUnsized { x: u32, y: Foo } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -375,6 +389,6 @@ note: required by a bound in `needs_metasized` LL | fn needs_metasized<T: MetaSized>() { } | ^^^^^^^^^ required by this bound in `needs_metasized` -error: aborting due to 26 previous errors +error: aborting due to 27 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.rs b/tests/ui/sized-hierarchy/pretty-print-opaque.rs index 43bda5c7a0b25..85ad722ac98d4 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.rs +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.rs @@ -57,6 +57,7 @@ pub fn pointeesized() -> Box<impl Tr + PointeeSized> { //~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known let y: Box<dyn Tr> = x; //~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known +//~| ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known } Box::new(1u32) } diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr index 38880898007f7..07261931c7e92 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -54,6 +54,15 @@ LL | let y: Box<dyn Tr> = x; = help: the trait `Sized` is not implemented for `impl Tr + PointeeSized` = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` -error: aborting due to 6 previous errors +error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known + --> $DIR/pretty-print-opaque.rs:58:30 + | +LL | let y: Box<dyn Tr> = x; + | ^ doesn't have a known size + | + = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` + = note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>` + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index fa3b8e9d8c9ca..8fe53d6773b95 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -19,6 +19,5 @@ impl<T> Overlap<T> for T {} impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} //~^ ERROR cannot find type `Missing` in this scope //~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied -//~| ERROR the trait bound `{type error}: const MetaSized` is not satisfied fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 50cc145471c55..d2a58e95629a4 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -37,19 +37,7 @@ help: consider further restricting type parameter `T` with trait `Overlap` LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {} | ++++++++++++++++++++++++++++++++++++++ -error[E0277]: the trait bound `{type error}: const MetaSized` is not satisfied - --> $DIR/issue-118950-root-region.rs:19:64 - | -LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} - | ^^^^^^^^^^ - | -note: required by a bound in `Overlap` - --> $DIR/issue-118950-root-region.rs:12:1 - | -LL | trait Overlap<T> {} - | ^^^^^^^^^^^^^^^^ required by this bound in `Overlap` - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0412. For more information about an error, try `rustc --explain E0277`. From 0f821993edc30ff71900254792b5a12c91b50273 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood2@arm.com> Date: Tue, 18 Mar 2025 03:06:17 +0000 Subject: [PATCH 43/43] wip: trait_sel: add sizedness traits to fast path There's an existing fast path for the `type_op_prove_predicate` predicate which can be extended to support the new sizedness traits and host effect predicates, avoiding lots of machinery. This fast path logic can also be reused as a fast path for within-query trait solving. --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 7 +- compiler/rustc_middle/src/ty/sty.rs | 49 ++++++++----- compiler/rustc_middle/src/ty/util.rs | 4 +- .../src/solve/assembly/structural_traits.rs | 3 +- .../src/traits/effects.rs | 3 +- .../src/traits/fulfill.rs | 6 +- .../rustc_trait_selection/src/traits/mod.rs | 4 +- .../traits/query/type_op/prove_predicate.rs | 13 +--- .../src/traits/select/mod.rs | 8 ++- .../rustc_trait_selection/src/traits/util.rs | 68 ++++++++++++++++++- compiler/rustc_traits/src/codegen.rs | 11 ++- .../rustc_traits/src/evaluate_obligation.rs | 5 ++ .../assoc-const-eq-bound-var-in-ty-not-wf.rs | 1 + ...soc-const-eq-bound-var-in-ty-not-wf.stderr | 15 +++- tests/ui/closures/issue-78720.rs | 1 + tests/ui/closures/issue-78720.stderr | 16 +++-- tests/ui/codegen/overflow-during-mono.rs | 2 +- tests/ui/codegen/overflow-during-mono.stderr | 2 +- tests/ui/recursion/issue-83150.rs | 2 +- tests/ui/recursion/issue-83150.stderr | 2 +- tests/ui/where-clauses/ignore-err-clauses.rs | 1 + .../where-clauses/ignore-err-clauses.stderr | 13 +++- 22 files changed, 182 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d75c2853ba080..2f1afd4aec1f0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -23,7 +23,8 @@ use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericArgKind, GenericArgsRef, GenericParamDefKind, - IsIdentity, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs, UserSelfTy, + IsIdentity, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, + UserArgs, UserSelfTy, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -439,7 +440,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || {}, ); // Sized types have static alignment, and so do slices. - if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) { + if tail.has_trivial_sizedness(self.tcx, SizedTraitKind::Sized) + || matches!(tail.kind(), ty::Slice(..)) + { // Nothing else is required here. } else { // We can't be sure, let's required full `Sized`. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 74a94d8278453..3293e90de0175 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -16,6 +16,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension}; use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; +use rustc_type_ir::solve::SizedTraitKind; use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, TypeVisitableExt, elaborate}; use tracing::instrument; use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; @@ -1783,7 +1784,7 @@ impl<'tcx> Ty<'tcx> { let Some(pointee_ty) = self.builtin_deref(true) else { bug!("Type {self:?} is not a pointer or reference type") }; - if pointee_ty.is_trivially_sized(tcx) { + if pointee_ty.has_trivial_sizedness(tcx, SizedTraitKind::Sized) { tcx.types.unit } else { match pointee_ty.ptr_metadata_ty_or_tail(tcx, |x| x) { @@ -1886,17 +1887,17 @@ impl<'tcx> Ty<'tcx> { } } - /// Fast path helper for testing if a type is `Sized`. + /// Fast path helper for testing if a type is `Sized`, `MetaSized` or `PointeeSized`. /// - /// Returning true means the type is known to be sized. Returning - /// `false` means nothing -- could be sized, might not be. + /// Returning true means the type is known to implement the sizedness trait. Returning `false` + /// means nothing -- could be sized, might not be. /// - /// Note that we could never rely on the fact that a type such as `[_]` is - /// trivially `!Sized` because we could be in a type environment with a - /// bound such as `[_]: Copy`. A function with such a bound obviously never - /// can be called, but that doesn't mean it shouldn't typecheck. This is why - /// this method doesn't return `Option<bool>`. - pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { + /// Note that we could never rely on the fact that a type such as `[_]` is trivially `!Sized` + /// because we could be in a type environment with a bound such as `[_]: Copy`. A function with + /// such a bound obviously never can be called, but that doesn't mean it shouldn't typecheck. + /// This is why this method doesn't return `Option<bool>`. + #[instrument(skip(tcx), level = "debug")] + pub fn has_trivial_sizedness(self, tcx: TyCtxt<'tcx>, sizedness: SizedTraitKind) -> bool { match self.kind() { ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Uint(_) @@ -1919,20 +1920,36 @@ impl<'tcx> Ty<'tcx> { | ty::Error(_) | ty::Dynamic(_, _, ty::DynStar) => true, - ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false, + ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) => match sizedness { + SizedTraitKind::Sized => false, + SizedTraitKind::MetaSized | SizedTraitKind::PointeeSized => true, + }, + + ty::Foreign(..) => match sizedness { + SizedTraitKind::Sized | SizedTraitKind::MetaSized => false, + SizedTraitKind::PointeeSized => true, + }, - ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.is_trivially_sized(tcx)), + ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.has_trivial_sizedness(tcx, sizedness)), - ty::Adt(def, args) => def - .sized_constraint(tcx) - .is_none_or(|ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)), + ty::Adt(def, args) => { + let constraint = match sizedness { + SizedTraitKind::Sized => def.sized_constraint(tcx), + SizedTraitKind::MetaSized => def.meta_sized_constraint(tcx), + SizedTraitKind::PointeeSized => def.pointee_sized_constraint(tcx), + }; + + constraint.is_none_or(|ty| { + ty.instantiate(tcx, args).has_trivial_sizedness(tcx, sizedness) + }) + } ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, ty::Infer(ty::TyVar(_)) => false, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { - bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) + bug!("`has_trivial_sizedness` applied to unexpected type: {:?}", self) } } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c0d4130336e52..05a362359e161 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -16,6 +16,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension}; use rustc_session::Limit; use rustc_span::sym; +use rustc_type_ir::solve::SizedTraitKind; use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; @@ -1189,7 +1190,8 @@ impl<'tcx> Ty<'tcx> { /// strange rules like `<T as Foo<'static>>::Bar: Sized` that /// actually carry lifetime requirements. pub fn is_sized(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> bool { - self.is_trivially_sized(tcx) || tcx.is_sized_raw(typing_env.as_query_input(self)) + self.has_trivial_sizedness(tcx, SizedTraitKind::Sized) + || tcx.is_sized_raw(typing_env.as_query_input(self)) } /// Checks whether values of this type `T` implement the `Freeze` diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index b40031704fe10..fbbcef6071898 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -196,7 +196,8 @@ where /// trait to be implemented (see the trait goal for that), as these are orthogonal. This means that /// the effect predicate can succeed while the trait predicate can fail - this is unintuitive but /// allows this function to be much simpler. -// NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver. +// NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver and +// `ProvePredicate::try_fast_path` #[instrument(level = "trace", skip(cx), ret)] pub(in crate::solve) fn const_conditions_for_sizedness<I: Interner>( cx: I, diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index 54679a7dbb55e..c9e8ee8d46544 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -253,7 +253,8 @@ fn evaluate_host_effect_from_builtin_impls<'tcx>( } } -// NOTE: Keep this in sync with `const_conditions_for_sizedness` in the new solver. +// NOTE: Keep this in sync with `const_conditions_for_sizedness` in the new solver and +// `ProvePredicate::try_fast_path` fn evaluate_host_effect_for_sizedness_goal<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &HostEffectObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e39f8e673dbac..ae9fdf7006c86 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -24,10 +24,10 @@ use super::{ }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; -use crate::traits::EvaluateConstErr; use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::traits::{EvaluateConstErr, sizedness_fast_path}; pub(crate) type PendingPredicateObligations<'tcx> = ThinVec<PendingPredicateObligation<'tcx>>; @@ -329,6 +329,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { let infcx = self.selcx.infcx; + if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) { + return ProcessResult::Changed(thin_vec::thin_vec![]); + } + if obligation.predicate.has_aliases() { let mut obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index de337710b5ef7..f2713b98f0a26 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -65,8 +65,8 @@ pub use self::specialize::{ pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::{ BoundVarReplacer, PlaceholderReplacer, elaborate, expand_trait_aliases, impl_item_is_final, - supertrait_def_ids, supertraits, transitive_bounds_that_define_assoc_item, upcast_choices, - with_replaced_escaping_bound_vars, + sizedness_fast_path, supertrait_def_ids, supertraits, transitive_bounds_that_define_assoc_item, + upcast_choices, with_replaced_escaping_bound_vars, }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::outlives::env::OutlivesEnvironment; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 4f9e2e79d624c..8b16356281f5f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -1,4 +1,3 @@ -use rustc_hir::LangItem; use rustc_infer::traits::Obligation; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; @@ -7,7 +6,7 @@ use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; use rustc_span::Span; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; -use crate::traits::ObligationCtxt; +use crate::traits::{ObligationCtxt, sizedness_fast_path}; impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { type QueryResponse = (); @@ -16,15 +15,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>, ) -> Option<Self::QueryResponse> { - // Proving Sized, very often on "obviously sized" types like - // `&T`, accounts for about 60% percentage of the predicates - // we have to prove. No need to canonicalize and all that for - // such cases. - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = - key.value.predicate.kind().skip_binder() - && tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) - && trait_ref.self_ty().is_trivially_sized(tcx) - { + if sizedness_fast_path(tcx, key.value.predicate, key.param_env) { return Some(()); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a9bb24a862c7b..76fdd685c0ba7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -51,7 +51,9 @@ use crate::infer::{InferCtxt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt}; -use crate::traits::{EvaluateConstErr, ProjectionCacheKey, Unimplemented, effects}; +use crate::traits::{ + EvaluateConstErr, ProjectionCacheKey, Unimplemented, effects, sizedness_fast_path, +}; mod _match; mod candidate_assembly; @@ -605,6 +607,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { None => self.check_recursion_limit(&obligation, &obligation)?, } + if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) { + return Ok(EvaluatedToOk); + } + ensure_sufficient_stack(|| { let bound_predicate = obligation.predicate.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c7ceefe2491ae..5117a81dcbf90 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,12 +1,13 @@ use std::collections::{BTreeMap, VecDeque}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; pub use rustc_infer::traits::util::*; use rustc_middle::bug; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, + self, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::Span; use rustc_type_ir::lang_items::TraitSolverLangItem; @@ -571,3 +572,68 @@ where && infcx.cx().is_lang_item(c.def_id(), TraitSolverLangItem::Sized) }) } + +pub fn sizedness_fast_path<'tcx>( + tcx: TyCtxt<'tcx>, + predicate: ty::Predicate<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> bool { + // Proving `Sized`/`MetaSized`/`PointeeSized`, very often on "obviously sized" types like + // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to + // canonicalize and all that for such cases. + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = + predicate.kind().skip_binder() + { + let sizedness = if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + Some(SizedTraitKind::Sized) + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::MetaSized) { + Some(SizedTraitKind::MetaSized) + } else if tcx.is_lang_item(trait_ref.def_id(), LangItem::PointeeSized) { + Some(SizedTraitKind::PointeeSized) + } else { + None + }; + + if let Some(sizedness) = sizedness + && trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) + { + debug!("fast path -- trivial sizedness"); + return true; + } + + if matches!(sizedness, Some(SizedTraitKind::MetaSized)) { + let has_sized_in_param_env = param_env + .caller_bounds() + .iter() + .rev() // sizedness predicates are normally at the end for diagnostics reasons + .filter_map(|p| p.as_trait_clause()) + .any(|c| { + trait_ref.self_ty() == c.skip_binder().self_ty() + && tcx.is_lang_item(c.def_id(), LangItem::Sized) + }); + if has_sized_in_param_env { + debug!("fast path -- metasized paramenv"); + return true; + } + } + } + + // Likewise, determining if a sizedness trait is implemented const-ly is a trivial + // determination that can happen in the fast path. + // + // NOTE: Keep this in sync with `evaluate_host_effect_for_sizedness_goal` in the old solver, + // `const_conditions_for_sizedness` in the new solver. + if let ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(host_pred)) = + predicate.kind().skip_binder() + { + let is_sizedness = tcx.is_lang_item(host_pred.def_id(), LangItem::Sized) + || tcx.is_lang_item(host_pred.def_id(), LangItem::MetaSized); + + if is_sizedness && !host_pred.self_ty().has_non_const_sizedness() { + debug!("fast path -- host effect"); + return true; + } + } + + false +} diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 4a889abfc28f1..e86507335cc5f 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,11 +6,11 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Upcast}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, - Unimplemented, + Unimplemented, sizedness_fast_path, }; use tracing::debug; @@ -34,6 +34,13 @@ pub(crate) fn codegen_select_candidate<'tcx>( let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let mut selcx = SelectionContext::new(&infcx); + if sizedness_fast_path(tcx, trait_ref.upcast(tcx), param_env) { + return Ok(&*tcx.arena.alloc(ImplSource::Builtin( + ty::solve::BuiltinImplSource::Trivial, + Default::default(), + ))); + } + let obligation_cause = ObligationCause::dummy(); let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref); diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index c9ad096c6e9d0..819b8e3231ce2 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -5,6 +5,7 @@ use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::CanonicalPredicateGoal; use rustc_trait_selection::traits::{ EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode, + sizedness_fast_path, }; use tracing::debug; @@ -23,6 +24,10 @@ fn evaluate_obligation<'tcx>( debug!("evaluate_obligation: goal={:#?}", goal); let ParamEnvAnd { param_env, value: predicate } = goal; + if sizedness_fast_path(tcx, predicate, param_env) { + return Ok(EvaluationResult::EvaluatedToOk); + } + let mut selcx = SelectionContext::with_query_mode(infcx, TraitQueryMode::Canonical); let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate); diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 40546efa40b9c..5dd263656edb7 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -7,6 +7,7 @@ trait Trait<T> { } fn take( +//~^ ERROR implementation of `Project` is not general enough _: impl Trait< <<for<'a> fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, K = { () } diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index f77f37f101eef..061e955756399 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -1,16 +1,25 @@ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:13:13 | LL | K = { () } | ^^^^^^ error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:12:13 + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:13:13 | LL | K = { () } | ^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error: implementation of `Project` is not general enough + --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:9:4 + | +LL | fn take( + | ^^^^ implementation of `Project` is not general enough + | + = note: `Project` would have to be implemented for the type `for<'a> fn(&'a str) -> &'a str` + = note: ...but `Project` is actually implemented for the type `fn(&'0 str) -> &'0 str`, for some specific lifetime `'0` + +error: aborting due to 3 previous errors diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 81af030fe5568..0c4f337ba57b8 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -1,5 +1,6 @@ fn server() -> impl { //~^ ERROR at least one trait must be specified + //~| ERROR type annotations needed ().map2(|| "") } diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 90672cd83d7cf..3e95fab441ade 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -5,7 +5,7 @@ LL | fn server() -> impl { | ^^^^ error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-78720.rs:13:12 + --> $DIR/issue-78720.rs:14:12 | LL | _func: F, | ^ @@ -22,8 +22,14 @@ help: you might be missing a type parameter LL | struct Map2<Segment2, F> { | +++ +error[E0282]: type annotations needed + --> $DIR/issue-78720.rs:1:16 + | +LL | fn server() -> impl { + | ^^^^ cannot infer type + error[E0308]: mismatched types - --> $DIR/issue-78720.rs:7:39 + --> $DIR/issue-78720.rs:8:39 | LL | fn map2<F>(self, f: F) -> Map2<F> {} | ^^ expected `Map2<F>`, found `()` @@ -32,7 +38,7 @@ LL | fn map2<F>(self, f: F) -> Map2<F> {} found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-78720.rs:7:16 + --> $DIR/issue-78720.rs:8:16 | LL | fn map2<F>(self, f: F) -> Map2<F> {} | ^^^^ doesn't have a size known at compile-time @@ -47,7 +53,7 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn map2<F>(&self, f: F) -> Map2<F> {} | + -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0308, E0412. +Some errors have detailed explanations: E0277, E0282, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 83a8b6b3ef6a2..a9045840173e7 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +//~ ERROR overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` //@ build-fail #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index f7a3e2df3dbaa..74d98fde285bb 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,4 +1,4 @@ -error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +error[E0275]: overflow evaluating the requirement `for<'a> {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: FnMut(&'a _)` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) = note: required for `Filter<std::array::IntoIter<i32, 11>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index 5b8161f7d0a9b..b720c168187b8 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,4 +1,4 @@ -//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: MetaSized` +//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 7e603ba3f6e0e..600922f1e57a7 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -10,7 +10,7 @@ LL | func(&mut iter.map(|x| x + 1)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: MetaSized` +error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) = note: required for `&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator` diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs index c76f0e1a8b2b5..428ebf4b40836 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.rs +++ b/tests/ui/where-clauses/ignore-err-clauses.rs @@ -1,6 +1,7 @@ use std::ops::Add; fn dbl<T>(x: T) -> <T as Add>::Output +//~^ ERROR type annotations needed where T: Copy + Add, UUU: Copy, diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr index 4cf553da4c5fc..fbf1b99334f42 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.stderr +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -1,9 +1,16 @@ error[E0412]: cannot find type `UUU` in this scope - --> $DIR/ignore-err-clauses.rs:6:5 + --> $DIR/ignore-err-clauses.rs:7:5 | LL | UUU: Copy, | ^^^ not found in this scope -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/ignore-err-clauses.rs:3:14 + | +LL | fn dbl<T>(x: T) -> <T as Add>::Output + | ^ cannot infer type for type parameter `T` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0282, E0412. +For more information about an error, try `rustc --explain E0282`.