Skip to content

Commit e263457

Browse files
committed
Allow only single-segment const paths for now
1 parent 034661e commit e263457

28 files changed

+539
-92
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rustc_data_structures::sorted_map::SortedMap;
5252
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
5353
use rustc_data_structures::sync::Lrc;
5454
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
55-
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
55+
use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
5656
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
5757
use rustc_hir::{
5858
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, MissingLifetimeKind,
@@ -2298,19 +2298,60 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22982298
ty_id: NodeId,
22992299
span: Span,
23002300
) -> &'hir hir::ConstArg<'hir> {
2301-
let qpath = self.lower_qpath(
2302-
ty_id,
2303-
&None,
2304-
path,
2305-
ParamMode::Optional,
2306-
AllowReturnTypeNotation::No,
2307-
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2308-
None,
2309-
);
2301+
let ct_kind = match res {
2302+
// FIXME(min_generic_const_args): only allow one-segment const paths for now
2303+
Res::Def(
2304+
DefKind::ConstParam | DefKind::Const | DefKind::Ctor(_, CtorKind::Const),
2305+
_,
2306+
) if path.is_potential_trivial_const_arg() => {
2307+
let qpath = self.lower_qpath(
2308+
ty_id,
2309+
&None,
2310+
path,
2311+
ParamMode::Optional,
2312+
AllowReturnTypeNotation::No,
2313+
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2314+
None,
2315+
);
2316+
hir::ConstArgKind::Path(qpath)
2317+
}
2318+
_ => {
2319+
// Construct an AnonConst where the expr is the "ty"'s path.
2320+
2321+
let parent_def_id = self.current_def_id_parent;
2322+
let node_id = self.next_node_id();
2323+
let span = self.lower_span(span);
2324+
2325+
// Add a definition for the in-band const def.
2326+
let def_id =
2327+
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
2328+
let hir_id = self.lower_node_id(node_id);
2329+
2330+
let path_expr = Expr {
2331+
id: ty_id,
2332+
kind: ExprKind::Path(None, path.clone()),
2333+
span,
2334+
attrs: AttrVec::new(),
2335+
tokens: None,
2336+
};
2337+
2338+
let ct = self.with_new_scopes(span, |this| {
2339+
self.arena.alloc(hir::AnonConst {
2340+
def_id,
2341+
hir_id,
2342+
body: this.with_def_id_parent(def_id, |this| {
2343+
this.lower_const_body(path_expr.span, Some(&path_expr))
2344+
}),
2345+
span,
2346+
})
2347+
});
2348+
hir::ConstArgKind::Anon(ct)
2349+
}
2350+
};
23102351

23112352
self.arena.alloc(hir::ConstArg {
23122353
hir_id: self.next_id(),
2313-
kind: hir::ConstArgKind::Path(qpath),
2354+
kind: ct_kind,
23142355
is_desugared_from_effects: false,
23152356
})
23162357
}
@@ -2334,7 +2375,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23342375
} else {
23352376
&anon.value
23362377
};
2337-
if let ExprKind::Path(qself, path) = &expr.kind {
2378+
let maybe_res =
2379+
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
2380+
debug!("res={:?}", maybe_res);
2381+
// FIXME(min_generic_const_args): for now we only lower params to ConstArgKind::Path
2382+
if let Some(res) = maybe_res
2383+
&& let ExprKind::Path(qself, path) = &expr.kind
2384+
&& let Res::Def(DefKind::ConstParam, _) = res
2385+
// FIXME(min_generic_const_args): only allow one-segment const paths for now
2386+
&& let Res::Def(
2387+
DefKind::ConstParam | DefKind::Const | DefKind::Ctor(_, CtorKind::Const),
2388+
_,
2389+
) = res
2390+
&& path.is_potential_trivial_const_arg()
2391+
{
23382392
let qpath = self.lower_qpath(
23392393
expr.id,
23402394
qself,

tests/ui/associated-consts/issue-58022.stderr

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
2+
--> $DIR/issue-58022.rs:4:25
3+
|
4+
LL | const SIZE: usize;
5+
| ------------------ `Foo::SIZE` defined here
6+
LL |
7+
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
8+
| ^^^^^^^^^ cannot refer to the associated constant of trait
9+
110
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
211
--> $DIR/issue-58022.rs:13:41
312
|
@@ -18,7 +27,7 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo
1827
LL | Foo(Box::new(*slice))
1928
| ^^^ not a function, tuple struct or tuple variant
2029

21-
error: aborting due to 2 previous errors
30+
error: aborting due to 3 previous errors
2231

23-
Some errors have detailed explanations: E0277, E0423.
32+
Some errors have detailed explanations: E0277, E0423, E0790.
2433
For more information about an error, try `rustc --explain E0277`.

tests/ui/associated-item/issue-48027.stderr

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ LL | const X: usize;
1313
| ^ ...because it contains this associated `const`
1414
= help: consider moving `X` to another trait
1515

16-
error: aborting due to 1 previous error
16+
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
17+
--> $DIR/issue-48027.rs:3:32
18+
|
19+
LL | const X: usize;
20+
| --------------- `Bar::X` defined here
21+
LL | fn return_n(&self) -> [u8; Bar::X];
22+
| ^^^^^^ cannot refer to the associated constant of trait
23+
24+
error: aborting due to 2 previous errors
1725

18-
For more information about this error, try `rustc --explain E0038`.
26+
Some errors have detailed explanations: E0038, E0790.
27+
For more information about an error, try `rustc --explain E0038`.
Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
1-
error: the constant `1` is not of type `usize`
2-
--> $DIR/bad-generic-in-copy-impl.rs:3:8
1+
error[E0308]: mismatched types
2+
--> $DIR/bad-generic-in-copy-impl.rs:3:13
33
|
44
LL | x: [u8; SIZE],
5-
| ^^^^^^^^^^ expected `usize`, found `u32`
5+
| ^^^^ expected `usize`, found `u32`
66

7-
error[E0204]: the trait `Copy` cannot be implemented for this type
8-
--> $DIR/bad-generic-in-copy-impl.rs:1:10
7+
error[E0308]: mismatched types
8+
--> $DIR/bad-generic-in-copy-impl.rs:3:13
99
|
10-
LL | #[derive(Copy, Clone)]
11-
| ^^^^
12-
LL | pub struct Foo {
1310
LL | x: [u8; SIZE],
14-
| ------------- this field does not implement `Copy`
11+
| ^^^^ expected `usize`, found `u32`
1512
|
16-
note: the `Copy` impl for `[u8; 1]` requires that `the constant `1` has type `usize``
17-
--> $DIR/bad-generic-in-copy-impl.rs:3:8
18-
|
19-
LL | x: [u8; SIZE],
20-
| ^^^^^^^^^^
21-
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
22-
23-
error: the constant `1` is not of type `usize`
24-
--> $DIR/bad-generic-in-copy-impl.rs:3:5
25-
|
26-
LL | #[derive(Copy, Clone)]
27-
| ----- in this derive macro expansion
28-
LL | pub struct Foo {
29-
LL | x: [u8; SIZE],
30-
| ^^^^^^^^^^^^^ expected `usize`, found `u32`
31-
|
32-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3314

34-
error: aborting due to 3 previous errors
15+
error: aborting due to 2 previous errors
3516

36-
For more information about this error, try `rustc --explain E0204`.
17+
For more information about this error, try `rustc --explain E0308`.

tests/ui/const-generics/bad-subst-const-kind.stderr

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,19 @@ error: the constant `N` is not of type `usize`
44
LL | impl<const N: u64> Q for [u8; N] {
55
| ^^^^^^^ expected `usize`, found `u64`
66

7-
error: aborting due to 1 previous error
7+
error: the constant `13` is not of type `u64`
8+
--> $DIR/bad-subst-const-kind.rs:13:24
9+
|
10+
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
11+
| ^^^^^^^^ expected `u64`, found `usize`
12+
|
13+
note: required for `[u8; 13]` to implement `Q`
14+
--> $DIR/bad-subst-const-kind.rs:8:20
15+
|
16+
LL | impl<const N: u64> Q for [u8; N] {
17+
| ------------ ^ ^^^^^^^
18+
| |
19+
| unsatisfied trait bound introduced here
20+
21+
error: aborting due to 2 previous errors
822

tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,30 @@ LL | pub struct SelfDependent<const N: [u8; N]>;
1414
|
1515
= note: const parameters may not be used in the type of const parameters
1616

17-
error: aborting due to 2 previous errors
17+
error: `[u8; N]` is forbidden as the type of a const generic parameter
18+
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
19+
|
20+
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
21+
| ^^^^^^^
22+
|
23+
= note: the only supported types are integers, `bool`, and `char`
24+
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
25+
|
26+
LL + #![feature(adt_const_params)]
27+
|
28+
29+
error: `[u8; N]` is forbidden as the type of a const generic parameter
30+
--> $DIR/const-param-type-depends-on-const-param.rs:15:35
31+
|
32+
LL | pub struct SelfDependent<const N: [u8; N]>;
33+
| ^^^^^^^
34+
|
35+
= note: the only supported types are integers, `bool`, and `char`
36+
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
37+
|
38+
LL + #![feature(adt_const_params)]
39+
|
40+
41+
error: aborting due to 4 previous errors
1842

1943
For more information about this error, try `rustc --explain E0770`.

tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ error[E0741]: using function pointers as const generic parameters is forbidden
44
LL | struct Checked<const F: fn(usize) -> bool>;
55
| ^^^^^^^^^^^^^^^^^
66

7-
error: aborting due to 1 previous error
7+
error[E0308]: mismatched types
8+
--> $DIR/fn-const-param-infer.rs:33:25
9+
|
10+
LL | let _ = Checked::<{ generic_arg::<u32> }>;
11+
| ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
12+
|
13+
= note: expected fn pointer `fn(usize) -> _`
14+
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
15+
16+
error[E0282]: type annotations needed
17+
--> $DIR/fn-const-param-infer.rs:35:23
18+
|
19+
LL | let _ = Checked::<generic>;
20+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
21+
|
22+
help: consider specifying the generic argument
23+
|
24+
LL | let _ = Checked::<generic::<T>>;
25+
| +++++
26+
27+
error: aborting due to 3 previous errors
828

9-
For more information about this error, try `rustc --explain E0741`.
29+
Some errors have detailed explanations: E0282, E0308, E0741.
30+
For more information about an error, try `rustc --explain E0282`.

tests/ui/const-generics/fn-const-param-infer.full.stderr

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ error[E0741]: using function pointers as const generic parameters is forbidden
44
LL | struct Checked<const F: fn(usize) -> bool>;
55
| ^^^^^^^^^^^^^^^^^
66

7-
error: aborting due to 1 previous error
7+
error[E0308]: mismatched types
8+
--> $DIR/fn-const-param-infer.rs:33:25
9+
|
10+
LL | let _ = Checked::<{ generic_arg::<u32> }>;
11+
| ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
12+
|
13+
= note: expected fn pointer `fn(usize) -> _`
14+
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
15+
16+
error[E0282]: type annotations needed
17+
--> $DIR/fn-const-param-infer.rs:35:23
18+
|
19+
LL | let _ = Checked::<generic>;
20+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
21+
|
22+
help: consider specifying the generic argument
23+
|
24+
LL | let _ = Checked::<generic::<T>>;
25+
| +++++
26+
27+
error: aborting due to 3 previous errors
828

9-
For more information about this error, try `rustc --explain E0741`.
29+
Some errors have detailed explanations: E0282, E0308, E0741.
30+
For more information about an error, try `rustc --explain E0282`.

tests/ui/const-generics/fn-const-param-infer.min.stderr

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,27 @@ LL | struct Checked<const F: fn(usize) -> bool>;
66
|
77
= note: the only supported types are integers, `bool`, and `char`
88

9-
error: aborting due to 1 previous error
9+
error[E0308]: mismatched types
10+
--> $DIR/fn-const-param-infer.rs:33:25
11+
|
12+
LL | let _ = Checked::<{ generic_arg::<u32> }>;
13+
| ^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
14+
|
15+
= note: expected fn pointer `fn(usize) -> _`
16+
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
17+
18+
error[E0282]: type annotations needed
19+
--> $DIR/fn-const-param-infer.rs:35:23
20+
|
21+
LL | let _ = Checked::<generic>;
22+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
23+
|
24+
help: consider specifying the generic argument
25+
|
26+
LL | let _ = Checked::<generic::<T>>;
27+
| +++++
28+
29+
error: aborting due to 3 previous errors
1030

31+
Some errors have detailed explanations: E0282, E0308.
32+
For more information about an error, try `rustc --explain E0282`.
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
error[E0741]: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
2-
--> $DIR/adt_wf_hang.rs:9:19
1+
error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed`
2+
--> $DIR/adt_wf_hang.rs:11:5
33
|
4-
LL | struct S<const N: U>()
5-
| ^
6-
|
7-
help: add `#[derive(ConstParamTy)]` to the struct
4+
LL | S<{ U }>:;
5+
| ^^^^^^^^
86
|
9-
LL + #[derive(ConstParamTy)]
10-
LL | struct U;
7+
note: required by a bound in `S`
8+
--> $DIR/adt_wf_hang.rs:11:5
119
|
10+
LL | struct S<const N: U>()
11+
| - required by a bound in this struct
12+
LL | where
13+
LL | S<{ U }>:;
14+
| ^^^^^^^^ required by this bound in `S`
1215

1316
error: aborting due to 1 previous error
1417

15-
For more information about this error, try `rustc --explain E0741`.
18+
For more information about this error, try `rustc --explain E0275`.

0 commit comments

Comments
 (0)