diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 313744efb3fce..32481bf2b9574 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -570,6 +570,9 @@ declare_features! ( /// Allows capturing variables in scope using format_args! (active, format_args_capture, "1.46.0", Some(67984), None), + /// Lazily evaluate constants. This allows constants to depend on type parameters. + (active, lazy_normalization_consts, "1.46.0", Some(72219), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -586,5 +589,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::raw_dylib, sym::const_trait_impl, sym::const_trait_bound_opt_out, + sym::lazy_normalization_consts, sym::specialization, ]; diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index d942c07965a49..698bef4374545 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1370,7 +1370,7 @@ impl<'tcx> TyCtxt<'tcx> { /// we still evaluate them eagerly. #[inline] pub fn lazy_normalization(self) -> bool { - self.features().const_generics + self.features().const_generics || self.features().lazy_normalization_consts } #[inline] diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index c34da8b1cf326..92afb7dab88c3 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -459,6 +459,7 @@ symbols! { label_break_value, lang, lang_items, + lazy_normalization_consts, lateout, let_chains, lhs, diff --git a/src/test/ui/const-generics/lazy-normalization/issue-71986.rs b/src/test/ui/const-generics/issue-71986.rs similarity index 100% rename from src/test/ui/const-generics/lazy-normalization/issue-71986.rs rename to src/test/ui/const-generics/issue-71986.rs diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs new file mode 100644 index 0000000000000..44cb74815c6a0 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs @@ -0,0 +1,10 @@ +pub const fn sof() -> usize { + 10 +} + +fn test() { + let _: [u8; sof::()]; + //~^ ERROR the size for values of type `T` +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr new file mode 100644 index 0000000000000..6e19251c72800 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.stderr @@ -0,0 +1,21 @@ +error[E0277]: the size for values of type `T` cannot be known at compilation time + --> $DIR/feature-gate-lazy_normalization_consts.rs:6:23 + | +LL | pub const fn sof() -> usize { + | - required by this bound in `sof` +... +LL | fn test() { + | - this type parameter needs to be `std::marker::Sized` +LL | let _: [u8; sof::()]; + | ^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `T` + = note: to learn more, visit +help: consider relaxing the implicit `Sized` restriction + | +LL | pub const fn sof() -> usize { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/lazy_normalization_consts/issue-47814.rs b/src/test/ui/lazy_normalization_consts/issue-47814.rs new file mode 100644 index 0000000000000..1fd0c45841b0d --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-47814.rs @@ -0,0 +1,16 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] +pub struct ArpIPv4<'a> { + _s: &'a u8 +} + +impl<'a> ArpIPv4<'a> { + const LENGTH: usize = 20; + + pub fn to_buffer() -> [u8; Self::LENGTH] { + unimplemented!() + } +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/issue-57739.rs b/src/test/ui/lazy_normalization_consts/issue-57739.rs new file mode 100644 index 0000000000000..4607f3e99b51f --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-57739.rs @@ -0,0 +1,17 @@ +#![feature(lazy_normalization_consts)] +//~^ WARN the feature `lazy_normalization_consts` is incomplete +trait ArraySizeTrait { + const SIZE: usize = 0; +} + +impl ArraySizeTrait for T { + const SIZE: usize = 1; +} + +struct SomeArray { + array: [u8; T::SIZE], + //~^ ERROR constant expression depends on a generic parameter + phantom: std::marker::PhantomData, +} + +fn main() {} diff --git a/src/test/ui/lazy_normalization_consts/issue-57739.stderr b/src/test/ui/lazy_normalization_consts/issue-57739.stderr new file mode 100644 index 0000000000000..1987f5890c041 --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-57739.stderr @@ -0,0 +1,19 @@ +warning: the feature `lazy_normalization_consts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-57739.rs:1:12 + | +LL | #![feature(lazy_normalization_consts)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #72219 for more information + +error: constant expression depends on a generic parameter + --> $DIR/issue-57739.rs:12:5 + | +LL | array: [u8; T::SIZE], + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error; 1 warning emitted + diff --git a/src/test/ui/lazy_normalization_consts/issue-73980.rs b/src/test/ui/lazy_normalization_consts/issue-73980.rs new file mode 100644 index 0000000000000..339b22c0b423d --- /dev/null +++ b/src/test/ui/lazy_normalization_consts/issue-73980.rs @@ -0,0 +1,14 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] + +pub struct X(P, Q); +pub struct L(T); + +impl L { + const S: usize = 1; +} + +impl X::S]> {} + +fn main() {}