mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 12:18:33 +00:00
Auto merge of #58903 - estebank:forgetful-delims, r=petrochenkov
Always emit unclosed delimiter diagnostics Fix #58886.
This commit is contained in:
commit
b58a0061a3
@ -439,8 +439,8 @@ impl cstore::CStore {
|
|||||||
|
|
||||||
let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
|
let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
|
||||||
let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
|
let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
|
||||||
let (body, errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
|
let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
|
||||||
emit_unclosed_delims(&errors, &sess.diagnostic());
|
emit_unclosed_delims(&mut errors, &sess.diagnostic());
|
||||||
|
|
||||||
// Mark the attrs as used
|
// Mark the attrs as used
|
||||||
let attrs = data.get_item_attrs(id.index, sess);
|
let attrs = data.get_item_attrs(id.index, sess);
|
||||||
|
@ -761,7 +761,7 @@ pub fn parse(
|
|||||||
else if bb_items.is_empty() && next_items.is_empty() {
|
else if bb_items.is_empty() && next_items.is_empty() {
|
||||||
return Failure(
|
return Failure(
|
||||||
parser.span,
|
parser.span,
|
||||||
parser.token,
|
parser.token.clone(),
|
||||||
"no rules expected this token in macro call",
|
"no rules expected this token in macro call",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use crate::source_map::{SourceMap, FilePathMapping};
|
|||||||
use crate::feature_gate::UnstableFeatures;
|
use crate::feature_gate::UnstableFeatures;
|
||||||
use crate::parse::parser::Parser;
|
use crate::parse::parser::Parser;
|
||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
|
use crate::syntax::parse::parser::emit_unclosed_delims;
|
||||||
use crate::tokenstream::{TokenStream, TokenTree};
|
use crate::tokenstream::{TokenStream, TokenTree};
|
||||||
use crate::diagnostics::plugin::ErrorMap;
|
use crate::diagnostics::plugin::ErrorMap;
|
||||||
use crate::print::pprust::token_to_string;
|
use crate::print::pprust::token_to_string;
|
||||||
@ -141,8 +142,14 @@ pub fn parse_stream_from_source_str(
|
|||||||
source: String,
|
source: String,
|
||||||
sess: &ParseSess,
|
sess: &ParseSess,
|
||||||
override_span: Option<Span>,
|
override_span: Option<Span>,
|
||||||
) -> (TokenStream, Vec<lexer::UnmatchedBrace>) {
|
) -> TokenStream {
|
||||||
source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span)
|
let (stream, mut errors) = source_file_to_stream(
|
||||||
|
sess,
|
||||||
|
sess.source_map().new_source_file(name, source),
|
||||||
|
override_span,
|
||||||
|
);
|
||||||
|
emit_unclosed_delims(&mut errors, &sess.span_diagnostic);
|
||||||
|
stream
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new parser from a source string.
|
/// Creates a new parser from a source string.
|
||||||
|
@ -46,7 +46,7 @@ use crate::ThinVec;
|
|||||||
use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
|
use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
|
||||||
use crate::symbol::{Symbol, keywords};
|
use crate::symbol::{Symbol, keywords};
|
||||||
|
|
||||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
|
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
|
||||||
use rustc_target::spec::abi::{self, Abi};
|
use rustc_target::spec::abi::{self, Abi};
|
||||||
use syntax_pos::{Span, MultiSpan, BytePos, FileName};
|
use syntax_pos::{Span, MultiSpan, BytePos, FileName};
|
||||||
use log::{debug, trace};
|
use log::{debug, trace};
|
||||||
@ -256,8 +256,15 @@ pub struct Parser<'a> {
|
|||||||
/// it gets removed from here. Every entry left at the end gets emitted as an independent
|
/// it gets removed from here. Every entry left at the end gets emitted as an independent
|
||||||
/// error.
|
/// error.
|
||||||
crate unclosed_delims: Vec<UnmatchedBrace>,
|
crate unclosed_delims: Vec<UnmatchedBrace>,
|
||||||
|
last_unexpected_token_span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Parser<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let diag = self.diagnostic();
|
||||||
|
emit_unclosed_delims(&mut self.unclosed_delims, diag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct TokenCursor {
|
struct TokenCursor {
|
||||||
@ -582,6 +589,7 @@ impl<'a> Parser<'a> {
|
|||||||
unmatched_angle_bracket_count: 0,
|
unmatched_angle_bracket_count: 0,
|
||||||
max_angle_bracket_count: 0,
|
max_angle_bracket_count: 0,
|
||||||
unclosed_delims: Vec::new(),
|
unclosed_delims: Vec::new(),
|
||||||
|
last_unexpected_token_span: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tok = parser.next_tok();
|
let tok = parser.next_tok();
|
||||||
@ -775,6 +783,8 @@ impl<'a> Parser<'a> {
|
|||||||
} else if inedible.contains(&self.token) {
|
} else if inedible.contains(&self.token) {
|
||||||
// leave it in the input
|
// leave it in the input
|
||||||
Ok(false)
|
Ok(false)
|
||||||
|
} else if self.last_unexpected_token_span == Some(self.span) {
|
||||||
|
FatalError.raise();
|
||||||
} else {
|
} else {
|
||||||
let mut expected = edible.iter()
|
let mut expected = edible.iter()
|
||||||
.map(|x| TokenType::Token(x.clone()))
|
.map(|x| TokenType::Token(x.clone()))
|
||||||
@ -802,6 +812,7 @@ impl<'a> Parser<'a> {
|
|||||||
(self.sess.source_map().next_point(self.prev_span),
|
(self.sess.source_map().next_point(self.prev_span),
|
||||||
format!("expected {} here", expect)))
|
format!("expected {} here", expect)))
|
||||||
};
|
};
|
||||||
|
self.last_unexpected_token_span = Some(self.span);
|
||||||
let mut err = self.fatal(&msg_exp);
|
let mut err = self.fatal(&msg_exp);
|
||||||
if self.token.is_ident_named("and") {
|
if self.token.is_ident_named("and") {
|
||||||
err.span_suggestion_short(
|
err.span_suggestion_short(
|
||||||
@ -1497,9 +1508,13 @@ impl<'a> Parser<'a> {
|
|||||||
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
|
pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
|
||||||
maybe_whole!(self, NtTraitItem, |x| x);
|
maybe_whole!(self, NtTraitItem, |x| x);
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
|
let mut unclosed_delims = vec![];
|
||||||
let (mut item, tokens) = self.collect_tokens(|this| {
|
let (mut item, tokens) = self.collect_tokens(|this| {
|
||||||
this.parse_trait_item_(at_end, attrs)
|
let item = this.parse_trait_item_(at_end, attrs);
|
||||||
|
unclosed_delims.append(&mut this.unclosed_delims);
|
||||||
|
item
|
||||||
})?;
|
})?;
|
||||||
|
self.unclosed_delims.append(&mut unclosed_delims);
|
||||||
// See `parse_item` for why this clause is here.
|
// See `parse_item` for why this clause is here.
|
||||||
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
|
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
|
||||||
item.tokens = Some(tokens);
|
item.tokens = Some(tokens);
|
||||||
@ -6333,7 +6348,10 @@ impl<'a> Parser<'a> {
|
|||||||
fn_inputs.append(&mut input);
|
fn_inputs.append(&mut input);
|
||||||
(fn_inputs, recovered)
|
(fn_inputs, recovered)
|
||||||
} else {
|
} else {
|
||||||
return self.unexpected();
|
match self.expect_one_of(&[], &[]) {
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
Ok(recovered) => (vec![self_arg], recovered),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
|
self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
|
||||||
@ -6459,9 +6477,13 @@ impl<'a> Parser<'a> {
|
|||||||
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
|
pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
|
||||||
maybe_whole!(self, NtImplItem, |x| x);
|
maybe_whole!(self, NtImplItem, |x| x);
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
|
let mut unclosed_delims = vec![];
|
||||||
let (mut item, tokens) = self.collect_tokens(|this| {
|
let (mut item, tokens) = self.collect_tokens(|this| {
|
||||||
this.parse_impl_item_(at_end, attrs)
|
let item = this.parse_impl_item_(at_end, attrs);
|
||||||
|
unclosed_delims.append(&mut this.unclosed_delims);
|
||||||
|
item
|
||||||
})?;
|
})?;
|
||||||
|
self.unclosed_delims.append(&mut unclosed_delims);
|
||||||
|
|
||||||
// See `parse_item` for why this clause is here.
|
// See `parse_item` for why this clause is here.
|
||||||
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
|
if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) {
|
||||||
@ -7781,9 +7803,13 @@ impl<'a> Parser<'a> {
|
|||||||
macros_allowed: bool,
|
macros_allowed: bool,
|
||||||
attributes_allowed: bool,
|
attributes_allowed: bool,
|
||||||
) -> PResult<'a, Option<P<Item>>> {
|
) -> PResult<'a, Option<P<Item>>> {
|
||||||
|
let mut unclosed_delims = vec![];
|
||||||
let (ret, tokens) = self.collect_tokens(|this| {
|
let (ret, tokens) = self.collect_tokens(|this| {
|
||||||
this.parse_item_implementation(attrs, macros_allowed, attributes_allowed)
|
let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed);
|
||||||
|
unclosed_delims.append(&mut this.unclosed_delims);
|
||||||
|
item
|
||||||
})?;
|
})?;
|
||||||
|
self.unclosed_delims.append(&mut unclosed_delims);
|
||||||
|
|
||||||
// Once we've parsed an item and recorded the tokens we got while
|
// Once we've parsed an item and recorded the tokens we got while
|
||||||
// parsing we may want to store `tokens` into the item we're about to
|
// parsing we may want to store `tokens` into the item we're about to
|
||||||
@ -8539,8 +8565,6 @@ impl<'a> Parser<'a> {
|
|||||||
module: self.parse_mod_items(&token::Eof, lo)?,
|
module: self.parse_mod_items(&token::Eof, lo)?,
|
||||||
span: lo.to(self.span),
|
span: lo.to(self.span),
|
||||||
});
|
});
|
||||||
emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
|
|
||||||
self.unclosed_delims.clear();
|
|
||||||
krate
|
krate
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8571,8 +8595,8 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
|
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
|
||||||
for unmatched in unclosed_delims {
|
for unmatched in unclosed_delims.iter() {
|
||||||
let mut err = handler.struct_span_err(unmatched.found_span, &format!(
|
let mut err = handler.struct_span_err(unmatched.found_span, &format!(
|
||||||
"incorrect close delimiter: `{}`",
|
"incorrect close delimiter: `{}`",
|
||||||
pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
|
pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
|
||||||
@ -8586,4 +8610,5 @@ pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors
|
|||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
unclosed_delims.clear();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ use crate::print::pprust;
|
|||||||
use crate::ptr::P;
|
use crate::ptr::P;
|
||||||
use crate::symbol::keywords;
|
use crate::symbol::keywords;
|
||||||
use crate::syntax::parse::parse_stream_from_source_str;
|
use crate::syntax::parse::parse_stream_from_source_str;
|
||||||
use crate::syntax::parse::parser::emit_unclosed_delims;
|
|
||||||
use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
|
use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
|
||||||
|
|
||||||
use syntax_pos::symbol::{self, Symbol};
|
use syntax_pos::symbol::{self, Symbol};
|
||||||
@ -675,9 +674,7 @@ impl Nonterminal {
|
|||||||
// FIXME(#43081): Avoid this pretty-print + reparse hack
|
// FIXME(#43081): Avoid this pretty-print + reparse hack
|
||||||
let source = pprust::nonterminal_to_string(self);
|
let source = pprust::nonterminal_to_string(self);
|
||||||
let filename = FileName::macro_expansion_source_code(&source);
|
let filename = FileName::macro_expansion_source_code(&source);
|
||||||
let (tokens_for_real, errors) =
|
let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
|
||||||
parse_stream_from_source_str(filename, source, sess, Some(span));
|
|
||||||
emit_unclosed_delims(&errors, &sess.span_diagnostic);
|
|
||||||
|
|
||||||
// During early phases of the compiler the AST could get modified
|
// During early phases of the compiler the AST could get modified
|
||||||
// directly (e.g., attributes added or removed) and the internal cache
|
// directly (e.g., attributes added or removed) and the internal cache
|
||||||
@ -740,13 +737,7 @@ fn prepend_attrs(sess: &ParseSess,
|
|||||||
let source = pprust::attr_to_string(attr);
|
let source = pprust::attr_to_string(attr);
|
||||||
let macro_filename = FileName::macro_expansion_source_code(&source);
|
let macro_filename = FileName::macro_expansion_source_code(&source);
|
||||||
if attr.is_sugared_doc {
|
if attr.is_sugared_doc {
|
||||||
let (stream, errors) = parse_stream_from_source_str(
|
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
|
||||||
macro_filename,
|
|
||||||
source,
|
|
||||||
sess,
|
|
||||||
Some(span),
|
|
||||||
);
|
|
||||||
emit_unclosed_delims(&errors, &sess.span_diagnostic);
|
|
||||||
builder.push(stream);
|
builder.push(stream);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -763,13 +754,7 @@ fn prepend_attrs(sess: &ParseSess,
|
|||||||
// ... and for more complicated paths, fall back to a reparse hack that
|
// ... and for more complicated paths, fall back to a reparse hack that
|
||||||
// should eventually be removed.
|
// should eventually be removed.
|
||||||
} else {
|
} else {
|
||||||
let (stream, errors) = parse_stream_from_source_str(
|
let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
|
||||||
macro_filename,
|
|
||||||
source,
|
|
||||||
sess,
|
|
||||||
Some(span),
|
|
||||||
);
|
|
||||||
emit_unclosed_delims(&errors, &sess.span_diagnostic);
|
|
||||||
brackets.push(stream);
|
brackets.push(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ use syntax::ast;
|
|||||||
use syntax::ext::base::ExtCtxt;
|
use syntax::ext::base::ExtCtxt;
|
||||||
use syntax::parse::lexer::comments;
|
use syntax::parse::lexer::comments;
|
||||||
use syntax::parse::{self, token, ParseSess};
|
use syntax::parse::{self, token, ParseSess};
|
||||||
use syntax::parse::parser::emit_unclosed_delims;
|
|
||||||
use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
|
use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
|
||||||
use syntax_pos::hygiene::{SyntaxContext, Transparency};
|
use syntax_pos::hygiene::{SyntaxContext, Transparency};
|
||||||
use syntax_pos::symbol::{keywords, Symbol};
|
use syntax_pos::symbol::{keywords, Symbol};
|
||||||
@ -410,14 +409,12 @@ impl server::TokenStream for Rustc<'_> {
|
|||||||
stream.is_empty()
|
stream.is_empty()
|
||||||
}
|
}
|
||||||
fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
fn from_str(&mut self, src: &str) -> Self::TokenStream {
|
||||||
let (tokens, errors) = parse::parse_stream_from_source_str(
|
parse::parse_stream_from_source_str(
|
||||||
FileName::proc_macro_source_code(src.clone()),
|
FileName::proc_macro_source_code(src.clone()),
|
||||||
src.to_string(),
|
src.to_string(),
|
||||||
self.sess,
|
self.sess,
|
||||||
Some(self.call_site),
|
Some(self.call_site),
|
||||||
);
|
)
|
||||||
emit_unclosed_delims(&errors, &self.sess.span_diagnostic);
|
|
||||||
tokens
|
|
||||||
}
|
}
|
||||||
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
|
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
|
||||||
stream.to_string()
|
stream.to_string()
|
||||||
|
6
src/test/ui/issues/issue-58856-1.rs
Normal file
6
src/test/ui/issues/issue-58856-1.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
impl A {
|
||||||
|
fn b(self>
|
||||||
|
//~^ ERROR expected one of `)`, `,`, or `:`, found `>`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
11
src/test/ui/issues/issue-58856-1.stderr
Normal file
11
src/test/ui/issues/issue-58856-1.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expected one of `)`, `,`, or `:`, found `>`
|
||||||
|
--> $DIR/issue-58856-1.rs:2:14
|
||||||
|
|
|
||||||
|
LL | fn b(self>
|
||||||
|
| - ^
|
||||||
|
| | |
|
||||||
|
| | help: `)` may belong here
|
||||||
|
| unclosed delimiter
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
14
src/test/ui/issues/issue-58856-2.rs
Normal file
14
src/test/ui/issues/issue-58856-2.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
struct Empty;
|
||||||
|
|
||||||
|
trait Howness {}
|
||||||
|
|
||||||
|
impl Howness for () {
|
||||||
|
fn how_are_you(&self -> Empty {
|
||||||
|
//~^ ERROR expected one of `)` or `,`, found `->`
|
||||||
|
//~| ERROR method `how_are_you` is not a member of trait `Howness`
|
||||||
|
Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`,
|
||||||
|
|
||||||
|
fn main() {}
|
30
src/test/ui/issues/issue-58856-2.stderr
Normal file
30
src/test/ui/issues/issue-58856-2.stderr
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
error: expected one of `)` or `,`, found `->`
|
||||||
|
--> $DIR/issue-58856-2.rs:6:26
|
||||||
|
|
|
||||||
|
LL | fn how_are_you(&self -> Empty {
|
||||||
|
| - -^^
|
||||||
|
| | |
|
||||||
|
| | help: `)` may belong here
|
||||||
|
| unclosed delimiter
|
||||||
|
|
||||||
|
error: expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `)`
|
||||||
|
--> $DIR/issue-58856-2.rs:11:1
|
||||||
|
|
|
||||||
|
LL | }
|
||||||
|
| - expected one of 11 possible tokens here
|
||||||
|
LL | }
|
||||||
|
| ^ unexpected token
|
||||||
|
|
||||||
|
error[E0407]: method `how_are_you` is not a member of trait `Howness`
|
||||||
|
--> $DIR/issue-58856-2.rs:6:5
|
||||||
|
|
|
||||||
|
LL | / fn how_are_you(&self -> Empty {
|
||||||
|
LL | | //~^ ERROR expected one of `)` or `,`, found `->`
|
||||||
|
LL | | //~| ERROR method `how_are_you` is not a member of trait `Howness`
|
||||||
|
LL | | Empty
|
||||||
|
LL | | }
|
||||||
|
| |_____^ not a member of trait `Howness`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0407`.
|
@ -25,9 +25,6 @@ fn main() {
|
|||||||
// fail again
|
// fail again
|
||||||
enum Test4 {
|
enum Test4 {
|
||||||
Nope(i32 {}) //~ ERROR: found `{`
|
Nope(i32 {}) //~ ERROR: found `{`
|
||||||
//~^ ERROR: found `{`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// still recover later
|
|
||||||
let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
|
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,5 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
|
|||||||
LL | Nope(i32 {}) //~ ERROR: found `{`
|
LL | Nope(i32 {}) //~ ERROR: found `{`
|
||||||
| ^ expected one of 7 possible tokens here
|
| ^ expected one of 7 possible tokens here
|
||||||
|
|
||||||
error: expected one of `!`, `&&`, `&`, `(`, `)`, `*`, `+`, `,`, `...`, `::`, `<`, `?`, `[`, `_`, `crate`, `dyn`, `extern`, `fn`, `for`, `impl`, `pub`, `unsafe`, `}`, or lifetime, found `{`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/recover-enum2.rs:27:22
|
|
||||||
|
|
|
||||||
LL | Nope(i32 {}) //~ ERROR: found `{`
|
|
||||||
| ^ expected one of 24 possible tokens here
|
|
||||||
|
|
||||||
error: expected expression, found reserved identifier `_`
|
|
||||||
--> $DIR/recover-enum2.rs:32:22
|
|
||||||
|
|
|
||||||
LL | let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
|
|
||||||
| ^ expected expression
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
|
6
src/test/ui/parser/unclosed-delimiter-in-dep.rs
Normal file
6
src/test/ui/parser/unclosed-delimiter-in-dep.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
mod unclosed_delim_mod;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _: usize = unclosed_delim_mod::new();
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
23
src/test/ui/parser/unclosed-delimiter-in-dep.stderr
Normal file
23
src/test/ui/parser/unclosed-delimiter-in-dep.stderr
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
error: incorrect close delimiter: `}`
|
||||||
|
--> $DIR/unclosed_delim_mod.rs:5:1
|
||||||
|
|
|
||||||
|
LL | pub fn new() -> Result<Value, ()> {
|
||||||
|
| - close delimiter possibly meant for this
|
||||||
|
LL | Ok(Value {
|
||||||
|
| - un-closed delimiter
|
||||||
|
LL | }
|
||||||
|
LL | }
|
||||||
|
| ^ incorrect close delimiter
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/unclosed-delimiter-in-dep.rs:4:20
|
||||||
|
|
|
||||||
|
LL | let _: usize = unclosed_delim_mod::new();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected usize, found enum `std::result::Result`
|
||||||
|
|
|
||||||
|
= note: expected type `usize`
|
||||||
|
found type `std::result::Result<unclosed_delim_mod::Value, ()>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
6
src/test/ui/parser/unclosed_delim_mod.rs
Normal file
6
src/test/ui/parser/unclosed_delim_mod.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
pub struct Value {}
|
||||||
|
pub fn new() -> Result<Value, ()> {
|
||||||
|
Ok(Value {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//~^ ERROR incorrect close delimiter
|
18
src/test/ui/parser/unclosed_delim_mod.stderr
Normal file
18
src/test/ui/parser/unclosed_delim_mod.stderr
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
error: incorrect close delimiter: `}`
|
||||||
|
--> $DIR/unclosed_delim_mod.rs:5:1
|
||||||
|
|
|
||||||
|
LL | pub fn new() -> Result<Value, ()> {
|
||||||
|
| - close delimiter possibly meant for this
|
||||||
|
LL | Ok(Value {
|
||||||
|
| - un-closed delimiter
|
||||||
|
LL | }
|
||||||
|
LL | }
|
||||||
|
| ^ incorrect close delimiter
|
||||||
|
|
||||||
|
error[E0601]: `main` function not found in crate `unclosed_delim_mod`
|
||||||
|
|
|
||||||
|
= note: consider adding a `main` function to `$DIR/unclosed_delim_mod.rs`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0601`.
|
@ -10,16 +10,14 @@ pub mod raw {
|
|||||||
pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P,
|
pub fn ensure_dir_exists<P: AsRef<Path>, F: FnOnce(&Path)>(path: P,
|
||||||
callback: F)
|
callback: F)
|
||||||
-> io::Result<bool> {
|
-> io::Result<bool> {
|
||||||
if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
|
if !is_directory(path.as_ref()) {
|
||||||
callback(path.as_ref(); //~ ERROR expected one of
|
//~^ ERROR cannot find function `is_directory`
|
||||||
fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
|
callback(path.as_ref();
|
||||||
//~^ expected (), found enum `std::result::Result`
|
//~^ ERROR expected one of
|
||||||
//~| expected type `()`
|
fs::create_dir_all(path.as_ref()).map(|()| true)
|
||||||
//~| found type `std::result::Result<bool, std::io::Error>`
|
//~^ ERROR mismatched types
|
||||||
//~| expected one of
|
|
||||||
} else {
|
} else {
|
||||||
//~^ ERROR: expected one of
|
//~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
|
||||||
//~| unexpected token
|
|
||||||
Ok(false);
|
Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
|
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
|
||||||
--> $DIR/token-error-correct-3.rs:14:35
|
--> $DIR/token-error-correct-3.rs:15:35
|
||||||
|
|
|
|
||||||
LL | callback(path.as_ref(); //~ ERROR expected one of
|
LL | callback(path.as_ref();
|
||||||
| - ^
|
| - ^
|
||||||
| | |
|
| | |
|
||||||
| | help: `)` may belong here
|
| | help: `)` may belong here
|
||||||
| unclosed delimiter
|
| unclosed delimiter
|
||||||
|
|
||||||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
|
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
|
||||||
--> $DIR/token-error-correct-3.rs:20:9
|
--> $DIR/token-error-correct-3.rs:19:9
|
||||||
|
|
|
|
||||||
LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true)
|
||||||
| - expected one of `.`, `;`, `?`, `}`, or an operator here
|
| - expected one of `.`, `;`, `?`, `}`, or an operator here
|
||||||
...
|
LL | //~^ ERROR mismatched types
|
||||||
LL | } else {
|
LL | } else {
|
||||||
| ^ unexpected token
|
| ^ unexpected token
|
||||||
|
|
||||||
error[E0425]: cannot find function `is_directory` in this scope
|
error[E0425]: cannot find function `is_directory` in this scope
|
||||||
--> $DIR/token-error-correct-3.rs:13:13
|
--> $DIR/token-error-correct-3.rs:13:13
|
||||||
|
|
|
|
||||||
LL | if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
|
LL | if !is_directory(path.as_ref()) {
|
||||||
| ^^^^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/token-error-correct-3.rs:15:13
|
--> $DIR/token-error-correct-3.rs:17:13
|
||||||
|
|
|
|
||||||
LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
|
LL | fs::create_dir_all(path.as_ref()).map(|()| true)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
|
||||||
| |
|
| |
|
||||||
| expected (), found enum `std::result::Result`
|
| expected (), found enum `std::result::Result`
|
||||||
|
Loading…
Reference in New Issue
Block a user