diff --git a/Cargo.lock b/Cargo.lock index b432f9ae2272a..6885ac65ca919 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,9 +435,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" dependencies = [ "jobserver", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 9bd5764f0730d..6a6f93d50d364 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -9,7 +9,7 @@ test = false [dependencies] bitflags = "1.2.1" -cc = "1.0.68" +cc = "1.0.69" itertools = "0.9" tracing = "0.1" libc = "0.2.50" diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index df673c6084b96..1ab7e15019eff 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -22,7 +22,9 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::Features; -use rustc_parse::parser::{AttemptLocalParseRecovery, ForceCollect, Parser, RecoverComma}; +use rustc_parse::parser::{ + AttemptLocalParseRecovery, ForceCollect, Parser, RecoverColon, RecoverComma, +}; use rustc_parse::validate_attr; use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS; use rustc_session::lint::BuiltinLintDiagnostics; @@ -930,9 +932,11 @@ pub fn parse_ast_fragment<'a>( } } AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?), - AstFragmentKind::Pat => { - AstFragment::Pat(this.parse_pat_allow_top_alt(None, RecoverComma::No)?) - } + AstFragmentKind::Pat => AstFragment::Pat(this.parse_pat_allow_top_alt( + None, + RecoverComma::No, + RecoverColon::Yes, + )?), AstFragmentKind::Arms | AstFragmentKind::Fields | AstFragmentKind::FieldPats diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 3fca2e1ccb97b..1bfa489d39eea 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -13,4 +13,4 @@ libc = "0.2.73" [build-dependencies] build_helper = { path = "../../src/build_helper" } -cc = "1.0.68" +cc = "1.0.69" diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9dff40ff1ed6e..47fdd852d90de 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1,4 +1,4 @@ -use super::pat::{RecoverComma, PARAM_EXPECTED}; +use super::pat::{RecoverColon, RecoverComma, PARAM_EXPECTED}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{AttrWrapper, BlockMode, ForceCollect, Parser, PathStyle, Restrictions, TokenType}; use super::{SemiColonMode, SeqSep, TokenExpectType, TrailingToken}; @@ -1813,7 +1813,7 @@ impl<'a> Parser<'a> { /// The `let` token has already been eaten. fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.prev_token.span; - let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes)?; + let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes, RecoverColon::Yes)?; self.expect(&token::Eq)?; let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| { this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) @@ -1876,7 +1876,7 @@ impl<'a> Parser<'a> { _ => None, }; - let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes)?; + let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes, RecoverColon::Yes)?; if !self.eat_keyword(kw::In) { self.error_missing_in_for_loop(); } @@ -2083,7 +2083,7 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; - let pat = this.parse_pat_allow_top_alt(None, RecoverComma::Yes)?; + let pat = this.parse_pat_allow_top_alt(None, RecoverComma::Yes, RecoverColon::Yes)?; let guard = if this.eat_keyword(kw::If) { let if_span = this.prev_token.span; let cond = this.parse_expr()?; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index cd9f84db5e559..51d4e007b5984 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -14,7 +14,7 @@ use crate::lexer::UnmatchedBrace; pub use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; use diagnostics::Error; -pub use pat::RecoverComma; +pub use pat::{RecoverColon, RecoverComma}; pub use path::PathStyle; use rustc_ast::ptr::P; diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 30a6b61407f69..313d9db58fc3f 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -5,7 +5,7 @@ use rustc_ast_pretty::pprust; use rustc_errors::PResult; use rustc_span::symbol::{kw, Ident}; -use crate::parser::pat::RecoverComma; +use crate::parser::pat::{RecoverColon, RecoverComma}; use crate::parser::{FollowedByType, ForceCollect, Parser, PathStyle}; impl<'a> Parser<'a> { @@ -125,7 +125,7 @@ impl<'a> Parser<'a> { token::NtPat(self.collect_tokens_no_attrs(|this| match kind { NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None), NonterminalKind::PatWithOr { .. } => { - this.parse_pat_allow_top_alt(None, RecoverComma::No) + this.parse_pat_allow_top_alt(None, RecoverComma::No, RecoverColon::No) } _ => unreachable!(), })?) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 566677d032aff..e047dae15973e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -24,6 +24,13 @@ pub enum RecoverComma { No, } +/// Whether or not to recover a `:` when parsing patterns that were meant to be paths. +#[derive(PartialEq, Copy, Clone)] +pub enum RecoverColon { + Yes, + 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)] @@ -58,8 +65,9 @@ impl<'a> Parser<'a> { &mut self, expected: Expected, rc: RecoverComma, + ra: RecoverColon, ) -> PResult<'a, P> { - self.parse_pat_allow_top_alt_inner(expected, rc).map(|(pat, _)| pat) + self.parse_pat_allow_top_alt_inner(expected, rc, ra).map(|(pat, _)| pat) } /// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true = @@ -68,6 +76,7 @@ impl<'a> Parser<'a> { &mut self, expected: Expected, rc: RecoverComma, + ra: RecoverColon, ) -> PResult<'a, (P, bool)> { // Keep track of whether we recovered from a trailing vert so that we can avoid duplicated // suggestions (which bothers rustfix). @@ -89,6 +98,56 @@ impl<'a> Parser<'a> { // If we parsed a leading `|` which should be gated, // then we should really gate the leading `|`. // This complicated procedure is done purely for diagnostics UX. + let mut first_pat = first_pat; + + if let (RecoverColon::Yes, token::Colon) = (ra, &self.token.kind) { + if matches!( + first_pat.kind, + PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None) + | PatKind::Path(..) + ) && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) + { + // The pattern looks like it might be a path with a `::` -> `:` typo: + // `match foo { bar:baz => {} }` + let span = self.token.span; + // We only emit "unexpected `:`" error here if we can successfully parse the + // whole pattern correctly in that case. + let snapshot = self.clone(); + + // Create error for "unexpected `:`". + match self.expected_one_of_not_found(&[], &[]) { + Err(mut err) => { + self.bump(); // Skip the `:`. + match self.parse_pat_no_top_alt(expected) { + Err(mut inner_err) => { + // Carry on as if we had not done anything, callers will emit a + // reasonable error. + inner_err.cancel(); + err.cancel(); + *self = snapshot; + } + Ok(pat) => { + // We've parsed the rest of the pattern. + err.span_suggestion( + span, + "maybe write a path separator here", + "::".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + first_pat = + self.mk_pat(first_pat.span.to(pat.span), PatKind::Wild); + } + } + } + _ => { + // Carry on as if we had not done anything. This should be unreachable. + *self = snapshot; + } + }; + } + } + if let Some(leading_vert_span) = leading_vert_span { // If there was a leading vert, treat this as an or-pattern. This improves // diagnostics. @@ -140,7 +199,8 @@ impl<'a> Parser<'a> { // 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, rc)?; + let (pat, trailing_vert) = + self.parse_pat_allow_top_alt_inner(expected, rc, RecoverColon::No)?; let colon = self.eat(&token::Colon); if let PatKind::Or(pats) = &pat.kind { @@ -350,7 +410,7 @@ impl<'a> Parser<'a> { } else if self.check(&token::OpenDelim(token::Bracket)) { // Parse `[pat, pat,...]` as a slice pattern. let (pats, _) = self.parse_delim_comma_seq(token::Bracket, |p| { - p.parse_pat_allow_top_alt(None, RecoverComma::No) + p.parse_pat_allow_top_alt(None, RecoverComma::No, RecoverColon::No) })?; PatKind::Slice(pats) } else if self.check(&token::DotDot) && !self.is_pat_range_end_start(1) { @@ -563,8 +623,9 @@ impl<'a> Parser<'a> { /// Parse a tuple or parenthesis pattern. fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> { - let (fields, trailing_comma) = - self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?; + let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| { + p.parse_pat_allow_top_alt(None, RecoverComma::No, RecoverColon::No) + })?; // Here, `(pat,)` is a tuple pattern. // For backward compatibility, `(..)` is a tuple pattern as well. @@ -873,8 +934,9 @@ impl<'a> Parser<'a> { /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`). fn parse_pat_tuple_struct(&mut self, qself: Option, path: Path) -> PResult<'a, PatKind> { - let (fields, _) = - self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?; + let (fields, _) = self.parse_paren_comma_seq(|p| { + p.parse_pat_allow_top_alt(None, RecoverComma::No, RecoverColon::No) + })?; if qself.is_some() { self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); } @@ -1033,7 +1095,7 @@ impl<'a> Parser<'a> { // Parsing a pattern of the form `fieldname: pat`. let fieldname = self.parse_field_name()?; self.bump(); - let pat = self.parse_pat_allow_top_alt(None, RecoverComma::No)?; + let pat = self.parse_pat_allow_top_alt(None, RecoverComma::No, RecoverColon::No)?; hi = pat.span; (pat, fieldname, false) } else { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 45ea30b538691..be740b05fb8ee 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -903,8 +903,8 @@ impl BTreeSet { self.map.append(&mut other.map); } - /// Splits the collection into two at the given key. Returns everything after the given key, - /// including the key. + /// Splits the collection into two at the given value. Returns everything after the given value, + /// including the value. /// /// # Examples /// @@ -933,11 +933,11 @@ impl BTreeSet { /// assert!(b.contains(&41)); /// ``` #[stable(feature = "btree_split_off", since = "1.11.0")] - pub fn split_off(&mut self, key: &Q) -> Self + pub fn split_off(&mut self, value: &Q) -> Self where T: Borrow + Ord, { - BTreeSet { map: self.map.split_off(key) } + BTreeSet { map: self.map.split_off(value) } } /// Creates an iterator that visits all values in ascending order and uses a closure diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index 7b7ca8029b49d..b7ab4f19f0ad9 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -14,4 +14,4 @@ core = { path = "../core" } compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -cc = "1.0.68" +cc = "1.0.69" diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index c76ba7667d4e6..031d2942c51ad 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -21,7 +21,7 @@ compiler_builtins = "0.1.0" cfg-if = "0.1.8" [build-dependencies] -cc = "1.0.68" +cc = "1.0.69" [features] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 6fb7a1c088f33..64f022b4e8dae 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -40,7 +40,7 @@ cmake = "0.1.38" filetime = "0.2" num_cpus = "1.0" getopts = "0.2.19" -cc = "1.0.68" +cc = "1.0.69" libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 171d06c0a3667..9da3fe07adea0 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -161,7 +161,7 @@ pre, .rustdoc.source .example-wrap { .search-results a { color: #0096cf; } -.search-results a span.desc { +.search-results a div.desc { color: #c5c5c5; } @@ -286,7 +286,7 @@ details.undocumented > summary::before { color: grey; } -tr.result span.primitive::after, tr.result span.keyword::after { +.result-name .primitive > i, .result-name .keyword > i { color: #788797; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index d9ea28058ad99..599fb942dbe2a 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -247,7 +247,7 @@ details.undocumented > summary::before { color: grey; } -tr.result span.primitive::after, tr.result span.keyword::after { +.result-name .primitive > i, .result-name .keyword > i { color: #ddd; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 6785b79ffda96..0c2799727f3e3 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -237,7 +237,7 @@ details.undocumented > summary::before { color: grey; } -tr.result span.primitive::after, tr.result span.keyword::after { +.result-name .primitive > i, .result-name .keyword > i { color: black; } diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml new file mode 100644 index 0000000000000..bb8ecb98fa387 --- /dev/null +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -0,0 +1,41 @@ +// The goal of this test is to ensure the color of the text is the one expected. +goto: file://|DOC_PATH|/test_docs/index.html?search=coo + +// This is needed so that the text color is computed. +show-text: true + +// Ayu theme +local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"} +reload: + +// Waiting for the search results to appear... +wait-for: "#titles" +assert-css: ("//*[@class='desc']//*[text()='Just a normal struct.']", {"color": "rgb(197, 197, 197)"}) +assert-css: ("//*[@class='result-name']/*[text()='test_docs::']", {"color": "rgb(0, 150, 207)"}) + +// Checking the color for "keyword". +assert-css: ("//*[@class='result-name']//*[text()='(keyword)']", {"color": "rgb(120, 135, 151)"}) + +// Dark theme +local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"} +reload: + +// Waiting for the search results to appear... +wait-for: "#titles" +assert-css: ("//*[@class='desc']//*[text()='Just a normal struct.']", {"color": "rgb(221, 221, 221)"}) +assert-css: ("//*[@class='result-name']/*[text()='test_docs::']", {"color": "rgb(221, 221, 221)"}) + +// Checking the color for "keyword". +assert-css: ("//*[@class='result-name']//*[text()='(keyword)']", {"color": "rgb(221, 221, 221)"}) + +// Light theme +local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"} +reload: + +// Waiting for the search results to appear... +wait-for: "#titles" +assert-css: ("//*[@class='desc']//*[text()='Just a normal struct.']", {"color": "rgb(0, 0, 0)"}) +assert-css: ("//*[@class='result-name']/*[text()='test_docs::']", {"color": "rgb(0, 0, 0)"}) + +// Checking the color for "keyword". +assert-css: ("//*[@class='result-name']//*[text()='(keyword)']", {"color": "rgb(0, 0, 0)"}) diff --git a/src/test/rustdoc-gui/search-result-go-to-first.goml b/src/test/rustdoc-gui/search-result-go-to-first.goml new file mode 100644 index 0000000000000..5d709f6588118 --- /dev/null +++ b/src/test/rustdoc-gui/search-result-go-to-first.goml @@ -0,0 +1,20 @@ +// This test ensures that the "go_to_first" feature is working as expected. + +// First, we check that the first page doesn't have the string we're looking for to ensure +// that the feature is changing page as expected. +goto: file://|DOC_PATH|/test_docs/index.html +assert-text-false: (".fqn .in-band", "Struct test_docs::Foo") + +// We now check that we land on the search result page if "go_to_first" isn't set. +goto: file://|DOC_PATH|/test_docs/index.html?search=struct%3AFoo +// Waiting for the search results to appear... +wait-for: "#titles" +assert-text-false: (".fqn .in-band", "Struct test_docs::Foo") +// Ensure that the search results are displayed, not the "normal" content. +assert-css: ("#main", {"display": "none"}) + +// Now we can check that the feature is working as expected! +goto: file://|DOC_PATH|/test_docs/index.html?search=struct%3AFoo&go_to_first=true +// Waiting for the page to load... +wait-for: 500 +assert-text: (".fqn .in-band", "Struct test_docs::Foo") diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs index 3e753cb4de8b1..1b9f652120e94 100644 --- a/src/test/rustdoc-gui/src/test_docs/lib.rs +++ b/src/test/rustdoc-gui/src/test_docs/lib.rs @@ -101,6 +101,7 @@ pub enum AnEnum { } #[doc(keyword = "CookieMonster")] +/// Some keyword. pub mod keyword {} /// Just some type alias. diff --git a/src/test/ui/issues/issue-20427.rs b/src/test/ui/issues/issue-20427.rs index 41922c6229351..cfd8b2191ac38 100644 --- a/src/test/ui/issues/issue-20427.rs +++ b/src/test/ui/issues/issue-20427.rs @@ -7,7 +7,6 @@ #![allow(deprecated, deprecated_in_future)] // aux-build:i8.rs -// ignore-pretty issue #37201 extern crate i8; use std::string as i16; diff --git a/src/test/ui/issues/issue-22992.rs b/src/test/ui/issues/issue-22992.rs index e2ae1f96ee533..292a0ae298dcf 100644 --- a/src/test/ui/issues/issue-22992.rs +++ b/src/test/ui/issues/issue-22992.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-pretty issue #37201 struct X { val: i32 } impl std::ops::Deref for X { diff --git a/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs b/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs index 823be8c832d09..a99f260dde3b2 100644 --- a/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs +++ b/src/test/ui/issues/issue-23338-ensure-param-drop-order.rs @@ -1,8 +1,6 @@ // run-pass #![allow(non_upper_case_globals)] -// ignore-pretty issue #37201 - // This test is ensuring that parameters are indeed dropped after // temporaries in a fn body. diff --git a/src/test/ui/issues/issue-27401-dropflag-reinit.rs b/src/test/ui/issues/issue-27401-dropflag-reinit.rs index e137575c2f825..ab54af29bd6b9 100644 --- a/src/test/ui/issues/issue-27401-dropflag-reinit.rs +++ b/src/test/ui/issues/issue-27401-dropflag-reinit.rs @@ -1,5 +1,4 @@ // run-pass -// ignore-pretty issue #37201 // Check that when a `let`-binding occurs in a loop, its associated // drop-flag is reinitialized (to indicate "needs-drop" at the end of diff --git a/src/test/ui/parser/issue-87086-colon-path-sep.rs b/src/test/ui/parser/issue-87086-colon-path-sep.rs new file mode 100644 index 0000000000000..4ee0b2054ff77 --- /dev/null +++ b/src/test/ui/parser/issue-87086-colon-path-sep.rs @@ -0,0 +1,66 @@ +// Tests that a suggestion is issued if the user wrote a colon instead of +// a path separator in a match arm. + +enum Foo { + Bar, + Baz, +} + +fn f() -> Foo { Foo::Bar } + +fn g1() { + match f() { + Foo:Bar => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + Foo::Bar:Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + Foo:Bar::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + match f() { + Foo: Bar::Baz if true => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + _ => {} + } + if let Bar:Baz = f() { + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + } +} + +fn g1_neg() { + match f() { + ref Foo: Bar::Baz => {} + //~^ ERROR: expected one of + _ => {} + } +} + +fn g2_neg() { + match f() { + mut Foo: Bar::Baz => {} + //~^ ERROR: expected one of + _ => {} + } +} + +fn main() { + let myfoo = Foo::Bar; + match myfoo { + Foo::Bar => {} + Foo:Bar::Baz => {} + //~^ ERROR: expected one of + //~| HELP: maybe write a path separator here + } +} diff --git a/src/test/ui/parser/issue-87086-colon-path-sep.stderr b/src/test/ui/parser/issue-87086-colon-path-sep.stderr new file mode 100644 index 0000000000000..8f93661a62646 --- /dev/null +++ b/src/test/ui/parser/issue-87086-colon-path-sep.stderr @@ -0,0 +1,68 @@ +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:13:12 + | +LL | Foo:Bar => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:19:17 + | +LL | Foo::Bar:Baz => {} + | ^ + | | + | expected one of 8 possible tokens + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:25:12 + | +LL | Foo:Bar::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:31:12 + | +LL | Foo: Bar::Baz if true => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:36:15 + | +LL | if let Bar:Baz = f() { + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: expected one of `=>`, `@`, `if`, or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:44:16 + | +LL | ref Foo: Bar::Baz => {} + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: expected one of `=>`, `@`, `if`, or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:52:16 + | +LL | mut Foo: Bar::Baz => {} + | ^ expected one of `=>`, `@`, `if`, or `|` + +error: expected one of `@` or `|`, found `:` + --> $DIR/issue-87086-colon-path-sep.rs:62:12 + | +LL | Foo:Bar::Baz => {} + | ^ + | | + | expected one of `@` or `|` + | help: maybe write a path separator here: `::` + +error: aborting due to 8 previous errors +