Skip to content

Commit

Permalink
Add min_generic_const_args and gate new const path lowering with it
Browse files Browse the repository at this point in the history
  • Loading branch information
camelid committed Nov 13, 2024
1 parent 94e4efe commit 87790f1
Show file tree
Hide file tree
Showing 44 changed files with 383 additions and 183 deletions.
12 changes: 11 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2063,8 +2063,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ty_id: NodeId,
span: Span,
) -> &'hir hir::ConstArg<'hir> {
let tcx = self.tcx;

// FIXME(min_generic_const_args): we only allow one-segment const paths for now
let ct_kind = if path.is_potential_trivial_const_arg() {
let ct_kind = if path.is_potential_trivial_const_arg()
&& (tcx.features().min_generic_const_args()
|| matches!(res, Res::Def(DefKind::ConstParam, _)))
{
let qpath = self.lower_qpath(
ty_id,
&None,
Expand Down Expand Up @@ -2127,6 +2132,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

#[instrument(level = "debug", skip(self))]
fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
let tcx = self.tcx;
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
let expr = if let ExprKind::Block(block, _) = &anon.value.kind
Expand All @@ -2138,9 +2144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
&anon.value
};
let maybe_res =
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
// FIXME(min_generic_const_args): we only allow one-segment const paths for now
if let ExprKind::Path(None, path) = &expr.kind
&& path.is_potential_trivial_const_arg()
&& (tcx.features().min_generic_const_args()
|| matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
{
let qpath = self.lower_qpath(
expr.id,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ declare_features! (
(unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)),
/// Allows `#[marker]` on certain traits allowing overlapping implementations.
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
/// Enables the generic const args MVP (only bare paths, not arbitrary computation).
(incomplete, min_generic_const_args, "CURRENT_RUSTC_VERSION", Some(132980)),
/// A minimal, sound subset of specialization intended to be used by the
/// standard library until the soundness issues with specialization
/// are fixed.
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ fn generic_arg_mismatch_err(
{
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
err.help("function item types cannot be named directly");
} else if let hir::ConstArgKind::Anon(anon) = cnst.kind
&& let body = tcx.hir().body(anon.body)
&& let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) =
body.value.kind
&& let Res::Def(DefKind::Fn { .. }, id) = path.res
{
// FIXME(min_generic_const_args): this branch is dead once new const path lowering
// (for single-segment paths) is no longer gated
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
err.help("function item types cannot be named directly");
}
}
_ => {}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,7 @@ symbols! {
min_const_generics,
min_const_unsafe_fn,
min_exhaustive_patterns,
min_generic_const_args,
min_specialization,
min_type_alias_impl_trait,
minnumf128,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ impl Wrapper<{ bar() }> {

fn main() {
Wrapper::<function>::call;
//~^ ERROR: the function or associated item `call` exists for struct `Wrapper<function>`,
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,25 @@ error[E0741]: using function pointers as const generic parameters is forbidden
LL | struct Wrapper<const F: fn()>;
| ^^^^

error: aborting due to 2 previous errors
error[E0599]: the function or associated item `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied
--> $DIR/non_valtreeable_const_arg-2.rs:17:26
|
LL | struct Wrapper<const F: fn()>;
| ----------------------------- function or associated item `call` not found for this struct because it doesn't satisfy `Wrapper<function>: Fn<_>`
...
LL | Wrapper::<function>::call;
| ^^^^ function or associated item cannot be called on `Wrapper<function>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`Wrapper<function>: Fn<_>`
which is required by `&Wrapper<function>: Fn<_>`
note: the trait `Fn` must be implemented
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `call`, perhaps you need to implement it:
candidate #1: `Fn`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0425, E0741.
Some errors have detailed explanations: E0425, E0599, E0741.
For more information about an error, try `rustc --explain E0425`.
5 changes: 2 additions & 3 deletions tests/ui/const-generics/bad-generic-in-copy-impl.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#[derive(Copy, Clone)]
//~^ ERROR the trait `Copy` cannot be implemented for this type
pub struct Foo {
x: [u8; SIZE],
//~^ ERROR the constant `1` is not of type `usize`
//~| ERROR the constant `1` is not of type `usize`
//~^ ERROR mismatched types
//~| ERROR mismatched types
}

const SIZE: u32 = 1;
Expand Down
37 changes: 9 additions & 28 deletions tests/ui/const-generics/bad-generic-in-copy-impl.stderr
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
error: the constant `1` is not of type `usize`
--> $DIR/bad-generic-in-copy-impl.rs:4:8
error[E0308]: mismatched types
--> $DIR/bad-generic-in-copy-impl.rs:3:13
|
LL | x: [u8; SIZE],
| ^^^^^^^^^^ expected `usize`, found `u32`
| ^^^^ expected `usize`, found `u32`

error[E0204]: the trait `Copy` cannot be implemented for this type
--> $DIR/bad-generic-in-copy-impl.rs:1:10
error[E0308]: mismatched types
--> $DIR/bad-generic-in-copy-impl.rs:3:13
|
LL | #[derive(Copy, Clone)]
| ^^^^
...
LL | x: [u8; SIZE],
| ------------- this field does not implement `Copy`
| ^^^^ expected `usize`, found `u32`
|
note: the `Copy` impl for `[u8; 1]` requires that `the constant `1` has type `usize``
--> $DIR/bad-generic-in-copy-impl.rs:4:8
|
LL | x: [u8; SIZE],
| ^^^^^^^^^^
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)

error: the constant `1` is not of type `usize`
--> $DIR/bad-generic-in-copy-impl.rs:4:5
|
LL | #[derive(Copy, Clone)]
| ----- in this derive macro expansion
...
LL | x: [u8; SIZE],
| ^^^^^^^^^^^^^ expected `usize`, found `u32`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0204`.
For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
= note: const parameters may not be used in the type of const parameters

error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:14:40
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,37 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
= note: const parameters may not be used in the type of const parameters

error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/const-param-type-depends-on-const-param.rs:14:40
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^ the type must not depend on the parameter `N`
|
= note: const parameters may not be used in the type of const parameters

error: aborting due to 2 previous errors
error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
|
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
| ^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|

error: `[u8; N]` is forbidden as the type of a const generic parameter
--> $DIR/const-param-type-depends-on-const-param.rs:15:35
|
LL | pub struct SelfDependent<const N: [u8; N]>;
| ^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0770`.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@

pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^^ ERROR `[u8; N]` is forbidden

pub struct SelfDependent<const N: [u8; N]>;
//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^^ ERROR `[u8; N]` is forbidden

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error: aborting due to 2 previous errors
error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0308, E0741.
For more information about an error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0282, E0308, E0741.
For more information about an error, try `rustc --explain E0282`.
17 changes: 14 additions & 3 deletions tests/ui/const-generics/fn-const-param-infer.full.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error: aborting due to 2 previous errors
error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0308, E0741.
For more information about an error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0282, E0308, E0741.
For more information about an error, try `rustc --explain E0282`.
16 changes: 14 additions & 2 deletions tests/ui/const-generics/fn-const-param-infer.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error: aborting due to 2 previous errors
error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
2 changes: 1 addition & 1 deletion tests/ui/const-generics/fn-const-param-infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn main() {
let _ = Checked::<{ generic_arg::<usize> }>;
let _ = Checked::<{ generic_arg::<u32> }>; //~ ERROR: mismatched types

let _ = Checked::<generic>;
let _ = Checked::<generic>; //~ ERROR: type annotations needed
let _ = Checked::<{ generic::<u16> }>;
let _: Checked<{ generic::<u16> }> = Checked::<{ generic::<u16> }>;
let _: Checked<{ generic::<u32> }> = Checked::<{ generic::<u16> }>;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
struct U;

struct S<const N: U>()
//~^ ERROR: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
where
S<{ U }>:;
//~^ ERROR: overflow evaluating the requirement `S<{ U }> well-formed`

fn main() {}
21 changes: 12 additions & 9 deletions tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
error[E0741]: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/adt_wf_hang.rs:9:19
error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed`
--> $DIR/adt_wf_hang.rs:11:5
|
LL | struct S<const N: U>()
| ^
|
help: add `#[derive(ConstParamTy)]` to the struct
LL | S<{ U }>:;
| ^^^^^^^^
|
LL + #[derive(ConstParamTy)]
LL | struct U;
note: required by a bound in `S`
--> $DIR/adt_wf_hang.rs:11:5
|
LL | struct S<const N: U>()
| - required by a bound in this struct
LL | where
LL | S<{ U }>:;
| ^^^^^^^^ required by this bound in `S`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0741`.
For more information about this error, try `rustc --explain E0275`.
3 changes: 3 additions & 0 deletions tests/ui/const-generics/generic_const_exprs/error_in_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@

pub struct A<const z: [usize; x]> {}
//~^ ERROR: cannot find value `x` in this scope
//~| ERROR: `[usize; x]` is forbidden as the type of a const generic parameter

impl A<2> {
//~^ ERROR: mismatched types
pub const fn B() {}
//~^ ERROR: duplicate definitions
}

impl A<2> {
//~^ ERROR: mismatched types
pub const fn B() {}
}

Expand Down
32 changes: 28 additions & 4 deletions tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,40 @@ LL | pub struct A<const z: [usize; x]> {}
| |
| similarly named const parameter `z` defined here

error: `[usize; x]` is forbidden as the type of a const generic parameter
--> $DIR/error_in_ty.rs:6:23
|
LL | pub struct A<const z: [usize; x]> {}
| ^^^^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
LL + #![feature(adt_const_params)]
|

error[E0308]: mismatched types
--> $DIR/error_in_ty.rs:10:8
|
LL | impl A<2> {
| ^ expected `[usize; x]`, found integer

error[E0308]: mismatched types
--> $DIR/error_in_ty.rs:16:8
|
LL | impl A<2> {
| ^ expected `[usize; x]`, found integer

error[E0592]: duplicate definitions with name `B`
--> $DIR/error_in_ty.rs:10:5
--> $DIR/error_in_ty.rs:12:5
|
LL | pub const fn B() {}
| ^^^^^^^^^^^^^^^^ duplicate definitions for `B`
...
LL | pub const fn B() {}
| ---------------- other definition for `B`

error: aborting due to 2 previous errors
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0425, E0592.
For more information about an error, try `rustc --explain E0425`.
Some errors have detailed explanations: E0308, E0425, E0592.
For more information about an error, try `rustc --explain E0308`.
Loading

0 comments on commit 87790f1

Please sign in to comment.