mirror of https://github.com/rust-lang/rust.git
Disallow guards on never patterns
This commit is contained in:
parent
a2dcb3a6d9
commit
06a8ed10b6
|
@ -108,6 +108,10 @@ ast_lowering_misplaced_impl_trait =
|
||||||
ast_lowering_misplaced_relax_trait_bound =
|
ast_lowering_misplaced_relax_trait_bound =
|
||||||
`?Trait` bounds are only permitted at the point where a type parameter is declared
|
`?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||||
|
|
||||||
|
ast_lowering_never_pattern_with_guard =
|
||||||
|
a guard on a never pattern will never be run
|
||||||
|
.suggestion = remove this guard
|
||||||
|
|
||||||
ast_lowering_not_supported_for_lifetime_binder_async_closure =
|
ast_lowering_not_supported_for_lifetime_binder_async_closure =
|
||||||
`for<...>` binders on `async` closures are not currently supported
|
`for<...>` binders on `async` closures are not currently supported
|
||||||
|
|
||||||
|
|
|
@ -349,6 +349,14 @@ pub struct MatchArmWithNoBody {
|
||||||
pub suggestion: Span,
|
pub suggestion: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(ast_lowering_never_pattern_with_guard)]
|
||||||
|
pub struct NeverPatternWithGuard {
|
||||||
|
#[primary_span]
|
||||||
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic, Clone, Copy)]
|
#[derive(Diagnostic, Clone, Copy)]
|
||||||
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
|
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
|
||||||
pub struct ArbitraryExpressionInPattern {
|
pub struct ArbitraryExpressionInPattern {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::errors::{
|
||||||
AsyncCoroutinesNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
|
AsyncCoroutinesNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
|
||||||
BaseExpressionDoubleDot, ClosureCannotBeStatic, CoroutineTooManyParameters,
|
BaseExpressionDoubleDot, ClosureCannotBeStatic, CoroutineTooManyParameters,
|
||||||
FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd, MatchArmWithNoBody,
|
FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd, MatchArmWithNoBody,
|
||||||
NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign,
|
NeverPatternWithGuard, NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign,
|
||||||
};
|
};
|
||||||
use super::ResolverAstLoweringExt;
|
use super::ResolverAstLoweringExt;
|
||||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
||||||
|
@ -550,7 +550,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
|
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
|
||||||
let pat = self.lower_pat(&arm.pat);
|
let pat = self.lower_pat(&arm.pat);
|
||||||
let guard = arm.guard.as_ref().map(|cond| {
|
let mut guard = arm.guard.as_ref().map(|cond| {
|
||||||
if let ExprKind::Let(pat, scrutinee, span, is_recovered) = &cond.kind {
|
if let ExprKind::Let(pat, scrutinee, span, is_recovered) = &cond.kind {
|
||||||
hir::Guard::IfLet(self.arena.alloc(hir::Let {
|
hir::Guard::IfLet(self.arena.alloc(hir::Let {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
|
@ -575,6 +575,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.emit_err(MatchArmWithNoBody { span, suggestion: span.shrink_to_hi() });
|
.emit_err(MatchArmWithNoBody { span, suggestion: span.shrink_to_hi() });
|
||||||
|
} else if let Some(g) = &arm.guard {
|
||||||
|
self.tcx.sess.emit_err(NeverPatternWithGuard { span: g.span });
|
||||||
|
guard = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An arm without a body, meant for never patterns.
|
// An arm without a body, meant for never patterns.
|
||||||
|
|
|
@ -15,12 +15,11 @@ fn no_arms_or_guards(x: Void) {
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match None::<Void> {
|
match None::<Void> {
|
||||||
//~^ ERROR non-exhaustive
|
|
||||||
Some(!) if true,
|
Some(!) if true,
|
||||||
|
//~^ ERROR guard on a never pattern
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match None::<Void> {
|
match None::<Void> {
|
||||||
//~^ ERROR non-exhaustive
|
|
||||||
Some(!) if true => {}
|
Some(!) if true => {}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,8 @@
|
||||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
error: a guard on a never pattern will never be run
|
||||||
--> $DIR/check.rs:17:11
|
--> $DIR/check.rs:18:20
|
||||||
|
|
|
||||||
LL | match None::<Void> {
|
|
||||||
| ^^^^^^^^^^^^ pattern `Some(_)` not covered
|
|
||||||
|
|
|
||||||
note: `Option<Void>` defined here
|
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
|
||||||
::: $SRC_DIR/core/src/option.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: not covered
|
|
||||||
= note: the matched value is of type `Option<Void>`
|
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
|
||||||
|
|
|
||||||
LL ~ None => {},
|
|
||||||
LL + Some(_) => todo!()
|
|
||||||
|
|
|
|
||||||
|
LL | Some(!) if true,
|
||||||
|
| ^^^^ help: remove this guard
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/check.rs:22:11
|
|
||||||
|
|
|
||||||
LL | match None::<Void> {
|
|
||||||
| ^^^^^^^^^^^^ pattern `Some(_)` not covered
|
|
||||||
|
|
|
||||||
note: `Option<Void>` defined here
|
|
||||||
--> $SRC_DIR/core/src/option.rs:LL:COL
|
|
||||||
::: $SRC_DIR/core/src/option.rs:LL:COL
|
|
||||||
|
|
|
||||||
= note: not covered
|
|
||||||
= note: the matched value is of type `Option<Void>`
|
|
||||||
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
|
||||||
|
|
|
||||||
LL ~ None => {},
|
|
||||||
LL + Some(_) => todo!()
|
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0004`.
|
|
||||||
|
|
|
@ -30,10 +30,12 @@ fn parse(x: Void) {
|
||||||
match None::<Void> {
|
match None::<Void> {
|
||||||
Some(!) if true
|
Some(!) if true
|
||||||
//~^ ERROR expected `,` following `match` arm
|
//~^ ERROR expected `,` following `match` arm
|
||||||
|
//~| ERROR guard on a never pattern
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match None::<Void> {
|
match None::<Void> {
|
||||||
Some(!) if true,
|
Some(!) if true,
|
||||||
|
//~^ ERROR guard on a never pattern
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match None::<Void> {
|
match None::<Void> {
|
||||||
|
@ -45,6 +47,7 @@ fn parse(x: Void) {
|
||||||
}
|
}
|
||||||
match x {
|
match x {
|
||||||
never!() if true,
|
never!() if true,
|
||||||
|
//~^ ERROR guard on a never pattern
|
||||||
}
|
}
|
||||||
match x {
|
match x {
|
||||||
never!()
|
never!()
|
||||||
|
|
|
@ -11,16 +11,34 @@ LL | Some(!) if true
|
||||||
| ^ help: missing a comma here to end this `match` arm: `,`
|
| ^ help: missing a comma here to end this `match` arm: `,`
|
||||||
|
|
||||||
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `<=`
|
error: expected one of `,`, `=>`, `if`, `|`, or `}`, found `<=`
|
||||||
--> $DIR/parse.rs:40:17
|
--> $DIR/parse.rs:42:17
|
||||||
|
|
|
|
||||||
LL | Some(!) <=
|
LL | Some(!) <=
|
||||||
| ^^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
| ^^ expected one of `,`, `=>`, `if`, `|`, or `}`
|
||||||
|
|
||||||
error: top-level or-patterns are not allowed in `let` bindings
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
--> $DIR/parse.rs:64:9
|
--> $DIR/parse.rs:67:9
|
||||||
|
|
|
|
||||||
LL | let Ok(_) | Err(!) = &res; // Disallowed; see #82048.
|
LL | let Ok(_) | Err(!) = &res; // Disallowed; see #82048.
|
||||||
| ^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(Ok(_) | Err(!))`
|
| ^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(Ok(_) | Err(!))`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: a guard on a never pattern will never be run
|
||||||
|
--> $DIR/parse.rs:31:20
|
||||||
|
|
|
||||||
|
LL | Some(!) if true
|
||||||
|
| ^^^^ help: remove this guard
|
||||||
|
|
||||||
|
error: a guard on a never pattern will never be run
|
||||||
|
--> $DIR/parse.rs:37:20
|
||||||
|
|
|
||||||
|
LL | Some(!) if true,
|
||||||
|
| ^^^^ help: remove this guard
|
||||||
|
|
||||||
|
error: a guard on a never pattern will never be run
|
||||||
|
--> $DIR/parse.rs:49:21
|
||||||
|
|
|
||||||
|
LL | never!() if true,
|
||||||
|
| ^^^^ help: remove this guard
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue