Allow using named consts in pattern types
This commit is contained in:
parent
f0308938ba
commit
fbcaa9b0a1
9 changed files with 186 additions and 56 deletions
|
|
@ -440,17 +440,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let node = loop {
|
||||
match &pattern.kind {
|
||||
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
||||
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
|
||||
// That requires first modifying the AST to have const args here.
|
||||
let mut lower_expr = |e: &Expr| -> &_ {
|
||||
let kind = if let ExprKind::Path(qself, path) = &e.kind {
|
||||
hir::ConstArgKind::Path(self.lower_qpath(
|
||||
e.id,
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
))
|
||||
if let ExprKind::Path(None, path) = &e.kind
|
||||
&& let Some(res) = self
|
||||
.resolver
|
||||
.get_partial_res(e.id)
|
||||
.and_then(|partial_res| partial_res.full_res())
|
||||
{
|
||||
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
|
||||
} else {
|
||||
let node_id = self.next_node_id();
|
||||
let def_id = self.create_def(
|
||||
|
|
@ -467,9 +466,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
body: self.lower_const_body(pattern.span, Some(e)),
|
||||
span: self.lower_span(pattern.span),
|
||||
});
|
||||
hir::ConstArgKind::Anon(ac)
|
||||
};
|
||||
self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind })
|
||||
self.arena.alloc(hir::ConstArg {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ConstArgKind::Anon(ac),
|
||||
})
|
||||
}
|
||||
};
|
||||
break hir::TyPatKind::Range(
|
||||
e1.as_deref().map(|e| lower_expr(e)),
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
{
|
||||
Some(parent_did)
|
||||
}
|
||||
Node::TyPat(_) => Some(parent_did),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/assoc_const.rs:17:19
|
||||
|
|
||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/assoc_const.rs:17:19
|
||||
|
|
||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/assoc_const.rs:20:19
|
||||
|
|
||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/assoc_const.rs:20:19
|
||||
|
|
||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#![feature(pattern_types)]
|
||||
#![feature(pattern_type_macro)]
|
||||
#![cfg_attr(const_arg, feature(generic_const_exprs))]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
//@ revisions: default const_arg
|
||||
|
||||
//@[const_arg] check-pass
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
trait Foo {
|
||||
const START: u32;
|
||||
const END: u32;
|
||||
}
|
||||
|
||||
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
//@known-bug: #127972
|
||||
//@ failure-status: 101
|
||||
//@ normalize-stderr: "note: .*\n\n" -> ""
|
||||
//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
|
||||
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||
//@ rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
#![feature(pattern_types, pattern_type_macro)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
type Pat<const START: u32, const END: u32> =
|
||||
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
||||
//~| ERROR generic arguments are not allowed on const parameter `END`
|
||||
//~| ERROR associated item constraints are not allowed here
|
||||
//~| ERROR `_` is not allowed within types on item signatures for type aliases
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,14 @@
|
|||
error[E0109]: type and const arguments are not allowed on const parameter `START`
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:44
|
||||
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
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
|
||||
|
|
||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||
| ----- ^^ ^^^ ^ type and const arguments not allowed
|
||||
| |
|
||||
| not allowed on const parameter `START`
|
||||
|
|
||||
note: const parameter `START` defined here
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:16
|
||||
|
|
||||
LL | type Pat<const START: u32, const END: u32> =
|
||||
| ^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0109]: generic arguments are not allowed on const parameter `END`
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
|
||||
|
|
||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||
| --- ^ generic argument not allowed
|
||||
| |
|
||||
| not allowed on const parameter `END`
|
||||
|
|
||||
note: const parameter `END` defined here
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:34
|
||||
|
|
||||
LL | type Pat<const START: u32, const END: u32> =
|
||||
| ^^^
|
||||
|
||||
error[E0229]: associated item constraints are not allowed here
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
|
||||
|
|
||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||
| ^^^^^^^^^^ associated item constraint not allowed here
|
||||
Box<dyn Any>
|
||||
query stack during panic:
|
||||
#0 [type_of] expanding type alias `Pat`
|
||||
#1 [check_well_formed] checking that `Pat` is well-formed
|
||||
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases
|
||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
|
||||
|
|
||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||
| ^ not allowed in type signatures
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0109, E0121, E0229.
|
||||
For more information about an error, try `rustc --explain E0109`.
|
||||
|
|
|
|||
10
tests/ui/type/pattern_types/const_block.rs
Normal file
10
tests/ui/type/pattern_types/const_block.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#![feature(pattern_types)]
|
||||
#![feature(pattern_type_macro)]
|
||||
#![feature(inline_const_pat)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
//~^ ERROR: cycle
|
||||
|
||||
fn main() {}
|
||||
72
tests/ui/type/pattern_types/const_block.stderr
Normal file
72
tests/ui/type/pattern_types/const_block.stderr
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
error[E0391]: cycle detected when evaluating type-level constant
|
||||
--> $DIR/const_block.rs:7:36
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires const-evaluating + checking `bar::{constant#2}`...
|
||||
--> $DIR/const_block.rs:7:36
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: ...which requires caching mir of `bar::{constant#2}` for CTFE...
|
||||
--> $DIR/const_block.rs:7:36
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: ...which requires elaborating drops for `bar::{constant#2}`...
|
||||
--> $DIR/const_block.rs:7:36
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: ...which requires borrow-checking `bar::{constant#2}`...
|
||||
--> $DIR/const_block.rs:7:36
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: ...which requires borrow-checking `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires promoting constants in MIR for `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires const checking `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires building MIR for `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires match-checking `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires type-checking `bar::{constant#0}`...
|
||||
--> $DIR/const_block.rs:7:41
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^
|
||||
note: ...which requires type-checking `bar`...
|
||||
--> $DIR/const_block.rs:7:1
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires evaluating type-level constant, completing the cycle
|
||||
note: cycle used when checking that `bar` is well-formed
|
||||
--> $DIR/const_block.rs:7:1
|
||||
|
|
||||
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= 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
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
13
tests/ui/type/pattern_types/free_const.rs
Normal file
13
tests/ui/type/pattern_types/free_const.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(pattern_types)]
|
||||
#![feature(pattern_type_macro)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
const START: u32 = 0;
|
||||
const END: u32 = 10;
|
||||
|
||||
fn foo(_: pattern_type!(u32 is START..=END)) {}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue