1
Fork 0

Use hygiene to access the injected crate (core or std) from builtin macros.

This commit is contained in:
Jeffrey Seyfried 2017-12-06 10:50:55 -08:00
parent 8db163e53d
commit 9c7969d3df
20 changed files with 99 additions and 102 deletions

View file

@ -262,6 +262,10 @@ impl<'a> Resolver<'a> {
let module = let module =
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }); self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(module); self.populate_module_if_necessary(module);
if self.injected_crate_name.map_or(false, |name| item.ident.name == name) {
self.injected_crate = Some(module);
}
let used = self.process_legacy_macro_imports(item, module, expansion); let used = self.process_legacy_macro_imports(item, module, expansion);
let binding = let binding =
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas); (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
@ -561,8 +565,7 @@ impl<'a> Resolver<'a> {
if let Some(id) = self.definitions.as_local_node_id(def_id) { if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id] self.local_macro_def_scopes[&id]
} else if def_id.krate == BUILTIN_MACROS_CRATE { } else if def_id.krate == BUILTIN_MACROS_CRATE {
// FIXME(jseyfried): This happens when `include!()`ing a `$crate::` path, c.f, #40469. self.injected_crate.unwrap_or(self.graph_root)
self.graph_root
} else { } else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap(); let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
self.get_module(module_def_id) self.get_module(module_def_id)

View file

@ -58,6 +58,7 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
use syntax::ast::{Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind}; use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue}; use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
use syntax::std_inject::injected_crate_name;
use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use errors::{DiagnosticBuilder, DiagnosticId}; use errors::{DiagnosticBuilder, DiagnosticId};
@ -1333,6 +1334,9 @@ pub struct Resolver<'a> {
// Only used for better errors on `fn(): fn()` // Only used for better errors on `fn(): fn()`
current_type_ascription: Vec<Span>, current_type_ascription: Vec<Span>,
injected_crate_name: Option<&'static str>,
injected_crate: Option<Module<'a>>,
} }
pub struct ResolverArenas<'a> { pub struct ResolverArenas<'a> {
@ -1532,6 +1536,8 @@ impl<'a> Resolver<'a> {
found_unresolved_macro: false, found_unresolved_macro: false,
unused_macros: FxHashSet(), unused_macros: FxHashSet(),
current_type_ascription: Vec::new(), current_type_ascription: Vec::new(),
injected_crate_name: injected_crate_name(krate),
injected_crate: None,
} }
} }

View file

