Maintain a list of types permitted per pattern
This commit is contained in:
parent
ded0836c18
commit
7e4ccc2f12
10 changed files with 211 additions and 2 deletions
|
@ -234,6 +234,9 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
|
||||||
.help = consider moving this inherent impl into the crate defining the type if possible
|
.help = consider moving this inherent impl into the crate defining the type if possible
|
||||||
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
|
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
|
||||||
|
|
||||||
|
hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
|
||||||
|
.note = range patterns only support integers
|
||||||
|
|
||||||
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
|
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
|
||||||
.note = type of `self` must not be a method generic parameter type
|
.note = type of `self` must not be a method generic parameter type
|
||||||
|
|
||||||
|
@ -438,7 +441,6 @@ hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pat
|
||||||
.label = this type is the same as the inner type without a pattern
|
.label = this type is the same as the inner type without a pattern
|
||||||
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
||||||
.label = not allowed in type signatures
|
.label = not allowed in type signatures
|
||||||
|
|
||||||
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
||||||
.label = `Self` is not a generic argument, but an alias to the type of the {$what}
|
.label = `Self` is not a generic argument, but an alias to the type of the {$what}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use rustc_macros::Diagnostic;
|
use rustc_macros::Diagnostic;
|
||||||
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -7,3 +8,14 @@ pub(crate) struct WildPatTy {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_invalid_base_type)]
|
||||||
|
pub(crate) struct InvalidBaseType<'tcx> {
|
||||||
|
pub ty: Ty<'tcx>,
|
||||||
|
#[primary_span]
|
||||||
|
pub ty_span: Span,
|
||||||
|
pub pat: &'static str,
|
||||||
|
#[note]
|
||||||
|
pub pat_span: Span,
|
||||||
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::check::check_abi_fn_ptr;
|
use crate::check::check_abi_fn_ptr;
|
||||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
|
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, WildPatTy};
|
||||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
||||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||||
use crate::middle::resolve_bound_vars as rbv;
|
use crate::middle::resolve_bound_vars as rbv;
|
||||||
|
@ -2432,6 +2432,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
self.ty_infer(None, hir_ty.span)
|
self.ty_infer(None, hir_ty.span)
|
||||||
}
|
}
|
||||||
hir::TyKind::Pat(ty, pat) => {
|
hir::TyKind::Pat(ty, pat) => {
|
||||||
|
let ty_span = ty.span;
|
||||||
let ty = self.lower_ty(ty);
|
let ty = self.lower_ty(ty);
|
||||||
let pat_ty = match pat.kind {
|
let pat_ty = match pat.kind {
|
||||||
hir::PatKind::Wild => {
|
hir::PatKind::Wild => {
|
||||||
|
@ -2439,6 +2440,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
Ty::new_error(tcx, err)
|
Ty::new_error(tcx, err)
|
||||||
}
|
}
|
||||||
hir::PatKind::Range(start, end, include_end) => {
|
hir::PatKind::Range(start, end, include_end) => {
|
||||||
|
let ty = match ty.kind() {
|
||||||
|
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
||||||
|
_ => Ty::new_error(
|
||||||
|
tcx,
|
||||||
|
self.dcx().emit_err(InvalidBaseType {
|
||||||
|
ty,
|
||||||
|
pat: "range",
|
||||||
|
ty_span,
|
||||||
|
pat_span: pat.span,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
};
|
||||||
let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
|
let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
|
||||||
let (c, c_ty) = match expr.kind {
|
let (c, c_ty) = match expr.kind {
|
||||||
hir::PatExprKind::Lit { lit, negated } => {
|
hir::PatExprKind::Lit { lit, negated } => {
|
||||||
|
|
12
tests/ui/type/pattern_types/chars.rs
Normal file
12
tests/ui/type/pattern_types/chars.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
//! Check that chars can be used in ranges
|
||||||
|
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
const LOWERCASE: pattern_type!(char is 'a'..='z') = unsafe { std::mem::transmute('b') };
|
||||||
|
|
||||||
|
fn main() {}
|
26
tests/ui/type/pattern_types/nested.rs
Normal file
26
tests/ui/type/pattern_types/nested.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//! Check that pattern types can only have specific base types
|
||||||
|
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
// Undoing an inner pattern type's restrictions should either be forbidden,
|
||||||
|
// or still validate correctly.
|
||||||
|
const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||||
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
||||||
|
// We want to get the most narrowest version that a pattern could be
|
||||||
|
const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
||||||
|
const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||||
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
||||||
|
const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
||||||
|
const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
||||||
|
fn main() {}
|
62
tests/ui/type/pattern_types/nested.stderr
Normal file
62
tests/ui/type/pattern_types/nested.stderr
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
error: `(u32) is 1..=` is not a valid base type for range patterns
|
||||||
|
--> $DIR/nested.rs:10:34
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: range patterns only support integers
|
||||||
|
--> $DIR/nested.rs:10:63
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||||
|
--> $DIR/nested.rs:14:35
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: range patterns only support integers
|
||||||
|
--> $DIR/nested.rs:14:64
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||||
|
--> $DIR/nested.rs:17:35
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: range patterns only support integers
|
||||||
|
--> $DIR/nested.rs:17:64
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: `()` is not a valid base type for range patterns
|
||||||
|
--> $DIR/nested.rs:20:35
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
note: range patterns only support integers
|
||||||
|
--> $DIR/nested.rs:20:41
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: `f32` is not a valid base type for range patterns
|
||||||
|
--> $DIR/nested.rs:23:35
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
note: range patterns only support integers
|
||||||
|
--> $DIR/nested.rs:23:42
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
20
tests/ui/type/pattern_types/pattern_type_mismatch.rs
Normal file
20
tests/ui/type/pattern_types/pattern_type_mismatch.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//! Check that pattern types patterns must be of the type of the base type
|
||||||
|
|
||||||
|
//@ known-bug: unknown
|
||||||
|
//@ 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: "
|
||||||
|
//@ normalize-stderr: "(delayed at compiler/rustc_mir_transform/src/lib.rs:)\d+:\d+" -> "$1:LL:CC"
|
||||||
|
//@ rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
|
|
||||||
|
const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
|
|
||||||
|
fn main() {}
|
31
tests/ui/type/pattern_types/pattern_type_mismatch.stderr
Normal file
31
tests/ui/type/pattern_types/pattern_type_mismatch.stderr
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
error: internal compiler error: ty::ConstKind::Error constructed but no error reported
|
||||||
|
|
|
||||||
|
= error: internal compiler error: ty::ConstKind::Error constructed but no error reported
|
||||||
|
|
|
||||||
|
= note: delayed at compiler/rustc_mir_build/src/thir/constant.rs:72:21 - disabled backtrace
|
||||||
|
= error: internal compiler error: mir_const_qualif: MIR had errors
|
||||||
|
--> $DIR/pattern_type_mismatch.rs:16:1
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: delayed at compiler/rustc_mir_transform/src/lib.rs::LL:CC - disabled backtrace
|
||||||
|
--> $DIR/pattern_type_mismatch.rs:16:1
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: internal compiler error: mir_const_qualif: MIR had errors
|
||||||
|
--> $DIR/pattern_type_mismatch.rs:18:1
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: delayed at compiler/rustc_mir_transform/src/lib.rs::LL:CC - disabled backtrace
|
||||||
|
--> $DIR/pattern_type_mismatch.rs:18:1
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
query stack during panic:
|
||||||
|
end of query stack
|
14
tests/ui/type/pattern_types/reverse_range.rs
Normal file
14
tests/ui/type/pattern_types/reverse_range.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//! Check that the range start must be smaller than the range end
|
||||||
|
//@ known-bug: unknown
|
||||||
|
//@ 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)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
|
17
tests/ui/type/pattern_types/reverse_range.stderr
Normal file
17
tests/ui/type/pattern_types/reverse_range.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0601]: `main` function not found in crate `reverse_range`
|
||||||
|
--> $DIR/reverse_range.rs:14:78
|
||||||
|
|
|
||||||
|
LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
|
||||||
|
| ^ consider adding a `main` function to `$DIR/reverse_range.rs`
|
||||||
|
|
||||||
|
|
||||||
|
assertion failed: end <= max_value
|
||||||
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
|
query stack during panic:
|
||||||
|
#0 [eval_to_allocation_raw] const-evaluating + checking `NONE`
|
||||||
|
#1 [eval_to_const_value_raw] simplifying constant for the type system `NONE`
|
||||||
|
... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0601`.
|
Loading…
Add table
Add a link
Reference in a new issue