Auto merge of #43832 - huntiep:compiler-desugaring-enum, r=nikomatsakis

Implement CompilerDesugaringKind enum

This is the first step outlined in #35946. I think that the variants of `CompilerDesugaringKind` should be changed, I didn't know what the official names for `...` and `<-` are.

I'm not to sure how tests for the compiler work, but I would imagine that tests should be added such that
`Symbol::intern(s) == CompilerDesugaringKind::from(s).as_symbol()` for valid `s`.
This commit is contained in:
bors 2017-08-18 00:26:08 +00:00
commit 4ac7646d39
3 changed files with 48 additions and 11 deletions

View File

@ -59,7 +59,7 @@ use syntax::ast::*;
use syntax::errors; use syntax::errors;
use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::codemap::{self, respan, Spanned}; use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
use syntax::std_inject; use syntax::std_inject;
use syntax::symbol::{Symbol, keywords}; use syntax::symbol::{Symbol, keywords};
use syntax::util::small_vector::SmallVector; use syntax::util::small_vector::SmallVector;
@ -414,12 +414,14 @@ impl<'a> LoweringContext<'a> {
Symbol::gensym(s) Symbol::gensym(s)
} }
fn allow_internal_unstable(&self, reason: &'static str, mut span: Span) -> Span { fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, mut span: Span)
-> Span
{
let mark = Mark::fresh(Mark::root()); let mark = Mark::fresh(Mark::root());
mark.set_expn_info(codemap::ExpnInfo { mark.set_expn_info(codemap::ExpnInfo {
call_site: span, call_site: span,
callee: codemap::NameAndSpan { callee: codemap::NameAndSpan {
format: codemap::CompilerDesugaring(Symbol::intern(reason)), format: codemap::CompilerDesugaring(reason),
span: Some(span), span: Some(span),
allow_internal_unstable: true, allow_internal_unstable: true,
allow_internal_unsafe: false, allow_internal_unsafe: false,
@ -1790,7 +1792,8 @@ impl<'a> LoweringContext<'a> {
let move_val_init = ["intrinsics", "move_val_init"]; let move_val_init = ["intrinsics", "move_val_init"];
let inplace_finalize = ["ops", "InPlace", "finalize"]; let inplace_finalize = ["ops", "InPlace", "finalize"];
let unstable_span = self.allow_internal_unstable("<-", e.span); let unstable_span =
self.allow_internal_unstable(CompilerDesugaringKind::BackArrow, e.span);
let make_call = |this: &mut LoweringContext, p, args| { let make_call = |this: &mut LoweringContext, p, args| {
let path = P(this.expr_std_path(unstable_span, p, ThinVec::new())); let path = P(this.expr_std_path(unstable_span, p, ThinVec::new()));
P(this.expr_call(e.span, path, args)) P(this.expr_call(e.span, path, args))
@ -2007,12 +2010,14 @@ impl<'a> LoweringContext<'a> {
e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e))) e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
.map(|(s, e)| { .map(|(s, e)| {
let expr = P(self.lower_expr(&e)); let expr = P(self.lower_expr(&e));
let unstable_span = self.allow_internal_unstable("...", e.span); let unstable_span =
self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
self.field(Symbol::intern(s), expr, unstable_span) self.field(Symbol::intern(s), expr, unstable_span)
}).collect::<P<[hir::Field]>>(); }).collect::<P<[hir::Field]>>();
let is_unit = fields.is_empty(); let is_unit = fields.is_empty();
let unstable_span = self.allow_internal_unstable("...", e.span); let unstable_span =
self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
let struct_path = let struct_path =
iter::once("ops").chain(iter::once(path)) iter::once("ops").chain(iter::once(path))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -2353,7 +2358,8 @@ impl<'a> LoweringContext<'a> {
// return Try::from_error(From::from(err)), // return Try::from_error(From::from(err)),
// } // }
let unstable_span = self.allow_internal_unstable("?", e.span); let unstable_span =
self.allow_internal_unstable(CompilerDesugaringKind::QuestionMark, e.span);
// Try::into_result(<expr>) // Try::into_result(<expr>)
let discr = { let discr = {

View File

@ -323,8 +323,8 @@ impl NameAndSpan {
pub fn name(&self) -> Symbol { pub fn name(&self) -> Symbol {
match self.format { match self.format {
ExpnFormat::MacroAttribute(s) | ExpnFormat::MacroAttribute(s) |
ExpnFormat::MacroBang(s) | ExpnFormat::MacroBang(s) => s,
ExpnFormat::CompilerDesugaring(s) => s, ExpnFormat::CompilerDesugaring(ref kind) => kind.as_symbol(),
} }
} }
} }
@ -337,7 +337,27 @@ pub enum ExpnFormat {
/// e.g. `format!()` /// e.g. `format!()`
MacroBang(Symbol), MacroBang(Symbol),
/// Desugaring done by the compiler during HIR lowering. /// Desugaring done by the compiler during HIR lowering.
CompilerDesugaring(Symbol) CompilerDesugaring(CompilerDesugaringKind)
}
/// The kind of compiler desugaring.
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
pub enum CompilerDesugaringKind {
BackArrow,
DotFill,
QuestionMark,
}
impl CompilerDesugaringKind {
pub fn as_symbol(&self) -> Symbol {
use CompilerDesugaringKind::*;
let s = match *self {
BackArrow => "<-",
DotFill => "...",
QuestionMark => "?",
};
Symbol::intern(s)
}
} }
impl Encodable for SyntaxContext { impl Encodable for SyntaxContext {

View File

@ -47,7 +47,7 @@ extern crate serialize;
extern crate serialize as rustc_serialize; // used by deriving extern crate serialize as rustc_serialize; // used by deriving
pub mod hygiene; pub mod hygiene;
pub use hygiene::{SyntaxContext, ExpnInfo, ExpnFormat, NameAndSpan}; pub use hygiene::{SyntaxContext, ExpnInfo, ExpnFormat, NameAndSpan, CompilerDesugaringKind};
pub mod symbol; pub mod symbol;
@ -153,6 +153,17 @@ impl Span {
} }
} }
/// Check if this span arises from a compiler desugaring of kind `kind`.
pub fn is_compiler_desugaring(&self, kind: CompilerDesugaringKind) -> bool {
match self.ctxt.outer().expn_info() {
Some(info) => match info.callee.format {
ExpnFormat::CompilerDesugaring(k) => k == kind,
_ => false,
},
None => false,
}
}
/// Check if a span is "internal" to a macro in which `unsafe` /// Check if a span is "internal" to a macro in which `unsafe`
/// can be used without triggering the `unsafe_code` lint /// can be used without triggering the `unsafe_code` lint
// (that is, a macro marked with `#[allow_internal_unsafe]`). // (that is, a macro marked with `#[allow_internal_unsafe]`).