diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 84aa57d7d86e..1efe0b3478db 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -456,7 +456,8 @@ impl MacResult for MacEager { #[derive(Copy, Clone)] pub struct DummyResult { expr_only: bool, - span: Span + is_error: bool, + span: Span, } impl DummyResult { @@ -464,8 +465,13 @@ impl DummyResult { /// /// Use this as a return value after hitting any errors and /// calling `span_err`. - pub fn any(sp: Span) -> Box { - Box::new(DummyResult { expr_only: false, span: sp }) + pub fn any(span: Span) -> Box { + Box::new(DummyResult { expr_only: false, is_error: true, span }) + } + + /// Same as `any`, but must be a valid fragment, not error. + pub fn any_valid(span: Span) -> Box { + Box::new(DummyResult { expr_only: false, is_error: false, span }) } /// Create a default MacResult that can only be an expression. @@ -473,15 +479,15 @@ impl DummyResult { /// Use this for macros that must expand to an expression, so even /// if an error is encountered internally, the user will receive /// an error that they also used it in the wrong place. - pub fn expr(sp: Span) -> Box { - Box::new(DummyResult { expr_only: true, span: sp }) + pub fn expr(span: Span) -> Box { + Box::new(DummyResult { expr_only: true, is_error: true, span }) } /// A plain dummy expression. - pub fn raw_expr(sp: Span) -> P { + pub fn raw_expr(sp: Span, is_error: bool) -> P { P(ast::Expr { id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Err, + node: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(Vec::new()) }, span: sp, attrs: ThinVec::new(), }) @@ -497,10 +503,10 @@ impl DummyResult { } /// A plain dummy type. - pub fn raw_ty(sp: Span) -> P { + pub fn raw_ty(sp: Span, is_error: bool) -> P { P(ast::Ty { id: ast::DUMMY_NODE_ID, - node: ast::TyKind::Err, + node: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(Vec::new()) }, span: sp }) } @@ -508,7 +514,7 @@ impl DummyResult { impl MacResult for DummyResult { fn make_expr(self: Box) -> Option> { - Some(DummyResult::raw_expr(self.span)) + Some(DummyResult::raw_expr(self.span, self.is_error)) } fn make_pat(self: Box) -> Option> { @@ -551,13 +557,13 @@ impl MacResult for DummyResult { fn make_stmts(self: Box) -> Option> { Some(smallvec![ast::Stmt { id: ast::DUMMY_NODE_ID, - node: ast::StmtKind::Expr(DummyResult::raw_expr(self.span)), + node: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.is_error)), span: self.span, }]) } fn make_ty(self: Box) -> Option> { - Some(DummyResult::raw_ty(self.span)) + Some(DummyResult::raw_ty(self.span, self.is_error)) } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d68a6546f486..11d570072cd6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4974,7 +4974,7 @@ impl<'a> Parser<'a> { self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore); Some(Stmt { id: ast::DUMMY_NODE_ID, - node: StmtKind::Expr(DummyResult::raw_expr(self.span)), + node: StmtKind::Expr(DummyResult::raw_expr(self.span, true)), span: self.span, }) } diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index 771a559b37cc..32d02bec7989 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -69,7 +69,7 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur span_err!(cx, trait_span, E0665, "`Default` cannot be derived for enums, only structs"); // let compilation continue - DummyResult::raw_expr(trait_span) + DummyResult::raw_expr(trait_span, true) } _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"), }; diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index c6f427e63cd8..105165034803 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -666,7 +666,7 @@ impl<'a, 'b> Context<'a, 'b> { "X" => "UpperHex", _ => { ecx.span_err(sp, &format!("unknown format trait `{}`", *tyname)); - return DummyResult::raw_expr(sp); + return DummyResult::raw_expr(sp, true); } } } @@ -761,7 +761,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, Applicability::MaybeIncorrect, ); err.emit(); - return DummyResult::raw_expr(sp); + return DummyResult::raw_expr(sp, true); } }; @@ -857,7 +857,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, e.span_label(sp, label); } e.emit(); - return DummyResult::raw_expr(sp); + return DummyResult::raw_expr(sp, true); } let arg_spans = parser.arg_places.iter() diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 5f24ed81cddb..f6bb1285c535 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -20,5 +20,5 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt, println!("{}", print::pprust::tts_to_string(tts)); // any so that `log_syntax` can be invoked as an expression and item. - base::DummyResult::any(sp) + base::DummyResult::any_valid(sp) } diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index f17c6de19d96..b20da5af09a8 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -28,5 +28,5 @@ pub fn expand_trace_macros(cx: &mut ExtCtxt, _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"), } - base::DummyResult::any(sp) + base::DummyResult::any_valid(sp) }