Rollup merge of #63528 - petrochenkov:anyany, r=estebank
syntax: Remove `DummyResult::expr_only` The effect is that if a built-in macro both returns an erroneous AST fragment and is used in unexpected position, then the incorrect position error won't be reported. This combination of two errors should be rare and isn't worth an extra field that makes people ask questions in comments. (There wasn't even a test making sure it worked.) Addresses https://github.com/rust-lang/rust/pull/63468#discussion_r313504644 r? @estebank
This commit is contained in:
commit
409df9b530
8 changed files with 27 additions and 54 deletions
|
|
@ -405,7 +405,6 @@ impl MacResult for MacEager {
|
|||
/// after hitting errors.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct DummyResult {
|
||||
expr_only: bool,
|
||||
is_error: bool,
|
||||
span: Span,
|
||||
}
|
||||
|
|
@ -416,21 +415,12 @@ impl DummyResult {
|
|||
/// Use this as a return value after hitting any errors and
|
||||
/// calling `span_err`.
|
||||
pub fn any(span: Span) -> Box<dyn MacResult+'static> {
|
||||
Box::new(DummyResult { expr_only: false, is_error: true, span })
|
||||
Box::new(DummyResult { is_error: true, span })
|
||||
}
|
||||
|
||||
/// Same as `any`, but must be a valid fragment, not error.
|
||||
pub fn any_valid(span: Span) -> Box<dyn MacResult+'static> {
|
||||
Box::new(DummyResult { expr_only: false, is_error: false, span })
|
||||
}
|
||||
|
||||
/// Creates a default MacResult that can only be an expression.
|
||||
///
|
||||
/// 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(span: Span) -> Box<dyn MacResult+'static> {
|
||||
Box::new(DummyResult { expr_only: true, is_error: true, span })
|
||||
Box::new(DummyResult { is_error: false, span })
|
||||
}
|
||||
|
||||
/// A plain dummy expression.
|
||||
|
|
@ -472,36 +462,19 @@ impl MacResult for DummyResult {
|
|||
}
|
||||
|
||||
fn make_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
|
||||
// this code needs a comment... why not always just return the Some() ?
|
||||
if self.expr_only {
|
||||
None
|
||||
} else {
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
|
||||
fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[ast::ImplItem; 1]>> {
|
||||
if self.expr_only {
|
||||
None
|
||||
} else {
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
|
||||
fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[ast::TraitItem; 1]>> {
|
||||
if self.expr_only {
|
||||
None
|
||||
} else {
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
|
||||
fn make_foreign_items(self: Box<Self>) -> Option<SmallVec<[ast::ForeignItem; 1]>> {
|
||||
if self.expr_only {
|
||||
None
|
||||
} else {
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
Some(SmallVec::new())
|
||||
}
|
||||
|
||||
fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
|||
-> Box<dyn base::MacResult + 'cx> {
|
||||
let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
|
||||
Ok(Some(inline_asm)) => inline_asm,
|
||||
Ok(None) => return DummyResult::expr(sp),
|
||||
Ok(None) => return DummyResult::any(sp),
|
||||
Err(mut err) => {
|
||||
err.emit();
|
||||
return DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub fn expand_assert<'cx>(
|
|||
Ok(assert) => assert,
|
||||
Err(mut err) => {
|
||||
err.emit();
|
||||
return DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub fn expand_cfg(
|
|||
}
|
||||
Err(mut err) => {
|
||||
err.emit();
|
||||
DummyResult::expr(sp)
|
||||
DummyResult::any(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use syntax::ast;
|
||||
use syntax::ext::base;
|
||||
use syntax::ext::base::{self, DummyResult};
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::tokenstream;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ pub fn expand_syntax_ext(
|
|||
) -> Box<dyn base::MacResult + 'static> {
|
||||
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
||||
Some(e) => e,
|
||||
None => return base::DummyResult::expr(sp),
|
||||
None => return DummyResult::any(sp),
|
||||
};
|
||||
let mut accumulator = String::new();
|
||||
let mut missing_literal = vec![];
|
||||
|
|
@ -55,9 +55,9 @@ pub fn expand_syntax_ext(
|
|||
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
|
||||
err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
|
||||
err.emit();
|
||||
return base::DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
} else if has_errors {
|
||||
return base::DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
let sp = sp.apply_mark(cx.current_expansion.id);
|
||||
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
|||
tts: &[tokenstream::TokenTree])
|
||||
-> Box<dyn base::MacResult + 'cx> {
|
||||
let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
|
||||
None => return DummyResult::expr(sp),
|
||||
None => return DummyResult::any(sp),
|
||||
Some(v) => v,
|
||||
};
|
||||
|
||||
|
|
@ -50,21 +50,21 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
|||
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
|
||||
Some(ref exprs) if exprs.is_empty() => {
|
||||
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
||||
return DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
None => return DummyResult::expr(sp),
|
||||
None => return DummyResult::any(sp),
|
||||
Some(exprs) => exprs.into_iter(),
|
||||
};
|
||||
|
||||
let var = match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
|
||||
None => return DummyResult::expr(sp),
|
||||
None => return DummyResult::any(sp),
|
||||
Some((v, _style)) => v,
|
||||
};
|
||||
let msg = match exprs.next() {
|
||||
None => Symbol::intern(&format!("environment variable `{}` not defined", var)),
|
||||
Some(second) => {
|
||||
match expr_to_string(cx, second, "expected string literal") {
|
||||
None => return DummyResult::expr(sp),
|
||||
None => return DummyResult::any(sp),
|
||||
Some((s, _style)) => s,
|
||||
}
|
||||
}
|
||||
|
|
@ -72,13 +72,13 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
|
|||
|
||||
if exprs.next().is_some() {
|
||||
cx.span_err(sp, "env! takes 1 or 2 arguments");
|
||||
return DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
|
||||
let e = match env::var(&*var.as_str()) {
|
||||
Err(_) => {
|
||||
cx.span_err(sp, &msg.as_str());
|
||||
return DummyResult::expr(sp);
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -805,7 +805,7 @@ fn expand_format_args_impl<'cx>(
|
|||
}
|
||||
Err(mut err) => {
|
||||
err.emit();
|
||||
DummyResult::expr(sp)
|
||||
DummyResult::any(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
|
|||
-> Box<dyn base::MacResult+'static> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp)
|
||||
None => return DummyResult::any(sp)
|
||||
};
|
||||
let file = cx.resolve_path(file, sp);
|
||||
match fs::read_to_string(&file) {
|
||||
|
|
@ -126,11 +126,11 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
|
|||
},
|
||||
Err(ref e) if e.kind() == ErrorKind::InvalidData => {
|
||||
cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
|
||||
DummyResult::expr(sp)
|
||||
DummyResult::any(sp)
|
||||
}
|
||||
Err(e) => {
|
||||
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
|
||||
DummyResult::expr(sp)
|
||||
DummyResult::any(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::
|
|||
-> Box<dyn base::MacResult+'static> {
|
||||
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
|
||||
Some(f) => f,
|
||||
None => return DummyResult::expr(sp)
|
||||
None => return DummyResult::any(sp)
|
||||
};
|
||||
let file = cx.resolve_path(file, sp);
|
||||
match fs::read(&file) {
|
||||
|
|
@ -158,7 +158,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::
|
|||
},
|
||||
Err(e) => {
|
||||
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
|
||||
DummyResult::expr(sp)
|
||||
DummyResult::any(sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue