Skip to content

Commit 5337e0d

Browse files
committed
Allow using named consts in pattern types
1 parent 59fce27 commit 5337e0d

File tree

9 files changed

+184
-49
lines changed

9 files changed

+184
-49
lines changed

compiler/rustc_ast_lowering/src/pat.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -441,16 +441,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
441441
match &pattern.kind {
442442
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
443443
let mut lower_expr = |e: &Expr| -> &_ {
444-
let kind = if let ExprKind::Path(qself, path) = &e.kind {
445-
hir::ConstArgKind::Path(self.lower_qpath(
446-
e.id,
447-
qself,
448-
path,
449-
ParamMode::Optional,
450-
AllowReturnTypeNotation::No,
451-
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
452-
None,
453-
))
444+
if let ExprKind::Path(None, path) = &e.kind
445+
&& let Some(res) = self
446+
.resolver
447+
.get_partial_res(e.id)
448+
.and_then(|partial_res| partial_res.full_res())
449+
{
450+
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
454451
} else {
455452
let node_id = self.next_node_id();
456453
let def_id = self.create_def(
@@ -467,9 +464,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
467464
body: self.lower_const_body(pattern.span, Some(e)),
468465
span: self.lower_span(pattern.span),
469466
});
470-
hir::ConstArgKind::Anon(ac)
471-
};
472-
self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind })
467+
self.arena.alloc(hir::ConstArg {
468+
hir_id: self.next_id(),
469+
kind: hir::ConstArgKind::Anon(ac),
470+
})
471+
}
473472
};
474473
break hir::TyPatKind::Range(
475474
e1.as_deref().map(|e| lower_expr(e)),

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
198198
{
199199
Some(parent_did)
200200
}
201+
Node::TyPat(_) => Some(parent_did),
201202
_ => None,
202203
}
203204
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error: constant expression depends on a generic parameter
2+
--> $DIR/assoc_const.rs:17:19
3+
|
4+
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this may fail depending on what value the parameter takes
8+
9+
error: constant expression depends on a generic parameter
10+
--> $DIR/assoc_const.rs:17:19
11+
|
12+
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
|
15+
= note: this may fail depending on what value the parameter takes
16+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
17+
18+
error: constant expression depends on a generic parameter
19+
--> $DIR/assoc_const.rs:20:19
20+
|
21+
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
|
24+
= note: this may fail depending on what value the parameter takes
25+
26+
error: constant expression depends on a generic parameter
27+
--> $DIR/assoc_const.rs:20:19
28+
|
29+
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
|
32+
= note: this may fail depending on what value the parameter takes
33+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
34+
35+
error: aborting due to 4 previous errors
36+
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(pattern_types)]
2+
#![feature(pattern_type_macro)]
3+
#![cfg_attr(const_arg, feature(generic_const_exprs))]
4+
#![expect(incomplete_features)]
5+
6+
//@ revisions: default const_arg
7+
8+
//@[const_arg] check-pass
9+
10+
use std::pat::pattern_type;
11+
12+
trait Foo {
13+
const START: u32;
14+
const END: u32;
15+
}
16+
17+
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
18+
//[default]~^ ERROR: constant expression depends on a generic parameter
19+
//[default]~| ERROR: constant expression depends on a generic parameter
20+
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
21+
//[default]~^ ERROR: constant expression depends on a generic parameter
22+
//[default]~| ERROR: constant expression depends on a generic parameter
23+
24+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
//@known-bug: #127972
2+
//@ failure-status: 101
3+
//@ normalize-stderr: "note: .*\n\n" -> ""
4+
//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
5+
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
6+
//@ rustc-env:RUST_BACKTRACE=0
7+
18
#![feature(pattern_types, pattern_type_macro)]
29
#![allow(internal_features)]
310

411
type Pat<const START: u32, const END: u32> =
512
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
6-
//~^ ERROR type and const arguments are not allowed on const parameter `START`
7-
//~| ERROR generic arguments are not allowed on const parameter `END`
8-
//~| ERROR associated item constraints are not allowed here
913

1014
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,14 @@
1-
error[E0109]: type and const arguments are not allowed on const parameter `START`
2-
--> $DIR/bad_const_generics_args_on_const_param.rs:5:44
1+
error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
2+
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
33
|
44
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
5-
| ----- ^^ ^^^ ^ type and const arguments not allowed
6-
| |
7-
| not allowed on const parameter `START`
8-
|
9-
note: const parameter `START` defined here
10-
--> $DIR/bad_const_generics_args_on_const_param.rs:4:16
11-
|
12-
LL | type Pat<const START: u32, const END: u32> =
13-
| ^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^
146

15-
error[E0109]: generic arguments are not allowed on const parameter `END`
16-
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
17-
|
18-
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
19-
| --- ^ generic argument not allowed
20-
| |
21-
| not allowed on const parameter `END`
22-
|
23-
note: const parameter `END` defined here
24-
--> $DIR/bad_const_generics_args_on_const_param.rs:4:34
25-
|
26-
LL | type Pat<const START: u32, const END: u32> =
27-
| ^^^
28-
29-
error[E0229]: associated item constraints are not allowed here
30-
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
31-
|
32-
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
33-
| ^^^^^^^^^^ associated item constraint not allowed here
347

35-
error: aborting due to 3 previous errors
8+
Box<dyn Any>
9+
query stack during panic:
10+
#0 [type_of] expanding type alias `Pat`
11+
#1 [check_well_formed] checking that `Pat` is well-formed
12+
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
13+
error: aborting due to 1 previous error
3614

37-
Some errors have detailed explanations: E0109, E0229.
38-
For more information about an error, try `rustc --explain E0109`.
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(pattern_types)]
2+
#![feature(pattern_type_macro)]
3+
#![feature(inline_const_pat)]
4+
5+
use std::pat::pattern_type;
6+
7+
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
8+
//~^ ERROR: cycle
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
error[E0391]: cycle detected when evaluating type-level constant
2+
--> $DIR/const_block.rs:7:36
3+
|
4+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
5+
| ^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `bar::{constant#2}`...
8+
--> $DIR/const_block.rs:7:36
9+
|
10+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
11+
| ^^^^^^^^^^^^^^
12+
note: ...which requires caching mir of `bar::{constant#2}` for CTFE...
13+
--> $DIR/const_block.rs:7:36
14+
|
15+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
16+
| ^^^^^^^^^^^^^^
17+
note: ...which requires elaborating drops for `bar::{constant#2}`...
18+
--> $DIR/const_block.rs:7:36
19+
|
20+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
21+
| ^^^^^^^^^^^^^^
22+
note: ...which requires borrow-checking `bar::{constant#2}`...
23+
--> $DIR/const_block.rs:7:36
24+
|
25+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
26+
| ^^^^^^^^^^^^^^
27+
note: ...which requires borrow-checking `bar::{constant#0}`...
28+
--> $DIR/const_block.rs:7:41
29+
|
30+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
31+
| ^^^^^^^^^
32+
note: ...which requires promoting constants in MIR for `bar::{constant#0}`...
33+
--> $DIR/const_block.rs:7:41
34+
|
35+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
36+
| ^^^^^^^^^
37+
note: ...which requires const checking `bar::{constant#0}`...
38+
--> $DIR/const_block.rs:7:41
39+
|
40+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
41+
| ^^^^^^^^^
42+
note: ...which requires building MIR for `bar::{constant#0}`...
43+
--> $DIR/const_block.rs:7:41
44+
|
45+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
46+
| ^^^^^^^^^
47+
note: ...which requires match-checking `bar::{constant#0}`...
48+
--> $DIR/const_block.rs:7:41
49+
|
50+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
51+
| ^^^^^^^^^
52+
note: ...which requires type-checking `bar::{constant#0}`...
53+
--> $DIR/const_block.rs:7:41
54+
|
55+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
56+
| ^^^^^^^^^
57+
note: ...which requires type-checking `bar`...
58+
--> $DIR/const_block.rs:7:1
59+
|
60+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
62+
= note: ...which again requires evaluating type-level constant, completing the cycle
63+
note: cycle used when checking that `bar` is well-formed
64+
--> $DIR/const_block.rs:7:1
65+
|
66+
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
69+
70+
error: aborting due to 1 previous error
71+
72+
For more information about this error, try `rustc --explain E0391`.
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ check-pass
2+
3+
#![feature(pattern_types)]
4+
#![feature(pattern_type_macro)]
5+
6+
use std::pat::pattern_type;
7+
8+
const START: u32 = 0;
9+
const END: u32 = 10;
10+
11+
fn foo(_: pattern_type!(u32 is START..=END)) {}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)