@ -21,10 +21,11 @@ use fold::{self, Folder};
use parse::{self, parser, DirectoryOwnership}; use parse::{self, parser, DirectoryOwnership};
use parse::token; use parse::token;
use ptr::P; use ptr::P;
use symbol::Symbol; use symbol::{keywords, Ident, Symbol};
use util::small_vector::SmallVector; use util::small_vector::SmallVector;
use std::collections::HashMap; use std::collections::HashMap;
use std::iter;
use std::path::PathBuf; use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use std::default::Default; use std::default::Default;
@ -664,7 +665,6 @@ pub struct ExpansionData {
pub struct ExtCtxt<'a> { pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess, pub parse_sess: &'a parse::ParseSess,
pub ecfg: expand::ExpansionConfig<'a>, pub ecfg: expand::ExpansionConfig<'a>,
pub crate_root: Option<&'static str>,
pub root_path: PathBuf, pub root_path: PathBuf,
pub resolver: &'a mut Resolver, pub resolver: &'a mut Resolver,
pub resolve_err_count: usize, pub resolve_err_count: usize,
@ -680,7 +680,6 @@ impl<'a> ExtCtxt<'a> {
ExtCtxt { ExtCtxt {
parse_sess, parse_sess,
ecfg, ecfg,
crate_root: None,
root_path: PathBuf::new(), root_path: PathBuf::new(),
resolver, resolver,
resolve_err_count: 0, resolve_err_count: 0,
@ -822,12 +821,10 @@ impl<'a> ExtCtxt<'a> {
ast::Ident::from_str(st) ast::Ident::from_str(st)
} }
pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> { pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
let mut v = Vec::new(); let def_site = SyntaxContext::empty().apply_mark(self.current_expansion.mark);
if let Some(s) = self.crate_root { iter::once(Ident { ctxt: def_site, ..keywords::DollarCrate.ident() })
v.push(self.ident_of(s)); .chain(components.iter().map(|s| self.ident_of(s)))
} .collect()
v.extend(components.iter().map(|s| self.ident_of(s)));
v
} }
pub fn name_of(&self, st: &str) -> ast::Name { pub fn name_of(&self, st: &str) -> ast::Name {
Symbol::intern(st) Symbol::intern(st)

View file

@ -319,9 +319,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
types: Vec<P<ast::Ty>>, types: Vec<P<ast::Ty>>,
bindings: Vec<ast::TypeBinding> ) bindings: Vec<ast::TypeBinding> )
-> ast::Path { -> ast::Path {
use syntax::parse::token;
let last_identifier = idents.pop().unwrap(); let last_identifier = idents.pop().unwrap();
let mut segments: Vec<ast::PathSegment> = Vec::new(); let mut segments: Vec<ast::PathSegment> = Vec::new();
if global { if global &&
!idents.first().map_or(false, |&ident| token::Ident(ident).is_path_segment_keyword()) {
segments.push(ast::PathSegment::crate_root(span)); segments.push(ast::PathSegment::crate_root(span));
} }

View file

@ -25,7 +25,6 @@ use parse::{DirectoryOwnership, PResult};
use parse::token::{self, Token}; use parse::token::{self, Token};
use parse::parser::Parser; use parse::parser::Parser;
use ptr::P; use ptr::P;
use std_inject;
use symbol::Symbol; use symbol::Symbol;
use symbol::keywords; use symbol::keywords;
use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::{Span, DUMMY_SP};
@ -219,7 +218,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
} }
pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
self.cx.crate_root = std_inject::injected_crate_name(&krate);
let mut module = ModuleData { let mut module = ModuleData {
mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)], mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
directory: self.cx.codemap().span_to_unmapped_path(krate.span), directory: self.cx.codemap().span_to_unmapped_path(krate.span),

View file

@ -272,7 +272,7 @@ fn generate_test_harness(sess: &ParseSess,
let mark = Mark::fresh(Mark::root()); let mark = Mark::fresh(Mark::root());
let mut cx: TestCtxt = TestCtxt { let cx = TestCtxt {
span_diagnostic: sd, span_diagnostic: sd,
ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver), ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver),
path: Vec::new(), path: Vec::new(),
@ -283,7 +283,6 @@ fn generate_test_harness(sess: &ParseSess,
toplevel_reexport: None, toplevel_reexport: None,
ctxt: SyntaxContext::empty().apply_mark(mark), ctxt: SyntaxContext::empty().apply_mark(mark),
}; };
cx.ext_cx.crate_root = Some("std");
mark.set_expn_info(ExpnInfo { mark.set_expn_info(ExpnInfo {
call_site: DUMMY_SP, call_site: DUMMY_SP,

View file

@ -8,9 +8,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
use syntax::ast::MetaItem; use syntax::ast::MetaItem;
use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax_pos::Span; use syntax_pos::Span;
@ -28,15 +28,10 @@ pub fn expand_deriving_copy(cx: &mut ExtCtxt,
mitem: &MetaItem, mitem: &MetaItem,
item: &Annotatable, item: &Annotatable,
push: &mut FnMut(Annotatable)) { push: &mut FnMut(Annotatable)) {
let mut v = cx.crate_root.map(|s| vec![s]).unwrap_or(Vec::new());
v.push("marker");
v.push("Copy");
let path = Path::new(v);
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path, path: path_std!(cx, marker::Copy),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -55,7 +56,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
})); }));
} }
ItemKind::Union(..) => { ItemKind::Union(..) => {
bounds = vec![Literal(path_std!(cx, core::marker::Copy))]; bounds = vec![Literal(path_std!(cx, marker::Copy))];
is_shallow = true; is_shallow = true;
substructure = combine_substructure(Box::new(|c, s, sub| { substructure = combine_substructure(Box::new(|c, s, sub| {
cs_clone_shallow("Clone", c, s, sub, true) cs_clone_shallow("Clone", c, s, sub, true)
@ -79,7 +80,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::clone::Clone), path: path_std!(cx, clone::Clone),
additional_bounds: bounds, additional_bounds: bounds,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -30,7 +31,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::cmp::Eq), path: path_std!(cx, cmp::Eq),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -28,7 +29,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::cmp::Ord), path: path_std!(cx, cmp::Ord),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,
@ -38,7 +39,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![borrowed_self()], args: vec![borrowed_self()],
ret_ty: Literal(path_std!(cx, core::cmp::Ordering)), ret_ty: Literal(path_std!(cx, cmp::Ordering)),
attributes: attrs, attributes: attrs,
is_unsafe: false, is_unsafe: false,
unify_fieldless_variants: true, unify_fieldless_variants: true,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::{path_local, path_std};
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -93,7 +94,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::cmp::PartialEq), path: path_std!(cx, cmp::PartialEq),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -10,6 +10,7 @@
pub use self::OrderingOp::*; pub use self::OrderingOp::*;
use deriving::{path_local, pathvec_std, path_std};
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -45,11 +46,11 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
} } } }
} }
let ordering_ty = Literal(path_std!(cx, core::cmp::Ordering)); let ordering_ty = Literal(path_std!(cx, cmp::Ordering));
let ret_ty = Literal(Path::new_(pathvec_std!(cx, core::option::Option), let ret_ty = Literal(Path::new_(pathvec_std!(cx, option::Option),
None, None,
vec![Box::new(ordering_ty)], vec![Box::new(ordering_ty)],
true)); PathKind::Std));
let inline = cx.meta_word(span, Symbol::intern("inline")); let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)]; let attrs = vec![cx.attribute(span, inline)];
@ -84,7 +85,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: vec![], attributes: vec![],
path: path_std!(cx, core::cmp::PartialOrd), path: path_std!(cx, cmp::PartialOrd),
additional_bounds: vec![], additional_bounds: vec![],
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -24,13 +25,13 @@ pub fn expand_deriving_debug(cx: &mut ExtCtxt,
item: &Annotatable, item: &Annotatable,
push: &mut FnMut(Annotatable)) { push: &mut FnMut(Annotatable)) {
// &mut ::std::fmt::Formatter // &mut ::std::fmt::Formatter
let fmtr = Ptr(Box::new(Literal(path_std!(cx, core::fmt::Formatter))), let fmtr = Ptr(Box::new(Literal(path_std!(cx, fmt::Formatter))),
Borrowed(None, ast::Mutability::Mutable)); Borrowed(None, ast::Mutability::Mutable));
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::fmt::Debug), path: path_std!(cx, fmt::Debug),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,
@ -40,7 +41,7 @@ pub fn expand_deriving_debug(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![fmtr], args: vec![fmtr],
ret_ty: Literal(path_std!(cx, core::fmt::Result)), ret_ty: Literal(path_std!(cx, fmt::Result)),
attributes: Vec::new(), attributes: Vec::new(),
is_unsafe: false, is_unsafe: false,
unify_fieldless_variants: false, unify_fieldless_variants: false,

View file

@ -10,7 +10,7 @@
//! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more. //! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
use deriving; use deriving::{self, pathvec_std};
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
use deriving::warn_if_deprecated; use deriving::warn_if_deprecated;
@ -46,20 +46,12 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
item: &Annotatable, item: &Annotatable,
push: &mut FnMut(Annotatable), push: &mut FnMut(Annotatable),
krate: &'static str) { krate: &'static str) {
if cx.crate_root != Some("std") {
// FIXME(#21880): lift this requirement.
cx.span_err(span,
"this trait cannot be derived with #![no_std] \
or #![no_core]");
return;
}
let typaram = &*deriving::hygienic_type_parameter(item, "__D"); let typaram = &*deriving::hygienic_type_parameter(item, "__D");
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: Path::new_(vec![krate, "Decodable"], None, vec![], true), path: Path::new_(vec![krate, "Decodable"], None, vec![], PathKind::Global),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,
@ -72,18 +64,18 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
vec![Path::new_(vec![krate, "Decoder"], vec![Path::new_(vec![krate, "Decoder"],
None, None,
vec![], vec![],
true)])], PathKind::Global)])],
}, },
explicit_self: None, explicit_self: None,
args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))), args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
Borrowed(None, Mutability::Mutable))], Borrowed(None, Mutability::Mutable))],
ret_ty: ret_ty:
Literal(Path::new_(pathvec_std!(cx, core::result::Result), Literal(Path::new_(pathvec_std!(cx, result::Result),
None, None,
vec![Box::new(Self_), Box::new(Literal(Path::new_( vec![Box::new(Self_), Box::new(Literal(Path::new_(
vec![typaram, "Error"], None, vec![], false vec![typaram, "Error"], None, vec![], PathKind::Local
)))], )))],
true)), PathKind::Std)),
attributes: Vec::new(), attributes: Vec::new(),
is_unsafe: false, is_unsafe: false,
unify_fieldless_variants: false, unify_fieldless_variants: false,

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving::path_std;
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -28,7 +29,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: path_std!(cx, core::default::Default), path: path_std!(cx, default::Default),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,

