use pat<no_top_alt> for patterns in let bindings
This commit is contained in:
parent
5233edcf1c
commit
e64138c534
36 changed files with 602 additions and 357 deletions
|
@ -847,7 +847,7 @@ impl EarlyLintPass for UnusedParens {
|
||||||
|
|
||||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||||
if let StmtKind::Local(ref local) = s.kind {
|
if let StmtKind::Local(ref local) = s.kind {
|
||||||
self.check_unused_parens_pat(cx, &local.pat, false, false);
|
self.check_unused_parens_pat(cx, &local.pat, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
|
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
|
||||||
|
|
|
@ -1757,8 +1757,9 @@ impl<'a> Parser<'a> {
|
||||||
let (pat, ty) = if is_name_required || this.is_named_param() {
|
let (pat, ty) = if is_name_required || this.is_named_param() {
|
||||||
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
|
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
|
||||||
|
|
||||||
let pat = this.parse_fn_param_pat()?;
|
let (pat, colon) = this.parse_fn_param_pat_colon()?;
|
||||||
if let Err(mut err) = this.expect(&token::Colon) {
|
if !colon {
|
||||||
|
let mut err = this.unexpected::<()>().unwrap_err();
|
||||||
return if let Some(ident) =
|
return if let Some(ident) =
|
||||||
this.parameter_without_type(&mut err, pat, is_name_required, first_param)
|
this.parameter_without_type(&mut err, pat, is_name_required, first_param)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,18 @@ pub enum RecoverComma {
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The result of `eat_or_separator`. We want to distinguish which case we are in to avoid
|
||||||
|
/// emitting duplicate diagnostics.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum EatOrResult {
|
||||||
|
/// We recovered from a trailing vert.
|
||||||
|
TrailingVert,
|
||||||
|
/// We ate an `|` (or `||` and recovered).
|
||||||
|
AteOr,
|
||||||
|
/// We did not eat anything (i.e. the current token is not `|` or `||`).
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
/// Parses a pattern.
|
/// Parses a pattern.
|
||||||
///
|
///
|
||||||
|
@ -55,9 +67,26 @@ impl<'a> Parser<'a> {
|
||||||
gate_or: GateOr,
|
gate_or: GateOr,
|
||||||
rc: RecoverComma,
|
rc: RecoverComma,
|
||||||
) -> PResult<'a, P<Pat>> {
|
) -> PResult<'a, P<Pat>> {
|
||||||
|
self.parse_pat_allow_top_alt_inner(expected, gate_or, rc).map(|(pat, _)| pat)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
|
||||||
|
/// recovered).
|
||||||
|
fn parse_pat_allow_top_alt_inner(
|
||||||
|
&mut self,
|
||||||
|
expected: Expected,
|
||||||
|
gate_or: GateOr,
|
||||||
|
rc: RecoverComma,
|
||||||
|
) -> PResult<'a, (P<Pat>, bool)> {
|
||||||
|
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
|
||||||
|
// suggestions (which bothers rustfix).
|
||||||
|
//
|
||||||
// Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
|
// Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
|
||||||
let leading_vert_span =
|
let (leading_vert_span, mut trailing_vert) = match self.eat_or_separator(None) {
|
||||||
if self.eat_or_separator(None) { Some(self.prev_token.span) } else { None };
|
EatOrResult::AteOr => (Some(self.prev_token.span), false),
|
||||||
|
EatOrResult::TrailingVert => (None, true),
|
||||||
|
EatOrResult::None => (None, false),
|
||||||
|
};
|
||||||
|
|
||||||
// Parse the first pattern (`p_0`).
|
// Parse the first pattern (`p_0`).
|
||||||
let first_pat = self.parse_pat_no_top_alt(expected)?;
|
let first_pat = self.parse_pat_no_top_alt(expected)?;
|
||||||
|
@ -77,16 +106,24 @@ impl<'a> Parser<'a> {
|
||||||
// If there was a leading vert, treat this as an or-pattern. This improves
|
// If there was a leading vert, treat this as an or-pattern. This improves
|
||||||
// diagnostics.
|
// diagnostics.
|
||||||
let span = leading_vert_span.to(self.prev_token.span);
|
let span = leading_vert_span.to(self.prev_token.span);
|
||||||
return Ok(self.mk_pat(span, PatKind::Or(vec![first_pat])));
|
return Ok((self.mk_pat(span, PatKind::Or(vec![first_pat])), trailing_vert));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(first_pat);
|
return Ok((first_pat, trailing_vert));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the patterns `p_1 | ... | p_n` where `n > 0`.
|
// Parse the patterns `p_1 | ... | p_n` where `n > 0`.
|
||||||
let lo = leading_vert_span.unwrap_or(first_pat.span);
|
let lo = leading_vert_span.unwrap_or(first_pat.span);
|
||||||
let mut pats = vec![first_pat];
|
let mut pats = vec![first_pat];
|
||||||
while self.eat_or_separator(Some(lo)) {
|
loop {
|
||||||
|
match self.eat_or_separator(Some(lo)) {
|
||||||
|
EatOrResult::AteOr => {}
|
||||||
|
EatOrResult::None => break,
|
||||||
|
EatOrResult::TrailingVert => {
|
||||||
|
trailing_vert = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| {
|
let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| {
|
||||||
err.span_label(lo, WHILE_PARSING_OR_MSG);
|
err.span_label(lo, WHILE_PARSING_OR_MSG);
|
||||||
err
|
err
|
||||||
|
@ -101,15 +138,63 @@ impl<'a> Parser<'a> {
|
||||||
self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
|
self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
|
Ok((self.mk_pat(or_pattern_span, PatKind::Or(pats)), trailing_vert))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the pattern for a function or function pointer parameter.
|
/// Parse a pattern and (maybe) a `Colon` in positions where a pattern may be followed by a
|
||||||
pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> {
|
/// type annotation (e.g. for `let` bindings or `fn` params).
|
||||||
// We actually do _not_ allow top-level or-patterns in function params, but we use
|
///
|
||||||
// `parse_pat_allow_top_alt` anyway so that we can detect when a user tries to use it. This
|
/// Generally, this corresponds to `pat_no_top_alt` followed by an optional `Colon`. It will
|
||||||
// allows us to print a better error message.
|
/// eat the `Colon` token if one is present.
|
||||||
//
|
///
|
||||||
|
/// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
|
||||||
|
/// otherwise).
|
||||||
|
pub(super) fn parse_pat_before_ty(
|
||||||
|
&mut self,
|
||||||
|
expected: Expected,
|
||||||
|
gate_or: GateOr,
|
||||||
|
rc: RecoverComma,
|
||||||
|
syntax_loc: &str,
|
||||||
|
) -> PResult<'a, (P<Pat>, bool)> {
|
||||||
|
// We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
|
||||||
|
// or-patterns so that we can detect when a user tries to use it. This allows us to print a
|
||||||
|
// better error message.
|
||||||
|
let (pat, trailing_vert) = self.parse_pat_allow_top_alt_inner(expected, gate_or, rc)?;
|
||||||
|
let colon = self.eat(&token::Colon);
|
||||||
|
|
||||||
|
if let PatKind::Or(pats) = &pat.kind {
|
||||||
|
let msg = format!("top-level or-patterns are not allowed in {}", syntax_loc);
|
||||||
|
let (help, fix) = if pats.len() == 1 {
|
||||||
|
// If all we have is a leading vert, then print a special message. This is the case
|
||||||
|
// if `parse_pat_allow_top_alt` returns an or-pattern with one variant.
|
||||||
|
let msg = "remove the `|`";
|
||||||
|
let fix = pprust::pat_to_string(&pat);
|
||||||
|
(msg, fix)
|
||||||
|
} else {
|
||||||
|
let msg = "wrap the pattern in parentheses";
|
||||||
|
let fix = format!("({})", pprust::pat_to_string(&pat));
|
||||||
|
(msg, fix)
|
||||||
|
};
|
||||||
|
|
||||||
|
if trailing_vert {
|
||||||
|
// We already emitted an error and suggestion to remove the trailing vert. Don't
|
||||||
|
// emit again.
|
||||||
|
self.sess.span_diagnostic.delay_span_bug(pat.span, &msg);
|
||||||
|
} else {
|
||||||
|
self.struct_span_err(pat.span, &msg)
|
||||||
|
.span_suggestion(pat.span, help, fix, Applicability::MachineApplicable)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((pat, colon))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse the pattern for a function or function pointer parameter, followed by a colon.
|
||||||
|
///
|
||||||
|
/// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
|
||||||
|
/// otherwise).
|
||||||
|
pub(super) fn parse_fn_param_pat_colon(&mut self) -> PResult<'a, (P<Pat>, bool)> {
|
||||||
// In order to get good UX, we first recover in the case of a leading vert for an illegal
|
// In order to get good UX, we first recover in the case of a leading vert for an illegal
|
||||||
// top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case,
|
// top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case,
|
||||||
// a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that
|
// a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that
|
||||||
|
@ -128,53 +213,28 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
|
|
||||||
let pat = self.parse_pat_allow_top_alt(PARAM_EXPECTED, GateOr::No, RecoverComma::No)?;
|
self.parse_pat_before_ty(
|
||||||
|
PARAM_EXPECTED,
|
||||||
if let PatKind::Or(..) = &pat.kind {
|
GateOr::No,
|
||||||
self.ban_illegal_fn_param_or_pat(&pat);
|
RecoverComma::No,
|
||||||
}
|
"function parameters",
|
||||||
|
)
|
||||||
Ok(pat)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ban `A | B` immediately in a parameter pattern and suggest wrapping in parens.
|
|
||||||
fn ban_illegal_fn_param_or_pat(&self, pat: &Pat) {
|
|
||||||
// If all we have a leading vert, then print a special message. This is the case if
|
|
||||||
// `parse_pat_allow_top_alt` returns an or-pattern with one variant.
|
|
||||||
let (msg, fix) = match &pat.kind {
|
|
||||||
PatKind::Or(pats) if pats.len() == 1 => {
|
|
||||||
let msg = "remove the leading `|`";
|
|
||||||
let fix = pprust::pat_to_string(pat);
|
|
||||||
(msg, fix)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let msg = "wrap the pattern in parentheses";
|
|
||||||
let fix = format!("({})", pprust::pat_to_string(pat));
|
|
||||||
(msg, fix)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.struct_span_err(pat.span, "an or-pattern parameter must be wrapped in parentheses")
|
|
||||||
.span_suggestion(pat.span, msg, fix, Applicability::MachineApplicable)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Eat the or-pattern `|` separator.
|
/// Eat the or-pattern `|` separator.
|
||||||
/// If instead a `||` token is encountered, recover and pretend we parsed `|`.
|
/// If instead a `||` token is encountered, recover and pretend we parsed `|`.
|
||||||
fn eat_or_separator(&mut self, lo: Option<Span>) -> bool {
|
fn eat_or_separator(&mut self, lo: Option<Span>) -> EatOrResult {
|
||||||
if self.recover_trailing_vert(lo) {
|
if self.recover_trailing_vert(lo) {
|
||||||
return false;
|
EatOrResult::TrailingVert
|
||||||
}
|
} else if matches!(self.token.kind, token::OrOr) {
|
||||||
|
// Found `||`; Recover and pretend we parsed `|`.
|
||||||
match self.token.kind {
|
self.ban_unexpected_or_or(lo);
|
||||||
token::OrOr => {
|
self.bump();
|
||||||
// Found `||`; Recover and pretend we parsed `|`.
|
EatOrResult::AteOr
|
||||||
self.ban_unexpected_or_or(lo);
|
} else if self.eat(&token::BinOp(token::Or)) {
|
||||||
self.bump();
|
EatOrResult::AteOr
|
||||||
true
|
} else {
|
||||||
}
|
EatOrResult::None
|
||||||
_ => self.eat(&token::BinOp(token::Or)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,14 +250,14 @@ impl<'a> Parser<'a> {
|
||||||
matches!(
|
matches!(
|
||||||
&token.uninterpolate().kind,
|
&token.uninterpolate().kind,
|
||||||
token::FatArrow // e.g. `a | => 0,`.
|
token::FatArrow // e.g. `a | => 0,`.
|
||||||
| token::Ident(kw::If, false) // e.g. `a | if expr`.
|
| token::Ident(kw::If, false) // e.g. `a | if expr`.
|
||||||
| token::Eq // e.g. `let a | = 0`.
|
| token::Eq // e.g. `let a | = 0`.
|
||||||
| token::Semi // e.g. `let a |;`.
|
| token::Semi // e.g. `let a |;`.
|
||||||
| token::Colon // e.g. `let a | :`.
|
| token::Colon // e.g. `let a | :`.
|
||||||
| token::Comma // e.g. `let (a |,)`.
|
| token::Comma // e.g. `let (a |,)`.
|
||||||
| token::CloseDelim(token::Bracket) // e.g. `let [a | ]`.
|
| token::CloseDelim(token::Bracket) // e.g. `let [a | ]`.
|
||||||
| token::CloseDelim(token::Paren) // e.g. `let (a | )`.
|
| token::CloseDelim(token::Paren) // e.g. `let (a | )`.
|
||||||
| token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`.
|
| token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`.
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
match (is_end_ahead, &self.token.kind) {
|
match (is_end_ahead, &self.token.kind) {
|
||||||
|
|
|
@ -13,7 +13,8 @@ use rustc_ast::token::{self, TokenKind};
|
||||||
use rustc_ast::util::classify;
|
use rustc_ast::util::classify;
|
||||||
use rustc_ast::AstLike;
|
use rustc_ast::AstLike;
|
||||||
use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
|
use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
|
||||||
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
|
use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
|
||||||
|
use rustc_ast::{StmtKind, DUMMY_NODE_ID};
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_span::source_map::{BytePos, Span};
|
use rustc_span::source_map::{BytePos, Span};
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
|
@ -220,9 +221,10 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses a local variable declaration.
|
/// Parses a local variable declaration.
|
||||||
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
||||||
let lo = self.prev_token.span;
|
let lo = self.prev_token.span;
|
||||||
let pat = self.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::Yes)?;
|
let (pat, colon) =
|
||||||
|
self.parse_pat_before_ty(None, GateOr::Yes, RecoverComma::Yes, "`let` bindings")?;
|
||||||
|
|
||||||
let (err, ty) = if self.eat(&token::Colon) {
|
let (err, ty) = if colon {
|
||||||
// Save the state of the parser before parsing type normally, in case there is a `:`
|
// Save the state of the parser before parsing type normally, in case there is a `:`
|
||||||
// instead of an `=` typo.
|
// instead of an `=` typo.
|
||||||
let parser_snapshot_before_type = self.clone();
|
let parser_snapshot_before_type = self.clone();
|
||||||
|
|
|
@ -18,10 +18,10 @@ fn main() {
|
||||||
let (A(a, _) | B(a), a) = (A(0, 1), 2);
|
let (A(a, _) | B(a), a) = (A(0, 1), 2);
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
|
|
||||||
let A(a, a) | B(a) = A(0, 1);
|
let (A(a, a) | B(a)) = A(0, 1);
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
|
|
||||||
let B(a) | A(a, a) = A(0, 1);
|
let (B(a) | A(a, a)) = A(0, 1);
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
|
|
||||||
match A(0, 1) {
|
match A(0, 1) {
|
||||||
|
@ -29,17 +29,17 @@ fn main() {
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
|
let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
//~| ERROR identifier `a` is bound more than once in the same pattern
|
//~| ERROR identifier `a` is bound more than once in the same pattern
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
//~| ERROR identifier `a` is bound more than once in the same pattern
|
//~| ERROR identifier `a` is bound more than once in the same pattern
|
||||||
//~| ERROR variable `a` is not bound in all patterns
|
//~| ERROR variable `a` is not bound in all patterns
|
||||||
|
|
||||||
let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
//~^ ERROR identifier `a` is bound more than once in the same pattern
|
||||||
//~| ERROR identifier `a` is bound more than once in the same pattern
|
//~| ERROR identifier `a` is bound more than once in the same pattern
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,16 @@ LL | let (A(a, _) | B(a), a) = (A(0, 1), 2);
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:21:14
|
--> $DIR/already-bound-name.rs:21:15
|
||||||
|
|
|
|
||||||
LL | let A(a, a) | B(a) = A(0, 1);
|
LL | let (A(a, a) | B(a)) = A(0, 1);
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:24:21
|
--> $DIR/already-bound-name.rs:24:22
|
||||||
|
|
|
|
||||||
LL | let B(a) | A(a, a) = A(0, 1);
|
LL | let (B(a) | A(a, a)) = A(0, 1);
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:28:21
|
--> $DIR/already-bound-name.rs:28:21
|
||||||
|
@ -41,55 +41,55 @@ LL | B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:32:36
|
--> $DIR/already-bound-name.rs:32:37
|
||||||
|
|
|
|
||||||
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
|
LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:32:46
|
--> $DIR/already-bound-name.rs:32:47
|
||||||
|
|
|
|
||||||
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
|
LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:37:36
|
--> $DIR/already-bound-name.rs:37:37
|
||||||
|
|
|
|
||||||
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:37:46
|
--> $DIR/already-bound-name.rs:37:47
|
||||||
|
|
|
|
||||||
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/already-bound-name.rs:37:9
|
--> $DIR/already-bound-name.rs:37:10
|
||||||
|
|
|
|
||||||
LL | let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
LL | let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
| ^^^^ pattern doesn't bind `a` - variable not in all patterns
|
| ^^^^ pattern doesn't bind `a` - variable not in all patterns
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:42:49
|
--> $DIR/already-bound-name.rs:42:50
|
||||||
|
|
|
|
||||||
LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
LL | let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0416]: identifier `a` is bound more than once in the same pattern
|
error[E0416]: identifier `a` is bound more than once in the same pattern
|
||||||
--> $DIR/already-bound-name.rs:42:59
|
--> $DIR/already-bound-name.rs:42:60
|
||||||
|
|
|
|
||||||
LL | let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
|
LL | let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
|
||||||
| ^ used in a pattern more than once
|
| ^ used in a pattern more than once
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/already-bound-name.rs:32:31
|
--> $DIR/already-bound-name.rs:32:32
|
||||||
|
|
|
|
||||||
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
|
LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
|
||||||
| - ^ ------- this expression has type `E<E<{integer}>>`
|
| - ^ ------- this expression has type `E<E<{integer}>>`
|
||||||
| | |
|
| | |
|
||||||
| | expected integer, found enum `E`
|
| | expected integer, found enum `E`
|
||||||
| first introduced with type `{integer}` here
|
| first introduced with type `{integer}` here
|
||||||
|
|
|
|
||||||
= note: expected type `{integer}`
|
= note: expected type `{integer}`
|
||||||
found type `E<{integer}>`
|
found type `E<{integer}>`
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// One level:
|
// One level:
|
||||||
let Ok(a) | Err(a) = Ok(0);
|
let (Ok(a) | Err(a)) = Ok(0);
|
||||||
let Ok(ref a) | Err(ref a) = Ok(0);
|
let (Ok(ref a) | Err(ref a)) = Ok(0);
|
||||||
let Ok(ref mut a) | Err(ref mut a) = Ok(0);
|
let (Ok(ref mut a) | Err(ref mut a)) = Ok(0);
|
||||||
|
|
||||||
// Two levels:
|
// Two levels:
|
||||||
enum Tri<S, T, U> {
|
enum Tri<S, T, U> {
|
||||||
|
@ -20,10 +20,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
use Tri::*;
|
use Tri::*;
|
||||||
|
|
||||||
let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))): Result<_, Result<_, _>> =
|
let (Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b)))): Result<_, Result<_, _>> =
|
||||||
Ok((V1(1), 1));
|
Ok((V1(1), 1));
|
||||||
|
|
||||||
let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))): Result<
|
let (Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b)))): Result<
|
||||||
_,
|
_,
|
||||||
Result<_, _>,
|
Result<_, _>,
|
||||||
> = Ok((V1(1), 1));
|
> = Ok((V1(1), 1));
|
||||||
|
|
|
@ -3,28 +3,28 @@
|
||||||
|
|
||||||
const fn foo((Ok(a) | Err(a)): Result<i32, i32>) {
|
const fn foo((Ok(a) | Err(a)): Result<i32, i32>) {
|
||||||
let x = Ok(3);
|
let x = Ok(3);
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
const X: () = {
|
const X: () = {
|
||||||
let x = Ok(3);
|
let x = Ok(3);
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Y: () = {
|
static Y: () = {
|
||||||
let x = Ok(3);
|
let x = Ok(3);
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
};
|
};
|
||||||
|
|
||||||
static mut Z: () = {
|
static mut Z: () = {
|
||||||
let x = Ok(3);
|
let x = Ok(3);
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: [(); {
|
let _: [(); {
|
||||||
let x = Ok(3);
|
let x = Ok(3);
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
2
|
2
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,5 @@ fn main() {}
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn gated_leading_vert_in_let() {
|
fn gated_leading_vert_in_let() {
|
||||||
let | A; //~ ERROR or-patterns syntax is experimental
|
let | A; //~ ERROR or-patterns syntax is experimental
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
|
||||||
|
|
|
||||||
|
LL | let | A;
|
||||||
|
| ^^^ help: remove the `|`: `A`
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
|
--> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
|
||||||
|
|
|
|
||||||
|
@ -7,6 +13,6 @@ LL | let | A;
|
||||||
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
|
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -26,7 +26,9 @@ fn or_patterns() {
|
||||||
// Gated:
|
// Gated:
|
||||||
|
|
||||||
let | A | B; //~ ERROR or-patterns syntax is experimental
|
let | A | B; //~ ERROR or-patterns syntax is experimental
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
let A | B; //~ ERROR or-patterns syntax is experimental
|
let A | B; //~ ERROR or-patterns syntax is experimental
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
|
for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
|
||||||
for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
|
for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
|
||||||
fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
|
fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/feature-gate-or_patterns.rs:28:9
|
||||||
|
|
|
||||||
|
LL | let | A | B;
|
||||||
|
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/feature-gate-or_patterns.rs:30:9
|
||||||
|
|
|
||||||
|
LL | let A | B;
|
||||||
|
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:5:14
|
--> $DIR/feature-gate-or_patterns.rs:5:14
|
||||||
|
|
|
|
||||||
|
@ -17,7 +29,7 @@ LL | let | A | B;
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:29:9
|
--> $DIR/feature-gate-or_patterns.rs:30:9
|
||||||
|
|
|
|
||||||
LL | let A | B;
|
LL | let A | B;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -26,7 +38,7 @@ LL | let A | B;
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:30:9
|
--> $DIR/feature-gate-or_patterns.rs:32:9
|
||||||
|
|
|
|
||||||
LL | for | A | B in 0 {}
|
LL | for | A | B in 0 {}
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -35,7 +47,7 @@ LL | for | A | B in 0 {}
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:31:9
|
--> $DIR/feature-gate-or_patterns.rs:33:9
|
||||||
|
|
|
|
||||||
LL | for A | B in 0 {}
|
LL | for A | B in 0 {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -44,7 +56,7 @@ LL | for A | B in 0 {}
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:32:13
|
--> $DIR/feature-gate-or_patterns.rs:34:13
|
||||||
|
|
|
|
||||||
LL | fn fun((A | B): _) {}
|
LL | fn fun((A | B): _) {}
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -53,7 +65,7 @@ LL | fn fun((A | B): _) {}
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:33:15
|
--> $DIR/feature-gate-or_patterns.rs:35:15
|
||||||
|
|
|
|
||||||
LL | let _ = |(A | B): u8| ();
|
LL | let _ = |(A | B): u8| ();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -62,7 +74,7 @@ LL | let _ = |(A | B): u8| ();
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:34:10
|
--> $DIR/feature-gate-or_patterns.rs:36:10
|
||||||
|
|
|
|
||||||
LL | let (A | B);
|
LL | let (A | B);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -71,7 +83,7 @@ LL | let (A | B);
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:35:10
|
--> $DIR/feature-gate-or_patterns.rs:37:10
|
||||||
|
|
|
|
||||||
LL | let (A | B,);
|
LL | let (A | B,);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -80,7 +92,7 @@ LL | let (A | B,);
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:36:11
|
--> $DIR/feature-gate-or_patterns.rs:38:11
|
||||||
|
|
|
|
||||||
LL | let A(B | C);
|
LL | let A(B | C);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -89,7 +101,7 @@ LL | let A(B | C);
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:37:14
|
--> $DIR/feature-gate-or_patterns.rs:39:14
|
||||||
|
|
|
|
||||||
LL | let E::V(B | C);
|
LL | let E::V(B | C);
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -98,7 +110,7 @@ LL | let E::V(B | C);
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:38:17
|
--> $DIR/feature-gate-or_patterns.rs:40:17
|
||||||
|
|
|
|
||||||
LL | let S { f1: B | C, f2 };
|
LL | let S { f1: B | C, f2 };
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -107,7 +119,7 @@ LL | let S { f1: B | C, f2 };
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:39:20
|
--> $DIR/feature-gate-or_patterns.rs:41:20
|
||||||
|
|
|
|
||||||
LL | let E::V { f1: B | C, f2 };
|
LL | let E::V { f1: B | C, f2 };
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -116,7 +128,7 @@ LL | let E::V { f1: B | C, f2 };
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: or-patterns syntax is experimental
|
error[E0658]: or-patterns syntax is experimental
|
||||||
--> $DIR/feature-gate-or_patterns.rs:40:10
|
--> $DIR/feature-gate-or_patterns.rs:42:10
|
||||||
|
|
|
|
||||||
LL | let [A | B];
|
LL | let [A | B];
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -169,6 +181,6 @@ LL | accept_pat!([p | q]);
|
||||||
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
|
= note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
|
||||||
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
= help: add `#![feature(or_patterns)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 19 previous errors
|
error: aborting due to 21 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -11,4 +11,4 @@ enum E { A, B }
|
||||||
use E::*;
|
use E::*;
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn fun1((A | B): E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
|
fn fun1((A | B): E) {} //~ ERROR top-level or-patterns are not allowed
|
||||||
|
|
|
@ -11,4 +11,4 @@ enum E { A, B }
|
||||||
use E::*;
|
use E::*;
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
|
fn fun1(A | B: E) {} //~ ERROR top-level or-patterns are not allowed
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: an or-pattern parameter must be wrapped in parentheses
|
error: top-level or-patterns are not allowed in function parameters
|
||||||
--> $DIR/fn-param-wrap-parens.rs:14:9
|
--> $DIR/fn-param-wrap-parens.rs:14:9
|
||||||
|
|
|
|
||||||
LL | fn fun1(A | B: E) {}
|
LL | fn fun1(A | B: E) {}
|
||||||
|
|
|
@ -4,23 +4,23 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
fn main() {
|
fn main() {
|
||||||
// One level:
|
// One level:
|
||||||
let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
|
let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
|
let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
|
let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
|
let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
//~| ERROR variable `b` is bound inconsistently
|
//~| ERROR variable `b` is bound inconsistently
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
// Two levels:
|
// Two levels:
|
||||||
let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
|
let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
|
|
||||||
// Three levels:
|
// Three levels:
|
||||||
let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
|
let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
|
||||||
//~^ ERROR variable `a` is bound inconsistently
|
//~^ ERROR variable `a` is bound inconsistently
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,74 +1,74 @@
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:7:25
|
--> $DIR/inconsistent-modes.rs:7:26
|
||||||
|
|
|
|
||||||
LL | let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
|
LL | let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
|
||||||
| - ^ bound in different ways
|
| - ^ bound in different ways
|
||||||
| |
|
| |
|
||||||
| first binding
|
| first binding
|
||||||
|
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:9:29
|
--> $DIR/inconsistent-modes.rs:9:30
|
||||||
|
|
|
|
||||||
LL | let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
|
LL | let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
|
||||||
| - ^ bound in different ways
|
| - ^ bound in different ways
|
||||||
| |
|
| |
|
||||||
| first binding
|
| first binding
|
||||||
|
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:11:33
|
--> $DIR/inconsistent-modes.rs:11:34
|
||||||
|
|
|
|
||||||
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
|
LL | let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
|
||||||
| - first binding ^ bound in different ways
|
| - first binding ^ bound in different ways
|
||||||
|
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:14:39
|
--> $DIR/inconsistent-modes.rs:14:40
|
||||||
|
|
|
|
||||||
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
|
LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
|
||||||
| - first binding ^ bound in different ways
|
| - first binding ^ bound in different ways
|
||||||
|
|
||||||
error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:14:46
|
--> $DIR/inconsistent-modes.rs:14:47
|
||||||
|
|
|
|
||||||
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
|
LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
|
||||||
| - first binding ^ bound in different ways
|
| - first binding ^ bound in different ways
|
||||||
|
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:20:38
|
--> $DIR/inconsistent-modes.rs:20:39
|
||||||
|
|
|
|
||||||
LL | let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
|
LL | let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
|
||||||
| - ^ bound in different ways
|
| - ^ bound in different ways
|
||||||
| |
|
| |
|
||||||
| first binding
|
| first binding
|
||||||
|
|
||||||
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
|
||||||
--> $DIR/inconsistent-modes.rs:24:33
|
--> $DIR/inconsistent-modes.rs:24:34
|
||||||
|
|
|
|
||||||
LL | let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
|
LL | let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
|
||||||
| - ^ bound in different ways
|
| - ^ bound in different ways
|
||||||
| |
|
| |
|
||||||
| first binding
|
| first binding
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/inconsistent-modes.rs:11:25
|
--> $DIR/inconsistent-modes.rs:11:26
|
||||||
|
|
|
|
||||||
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
|
LL | let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
|
||||||
| ----- ^^^^^^^^^ -------------------- expected due to this
|
| ----- ^^^^^^^^^ -------------------- expected due to this
|
||||||
| | |
|
| | |
|
||||||
| | types differ in mutability
|
| | types differ in mutability
|
||||||
| first introduced with type `&&u8` here
|
| first introduced with type `&&u8` here
|
||||||
|
|
|
|
||||||
= note: expected type `&&u8`
|
= note: expected type `&&u8`
|
||||||
found type `&mut &mut u8`
|
found type `&mut &mut u8`
|
||||||
= note: a binding must have the same type in all alternatives
|
= note: a binding must have the same type in all alternatives
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/inconsistent-modes.rs:14:31
|
--> $DIR/inconsistent-modes.rs:14:32
|
||||||
|
|
|
|
||||||
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
|
LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
|
||||||
| ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
|
| ----- ^^^^^^^^^ ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
|
||||||
| | |
|
| | |
|
||||||
| | types differ in mutability
|
| | types differ in mutability
|
||||||
| first introduced with type `&{integer}` here
|
| first introduced with type `&{integer}` here
|
||||||
|
|
|
|
||||||
= note: expected type `&{integer}`
|
= note: expected type `&{integer}`
|
||||||
found type `&mut _`
|
found type `&mut _`
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![feature(or_patterns)]
|
#![feature(or_patterns)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let 0 | (1 | 2) = 0; //~ ERROR refutable pattern in local binding
|
let (0 | (1 | 2)) = 0; //~ ERROR refutable pattern in local binding
|
||||||
match 0 {
|
match 0 {
|
||||||
//~^ ERROR non-exhaustive patterns
|
//~^ ERROR non-exhaustive patterns
|
||||||
0 | (1 | 2) => {}
|
0 | (1 | 2) => {}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
||||||
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:9
|
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:10
|
||||||
|
|
|
|
||||||
LL | let 0 | (1 | 2) = 0;
|
LL | let (0 | (1 | 2)) = 0;
|
||||||
| ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
| ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
||||||
|
|
|
|
||||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||||
= note: the matched value is of type `i32`
|
= note: the matched value is of type `i32`
|
||||||
help: you might want to use `if let` to ignore the variant that isn't matched
|
help: you might want to use `if let` to ignore the variant that isn't matched
|
||||||
|
|
|
|
||||||
LL | if let 0 | (1 | 2) = 0 { /* */ }
|
LL | if let (0 | (1 | 2)) = 0 { /* */ }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
|
||||||
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
|
--> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#![feature(or_patterns)]
|
#![feature(or_patterns)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let 0 | (1 | _) = 0;
|
let (0 | (1 | _)) = 0;
|
||||||
if let 0 | (1 | 2) = 0 {}
|
if let 0 | (1 | 2) = 0 {}
|
||||||
if let x @ 0 | x @ (1 | 2) = 0 {}
|
if let x @ 0 | x @ (1 | 2) = 0 {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
fn or_pat_let(x: Result<u32, u32>) -> u32 {
|
fn or_pat_let(x: Result<u32, u32>) -> u32 {
|
||||||
let Ok(y) | Err(y) = x;
|
let (Ok(y) | Err(y)) = x;
|
||||||
y
|
y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ async fn a((x | s): String) {}
|
||||||
//~| ERROR variable `s` is not bound in all patterns
|
//~| ERROR variable `s` is not bound in all patterns
|
||||||
|
|
||||||
async fn b() {
|
async fn b() {
|
||||||
let x | s = String::new();
|
let (x | s) = String::new();
|
||||||
//~^ ERROR variable `x` is not bound in all patterns
|
//~^ ERROR variable `x` is not bound in all patterns
|
||||||
//~| ERROR variable `s` is not bound in all patterns
|
//~| ERROR variable `s` is not bound in all patterns
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,20 +15,20 @@ LL | async fn a((x | s): String) {}
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `s` is not bound in all patterns
|
error[E0408]: variable `s` is not bound in all patterns
|
||||||
--> $DIR/mismatched-bindings-async-fn.rs:11:9
|
--> $DIR/mismatched-bindings-async-fn.rs:11:10
|
||||||
|
|
|
|
||||||
LL | let x | s = String::new();
|
LL | let (x | s) = String::new();
|
||||||
| ^ - variable not in all patterns
|
| ^ - variable not in all patterns
|
||||||
| |
|
| |
|
||||||
| pattern doesn't bind `s`
|
| pattern doesn't bind `s`
|
||||||
|
|
||||||
error[E0408]: variable `x` is not bound in all patterns
|
error[E0408]: variable `x` is not bound in all patterns
|
||||||
--> $DIR/mismatched-bindings-async-fn.rs:11:13
|
--> $DIR/mismatched-bindings-async-fn.rs:11:14
|
||||||
|
|
|
|
||||||
LL | let x | s = String::new();
|
LL | let (x | s) = String::new();
|
||||||
| - ^ pattern doesn't bind `x`
|
| - ^ pattern doesn't bind `x`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn check_handling_of_paths() {
|
||||||
}
|
}
|
||||||
|
|
||||||
use bar::foo::{alpha, charlie};
|
use bar::foo::{alpha, charlie};
|
||||||
let alpha | beta | charlie = alpha; //~ ERROR variable `beta` is not bound in all patterns
|
let (alpha | beta | charlie) = alpha; //~ ERROR variable `beta` is not bound in all patterns
|
||||||
match Some(alpha) {
|
match Some(alpha) {
|
||||||
Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
|
Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
|
||||||
}
|
}
|
||||||
|
@ -31,19 +31,19 @@ fn check_misc_nesting() {
|
||||||
|
|
||||||
// One level:
|
// One level:
|
||||||
const X: E<u8> = B(0);
|
const X: E<u8> = B(0);
|
||||||
let A(a, _) | _ = X; //~ ERROR variable `a` is not bound in all patterns
|
let (A(a, _) | _) = X; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let _ | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
|
let (_ | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let A(..) | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
|
let (A(..) | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let A(a, _) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
|
let (A(a, _) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let A(_, a) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
|
let (A(_, a) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let A(a, b) | B(a) = X; //~ ERROR variable `b` is not bound in all patterns
|
let (A(a, b) | B(a)) = X; //~ ERROR variable `b` is not bound in all patterns
|
||||||
|
|
||||||
// Two levels:
|
// Two levels:
|
||||||
const Y: E<E<u8>> = B(B(0));
|
const Y: E<E<u8>> = B(B(0));
|
||||||
let A(A(..) | B(_), _) | B(a) = Y; //~ ERROR variable `a` is not bound in all patterns
|
let (A(A(..) | B(_), _) | B(a)) = Y; //~ ERROR variable `a` is not bound in all patterns
|
||||||
let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
|
let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
|
||||||
//~^ ERROR variable `a` is not bound in all patterns
|
//~^ ERROR variable `a` is not bound in all patterns
|
||||||
let A(A(a, b) | B(c), d) | B(e) = Y;
|
let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
//~^ ERROR variable `a` is not bound in all patterns
|
//~^ ERROR variable `a` is not bound in all patterns
|
||||||
//~| ERROR variable `a` is not bound in all patterns
|
//~| ERROR variable `a` is not bound in all patterns
|
||||||
//~| ERROR variable `b` is not bound in all patterns
|
//~| ERROR variable `b` is not bound in all patterns
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0408]: variable `beta` is not bound in all patterns
|
error[E0408]: variable `beta` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:20:9
|
--> $DIR/missing-bindings.rs:20:10
|
||||||
|
|
|
|
||||||
LL | let alpha | beta | charlie = alpha;
|
LL | let (alpha | beta | charlie) = alpha;
|
||||||
| ^^^^^ ---- ^^^^^^^ pattern doesn't bind `beta`
|
| ^^^^^ ---- ^^^^^^^ pattern doesn't bind `beta`
|
||||||
| | |
|
| | |
|
||||||
| | variable not in all patterns
|
| | variable not in all patterns
|
||||||
| pattern doesn't bind `beta`
|
| pattern doesn't bind `beta`
|
||||||
|
|
||||||
error[E0408]: variable `beta` is not bound in all patterns
|
error[E0408]: variable `beta` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:22:14
|
--> $DIR/missing-bindings.rs:22:14
|
||||||
|
@ -16,132 +16,132 @@ LL | Some(alpha | beta) => {}
|
||||||
| pattern doesn't bind `beta`
|
| pattern doesn't bind `beta`
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:34:19
|
--> $DIR/missing-bindings.rs:34:20
|
||||||
|
|
|
|
||||||
LL | let A(a, _) | _ = X;
|
LL | let (A(a, _) | _) = X;
|
||||||
| - ^ pattern doesn't bind `a`
|
| - ^ pattern doesn't bind `a`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:35:9
|
--> $DIR/missing-bindings.rs:35:10
|
||||||
|
|
|
|
||||||
LL | let _ | B(a) = X;
|
LL | let (_ | B(a)) = X;
|
||||||
| ^ - variable not in all patterns
|
| ^ - variable not in all patterns
|
||||||
| |
|
| |
|
||||||
| pattern doesn't bind `a`
|
| pattern doesn't bind `a`
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:36:9
|
--> $DIR/missing-bindings.rs:36:10
|
||||||
|
|
|
|
||||||
LL | let A(..) | B(a) = X;
|
LL | let (A(..) | B(a)) = X;
|
||||||
| ^^^^^ - variable not in all patterns
|
| ^^^^^ - variable not in all patterns
|
||||||
| |
|
| |
|
||||||
| pattern doesn't bind `a`
|
| pattern doesn't bind `a`
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:37:19
|
--> $DIR/missing-bindings.rs:37:20
|
||||||
|
|
|
|
||||||
LL | let A(a, _) | B(_) = X;
|
LL | let (A(a, _) | B(_)) = X;
|
||||||
| - ^^^^ pattern doesn't bind `a`
|
| - ^^^^ pattern doesn't bind `a`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:38:19
|
--> $DIR/missing-bindings.rs:38:20
|
||||||
|
|
|
|
||||||
LL | let A(_, a) | B(_) = X;
|
LL | let (A(_, a) | B(_)) = X;
|
||||||
| - ^^^^ pattern doesn't bind `a`
|
| - ^^^^ pattern doesn't bind `a`
|
||||||
|
| |
|
||||||
|
| variable not in all patterns
|
||||||
|
|
||||||
|
error[E0408]: variable `b` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:39:20
|
||||||
|
|
|
||||||
|
LL | let (A(a, b) | B(a)) = X;
|
||||||
|
| - ^^^^ pattern doesn't bind `b`
|
||||||
|
| |
|
||||||
|
| variable not in all patterns
|
||||||
|
|
||||||
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:43:10
|
||||||
|
|
|
||||||
|
LL | let (A(A(..) | B(_), _) | B(a)) = Y;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ - variable not in all patterns
|
||||||
|
| |
|
||||||
|
| pattern doesn't bind `a`
|
||||||
|
|
||||||
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:44:12
|
||||||
|
|
|
||||||
|
LL | let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
|
||||||
|
| ^^^^^ - variable not in all patterns
|
||||||
|
| |
|
||||||
|
| pattern doesn't bind `a`
|
||||||
|
|
||||||
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:46:22
|
||||||
|
|
|
||||||
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
|
| - ^^^^ pattern doesn't bind `a`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `b` is not bound in all patterns
|
error[E0408]: variable `b` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:39:19
|
--> $DIR/missing-bindings.rs:46:22
|
||||||
|
|
|
|
||||||
LL | let A(a, b) | B(a) = X;
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
| - ^^^^ pattern doesn't bind `b`
|
| - ^^^^ pattern doesn't bind `b`
|
||||||
|
| |
|
||||||
|
| variable not in all patterns
|
||||||
|
|
||||||
|
error[E0408]: variable `c` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:46:12
|
||||||
|
|
|
||||||
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
|
| ^^^^^^^ - variable not in all patterns
|
||||||
|
| |
|
||||||
|
| pattern doesn't bind `c`
|
||||||
|
|
||||||
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
|
--> $DIR/missing-bindings.rs:46:33
|
||||||
|
|
|
||||||
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
|
| - ^^^^ pattern doesn't bind `a`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:43:9
|
|
||||||
|
|
|
||||||
LL | let A(A(..) | B(_), _) | B(a) = Y;
|
|
||||||
| ^^^^^^^^^^^^^^^^^^ - variable not in all patterns
|
|
||||||
| |
|
|
||||||
| pattern doesn't bind `a`
|
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:44:11
|
|
||||||
|
|
|
||||||
LL | let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
|
|
||||||
| ^^^^^ - variable not in all patterns
|
|
||||||
| |
|
|
||||||
| pattern doesn't bind `a`
|
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:46:21
|
|
||||||
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
|
||||||
| - ^^^^ pattern doesn't bind `a`
|
|
||||||
| |
|
|
||||||
| variable not in all patterns
|
|
||||||
|
|
||||||
error[E0408]: variable `b` is not bound in all patterns
|
error[E0408]: variable `b` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:46:21
|
--> $DIR/missing-bindings.rs:46:33
|
||||||
|
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
| - ^^^^ pattern doesn't bind `b`
|
| - ^^^^ pattern doesn't bind `b`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `c` is not bound in all patterns
|
error[E0408]: variable `c` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:46:11
|
--> $DIR/missing-bindings.rs:46:33
|
||||||
|
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
| ^^^^^^^ - variable not in all patterns
|
| - ^^^^ pattern doesn't bind `c`
|
||||||
| |
|
| |
|
||||||
| pattern doesn't bind `c`
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:46:32
|
|
||||||
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
|
||||||
| - ^^^^ pattern doesn't bind `a`
|
|
||||||
| |
|
|
||||||
| variable not in all patterns
|
|
||||||
|
|
||||||
error[E0408]: variable `b` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:46:32
|
|
||||||
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
|
||||||
| - ^^^^ pattern doesn't bind `b`
|
|
||||||
| |
|
|
||||||
| variable not in all patterns
|
|
||||||
|
|
||||||
error[E0408]: variable `c` is not bound in all patterns
|
|
||||||
--> $DIR/missing-bindings.rs:46:32
|
|
||||||
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
|
||||||
| - ^^^^ pattern doesn't bind `c`
|
|
||||||
| |
|
|
||||||
| variable not in all patterns
|
|
||||||
|
|
||||||
error[E0408]: variable `d` is not bound in all patterns
|
error[E0408]: variable `d` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:46:32
|
--> $DIR/missing-bindings.rs:46:33
|
||||||
|
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
| - ^^^^ pattern doesn't bind `d`
|
| - ^^^^ pattern doesn't bind `d`
|
||||||
| |
|
| |
|
||||||
| variable not in all patterns
|
| variable not in all patterns
|
||||||
|
|
||||||
error[E0408]: variable `e` is not bound in all patterns
|
error[E0408]: variable `e` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:46:9
|
--> $DIR/missing-bindings.rs:46:10
|
||||||
|
|
|
|
||||||
LL | let A(A(a, b) | B(c), d) | B(e) = Y;
|
LL | let (A(A(a, b) | B(c), d) | B(e)) = Y;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns
|
| ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns
|
||||||
| |
|
| |
|
||||||
| pattern doesn't bind `e`
|
| pattern doesn't bind `e`
|
||||||
|
|
||||||
error[E0408]: variable `a` is not bound in all patterns
|
error[E0408]: variable `a` is not bound in all patterns
|
||||||
--> $DIR/missing-bindings.rs:62:29
|
--> $DIR/missing-bindings.rs:62:29
|
||||||
|
|
46
src/test/ui/or-patterns/nested-undelimited-precedence.rs
Normal file
46
src/test/ui/or-patterns/nested-undelimited-precedence.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// This test tests the precedence of `|` (or-patterns) undelimited nested patterns. In particular,
|
||||||
|
// we want to reserve the syntactic space of a pattern followed by a type annotation for possible
|
||||||
|
// future type ascription, so we need to make sure that any time a pattern is followed by type
|
||||||
|
// annotation (for now), the pattern is not a top-level or-pattern. However, there are also a few
|
||||||
|
// types of patterns that allow undelimited subpatterns that could cause the same ambiguity.
|
||||||
|
// Currently, those should be impossible due to precedence rule. This test enforces that.
|
||||||
|
|
||||||
|
#![feature(or_patterns)]
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
use E::*;
|
||||||
|
|
||||||
|
// ok
|
||||||
|
let b @ (A | B): E = A;
|
||||||
|
|
||||||
|
let b @ A | B: E = A; //~ERROR `b` is not bound in all patterns
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
enum F {
|
||||||
|
A(usize),
|
||||||
|
B(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
use F::*;
|
||||||
|
|
||||||
|
// ok
|
||||||
|
let (A(x) | B(x)): F = A(3);
|
||||||
|
|
||||||
|
let &A(_) | B(_): F = A(3); //~ERROR mismatched types
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
let &&A(_) | B(_): F = A(3); //~ERROR mismatched types
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
let &mut A(_) | B(_): F = A(3); //~ERROR mismatched types
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
let &&mut A(_) | B(_): F = A(3); //~ERROR mismatched types
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
86
src/test/ui/or-patterns/nested-undelimited-precedence.stderr
Normal file
86
src/test/ui/or-patterns/nested-undelimited-precedence.stderr
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:21:9
|
||||||
|
|
|
||||||
|
LL | let b @ A | B: E = A;
|
||||||
|
| ^^^^^^^^^ help: wrap the pattern in parentheses: `(b @ A | B)`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:36:9
|
||||||
|
|
|
||||||
|
LL | let &A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&A(_) | B(_))`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:38:9
|
||||||
|
|
|
||||||
|
LL | let &&A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&A(_) | B(_))`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:40:9
|
||||||
|
|
|
||||||
|
LL | let &mut A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&mut A(_) | B(_))`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:42:9
|
||||||
|
|
|
||||||
|
LL | let &&mut A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&mut A(_) | B(_))`
|
||||||
|
|
||||||
|
error[E0408]: variable `b` is not bound in all patterns
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:21:17
|
||||||
|
|
|
||||||
|
LL | let b @ A | B: E = A;
|
||||||
|
| - ^ pattern doesn't bind `b`
|
||||||
|
| |
|
||||||
|
| variable not in all patterns
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:36:9
|
||||||
|
|
|
||||||
|
LL | let &A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^ - expected due to this
|
||||||
|
| |
|
||||||
|
| expected enum `F`, found reference
|
||||||
|
|
|
||||||
|
= note: expected enum `F`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:38:9
|
||||||
|
|
|
||||||
|
LL | let &&A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^ - expected due to this
|
||||||
|
| |
|
||||||
|
| expected enum `F`, found reference
|
||||||
|
|
|
||||||
|
= note: expected enum `F`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:40:9
|
||||||
|
|
|
||||||
|
LL | let &mut A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^ - expected due to this
|
||||||
|
| |
|
||||||
|
| expected enum `F`, found `&mut _`
|
||||||
|
|
|
||||||
|
= note: expected enum `F`
|
||||||
|
found mutable reference `&mut _`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested-undelimited-precedence.rs:42:9
|
||||||
|
|
|
||||||
|
LL | let &&mut A(_) | B(_): F = A(3);
|
||||||
|
| ^^^^^^^^^^ - expected due to this
|
||||||
|
| |
|
||||||
|
| expected enum `F`, found reference
|
||||||
|
|
|
||||||
|
= note: expected enum `F`
|
||||||
|
found reference `&_`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0308, E0408.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
|
@ -52,10 +52,10 @@ fn main() {
|
||||||
= Some((0u8, Some((1u16, 2u32))))
|
= Some((0u8, Some((1u16, 2u32))))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
|
let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
let (x, y) | (y, x) = (0u8, 1u16);
|
let ((x, y) | (y, x)) = (0u8, 1u16);
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
|
|
|
@ -187,35 +187,35 @@ LL | = Some((0u8, Some((1u16, 2u32))))
|
||||||
= note: a binding must have the same type in all alternatives
|
= note: a binding must have the same type in all alternatives
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/or-patterns-binding-type-mismatch.rs:55:39
|
--> $DIR/or-patterns-binding-type-mismatch.rs:55:40
|
||||||
|
|
|
|
||||||
LL | let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
|
LL | let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
|
||||||
| - ^ ---------------- this expression has type `Blah`
|
| - ^ ---------------- this expression has type `Blah`
|
||||||
| | |
|
| | |
|
||||||
| | expected `usize`, found `isize`
|
| | expected `usize`, found `isize`
|
||||||
| first introduced with type `usize` here
|
| first introduced with type `usize` here
|
||||||
|
|
|
|
||||||
= note: a binding must have the same type in all alternatives
|
= note: a binding must have the same type in all alternatives
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/or-patterns-binding-type-mismatch.rs:58:19
|
--> $DIR/or-patterns-binding-type-mismatch.rs:58:20
|
||||||
|
|
|
|
||||||
LL | let (x, y) | (y, x) = (0u8, 1u16);
|
LL | let ((x, y) | (y, x)) = (0u8, 1u16);
|
||||||
| - ^ ----------- this expression has type `(u8, u16)`
|
| - ^ ----------- this expression has type `(u8, u16)`
|
||||||
| | |
|
| | |
|
||||||
| | expected `u16`, found `u8`
|
| | expected `u16`, found `u8`
|
||||||
| first introduced with type `u16` here
|
| first introduced with type `u16` here
|
||||||
|
|
|
|
||||||
= note: a binding must have the same type in all alternatives
|
= note: a binding must have the same type in all alternatives
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/or-patterns-binding-type-mismatch.rs:58:22
|
--> $DIR/or-patterns-binding-type-mismatch.rs:58:23
|
||||||
|
|
|
|
||||||
LL | let (x, y) | (y, x) = (0u8, 1u16);
|
LL | let ((x, y) | (y, x)) = (0u8, 1u16);
|
||||||
| - ^ ----------- this expression has type `(u8, u16)`
|
| - ^ ----------- this expression has type `(u8, u16)`
|
||||||
| | |
|
| | |
|
||||||
| | expected `u8`, found `u16`
|
| | expected `u8`, found `u16`
|
||||||
| first introduced with type `u8` here
|
| first introduced with type `u8` here
|
||||||
|
|
|
|
||||||
= note: a binding must have the same type in all alternatives
|
= note: a binding must have the same type in all alternatives
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,11 @@ fn main() {
|
||||||
if let &(Ok(x) | Err(x)) = res {
|
if let &(Ok(x) | Err(x)) = res {
|
||||||
drop::<u8>(x);
|
drop::<u8>(x);
|
||||||
}
|
}
|
||||||
let Ok(mut x) | &Err(mut x) = res;
|
let (Ok(mut x) | &Err(mut x)) = res;
|
||||||
drop::<u8>(x);
|
drop::<u8>(x);
|
||||||
let &(Ok(x) | Err(x)) = res;
|
let &(Ok(x) | Err(x)) = res;
|
||||||
drop::<u8>(x);
|
drop::<u8>(x);
|
||||||
let Ok(x) | Err(x) = res;
|
let (Ok(x) | Err(x)) = res;
|
||||||
drop::<&u8>(x);
|
drop::<&u8>(x);
|
||||||
for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
|
for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
|
||||||
drop::<u8>(x);
|
drop::<u8>(x);
|
||||||
|
@ -119,9 +119,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let tri = &Tri::A(&Ok(0));
|
let tri = &Tri::A(&Ok(0));
|
||||||
let Tri::A(Ok(mut x) | Err(mut x))
|
let (Tri::A(Ok(mut x) | Err(mut x))
|
||||||
| Tri::B(&Ok(mut x) | Err(mut x))
|
| Tri::B(&Ok(mut x) | Err(mut x))
|
||||||
| &Tri::C(Ok(mut x) | Err(mut x)) = tri;
|
| &Tri::C(Ok(mut x) | Err(mut x))) = tri;
|
||||||
drop::<u8>(x);
|
drop::<u8>(x);
|
||||||
|
|
||||||
match tri {
|
match tri {
|
||||||
|
|
|
@ -14,8 +14,19 @@ fn no_top_level_or_patterns() {
|
||||||
// -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
|
// -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
|
||||||
|
|
||||||
// ...and for now neither do we allow or-patterns at the top level of functions.
|
// ...and for now neither do we allow or-patterns at the top level of functions.
|
||||||
fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
|
fn fun1(A | B: E) {}
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
|
||||||
fn fun2(| A | B: E) {}
|
fn fun2(| A | B: E) {}
|
||||||
//~^ ERROR an or-pattern parameter must be wrapped in parentheses
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
|
||||||
|
// We don't allow top-level or-patterns before type annotation in let-statements because we
|
||||||
|
// want to reserve this syntactic space for possible future type ascription.
|
||||||
|
let A | B: E = A;
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
|
||||||
|
let | A | B: E = A;
|
||||||
|
//~^ ERROR top-level or-patterns are not allowed
|
||||||
|
|
||||||
|
let (A | B): E = A; // ok -- wrapped in parens
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
error: an or-pattern parameter must be wrapped in parentheses
|
error: top-level or-patterns are not allowed in function parameters
|
||||||
--> $DIR/or-patterns-syntactic-fail.rs:17:13
|
--> $DIR/or-patterns-syntactic-fail.rs:17:13
|
||||||
|
|
|
|
||||||
LL | fn fun1(A | B: E) {}
|
LL | fn fun1(A | B: E) {}
|
||||||
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
error: an or-pattern parameter must be wrapped in parentheses
|
error: top-level or-patterns are not allowed in function parameters
|
||||||
--> $DIR/or-patterns-syntactic-fail.rs:19:13
|
--> $DIR/or-patterns-syntactic-fail.rs:20:13
|
||||||
|
|
|
|
||||||
LL | fn fun2(| A | B: E) {}
|
LL | fn fun2(| A | B: E) {}
|
||||||
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/or-patterns-syntactic-fail.rs:25:9
|
||||||
|
|
|
||||||
|
LL | let A | B: E = A;
|
||||||
|
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
|
error: top-level or-patterns are not allowed in `let` bindings
|
||||||
|
--> $DIR/or-patterns-syntactic-fail.rs:28:9
|
||||||
|
|
|
||||||
|
LL | let | A | B: E = A;
|
||||||
|
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
|
||||||
|
|
||||||
error[E0369]: no implementation for `E | ()`
|
error[E0369]: no implementation for `E | ()`
|
||||||
--> $DIR/or-patterns-syntactic-fail.rs:13:22
|
--> $DIR/or-patterns-syntactic-fail.rs:13:22
|
||||||
|
|
|
|
||||||
|
@ -20,6 +32,6 @@ LL | let _ = |A | B: E| ();
|
||||||
|
|
|
|
||||||
= note: an implementation of `std::ops::BitOr` might be missing for `E`
|
= note: an implementation of `std::ops::BitOr` might be missing for `E`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0369`.
|
For more information about this error, try `rustc --explain E0369`.
|
||||||
|
|
|
@ -23,11 +23,11 @@ accept_pat!([p | q]);
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn or_patterns() {
|
fn or_patterns() {
|
||||||
// Top level of `let`:
|
// Top level of `let`:
|
||||||
let | A | B;
|
let (| A | B);
|
||||||
let A | B;
|
let (A | B);
|
||||||
let A | B: u8;
|
let (A | B): u8;
|
||||||
let A | B = 0;
|
let (A | B) = 0;
|
||||||
let A | B: u8 = 0;
|
let (A | B): u8 = 0;
|
||||||
|
|
||||||
// Top level of `for`:
|
// Top level of `for`:
|
||||||
for | A | B in 0 {}
|
for | A | B in 0 {}
|
||||||
|
@ -69,10 +69,10 @@ fn or_patterns() {
|
||||||
let [A | B, .. | ..];
|
let [A | B, .. | ..];
|
||||||
|
|
||||||
// These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
|
// These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
|
||||||
let box 0 | 1; // Unstable; we *can* the precedence if we want.
|
let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
|
||||||
let &0 | 1;
|
let (&0 | 1);
|
||||||
let &mut 0 | 1;
|
let (&mut 0 | 1);
|
||||||
let x @ 0 | 1;
|
let (x @ 0 | 1);
|
||||||
let ref x @ 0 | 1;
|
let (ref x @ 0 | 1);
|
||||||
let ref mut x @ 0 | 1;
|
let (ref mut x @ 0 | 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn leading() {
|
fn leading() {
|
||||||
fn fun1( A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
|
fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
|
||||||
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
|
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
|
||||||
let ( | A): E;
|
let ( | A): E;
|
||||||
let ( | A): (E); //~ ERROR unexpected token `||` in pattern
|
let ( | A): (E); //~ ERROR unexpected token `||` in pattern
|
||||||
|
@ -40,6 +40,9 @@ fn trailing() {
|
||||||
//~^ ERROR a trailing `|` is not allowed in an or-pattern
|
//~^ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These test trailing-vert in `let` bindings, but they also test that we don't emit a
|
||||||
|
// duplicate suggestion that would confuse rustfix.
|
||||||
|
|
||||||
let a : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
let a = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
let a ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
|
|
|
@ -9,7 +9,7 @@ fn main() {}
|
||||||
|
|
||||||
#[cfg(FALSE)]
|
#[cfg(FALSE)]
|
||||||
fn leading() {
|
fn leading() {
|
||||||
fn fun1( | A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
|
fn fun1( | A: E) {} //~ ERROR top-level or-patterns are not allowed
|
||||||
fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
|
fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
|
||||||
let ( | A): E;
|
let ( | A): E;
|
||||||
let ( || A): (E); //~ ERROR unexpected token `||` in pattern
|
let ( || A): (E); //~ ERROR unexpected token `||` in pattern
|
||||||
|
@ -40,6 +40,9 @@ fn trailing() {
|
||||||
//~^ ERROR a trailing `|` is not allowed in an or-pattern
|
//~^ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These test trailing-vert in `let` bindings, but they also test that we don't emit a
|
||||||
|
// duplicate suggestion that would confuse rustfix.
|
||||||
|
|
||||||
let a | : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a | : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
let a | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: an or-pattern parameter must be wrapped in parentheses
|
error: top-level or-patterns are not allowed in function parameters
|
||||||
--> $DIR/remove-leading-vert.rs:12:14
|
--> $DIR/remove-leading-vert.rs:12:14
|
||||||
|
|
|
|
||||||
LL | fn fun1( | A: E) {}
|
LL | fn fun1( | A: E) {}
|
||||||
| ^^^ help: remove the leading `|`: `A`
|
| ^^^ help: remove the `|`: `A`
|
||||||
|
|
||||||
error: unexpected `||` before function parameter
|
error: unexpected `||` before function parameter
|
||||||
--> $DIR/remove-leading-vert.rs:13:14
|
--> $DIR/remove-leading-vert.rs:13:14
|
||||||
|
@ -135,7 +135,7 @@ LL | | A | B | => {}
|
||||||
| while parsing this or-pattern starting here
|
| while parsing this or-pattern starting here
|
||||||
|
|
||||||
error: a trailing `|` is not allowed in an or-pattern
|
error: a trailing `|` is not allowed in an or-pattern
|
||||||
--> $DIR/remove-leading-vert.rs:43:11
|
--> $DIR/remove-leading-vert.rs:46:11
|
||||||
|
|
|
|
||||||
LL | let a | : u8 = 0;
|
LL | let a | : u8 = 0;
|
||||||
| - ^ help: remove the `|`
|
| - ^ help: remove the `|`
|
||||||
|
@ -143,7 +143,7 @@ LL | let a | : u8 = 0;
|
||||||
| while parsing this or-pattern starting here
|
| while parsing this or-pattern starting here
|
||||||
|
|
||||||
error: a trailing `|` is not allowed in an or-pattern
|
error: a trailing `|` is not allowed in an or-pattern
|
||||||
--> $DIR/remove-leading-vert.rs:44:11
|
--> $DIR/remove-leading-vert.rs:47:11
|
||||||
|
|
|
|
||||||
LL | let a | = 0;
|
LL | let a | = 0;
|
||||||
| - ^ help: remove the `|`
|
| - ^ help: remove the `|`
|
||||||
|
@ -151,7 +151,7 @@ LL | let a | = 0;
|
||||||
| while parsing this or-pattern starting here
|
| while parsing this or-pattern starting here
|
||||||
|
|
||||||
error: a trailing `|` is not allowed in an or-pattern
|
error: a trailing `|` is not allowed in an or-pattern
|
||||||
--> $DIR/remove-leading-vert.rs:45:11
|
--> $DIR/remove-leading-vert.rs:48:11
|
||||||
|
|
|
|
||||||
LL | let a | ;
|
LL | let a | ;
|
||||||
| - ^ help: remove the `|`
|
| - ^ help: remove the `|`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue