Auto merge of #56897 - euclio:parse-fatal, r=estebank

make `panictry!` private to libsyntax

This commit completely removes usage of the `panictry!` macro from
outside libsyntax. The macro causes parse errors to be fatal, so using
it in libsyntax_ext caused parse failures *within* a syntax extension to
be fatal, which is probably not intended.

Furthermore, this commit adds spans to diagnostics emitted by empty
extensions if they were missing, à la #56491.
This commit is contained in:
bors 2019-01-04 19:39:24 +00:00
commit f381a96255
22 changed files with 451 additions and 134 deletions

View File

@ -23,7 +23,7 @@ use syntax::json::JsonEmitter;
use syntax::ptr::P;
use syntax::symbol::keywords;
use syntax_pos::DUMMY_SP;
use errors;
use errors::{self, FatalError};
use errors::emitter::{Emitter, EmitterWriter};
use parking_lot::ReentrantMutex;
@ -429,7 +429,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
let control = &driver::CompileController::basic();
let krate = panictry!(driver::phase_1_parse_input(control, &sess, &input));
let krate = match driver::phase_1_parse_input(control, &sess, &input) {
Ok(krate) => krate,
Err(mut e) => {
e.emit();
FatalError.raise();
}
};
let name = match crate_name {
Some(ref crate_name) => crate_name.clone(),

View File

@ -32,7 +32,7 @@ extern crate rustc_metadata;
extern crate rustc_target;
extern crate rustc_typeck;
extern crate serialize;
#[macro_use] extern crate syntax;
extern crate syntax;
extern crate syntax_pos;
extern crate test as testing;
#[macro_use] extern crate log;

View File

@ -1,4 +1,4 @@
use errors;
use errors::{self, FatalError};
use errors::emitter::ColorConfig;
use rustc_data_structures::sync::Lrc;
use rustc_lint;
@ -84,9 +84,14 @@ pub fn run(mut options: Options) -> isize {
target_features::add_configuration(&mut cfg, &sess, &*codegen_backend);
sess.parse_sess.config = cfg;
let krate = panictry!(driver::phase_1_parse_input(&driver::CompileController::basic(),
&sess,
&input));
let krate =
match driver::phase_1_parse_input(&driver::CompileController::basic(), &sess, &input) {
Ok(krate) => krate,
Err(mut e) => {
e.emit();
FatalError.raise();
}
};
let driver::ExpansionResult { defs, mut hir_forest, .. } = {
phase_2_configure_and_expand(
&sess,

View File

@ -44,8 +44,6 @@ use ast::AttrId;
// way towards a non-panic!-prone parser. It should be used for fatal parsing
// errors; eventually we plan to convert all code using panictry to just use
// normal try.
// Exported for syntax_ext, not meant for general use.
#[macro_export]
macro_rules! panictry {
($e:expr) => ({
use std::result::Result::{Ok, Err};

View File

@ -4,6 +4,7 @@ use self::State::*;
use rustc_data_structures::thin_vec::ThinVec;
use errors::DiagnosticBuilder;
use syntax::ast;
use syntax::ext::base;
use syntax::ext::base::*;
@ -51,6 +52,34 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
feature_gate::EXPLAIN_ASM);
}
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
Ok(Some(inline_asm)) => inline_asm,
Ok(None) => return DummyResult::expr(sp),
Err(mut err) => {
err.emit();
return DummyResult::expr(sp);
}
};
// If there are no outputs, the inline assembly is executed just for its side effects,
// so ensure that it is volatile
if inline_asm.outputs.is_empty() {
inline_asm.volatile = true;
}
MacEager::expr(P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp,
attrs: ThinVec::new(),
}))
}
fn parse_inline_asm<'a>(
cx: &mut ExtCtxt<'a>,
sp: Span,
tts: &[tokenstream::TokenTree],
) -> Result<Option<ast::InlineAsm>, DiagnosticBuilder<'a>> {
// Split the tts before the first colon, to avoid `asm!("x": y)` being
// parsed as `asm!(z)` with `z = "x": y` which is type ascription.
let first_colon = tts.iter()
@ -80,22 +109,33 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
if asm_str_style.is_some() {
// If we already have a string with instructions,
// ending up in Asm state again is an error.
span_err!(cx, sp, E0660, "malformed inline assembly");
return DummyResult::expr(sp);
return Err(struct_span_err!(
cx.parse_sess.span_diagnostic,
sp,
E0660,
"malformed inline assembly"
));
}
// Nested parser, stop before the first colon (see above).
let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
let (s, style) = match expr_to_string(cx,
panictry!(p2.parse_expr()),
"inline assembly must be a string literal") {
Some((s, st)) => (s, st),
// let compilation continue
None => return DummyResult::expr(sp),
};
if p2.token == token::Eof {
let mut err =
cx.struct_span_err(sp, "macro requires a string literal as an argument");
err.span_label(sp, "string literal required");
return Err(err);
}
let expr = p2.parse_expr()?;
let (s, style) =
match expr_to_string(cx, expr, "inline assembly must be a string literal") {
Some((s, st)) => (s, st),
None => return Ok(None),
};
// This is most likely malformed.
if p2.token != token::Eof {
let mut extra_tts = panictry!(p2.parse_all_token_trees());
let mut extra_tts = p2.parse_all_token_trees()?;
extra_tts.extend(tts[first_colon..].iter().cloned());
p = parse::stream_to_parser(cx.parse_sess, extra_tts.into_iter().collect());
}
@ -105,18 +145,17 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
}
Outputs => {
while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !outputs.is_empty() {
p.eat(&token::Comma);
}
let (constraint, _str_style) = panictry!(p.parse_str());
let (constraint, _) = p.parse_str()?;
let span = p.prev_span;
panictry!(p.expect(&token::OpenDelim(token::Paren)));
let out = panictry!(p.parse_expr());
panictry!(p.expect(&token::CloseDelim(token::Paren)));
p.expect(&token::OpenDelim(token::Paren))?;
let expr = p.parse_expr()?;
p.expect(&token::CloseDelim(token::Paren))?;
// Expands a read+write operand into two operands.
//
@ -143,7 +182,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
let is_indirect = constraint_str.contains("*");
outputs.push(ast::InlineAsmOutput {
constraint: output.unwrap_or(constraint),
expr: out,
expr,
is_rw,
is_indirect,
});
@ -151,12 +190,11 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
}
Inputs => {
while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !inputs.is_empty() {
p.eat(&token::Comma);
}
let (constraint, _str_style) = panictry!(p.parse_str());
let (constraint, _) = p.parse_str()?;
if constraint.as_str().starts_with("=") {
span_err!(cx, p.prev_span, E0662,
@ -166,21 +204,20 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
"input operand constraint contains '+'");
}
panictry!(p.expect(&token::OpenDelim(token::Paren)));
let input = panictry!(p.parse_expr());
panictry!(p.expect(&token::CloseDelim(token::Paren)));
p.expect(&token::OpenDelim(token::Paren))?;
let input = p.parse_expr()?;
p.expect(&token::CloseDelim(token::Paren))?;
inputs.push((constraint, input));
}
}
Clobbers => {
while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !clobs.is_empty() {
p.eat(&token::Comma);
}
let (s, _str_style) = panictry!(p.parse_str());
let (s, _) = p.parse_str()?;
if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.prev_span, "expected a clobber, found an option");
@ -193,7 +230,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
}
}
Options => {
let (option, _str_style) = panictry!(p.parse_str());
let (option, _) = p.parse_str()?;
if option == "volatile" {
// Indicates that the inline assembly has side effects
@ -234,26 +271,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
}
}
// If there are no outputs, the inline assembly is executed just for its side effects,
// so ensure that it is volatile
if outputs.is_empty() {
volatile = true;
}
MacEager::expr(P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::InlineAsm(P(ast::InlineAsm {
asm,
asm_str_style: asm_str_style.unwrap(),
outputs,
inputs,
clobbers: clobs,
volatile,
alignstack,
dialect,
ctxt: cx.backtrace(),
})),
span: sp,
attrs: ThinVec::new(),
Ok(Some(ast::InlineAsm {
asm,
asm_str_style: asm_str_style.unwrap(),
outputs,
inputs,
clobbers: clobs,
volatile,
alignstack,
dialect,
ctxt: cx.backtrace(),
}))
}

View File

@ -1,9 +1,11 @@
use syntax::ast::*;
use errors::DiagnosticBuilder;
use syntax::ast::{self, *};
use syntax::source_map::Spanned;
use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax::tokenstream::{TokenStream, TokenTree};
use syntax_pos::{Span, DUMMY_SP};
@ -13,33 +15,18 @@ pub fn expand_assert<'cx>(
sp: Span,
tts: &[TokenTree],
) -> Box<dyn MacResult + 'cx> {
let mut parser = cx.new_parser_from_tts(tts);
if parser.token == token::Eof {
cx.struct_span_err(sp, "macro requires a boolean expression as an argument")
.span_label(sp, "boolean expression required")
.emit();
return DummyResult::expr(sp);
}
let cond_expr = panictry!(parser.parse_expr());
let custom_msg_args = if parser.eat(&token::Comma) {
let ts = parser.parse_tokens();
if !ts.is_empty() {
Some(ts)
} else {
None
let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
Ok(assert) => assert,
Err(mut err) => {
err.emit();
return DummyResult::expr(sp);
}
} else {
None
};
let sp = sp.apply_mark(cx.current_expansion.mark);
let panic_call = Mac_ {
path: Path::from_ident(Ident::new(Symbol::intern("panic"), sp)),
tts: if let Some(ts) = custom_msg_args {
ts.into()
} else {
tts: custom_message.unwrap_or_else(|| {
TokenStream::from(TokenTree::Token(
DUMMY_SP,
token::Literal(
@ -49,8 +36,8 @@ pub fn expand_assert<'cx>(
))),
None,
),
)).into()
},
))
}).into(),
delim: MacDelimiter::Parenthesis,
};
let if_expr = cx.expr_if(
@ -67,3 +54,36 @@ pub fn expand_assert<'cx>(
);
MacEager::expr(if_expr)
}
struct Assert {
cond_expr: P<ast::Expr>,
custom_message: Option<TokenStream>,
}
fn parse_assert<'a>(
cx: &mut ExtCtxt<'a>,
sp: Span,
tts: &[TokenTree]
) -> Result<Assert, DiagnosticBuilder<'a>> {
let mut parser = cx.new_parser_from_tts(tts);
if parser.token == token::Eof {
let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
err.span_label(sp, "boolean expression required");
return Err(err);
}
Ok(Assert {
cond_expr: parser.parse_expr()?,
custom_message: if parser.eat(&token::Comma) {
let ts = parser.parse_tokens();
if !ts.is_empty() {
Some(ts)
} else {
None
}
} else {
None
},
})
}

View File

@ -2,6 +2,8 @@
/// a literal `true` or `false` based on whether the given cfg matches the
/// current compilation environment.
use errors::DiagnosticBuilder;
use syntax::ast;
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
@ -15,16 +17,39 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
tts: &[tokenstream::TokenTree])
-> Box<dyn base::MacResult + 'static> {
let sp = sp.apply_mark(cx.current_expansion.mark);
match parse_cfg(cx, sp, tts) {
Ok(cfg) => {
let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
MacEager::expr(cx.expr_bool(sp, matches_cfg))
}
Err(mut err) => {
err.emit();
DummyResult::expr(sp)
}
}
}
fn parse_cfg<'a>(
cx: &mut ExtCtxt<'a>,
sp: Span,
tts: &[tokenstream::TokenTree],
) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> {
let mut p = cx.new_parser_from_tts(tts);
let cfg = panictry!(p.parse_meta_item());
if p.token == token::Eof {
let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument");
err.span_label(sp, "cfg-pattern required");
return Err(err);
}
let cfg = p.parse_meta_item()?;
let _ = p.eat(&token::Comma);
if !p.eat(&token::Eof) {
cx.span_err(sp, "expected 1 cfg-pattern");
return DummyResult::expr(sp);
return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern"));
}
let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
MacEager::expr(cx.expr_bool(sp, matches_cfg))
Ok(cfg)
}

View File

@ -3,6 +3,7 @@ use self::Position::*;
use fmt_macros as parse;
use errors::DiagnosticBuilder;
use syntax::ast;
use syntax::ext::base::{self, *};
use syntax::ext::build::AstBuilder;
@ -112,7 +113,7 @@ struct Context<'a, 'b: 'a> {
is_literal: bool,
}
/// Parses the arguments from the given list of tokens, returning None
/// Parses the arguments from the given list of tokens, returning the diagnostic
/// if there's a parse error so we can continue parsing other format!
/// expressions.
///
@ -121,27 +122,26 @@ struct Context<'a, 'b: 'a> {
/// ```text
/// Some((fmtstr, parsed arguments, index map for named arguments))
/// ```
fn parse_args(ecx: &mut ExtCtxt,
sp: Span,
tts: &[tokenstream::TokenTree])
-> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>)> {
fn parse_args<'a>(
ecx: &mut ExtCtxt<'a>,
sp: Span,
tts: &[tokenstream::TokenTree]
) -> Result<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<String, usize>), DiagnosticBuilder<'a>> {
let mut args = Vec::<P<ast::Expr>>::new();
let mut names = FxHashMap::<String, usize>::default();
let mut p = ecx.new_parser_from_tts(tts);
if p.token == token::Eof {
ecx.span_err(sp, "requires at least a format string argument");
return None;
return Err(ecx.struct_span_err(sp, "requires at least a format string argument"));
}
let fmtstr = panictry!(p.parse_expr());
let fmtstr = p.parse_expr()?;
let mut named = false;
while p.token != token::Eof {
if !p.eat(&token::Comma) {
ecx.span_err(p.span, "expected token: `,`");
return None;
return Err(ecx.struct_span_err(p.span, "expected token: `,`"));
}
if p.token == token::Eof {
break;
@ -152,16 +152,15 @@ fn parse_args(ecx: &mut ExtCtxt,
p.bump();
i
} else {
ecx.span_err(
return Err(ecx.struct_span_err(
p.span,
"expected ident, positional arguments cannot follow named arguments",
);
return None;
));
};
let name: &str = &ident.as_str();
panictry!(p.expect(&token::Eq));
let e = panictry!(p.parse_expr());
p.expect(&token::Eq).unwrap();
let e = p.parse_expr()?;
if let Some(prev) = names.get(name) {
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
.span_note(args[*prev].span, "previously here")
@ -177,10 +176,11 @@ fn parse_args(ecx: &mut ExtCtxt,
names.insert(name.to_string(), slot);
args.push(e);
} else {
args.push(panictry!(p.parse_expr()));
let e = p.parse_expr()?;
args.push(e);
}
}
Some((fmtstr, args, names))
Ok((fmtstr, args, names))
}
impl<'a, 'b> Context<'a, 'b> {
@ -689,10 +689,13 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
-> Box<dyn base::MacResult + 'cx> {
sp = sp.apply_mark(ecx.current_expansion.mark);
match parse_args(ecx, sp, tts) {
Some((efmt, args, names)) => {
Ok((efmt, args, names)) => {
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, false))
}
None => DummyResult::expr(sp),
Err(mut err) => {
err.emit();
DummyResult::expr(sp)
}
}
}
@ -716,10 +719,13 @@ pub fn expand_format_args_nl<'cx>(
}
sp = sp.apply_mark(ecx.current_expansion.mark);
match parse_args(ecx, sp, tts) {
Some((efmt, args, names)) => {
Ok((efmt, args, names)) => {
MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, true))
}
None => DummyResult::expr(sp),
Err(mut err) => {
err.emit();
DummyResult::expr(sp)
}
}
}

View File

@ -8,11 +8,13 @@
/// LLVM's `module asm "some assembly here"`. All of LLVM's caveats
/// therefore apply.
use errors::DiagnosticBuilder;
use syntax::ast;
use syntax::source_map::respan;
use syntax::ext::base;
use syntax::ext::base::*;
use syntax::feature_gate;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax_pos::Span;
@ -31,24 +33,47 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
feature_gate::EXPLAIN_GLOBAL_ASM);
}
match parse_global_asm(cx, sp, tts) {
Ok(Some(global_asm)) => {
MacEager::items(smallvec![P(ast::Item {
ident: ast::Ident::with_empty_ctxt(Symbol::intern("")),
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::GlobalAsm(P(global_asm)),
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
span: sp,
tokens: None,
})])
}
Ok(None) => DummyResult::any(sp),
Err(mut err) => {
err.emit();
DummyResult::any(sp)
}
}
}
fn parse_global_asm<'a>(
cx: &mut ExtCtxt<'a>,
sp: Span,
tts: &[tokenstream::TokenTree]
) -> Result<Option<ast::GlobalAsm>, DiagnosticBuilder<'a>> {
let mut p = cx.new_parser_from_tts(tts);
let (asm, _) = match expr_to_string(cx,
panictry!(p.parse_expr()),
"inline assembly must be a string literal") {
if p.token == token::Eof {
let mut err = cx.struct_span_err(sp, "macro requires a string literal as an argument");
err.span_label(sp, "string literal required");
return Err(err);
}
let expr = p.parse_expr()?;
let (asm, _) = match expr_to_string(cx, expr, "inline assembly must be a string literal") {
Some((s, st)) => (s, st),
None => return DummyResult::any(sp),
None => return Ok(None),
};
MacEager::items(smallvec![P(ast::Item {
ident: ast::Ident::with_empty_ctxt(Symbol::intern("")),
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::GlobalAsm(P(ast::GlobalAsm {
asm,
ctxt: cx.backtrace(),
})),
vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
span: sp,
tokens: None,
})])
Ok(Some(ast::GlobalAsm {
asm,
ctxt: cx.backtrace(),
}))
}

View File

@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope
3 | no
| ^^ not found in this scope
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:316:13
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:321:13
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ----
@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 11)' panicked at 'test
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
', src/librustdoc/test.rs:351:17
', src/librustdoc/test.rs:356:17
failures:

View File

@ -0,0 +1,15 @@
#![feature(asm)]
fn main() {
asm!(); //~ ERROR requires a string literal as an argument
asm!("nop" : struct); //~ ERROR expected string literal
asm!("mov %eax, $$0x2" : struct); //~ ERROR expected string literal
asm!("mov %eax, $$0x2" : "={eax}" struct); //~ ERROR expected `(`
asm!("mov %eax, $$0x2" : "={eax}"(struct)); //~ ERROR expected expression
asm!("in %dx, %al" : "={al}"(result) : struct); //~ ERROR expected string literal
asm!("in %dx, %al" : "={al}"(result) : "{dx}" struct); //~ ERROR expected `(`
asm!("in %dx, %al" : "={al}"(result) : "{dx}"(struct)); //~ ERROR expected expression
asm!("mov $$0x200, %eax" : : : struct); //~ ERROR expected string literal
asm!("mov eax, 2" : "={eax}"(foo) : : : struct); //~ ERROR expected string literal
asm!(123); //~ ERROR inline assembly must be a string literal
}

View File

@ -0,0 +1,68 @@
error: macro requires a string literal as an argument
--> $DIR/asm-parse-errors.rs:4:5
|
LL | asm!(); //~ ERROR requires a string literal as an argument
| ^^^^^^^ string literal required
error: expected string literal
--> $DIR/asm-parse-errors.rs:5:18
|
LL | asm!("nop" : struct); //~ ERROR expected string literal
| ^^^^^^ expected string literal
error: expected string literal
--> $DIR/asm-parse-errors.rs:6:30
|
LL | asm!("mov %eax, $$0x2" : struct); //~ ERROR expected string literal
| ^^^^^^ expected string literal
error: expected `(`, found keyword `struct`
--> $DIR/asm-parse-errors.rs:7:39
|
LL | asm!("mov %eax, $$0x2" : "={eax}" struct); //~ ERROR expected `(`
| ^^^^^^ expected `(`
error: expected expression, found keyword `struct`
--> $DIR/asm-parse-errors.rs:8:39
|
LL | asm!("mov %eax, $$0x2" : "={eax}"(struct)); //~ ERROR expected expression
| ^^^^^^ expected expression
error: expected string literal
--> $DIR/asm-parse-errors.rs:9:44
|
LL | asm!("in %dx, %al" : "={al}"(result) : struct); //~ ERROR expected string literal
| ^^^^^^ expected string literal
error: expected `(`, found keyword `struct`
--> $DIR/asm-parse-errors.rs:10:51
|
LL | asm!("in %dx, %al" : "={al}"(result) : "{dx}" struct); //~ ERROR expected `(`
| ^^^^^^ expected `(`
error: expected expression, found keyword `struct`
--> $DIR/asm-parse-errors.rs:11:51
|
LL | asm!("in %dx, %al" : "={al}"(result) : "{dx}"(struct)); //~ ERROR expected expression
| ^^^^^^ expected expression
error: expected string literal
--> $DIR/asm-parse-errors.rs:12:36
|
LL | asm!("mov $$0x200, %eax" : : : struct); //~ ERROR expected string literal
| ^^^^^^ expected string literal
error: expected string literal
--> $DIR/asm-parse-errors.rs:13:45
|
LL | asm!("mov eax, 2" : "={eax}"(foo) : : : struct); //~ ERROR expected string literal
| ^^^^^^ expected string literal
error: inline assembly must be a string literal
--> $DIR/asm-parse-errors.rs:14:10
|
LL | asm!(123); //~ ERROR inline assembly must be a string literal
| ^^^
error: aborting due to 11 previous errors

View File

@ -1,5 +1,7 @@
#![feature(type_ascription)]
fn main() {
let a : u32 = 0;
let a : usize = 0;
let long_name : usize = 0;
println!("{}", a as usize > long_name);

View File

@ -1,5 +1,5 @@
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:6:31
--> $DIR/issue-22644.rs:8:31
|
LL | println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic
| ---------- ^ --------- interpreted as generic arguments
@ -8,7 +8,7 @@ LL | println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as
| help: try comparing the cast value: `(a as usize)`
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:7:33
--> $DIR/issue-22644.rs:9:33
|
LL | println!("{}{}", a as usize < long_name, long_name);
| ---------- ^ -------------------- interpreted as generic arguments
@ -17,7 +17,7 @@ LL | println!("{}{}", a as usize < long_name, long_name);
| help: try comparing the cast value: `(a as usize)`
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:9:31
--> $DIR/issue-22644.rs:11:31
|
LL | println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic
| ---------- ^ - interpreted as generic arguments
@ -26,7 +26,7 @@ LL | println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start
| help: try comparing the cast value: `(a as usize)`
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:11:31
--> $DIR/issue-22644.rs:13:31
|
LL | println!("{}{}", a: usize < long_name, long_name);
| -------- ^ -------------------- interpreted as generic arguments
@ -35,7 +35,7 @@ LL | println!("{}{}", a: usize < long_name, long_name);
| help: try comparing the cast value: `(a: usize)`
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:13:29
--> $DIR/issue-22644.rs:15:29
|
LL | println!("{}", a: usize < 4); //~ ERROR `<` is interpreted as a start of generic
| -------- ^ - interpreted as generic arguments
@ -44,7 +44,7 @@ LL | println!("{}", a: usize < 4); //~ ERROR `<` is interpreted as a start o
| help: try comparing the cast value: `(a: usize)`
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:18:20
--> $DIR/issue-22644.rs:20:20
|
LL | < //~ ERROR `<` is interpreted as a start of generic
| ^ not interpreted as comparison
@ -58,7 +58,7 @@ LL | usize)
|
error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
--> $DIR/issue-22644.rs:27:20
--> $DIR/issue-22644.rs:29:20
|
LL | < //~ ERROR `<` is interpreted as a start of generic
| ^ not interpreted as comparison
@ -75,7 +75,7 @@ LL |
...
error: `<` is interpreted as a start of generic arguments for `usize`, not a shift
--> $DIR/issue-22644.rs:30:31
--> $DIR/issue-22644.rs:32:31
|
LL | println!("{}", a as usize << long_name); //~ ERROR `<` is interpreted as a start of generic
| ---------- ^^ --------- interpreted as generic arguments
@ -84,7 +84,7 @@ LL | println!("{}", a as usize << long_name); //~ ERROR `<` is interpreted a
| help: try shifting the cast value: `(a as usize)`
error: expected type, found `4`
--> $DIR/issue-22644.rs:32:28
--> $DIR/issue-22644.rs:34:28
|
LL | println!("{}", a: &mut 4); //~ ERROR expected type, found `4`
| ^ expecting a type here because of type ascription

View File

@ -1,4 +1,6 @@
fn main() {
assert!(); //~ ERROR requires a boolean expression
assert!(struct); //~ ERROR expected expression
debug_assert!(); //~ ERROR requires a boolean expression
debug_assert!(struct); //~ ERROR expected expression
}

View File

@ -4,13 +4,25 @@ error: macro requires a boolean expression as an argument
LL | assert!(); //~ ERROR requires a boolean expression
| ^^^^^^^^^^ boolean expression required
error: expected expression, found keyword `struct`
--> $DIR/assert.rs:3:13
|
LL | assert!(struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: macro requires a boolean expression as an argument
--> $DIR/assert.rs:3:5
--> $DIR/assert.rs:4:5
|
LL | debug_assert!(); //~ ERROR requires a boolean expression
| ^^^^^^^^^^^^^^^^ boolean expression required
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to 2 previous errors
error: expected expression, found keyword `struct`
--> $DIR/assert.rs:5:19
|
LL | debug_assert!(struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: aborting due to 4 previous errors

View File

@ -0,0 +1,5 @@
fn main() {
cfg!(); //~ ERROR macro requires a cfg-pattern
cfg!(123); //~ ERROR expected identifier
cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string
}

View File

@ -0,0 +1,21 @@
error: macro requires a cfg-pattern as an argument
--> $DIR/cfg.rs:2:5
|
LL | cfg!(); //~ ERROR macro requires a cfg-pattern
| ^^^^^^^ cfg-pattern required
error: expected identifier, found `123`
--> $DIR/cfg.rs:3:10
|
LL | cfg!(123); //~ ERROR expected identifier
| ^^^ expected identifier
error[E0565]: literal in `cfg` predicate value must be a string
--> $DIR/cfg.rs:4:16
|
LL | cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string
| ^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0565`.

View File

@ -0,0 +1,10 @@
fn main() {
format!(); //~ ERROR requires at least a format string argument
format!(struct); //~ ERROR expected expression
format!("s", name =); //~ ERROR expected expression
format!("s", foo = struct); //~ ERROR expected expression
format!("s", struct); //~ ERROR expected expression
// This error should come after parsing errors to ensure they are non-fatal.
format!(123); //~ ERROR format argument must be a string literal
}

View File

@ -0,0 +1,44 @@
error: requires at least a format string argument
--> $DIR/format-parse-errors.rs:2:5
|
LL | format!(); //~ ERROR requires at least a format string argument
| ^^^^^^^^^^
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: expected expression, found keyword `struct`
--> $DIR/format-parse-errors.rs:3:13
|
LL | format!(struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: expected expression, found `<eof>`
--> $DIR/format-parse-errors.rs:4:23
|
LL | format!("s", name =); //~ ERROR expected expression
| ^ expected expression
error: expected expression, found keyword `struct`
--> $DIR/format-parse-errors.rs:5:24
|
LL | format!("s", foo = struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: expected expression, found keyword `struct`
--> $DIR/format-parse-errors.rs:6:18
|
LL | format!("s", struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: format argument must be a string literal
--> $DIR/format-parse-errors.rs:9:13
|
LL | format!(123); //~ ERROR format argument must be a string literal
| ^^^
help: you might be missing a string literal to format with
|
LL | format!("{}", 123); //~ ERROR format argument must be a string literal
| ^^^^^
error: aborting due to 6 previous errors

View File

@ -0,0 +1,7 @@
#![feature(global_asm)]
fn main() {
global_asm!(); //~ ERROR requires a string literal as an argument
global_asm!(struct); //~ ERROR expected expression
global_asm!(123); //~ ERROR inline assembly must be a string literal
}

View File

@ -0,0 +1,20 @@
error: macro requires a string literal as an argument
--> $DIR/global-asm.rs:4:5
|
LL | global_asm!(); //~ ERROR requires a string literal as an argument
| ^^^^^^^^^^^^^^ string literal required
error: expected expression, found keyword `struct`
--> $DIR/global-asm.rs:5:17
|
LL | global_asm!(struct); //~ ERROR expected expression
| ^^^^^^ expected expression
error: inline assembly must be a string literal
--> $DIR/global-asm.rs:6:17
|
LL | global_asm!(123); //~ ERROR inline assembly must be a string literal
| ^^^
error: aborting due to 3 previous errors