View file

@ -92,7 +92,7 @@
//! } //! }
//! ``` //! ```
use deriving; use deriving::{self, pathvec_std};
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
use deriving::warn_if_deprecated; use deriving::warn_if_deprecated;
@ -127,20 +127,12 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
item: &Annotatable, item: &Annotatable,
push: &mut FnMut(Annotatable), push: &mut FnMut(Annotatable),
krate: &'static str) { krate: &'static str) {
if cx.crate_root != Some("std") {
// FIXME(#21880): lift this requirement.
cx.span_err(span,
"this trait cannot be derived with #![no_std] \
or #![no_core]");
return;
}
let typaram = &*deriving::hygienic_type_parameter(item, "__S"); let typaram = &*deriving::hygienic_type_parameter(item, "__S");
let trait_def = TraitDef { let trait_def = TraitDef {
span, span,
attributes: Vec::new(), attributes: Vec::new(),
path: Path::new_(vec![krate, "Encodable"], None, vec![], true), path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global),
additional_bounds: Vec::new(), additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(), generics: LifetimeBounds::empty(),
is_unsafe: false, is_unsafe: false,
@ -150,19 +142,21 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
name: "encode", name: "encode",
generics: LifetimeBounds { generics: LifetimeBounds {
lifetimes: Vec::new(), lifetimes: Vec::new(),
bounds: vec![(typaram, bounds: vec![
vec![Path::new_(vec![krate, "Encoder"], None, vec![], true)])] (typaram,
vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)])
],
}, },
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))), args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
Borrowed(None, Mutability::Mutable))], Borrowed(None, Mutability::Mutable))],
ret_ty: Literal(Path::new_( ret_ty: Literal(Path::new_(
pathvec_std!(cx, core::result::Result), pathvec_std!(cx, result::Result),
None, None,
vec![Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_( vec![Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_(
vec![typaram, "Error"], None, vec![], false vec![typaram, "Error"], None, vec![], PathKind::Local
)))], )))],
true PathKind::Std
)), )),
attributes: Vec::new(), attributes: Vec::new(),
is_unsafe: false, is_unsafe: false,

View file

@ -21,6 +21,8 @@ use syntax::ext::build::AstBuilder;
use syntax::codemap::respan; use syntax::codemap::respan;
use syntax::ptr::P; use syntax::ptr::P;
use syntax_pos::Span; use syntax_pos::Span;
use syntax_pos::hygiene::SyntaxContext;
use syntax_pos::symbol::keywords;
/// The types of pointers /// The types of pointers
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
@ -36,29 +38,36 @@ pub enum PtrTy<'a> {
/// for type parameters and a lifetime. /// for type parameters and a lifetime.
#[derive(Clone, Eq, PartialEq)] #[derive(Clone, Eq, PartialEq)]
pub struct Path<'a> { pub struct Path<'a> {
pub path: Vec<&'a str>, path: Vec<&'a str>,
pub lifetime: Option<&'a str>, lifetime: Option<&'a str>,
pub params: Vec<Box<Ty<'a>>>, params: Vec<Box<Ty<'a>>>,
pub global: bool, kind: PathKind,
}
#[derive(Clone, Eq, PartialEq)]
pub enum PathKind {
Local,
Global,
Std,
} }
impl<'a> Path<'a> { impl<'a> Path<'a> {
pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> { pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> {
Path::new_(path, None, Vec::new(), true) Path::new_(path, None, Vec::new(), PathKind::Std)
} }
pub fn new_local<'r>(path: &'r str) -> Path<'r> { pub fn new_local<'r>(path: &'r str) -> Path<'r> {
Path::new_(vec![path], None, Vec::new(), false) Path::new_(vec![path], None, Vec::new(), PathKind::Local)
} }
pub fn new_<'r>(path: Vec<&'r str>, pub fn new_<'r>(path: Vec<&'r str>,
lifetime: Option<&'r str>, lifetime: Option<&'r str>,
params: Vec<Box<Ty<'r>>>, params: Vec<Box<Ty<'r>>>,
global: bool) kind: PathKind)
-> Path<'r> { -> Path<'r> {
Path { Path {
path, path,
lifetime, lifetime,
params, params,
global, kind,
} }
} }
@ -76,11 +85,20 @@ impl<'a> Path<'a> {
self_ty: Ident, self_ty: Ident,
self_generics: &Generics) self_generics: &Generics)
-> ast::Path { -> ast::Path {
let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect(); let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
let lt = mk_lifetimes(cx, span, &self.lifetime); let lt = mk_lifetimes(cx, span, &self.lifetime);
let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
cx.path_all(span, self.global, idents, lt, tys, Vec::new()) match self.kind {
PathKind::Global => cx.path_all(span, true, idents, lt, tys, Vec::new()),
PathKind::Local => cx.path_all(span, false, idents, lt, tys, Vec::new()),
PathKind::Std => {
let def_site = SyntaxContext::empty().apply_mark(cx.current_expansion.mark);
idents.insert(0, Ident { ctxt: def_site, ..keywords::DollarCrate.ident() });
cx.path_all(span, false, idents, lt, tys, Vec::new())
}
}
} }
} }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use deriving; use deriving::{self, pathvec_std, path_std};
use deriving::generic::*; use deriving::generic::*;
use deriving::generic::ty::*; use deriving::generic::ty::*;
@ -24,7 +24,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
item: &Annotatable, item: &Annotatable,
push: &mut FnMut(Annotatable)) { push: &mut FnMut(Annotatable)) {
let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None, vec![], true); let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
let typaram = &*deriving::hygienic_type_parameter(item, "__H"); let typaram = &*deriving::hygienic_type_parameter(item, "__H");
@ -41,7 +41,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
name: "hash", name: "hash",
generics: LifetimeBounds { generics: LifetimeBounds {
lifetimes: Vec::new(), lifetimes: Vec::new(),
bounds: vec![(typaram, vec![path_std!(cx, core::hash::Hasher)])], bounds: vec![(typaram, vec![path_std!(cx, hash::Hasher)])],
}, },
explicit_self: borrowed_explicit_self(), explicit_self: borrowed_explicit_self(),
args: vec![Ptr(Box::new(Literal(arg)), args: vec![Ptr(Box::new(Literal(arg)),

View file

@ -19,32 +19,16 @@ use syntax::ptr::P;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
use syntax_pos::Span; use syntax_pos::Span;
macro_rules! pathvec { macro path_local($x:ident) {
($($x:ident)::+) => ( generic::ty::Path::new_local(stringify!($x))
vec![ $( stringify!($x) ),+ ]
)
} }
macro_rules! path_local { macro pathvec_std($cx:expr, $($rest:ident)::+) {{
($x:ident) => ( vec![ $( stringify!($rest) ),+ ]
::deriving::generic::ty::Path::new_local(stringify!($x)) }}
)
}
macro_rules! pathvec_std { macro path_std($($x:tt)*) {
($cx:expr, $first:ident :: $($rest:ident)::+) => ({ generic::ty::Path::new( pathvec_std!( $($x)* ) )
let mut v = pathvec![$($rest)::+];
if let Some(s) = $cx.crate_root {
v.insert(0, s);
}
v
})
}
macro_rules! path_std {
($($x:tt)*) => (
::deriving::generic::ty::Path::new( pathvec_std!( $($x)* ) )
)
} }
pub mod bounds; pub mod bounds;

View file

@ -16,6 +16,7 @@
#![deny(warnings)] #![deny(warnings)]
#![feature(proc_macro_internals)] #![feature(proc_macro_internals)]
#![feature(decl_macro)]
extern crate fmt_macros; extern crate fmt_macros;
#[macro_use] #[macro_use]