if [ -n "$CFG_ANTLR4" ]
then
CFG_ANTLR4_JAR="\"$(find /usr/ -name antlr-complete.jar 2>/dev/null | head -n 1)\""
- if [ "x" -eq "x$CFG_ANTLR4_JAR" ]
+ if [ "x" = "x$CFG_ANTLR4_JAR" ]
then
CFG_ANTLR4_JAR="\"$(find ~ -name antlr-complete.jar 2>/dev/null | head -n 1)\""
fi
[**The Rust Reference**][ref]. While Rust does not have a
specification, the reference tries to describe its working in
-detail. It tends to be out of date.
+detail. It is accurate, but not necessarily complete.
[**Standard Library API Reference**][api]. Documentation for the
standard library.
pos += 1;
}
assert_eq!(pos, v.len());
+ assert_eq!(s.chars().count(), v.len());
}
#[test]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Peekable<I: Iterator> {
iter: I,
- peeked: Option<I::Item>,
+ /// Remember a peeked value, even if it was None.
+ peeked: Option<Option<I::Item>>,
}
+// Peekable must remember if a None has been seen in the `.peek()` method.
+// It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the
+// underlying iterator at most once. This does not by itself make the iterator
+// fused.
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> Iterator for Peekable<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
- match self.peeked {
- Some(_) => self.peeked.take(),
+ match self.peeked.take() {
+ Some(v) => v,
None => self.iter.next(),
}
}
#[inline]
#[rustc_inherit_overflow_checks]
- fn count(self) -> usize {
- (if self.peeked.is_some() { 1 } else { 0 }) + self.iter.count()
+ fn count(mut self) -> usize {
+ match self.peeked.take() {
+ Some(None) => 0,
+ Some(Some(_)) => 1 + self.iter.count(),
+ None => self.iter.count(),
+ }
}
#[inline]
fn nth(&mut self, n: usize) -> Option<I::Item> {
- match self.peeked {
- Some(_) if n == 0 => self.peeked.take(),
- Some(_) => {
- self.peeked = None;
- self.iter.nth(n-1)
- },
- None => self.iter.nth(n)
+ match self.peeked.take() {
+ // the .take() below is just to avoid "move into pattern guard"
+ Some(ref mut v) if n == 0 => v.take(),
+ Some(None) => None,
+ Some(Some(_)) => self.iter.nth(n - 1),
+ None => self.iter.nth(n),
}
}
#[inline]
- fn last(self) -> Option<I::Item> {
- self.iter.last().or(self.peeked)
+ fn last(mut self) -> Option<I::Item> {
+ let peek_opt = match self.peeked.take() {
+ Some(None) => return None,
+ Some(v) => v,
+ None => None,
+ };
+ self.iter.last().or(peek_opt)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
+ let peek_len = match self.peeked {
+ Some(None) => return (0, Some(0)),
+ Some(Some(_)) => 1,
+ None => 0,
+ };
let (lo, hi) = self.iter.size_hint();
- if self.peeked.is_some() {
- let lo = lo.saturating_add(1);
- let hi = hi.and_then(|x| x.checked_add(1));
- (lo, hi)
- } else {
- (lo, hi)
- }
+ let lo = lo.saturating_add(peek_len);
+ let hi = hi.and_then(|x| x.checked_add(peek_len));
+ (lo, hi)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
pub fn peek(&mut self) -> Option<&I::Item> {
if self.peeked.is_none() {
- self.peeked = self.iter.next();
+ self.peeked = Some(self.iter.next());
+ }
+ match self.peeked {
+ Some(Some(ref value)) => Some(value),
+ Some(None) => None,
+ _ => unreachable!(),
}
- self.peeked.as_ref()
}
}
})
}
+ #[inline]
+ fn count(self) -> usize {
+ // length in `char` is equal to the number of non-continuation bytes
+ let bytes_len = self.iter.len();
+ let mut cont_bytes = 0;
+ for &byte in self.iter {
+ cont_bytes += utf8_is_cont_byte(byte) as usize;
+ }
+ bytes_len - cont_bytes
+ }
+
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.iter.len();
}
}
+ #[inline]
+ fn count(self) -> usize {
+ self.iter.count()
+ }
+
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
let mut it = ys.iter().peekable();
assert_eq!(it.peek(), Some(&&0));
assert_eq!(it.last(), Some(&0));
+
+ let mut it = ys.iter().peekable();
+ assert_eq!(it.next(), Some(&0));
+ assert_eq!(it.peek(), None);
+ assert_eq!(it.last(), None);
+}
+
+/// This is an iterator that follows the Iterator contract,
+/// but it is not fused. After having returned None once, it will start
+/// producing elements if .next() is called again.
+pub struct CycleIter<'a, T: 'a> {
+ index: usize,
+ data: &'a [T],
+}
+
+pub fn cycle<T>(data: &[T]) -> CycleIter<T> {
+ CycleIter {
+ index: 0,
+ data: data,
+ }
+}
+
+impl<'a, T> Iterator for CycleIter<'a, T> {
+ type Item = &'a T;
+ fn next(&mut self) -> Option<Self::Item> {
+ let elt = self.data.get(self.index);
+ self.index += 1;
+ self.index %= 1 + self.data.len();
+ elt
+ }
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_1() {
+ // Check that the loop using .peek() terminates
+ let data = [1, 2, 3];
+ let mut iter = cycle(&data).peekable();
+
+ let mut n = 0;
+ while let Some(_) = iter.next() {
+ let is_the_last = iter.peek().is_none();
+ assert_eq!(is_the_last, n == data.len() - 1);
+ n += 1;
+ if n > data.len() { break; }
+ }
+ assert_eq!(n, data.len());
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_2() {
+ let data = [0];
+ let mut iter = cycle(&data).peekable();
+ iter.next();
+ assert_eq!(iter.peek(), None);
+ assert_eq!(iter.last(), None);
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_3() {
+ let data = [0];
+ let mut iter = cycle(&data).peekable();
+ iter.peek();
+ assert_eq!(iter.nth(0), Some(&0));
+
+ let mut iter = cycle(&data).peekable();
+ iter.next();
+ assert_eq!(iter.peek(), None);
+ assert_eq!(iter.nth(0), None);
}
#[test]
use std::prelude::v1::*;
use std::{i16, f64};
use super::super::*;
-use core::num::flt2dec::*;
use core::num::bignum::Big32x40 as Big;
use core::num::flt2dec::strategy::dragon::*;
use std::{i16, f64};
use super::super::*;
-use core::num::flt2dec::*;
use core::num::flt2dec::strategy::grisu::*;
#[test]
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::proc_macro_shim::build_block_emitter;
-use syntax::parse::token::{self, Token, gensym_ident, str_to_ident};
+use syntax::parse::token::{self, Token};
use syntax::print::pprust;
+use syntax::symbol::Symbol;
use syntax::tokenstream::{TokenTree, TokenStream};
// ____________________________________________________________________________________________
} // produce an error or something first
let exp = vec![exp.unwrap().to_owned()];
debug!("RHS: {:?}", exp.clone());
- let new_id = gensym_ident("tmp");
+ let new_id = Ident::with_empty_ctxt(Symbol::gensym("tmp"));
debug!("RHS TS: {:?}", TokenStream::from_tts(exp.clone()));
debug!("RHS TS TT: {:?}", TokenStream::from_tts(exp.clone()).to_vec());
bindings.push((new_id, TokenStream::from_tts(exp)));
};
while let Some(ts) = pushes.pop() {
- output = build_fn_call(str_to_ident("concat"),
+ output = build_fn_call(Ident::from_str("concat"),
concat(concat(ts,
from_tokens(vec![Token::Comma])),
output));
// FIXME handle sequence repetition tokens
QTT::QDL(qdl) => {
debug!(" QDL: {:?} ", qdl.tts);
- let new_id = gensym_ident("qdl_tmp");
+ let new_id = Ident::with_empty_ctxt(Symbol::gensym("qdl_tmp"));
let mut cct_rec = convert_complex_tts(cx, qdl.tts);
bindings.append(&mut cct_rec.0);
bindings.push((new_id, cct_rec.1));
let sep = build_delim_tok(qdl.delim);
- pushes.push(build_mod_call(vec![str_to_ident("proc_macro_tokens"),
- str_to_ident("build"),
- str_to_ident("build_delimited")],
- concat(from_tokens(vec![Token::Ident(new_id)]),
- concat(lex(","), sep))));
+ pushes.push(build_mod_call(
+ vec![Ident::from_str("proc_macro_tokens"),
+ Ident::from_str("build"),
+ Ident::from_str("build_delimited")],
+ concat(from_tokens(vec![Token::Ident(new_id)]), concat(lex(","), sep)),
+ ));
}
QTT::QIdent(t) => {
pushes.push(TokenStream::from_tts(vec![t]));
/// Checks if the Ident is `unquote`.
fn is_unquote(id: Ident) -> bool {
- let qq = str_to_ident("unquote");
+ let qq = Ident::from_str("unquote");
id.name == qq.name // We disregard context; unquote is _reserved_
}
/// Checks if the Ident is `quote`.
fn is_qquote(id: Ident) -> bool {
- let qq = str_to_ident("qquote");
+ let qq = Ident::from_str("qquote");
id.name == qq.name // We disregard context; qquote is _reserved_
}
use syntax::ast::{self, Ident};
use syntax::codemap::{DUMMY_SP};
- use syntax::parse::token::{self, Token, keywords, str_to_ident};
+ use syntax::parse::token::{self, Token, Lit};
+ use syntax::symbol::keywords;
use syntax::tokenstream::{TokenTree, TokenStream};
// ____________________________________________________________________________________________
build_paren_delimited(build_vec(build_token_tt(t))))
}
- pub fn emit_lit(l: token::Lit, n: Option<ast::Name>) -> TokenStream {
+ pub fn emit_lit(l: Lit, n: Option<ast::Name>) -> TokenStream {
let suf = match n {
- Some(n) => format!("Some(ast::Name({}))", n.0),
+ Some(n) => format!("Some(ast::Name({}))", n.as_u32()),
None => "None".to_string(),
};
let lit = match l {
- token::Lit::Byte(n) => format!("Lit::Byte(token::intern(\"{}\"))", n.to_string()),
- token::Lit::Char(n) => format!("Lit::Char(token::intern(\"{}\"))", n.to_string()),
- token::Lit::Integer(n) => format!("Lit::Integer(token::intern(\"{}\"))", n.to_string()),
- token::Lit::Float(n) => format!("Lit::Float(token::intern(\"{}\"))", n.to_string()),
- token::Lit::Str_(n) => format!("Lit::Str_(token::intern(\"{}\"))", n.to_string()),
- token::Lit::ByteStr(n) => format!("Lit::ByteStr(token::intern(\"{}\"))", n.to_string()),
+ Lit::Byte(n) => format!("Lit::Byte(Symbol::intern(\"{}\"))", n.to_string()),
+ Lit::Char(n) => format!("Lit::Char(Symbol::intern(\"{}\"))", n.to_string()),
+ Lit::Float(n) => format!("Lit::Float(Symbol::intern(\"{}\"))", n.to_string()),
+ Lit::Str_(n) => format!("Lit::Str_(Symbol::intern(\"{}\"))", n.to_string()),
+ Lit::Integer(n) => format!("Lit::Integer(Symbol::intern(\"{}\"))", n.to_string()),
+ Lit::ByteStr(n) => format!("Lit::ByteStr(Symbol::intern(\"{}\"))", n.to_string()),
_ => panic!("Unsupported literal"),
};
Token::Underscore => lex("_"),
Token::Literal(lit, sfx) => emit_lit(lit, sfx),
// fix ident expansion information... somehow
- Token::Ident(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))", ident.name)),
- Token::Lifetime(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))",
- ident.name)),
+ Token::Ident(ident) =>
+ lex(&format!("Token::Ident(Ident::from_str(\"{}\"))", ident.name)),
+ Token::Lifetime(ident) =>
+ lex(&format!("Token::Ident(Ident::from_str(\"{}\"))", ident.name)),
_ => panic!("Unhandled case!"),
}
}
/// Takes `input` and returns `vec![input]`.
pub fn build_vec(ts: TokenStream) -> TokenStream {
- build_mac_call(str_to_ident("vec"), ts)
+ build_mac_call(Ident::from_str("vec"), ts)
// tts.clone().to_owned()
}
use syntax::ast::Ident;
use syntax::codemap::DUMMY_SP;
-use syntax::parse::token::{self, Token, keywords, str_to_ident};
+use syntax::parse::token::{self, Token};
+use syntax::symbol::keywords;
use syntax::tokenstream::{self, TokenTree, TokenStream};
use std::rc::Rc;
/// Convert a `&str` into a Token.
pub fn str_to_token_ident(s: &str) -> Token {
- Token::Ident(str_to_ident(s))
+ Token::Ident(Ident::from_str(s))
}
/// Converts a keyword (from `syntax::parse::token::keywords`) into a Token that
/// corresponds to it.
pub fn keyword_to_token_ident(kw: keywords::Keyword) -> Token {
- Token::Ident(str_to_ident(&kw.name().as_str()[..]))
+ Token::Ident(Ident::from_str(&kw.name().as_str()[..]))
}
// ____________________________________________________________________________________________
expr_exit
}
- hir::ExprLoop(ref body, _) => {
+ hir::ExprLoop(ref body, _, _) => {
//
// [pred]
// |
self.add_unreachable_node()
}
- hir::ExprBreak(label) => {
+ hir::ExprBreak(label, ref opt_expr) => {
+ let v = self.opt_expr(opt_expr, pred);
let loop_scope = self.find_scope(expr, label.map(|l| l.node));
- let b = self.add_ast_node(expr.id, &[pred]);
+ let b = self.add_ast_node(expr.id, &[v]);
self.add_exiting_edge(expr, b,
loop_scope, loop_scope.break_index);
self.add_unreachable_node()
}
hir::ExprArray(ref elems) => {
- self.straightline(expr, pred, elems.iter().map(|e| &**e))
+ self.straightline(expr, pred, elems.iter().map(|e| &*e))
}
hir::ExprCall(ref func, ref args) => {
- self.call(expr, pred, &func, args.iter().map(|e| &**e))
+ self.call(expr, pred, &func, args.iter().map(|e| &*e))
}
hir::ExprMethodCall(.., ref args) => {
- self.call(expr, pred, &args[0], args[1..].iter().map(|e| &**e))
+ self.call(expr, pred, &args[0], args[1..].iter().map(|e| &*e))
}
hir::ExprIndex(ref l, ref r) |
}
hir::ExprTup(ref exprs) => {
- self.straightline(expr, pred, exprs.iter().map(|e| &**e))
+ self.straightline(expr, pred, exprs.iter().map(|e| &*e))
}
hir::ExprStruct(_, ref fields, ref base) => {
}
hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
- let post_outputs = self.exprs(outputs.iter().map(|e| &**e), pred);
- let post_inputs = self.exprs(inputs.iter().map(|e| &**e), post_outputs);
+ let post_outputs = self.exprs(outputs.iter().map(|e| &*e), pred);
+ let post_inputs = self.exprs(inputs.iter().map(|e| &*e), post_outputs);
self.add_ast_node(expr.id, &[post_inputs])
}
None => continue,
};
- let (message, label) = match &*name {
+ let (message, label) = match &*name.as_str() {
"C" => {
conflicting_reprs += 1;
if target != Target::Struct &&
}
fn check_attribute(&self, attr: &ast::Attribute, target: Target) {
- let name: &str = &attr.name();
+ let name: &str = &attr.name().as_str();
match name {
"inline" => self.check_inline(attr, target),
"repr" => self.check_repr(attr, target),
visitor.visit_block(block);
walk_opt_sp_name(visitor, opt_sp_name);
}
- ExprLoop(ref block, ref opt_sp_name) => {
+ ExprLoop(ref block, ref opt_sp_name, _) => {
visitor.visit_block(block);
walk_opt_sp_name(visitor, opt_sp_name);
}
}
visitor.visit_path(path, expression.id)
}
- ExprBreak(ref opt_sp_name) | ExprAgain(ref opt_sp_name) => {
+ ExprBreak(ref opt_sp_name, ref opt_expr) => {
+ walk_opt_sp_name(visitor, opt_sp_name);
+ walk_list!(visitor, visit_expr, opt_expr);
+ }
+ ExprAgain(ref opt_sp_name) => {
walk_opt_sp_name(visitor, opt_sp_name);
}
ExprRet(ref optional_expression) => {
use syntax::errors;
use syntax::ptr::P;
use syntax::codemap::{respan, Spanned};
-use syntax::parse::token;
use syntax::std_inject;
+use syntax::symbol::{Symbol, keywords};
use syntax::visit::{self, Visitor};
use syntax_pos::Span;
}
fn str_to_ident(&self, s: &'static str) -> Name {
- token::gensym(s)
+ Symbol::gensym(s)
}
fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
hir::Arm {
attrs: self.lower_attrs(&arm.attrs),
pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
- guard: arm.guard.as_ref().map(|ref x| self.lower_expr(x)),
- body: self.lower_expr(&arm.body),
+ guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
+ body: P(self.lower_expr(&arm.body)),
}
}
hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
}
TyKind::Array(ref ty, ref e) => {
- hir::TyArray(self.lower_ty(ty), self.lower_expr(e))
+ hir::TyArray(self.lower_ty(ty), P(self.lower_expr(e)))
}
TyKind::Typeof(ref expr) => {
- hir::TyTypeof(self.lower_expr(expr))
+ hir::TyTypeof(P(self.lower_expr(expr)))
}
TyKind::PolyTraitRef(ref bounds) => {
hir::TyPolyTraitRef(self.lower_bounds(bounds))
name: v.node.name.name,
attrs: self.lower_attrs(&v.node.attrs),
data: self.lower_variant_data(&v.node.data),
- disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_expr(e)),
+ disr_expr: v.node.disr_expr.as_ref().map(|e| P(self.lower_expr(e))),
},
span: v.span,
}
id: l.id,
ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
pat: self.lower_pat(&l.pat),
- init: l.init.as_ref().map(|e| self.lower_expr(e)),
+ init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
span: l.span,
attrs: l.attrs.clone(),
})
// Don't expose `Self` (recovered "keyword used as ident" parse error).
// `rustc::ty` expects `Self` to be only used for a trait's `Self`.
// Instead, use gensym("Self") to create a distinct name that looks the same.
- if name == token::keywords::SelfType.name() {
- name = token::gensym("Self");
+ if name == keywords::SelfType.name() {
+ name = Symbol::gensym("Self");
}
hir::TyParam {
hir::StructField {
span: f.span,
id: f.id,
- name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())),
+ name: f.ident.map(|ident| ident.name).unwrap_or(Symbol::intern(&index.to_string())),
vis: self.lower_visibility(&f.vis),
ty: self.lower_ty(&f.ty),
attrs: self.lower_attrs(&f.attrs),
fn lower_field(&mut self, f: &Field) -> hir::Field {
hir::Field {
name: respan(f.ident.span, f.ident.node.name),
- expr: self.lower_expr(&f.expr),
+ expr: P(self.lower_expr(&f.expr)),
span: f.span,
is_shorthand: f.is_shorthand,
}
ItemKind::Static(ref t, m, ref e) => {
hir::ItemStatic(self.lower_ty(t),
self.lower_mutability(m),
- self.lower_expr(e))
+ P(self.lower_expr(e)))
}
ItemKind::Const(ref t, ref e) => {
- hir::ItemConst(self.lower_ty(t), self.lower_expr(e))
+ hir::ItemConst(self.lower_ty(t), P(self.lower_expr(e)))
}
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
let body = self.lower_block(body);
self.lower_constness(constness),
abi,
self.lower_generics(generics),
- self.expr_block(body, ThinVec::new()))
+ P(self.expr_block(body, ThinVec::new())))
}
ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
node: match i.node {
TraitItemKind::Const(ref ty, ref default) => {
hir::ConstTraitItem(this.lower_ty(ty),
- default.as_ref().map(|x| this.lower_expr(x)))
+ default.as_ref().map(|x| P(this.lower_expr(x))))
}
TraitItemKind::Method(ref sig, ref body) => {
hir::MethodTraitItem(this.lower_method_sig(sig),
body.as_ref().map(|x| {
let body = this.lower_block(x);
- this.expr_block(body, ThinVec::new())
+ P(this.expr_block(body, ThinVec::new()))
}))
}
TraitItemKind::Type(ref bounds, ref default) => {
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
node: match i.node {
ImplItemKind::Const(ref ty, ref expr) => {
- hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
+ hir::ImplItemKind::Const(this.lower_ty(ty), P(this.lower_expr(expr)))
}
ImplItemKind::Method(ref sig, ref body) => {
let body = this.lower_block(body);
hir::ImplItemKind::Method(this.lower_method_sig(sig),
- this.expr_block(body, ThinVec::new()))
+ P(this.expr_block(body, ThinVec::new())))
}
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
}
})
}
- PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
+ PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
hir::PatKind::TupleStruct(self.lower_path(path),
pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
}
PatKind::Range(ref e1, ref e2) => {
- hir::PatKind::Range(self.lower_expr(e1), self.lower_expr(e2))
+ hir::PatKind::Range(P(self.lower_expr(e1)), P(self.lower_expr(e2)))
}
PatKind::Slice(ref before, ref slice, ref after) => {
hir::PatKind::Slice(before.iter().map(|x| self.lower_pat(x)).collect(),
})
}
- fn lower_expr(&mut self, e: &Expr) -> P<hir::Expr> {
- P(hir::Expr {
+ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
+ hir::Expr {
id: e.id,
node: match e.node {
// Issue #22181:
//
// But for now there are type-inference issues doing that.
ExprKind::Box(ref e) => {
- hir::ExprBox(self.lower_expr(e))
+ hir::ExprBox(P(self.lower_expr(e)))
}
// Desugar ExprBox: `in (PLACE) EXPR`
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
// InPlace::finalize(place)
// })
- let placer_expr = self.lower_expr(placer);
- let value_expr = self.lower_expr(value_expr);
+ let placer_expr = P(self.lower_expr(placer));
+ let value_expr = P(self.lower_expr(value_expr));
let placer_ident = self.str_to_ident("placer");
let place_ident = self.str_to_ident("place");
let make_call = |this: &mut LoweringContext, p, args| {
let path = this.std_path(e.span, p);
let path = this.expr_path(path, ThinVec::new());
- this.expr_call(e.span, path, args)
+ P(this.expr_call(e.span, path, args))
};
let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
// let placer = <placer_expr> ;
let (s1, placer_binding) = {
- let placer_expr = self.signal_block_expr(hir_vec![],
- placer_expr,
- e.span,
- hir::PopUnstableBlock,
- ThinVec::new());
+ let placer_expr = P(self.signal_block_expr(hir_vec![],
+ placer_expr,
+ e.span,
+ hir::PopUnstableBlock,
+ ThinVec::new()));
mk_stmt_let(self, placer_ident, placer_expr)
};
// let p_ptr = Place::pointer(&mut place);
let (s3, p_ptr_binding) = {
- let agent = self.expr_ident(e.span, place_ident, place_binding);
+ let agent = P(self.expr_ident(e.span, place_ident, place_binding));
let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
let call = make_call(self, &place_pointer, args);
mk_stmt_let(self, p_ptr_ident, call)
// pop_unsafe!(EXPR));
let pop_unsafe_expr = {
- let value_expr = self.signal_block_expr(hir_vec![],
- value_expr,
- e.span,
- hir::PopUnstableBlock,
- ThinVec::new());
+ let value_expr = P(self.signal_block_expr(hir_vec![],
+ value_expr,
+ e.span,
+ hir::PopUnstableBlock,
+ ThinVec::new()));
self.signal_block_expr(hir_vec![],
value_expr,
e.span,
let place = self.expr_ident(e.span, place_ident, place_binding);
let call = make_call(self, &inplace_finalize, hir_vec![place]);
- self.signal_block_expr(hir_vec![call_move_val_init],
- call,
- e.span,
- hir::PushUnsafeBlock(hir::CompilerGenerated),
- ThinVec::new())
+ P(self.signal_block_expr(hir_vec![call_move_val_init],
+ call,
+ e.span,
+ hir::PushUnsafeBlock(hir::CompilerGenerated),
+ ThinVec::new()))
};
return self.signal_block_expr(hir_vec![s1, s2, s3],
hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
}
ExprKind::Repeat(ref expr, ref count) => {
- let expr = self.lower_expr(expr);
- let count = self.lower_expr(count);
+ let expr = P(self.lower_expr(expr));
+ let count = P(self.lower_expr(count));
hir::ExprRepeat(expr, count)
}
ExprKind::Tup(ref elts) => {
hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
}
ExprKind::Call(ref f, ref args) => {
- let f = self.lower_expr(f);
+ let f = P(self.lower_expr(f));
hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
}
ExprKind::MethodCall(i, ref tps, ref args) => {
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {
let binop = self.lower_binop(binop);
- let lhs = self.lower_expr(lhs);
- let rhs = self.lower_expr(rhs);
+ let lhs = P(self.lower_expr(lhs));
+ let rhs = P(self.lower_expr(rhs));
hir::ExprBinary(binop, lhs, rhs)
}
ExprKind::Unary(op, ref ohs) => {
let op = self.lower_unop(op);
- let ohs = self.lower_expr(ohs);
+ let ohs = P(self.lower_expr(ohs));
hir::ExprUnary(op, ohs)
}
ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
ExprKind::Cast(ref expr, ref ty) => {
- let expr = self.lower_expr(expr);
+ let expr = P(self.lower_expr(expr));
hir::ExprCast(expr, self.lower_ty(ty))
}
ExprKind::Type(ref expr, ref ty) => {
- let expr = self.lower_expr(expr);
+ let expr = P(self.lower_expr(expr));
hir::ExprType(expr, self.lower_ty(ty))
}
ExprKind::AddrOf(m, ref ohs) => {
let m = self.lower_mutability(m);
- let ohs = self.lower_expr(ohs);
+ let ohs = P(self.lower_expr(ohs));
hir::ExprAddrOf(m, ohs)
}
// More complicated than you might expect because the else branch
ExprKind::IfLet(..) => {
// wrap the if-let expr in a block
let span = els.span;
- let els = self.lower_expr(els);
+ let els = P(self.lower_expr(els));
let id = self.next_id();
let blk = P(hir::Block {
stmts: hir_vec![],
rules: hir::DefaultBlock,
span: span,
});
- self.expr_block(blk, ThinVec::new())
+ P(self.expr_block(blk, ThinVec::new()))
}
- _ => self.lower_expr(els),
+ _ => P(self.lower_expr(els)),
}
});
- hir::ExprIf(self.lower_expr(cond), self.lower_block(blk), else_opt)
+ hir::ExprIf(P(self.lower_expr(cond)), self.lower_block(blk), else_opt)
}
ExprKind::While(ref cond, ref body, opt_ident) => {
- hir::ExprWhile(self.lower_expr(cond), self.lower_block(body),
+ hir::ExprWhile(P(self.lower_expr(cond)), self.lower_block(body),
self.lower_opt_sp_ident(opt_ident))
}
ExprKind::Loop(ref body, opt_ident) => {
- hir::ExprLoop(self.lower_block(body), self.lower_opt_sp_ident(opt_ident))
+ hir::ExprLoop(self.lower_block(body),
+ self.lower_opt_sp_ident(opt_ident),
+ hir::LoopSource::Loop)
}
ExprKind::Match(ref expr, ref arms) => {
- hir::ExprMatch(self.lower_expr(expr),
+ hir::ExprMatch(P(self.lower_expr(expr)),
arms.iter().map(|x| self.lower_arm(x)).collect(),
hir::MatchSource::Normal)
}
self.with_parent_def(e.id, |this| {
hir::ExprClosure(this.lower_capture_clause(capture_clause),
this.lower_fn_decl(decl),
- this.lower_expr(body),
+ P(this.lower_expr(body)),
fn_decl_span)
})
}
ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk)),
ExprKind::Assign(ref el, ref er) => {
- hir::ExprAssign(self.lower_expr(el), self.lower_expr(er))
+ hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er)))
}
ExprKind::AssignOp(op, ref el, ref er) => {
hir::ExprAssignOp(self.lower_binop(op),
- self.lower_expr(el),
- self.lower_expr(er))
+ P(self.lower_expr(el)),
+ P(self.lower_expr(er)))
}
ExprKind::Field(ref el, ident) => {
- hir::ExprField(self.lower_expr(el), respan(ident.span, ident.node.name))
+ hir::ExprField(P(self.lower_expr(el)), respan(ident.span, ident.node.name))
}
ExprKind::TupField(ref el, ident) => {
- hir::ExprTupField(self.lower_expr(el), ident)
+ hir::ExprTupField(P(self.lower_expr(el)), ident)
}
ExprKind::Index(ref el, ref er) => {
- hir::ExprIndex(self.lower_expr(el), self.lower_expr(er))
+ hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
}
ExprKind::Range(ref e1, ref e2, lims) => {
fn make_struct(this: &mut LoweringContext,
ast_expr: &Expr,
path: &[&str],
- fields: &[(&str, &P<Expr>)]) -> P<hir::Expr> {
+ fields: &[(&str, &P<Expr>)]) -> hir::Expr {
let struct_path = this.std_path(ast_expr.span,
&iter::once(&"ops").chain(path)
.map(|s| *s)
this.expr_path(struct_path, ast_expr.attrs.clone())
} else {
let fields = fields.into_iter().map(|&(s, e)| {
- let expr = this.lower_expr(&e);
- let signal_block = this.signal_block_expr(hir_vec![],
- expr,
- e.span,
- hir::PopUnstableBlock,
- ThinVec::new());
- this.field(token::intern(s), signal_block, ast_expr.span)
+ let expr = P(this.lower_expr(&e));
+ let signal_block = P(this.signal_block_expr(hir_vec![],
+ expr,
+ e.span,
+ hir::PopUnstableBlock,
+ ThinVec::new()));
+ this.field(Symbol::intern(s), signal_block, ast_expr.span)
}).collect();
let attrs = ast_expr.attrs.clone();
});
hir::ExprPath(hir_qself, self.lower_path(path))
}
- ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
+ ExprKind::Break(opt_ident, ref opt_expr) => {
+ hir::ExprBreak(self.lower_opt_sp_ident(opt_ident),
+ opt_expr.as_ref().map(|x| P(self.lower_expr(x))))
+ }
ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
- ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
+ ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
ExprKind::InlineAsm(ref asm) => {
let hir_asm = hir::InlineAsm {
inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
hir::ExprStruct(P(self.lower_path(path)),
fields.iter().map(|x| self.lower_field(x)).collect(),
- maybe_expr.as_ref().map(|x| self.lower_expr(x)))
+ maybe_expr.as_ref().map(|x| P(self.lower_expr(x))))
}
ExprKind::Paren(ref ex) => {
- return self.lower_expr(ex).map(|mut ex| {
- // include parens in span, but only if it is a super-span.
- if e.span.contains(ex.span) {
- ex.span = e.span;
- }
- // merge attributes into the inner expression.
- let mut attrs = e.attrs.clone();
- attrs.extend::<Vec<_>>(ex.attrs.into());
- ex.attrs = attrs;
- ex
- });
+ let mut ex = self.lower_expr(ex);
+ // include parens in span, but only if it is a super-span.
+ if e.span.contains(ex.span) {
+ ex.span = e.span;
+ }
+ // merge attributes into the inner expression.
+ let mut attrs = e.attrs.clone();
+ attrs.extend::<Vec<_>>(ex.attrs.into());
+ ex.attrs = attrs;
+ return ex;
}
// Desugar ExprIfLet
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, ThinVec::new());
+ let body_expr = P(self.expr_block(body, ThinVec::new()));
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
// `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
- let mut else_opt = else_opt.as_ref().map(|e| self.lower_expr(e));
+ let mut else_opt = else_opt.as_ref().map(|e| P(self.lower_expr(e)));
let else_if_arms = {
let mut arms = vec![];
loop {
attrs: hir_vec![],
pats: hir_vec![pat_under],
guard: Some(cond),
- body: self.expr_block(then, ThinVec::new()),
+ body: P(self.expr_block(then, ThinVec::new())),
});
else_opt.map(|else_opt| (else_opt, true))
}
arms.extend(else_if_arms);
arms.push(else_arm);
- let sub_expr = self.lower_expr(sub_expr);
+ let sub_expr = P(self.lower_expr(sub_expr));
// add attributes to the outer returned expr node
return self.expr(e.span,
hir::ExprMatch(sub_expr,
// `<pat> => <body>`
let pat_arm = {
let body = self.lower_block(body);
- let body_expr = self.expr_block(body, ThinVec::new());
+ let body_expr = P(self.expr_block(body, ThinVec::new()));
let pat = self.lower_pat(pat);
self.arm(hir_vec![pat], body_expr)
};
// `match <sub_expr> { ... }`
let arms = hir_vec![pat_arm, break_arm];
- let sub_expr = self.lower_expr(sub_expr);
+ let sub_expr = P(self.lower_expr(sub_expr));
let match_expr = self.expr(e.span,
hir::ExprMatch(sub_expr,
arms,
ThinVec::new());
// `[opt_ident]: loop { ... }`
- let loop_block = self.block_expr(match_expr);
- let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
+ let loop_block = P(self.block_expr(P(match_expr)));
+ let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
+ hir::LoopSource::WhileLet);
// add attributes to the outer returned expr node
let attrs = e.attrs.clone();
- return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs });
+ return hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs };
}
// Desugar ExprForLoop
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
let match_expr = {
let next_path = self.std_path(e.span, &["iter", "Iterator", "next"]);
- let iter = self.expr_ident(e.span, iter, iter_pat.id);
+ let iter = P(self.expr_ident(e.span, iter, iter_pat.id));
let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
let next_path = self.expr_path(next_path, ThinVec::new());
- let next_expr = self.expr_call(e.span, next_path, hir_vec![ref_mut_iter]);
+ let next_expr = P(self.expr_call(e.span, next_path,
+ hir_vec![ref_mut_iter]));
let arms = hir_vec![pat_arm, break_arm];
- self.expr(e.span,
- hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
- ThinVec::new())
+ P(self.expr(e.span,
+ hir::ExprMatch(next_expr, arms,
+ hir::MatchSource::ForLoopDesugar),
+ ThinVec::new()))
};
// `[opt_ident]: loop { ... }`
- let loop_block = self.block_expr(match_expr);
- let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
+ let loop_block = P(self.block_expr(match_expr));
+ let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
+ hir::LoopSource::ForLoop);
let loop_expr = P(hir::Expr {
id: e.id,
node: loop_expr,
&["iter", "IntoIterator", "into_iter"]);
let into_iter = self.expr_path(into_iter_path, ThinVec::new());
- self.expr_call(e.span, into_iter, hir_vec![head])
+ P(self.expr_call(e.span, into_iter, hir_vec![head]))
};
- let match_expr = self.expr_match(e.span,
- into_iter_expr,
- hir_vec![iter_arm],
- hir::MatchSource::ForLoopDesugar);
+ let match_expr = P(self.expr_match(e.span,
+ into_iter_expr,
+ hir_vec![iter_arm],
+ hir::MatchSource::ForLoopDesugar));
// `{ let _result = ...; _result }`
// underscore prevents an unused_variables lint if the head diverges
let (let_stmt, let_stmt_binding) =
self.stmt_let(e.span, false, result_ident, match_expr);
- let result = self.expr_ident(e.span, result_ident, let_stmt_binding);
- let block = self.block_all(e.span, hir_vec![let_stmt], Some(result));
+ let result = P(self.expr_ident(e.span, result_ident, let_stmt_binding));
+ let block = P(self.block_all(e.span, hir_vec![let_stmt], Some(result)));
// add the attributes to the outer returned expr node
return self.expr_block(block, e.attrs.clone());
}
// { Carrier::translate( { <expr> } ) }
let discr = {
// expand <expr>
- let sub_expr = self.lower_expr(sub_expr);
+ let sub_expr = P(self.lower_expr(sub_expr));
let sub_expr = self.signal_block_expr(hir_vec![],
sub_expr,
e.span,
let path = self.std_path(e.span, &["ops", "Carrier", "translate"]);
let path = self.expr_path(path, ThinVec::new());
- let call = self.expr_call(e.span, path, hir_vec![sub_expr]);
+ let call = P(self.expr_call(e.span, path, hir_vec![sub_expr]));
- self.signal_block_expr(hir_vec![],
- call,
- e.span,
- hir::PushUnstableBlock,
- ThinVec::new())
+ P(self.signal_block_expr(hir_vec![],
+ call,
+ e.span,
+ hir::PushUnstableBlock,
+ ThinVec::new()))
};
// Ok(val) => val
let ok_arm = {
let val_ident = self.str_to_ident("val");
let val_pat = self.pat_ident(e.span, val_ident);
- let val_expr = self.expr_ident(e.span, val_ident, val_pat.id);
+ let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id));
let ok_pat = self.pat_ok(e.span, val_pat);
self.arm(hir_vec![ok_pat], val_expr)
let from_err_expr = {
let path = self.std_path(e.span, &["ops", "Carrier", "from_error"]);
let from_err = self.expr_path(path, ThinVec::new());
- self.expr_call(e.span, from_err, hir_vec![from_expr])
+ P(self.expr_call(e.span, from_err, hir_vec![from_expr]))
};
- let ret_expr = self.expr(e.span,
- hir::Expr_::ExprRet(Some(from_err_expr)),
- ThinVec::new());
+ let ret_expr = P(self.expr(e.span,
+ hir::Expr_::ExprRet(Some(from_err_expr)),
+ ThinVec::new()));
let ret_stmt = self.stmt_expr(ret_expr);
- let block = self.signal_block_stmt(ret_stmt, e.span,
- hir::PushUnstableBlock, ThinVec::new());
+ let block = P(self.signal_block_stmt(ret_stmt, e.span,
+ hir::PushUnstableBlock,
+ ThinVec::new()));
let err_pat = self.pat_err(e.span, err_local);
self.arm(hir_vec![err_pat], block)
},
span: e.span,
attrs: e.attrs.clone(),
- })
+ }
}
fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
},
StmtKind::Expr(ref e) => {
Spanned {
- node: hir::StmtExpr(self.lower_expr(e), s.id),
+ node: hir::StmtExpr(P(self.lower_expr(e)), s.id),
span: s.span,
}
}
StmtKind::Semi(ref e) => {
Spanned {
- node: hir::StmtSemi(self.lower_expr(e), s.id),
+ node: hir::StmtSemi(P(self.lower_expr(e)), s.id),
span: s.span,
}
}
}
fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
- self.expr(span, hir::ExprBreak(None), attrs)
+ P(self.expr(span, hir::ExprBreak(None, None), attrs))
}
- fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<P<hir::Expr>>)
- -> P<hir::Expr> {
+ fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<hir::Expr>)
+ -> hir::Expr {
self.expr(span, hir::ExprCall(e, args), ThinVec::new())
}
- fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> P<hir::Expr> {
+ fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> hir::Expr {
let expr_path = hir::ExprPath(None, self.path_ident(span, id));
let expr = self.expr(span, expr_path, ThinVec::new());
expr
}
- fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
+ fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
}
fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, true);
- let expr = self.expr(path.span, hir::ExprPath(None, path), attrs);
+ let expr = P(self.expr(path.span, hir::ExprPath(None, path), attrs));
self.resolver.record_resolution(expr.id, def);
expr
}
arg: P<hir::Expr>,
arms: hir::HirVec<hir::Arm>,
source: hir::MatchSource)
- -> P<hir::Expr> {
+ -> hir::Expr {
self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
}
- fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
+ fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr {
self.expr(b.span, hir::ExprBlock(b), attrs)
}
- fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>) -> P<hir::Expr> {
- self.expr(sp, hir::ExprTup(exprs), ThinVec::new())
+ fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr> {
+ P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new()))
}
fn expr_struct(&mut self,
e: Option<P<hir::Expr>>,
attrs: ThinVec<Attribute>) -> P<hir::Expr> {
let def = self.resolver.resolve_generated_global_path(&path, false);
- let expr = self.expr(sp, hir::ExprStruct(P(path), fields, e), attrs);
+ let expr = P(self.expr(sp, hir::ExprStruct(P(path), fields, e), attrs));
self.resolver.record_resolution(expr.id, def);
expr
}
- fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
- P(hir::Expr {
+ fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
+ hir::Expr {
id: self.next_id(),
node: node,
span: span,
attrs: attrs,
- })
+ }
}
fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
}
}
- fn block_expr(&mut self, expr: P<hir::Expr>) -> P<hir::Block> {
+ fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
self.block_all(expr.span, hir::HirVec::new(), Some(expr))
}
fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
- -> P<hir::Block> {
- P(hir::Block {
+ -> hir::Block {
+ hir::Block {
stmts: stmts,
expr: expr,
id: self.next_id(),
rules: hir::DefaultBlock,
span: span,
- })
+ }
}
fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
fn std_path_components(&mut self, components: &[&str]) -> Vec<Name> {
let mut v = Vec::new();
if let Some(s) = self.crate_root {
- v.push(token::intern(s));
+ v.push(Symbol::intern(s));
}
- v.extend(components.iter().map(|s| token::intern(s)));
+ v.extend(components.iter().map(|s| Symbol::intern(s)));
return v;
}
span: Span,
rule: hir::BlockCheckMode,
attrs: ThinVec<Attribute>)
- -> P<hir::Expr> {
+ -> hir::Expr {
let id = self.next_id();
let block = P(hir::Block {
rules: rule,
span: Span,
rule: hir::BlockCheckMode,
attrs: ThinVec<Attribute>)
- -> P<hir::Expr> {
+ -> hir::Expr {
let id = self.next_id();
let block = P(hir::Block {
rules: rule,
// except according to those terms.
use super::*;
-use super::MapEntry::*;
-use hir::*;
use hir::intravisit::Visitor;
use hir::def_id::DefId;
use middle::cstore::InlinedItem;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use super::*;
+use hir::map::definitions::*;
use hir;
use hir::intravisit;
use syntax::ast::*;
use syntax::ext::hygiene::Mark;
use syntax::visit;
-use syntax::parse::token::{self, keywords};
+use syntax::symbol::{Symbol, keywords};
/// Creates def ids for nodes in the HIR.
pub struct DefCollector<'a> {
this.with_parent(variant_def_index, |this| {
for (index, field) in v.node.data.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name)
- .unwrap_or_else(|| token::intern(&index.to_string()));
+ .unwrap_or_else(|| Symbol::intern(&index.to_string()));
this.create_def(field.id, DefPathData::Field(name.as_str()));
}
for (index, field) in struct_def.fields().iter().enumerate() {
let name = field.ident.map(|ident| ident.name.as_str())
- .unwrap_or(token::intern(&index.to_string()).as_str());
+ .unwrap_or(Symbol::intern(&index.to_string()).as_str());
this.create_def(field.id, DefPathData::Field(name));
}
}
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;
use syntax::ast;
-use syntax::parse::token::{self, InternedString};
+use syntax::symbol::{Symbol, InternedString};
use ty::TyCtxt;
use util::nodemap::NodeMap;
pub fn to_string(&self, tcx: TyCtxt) -> String {
let mut s = String::with_capacity(self.data.len() * 16);
- s.push_str(&tcx.original_crate_name(self.krate));
+ s.push_str(&tcx.original_crate_name(self.krate).as_str());
s.push_str("/");
- s.push_str(&tcx.crate_disambiguator(self.krate));
+ s.push_str(&tcx.crate_disambiguator(self.krate).as_str());
for component in &self.data {
write!(s,
}
pub fn deterministic_hash_to<H: Hasher>(&self, tcx: TyCtxt, state: &mut H) {
- tcx.original_crate_name(self.krate).hash(state);
- tcx.crate_disambiguator(self.krate).hash(state);
+ tcx.original_crate_name(self.krate).as_str().hash(state);
+ tcx.crate_disambiguator(self.krate).as_str().hash(state);
self.data.hash(state);
}
}
LifetimeDef(ref name) |
EnumVariant(ref name) |
Binding(ref name) |
- Field(ref name) => Some(token::intern(name)),
+ Field(ref name) => Some(Symbol::intern(name)),
Impl |
CrateRoot |
pub fn as_interned_str(&self) -> InternedString {
use self::DefPathData::*;
- match *self {
+ let s = match *self {
TypeNs(ref name) |
ValueNs(ref name) |
Module(ref name) |
EnumVariant(ref name) |
Binding(ref name) |
Field(ref name) => {
- name.clone()
- }
-
- Impl => {
- InternedString::new("{{impl}}")
+ return name.clone();
}
// note that this does not show up in user printouts
- CrateRoot => {
- InternedString::new("{{root}}")
- }
+ CrateRoot => "{{root}}",
// note that this does not show up in user printouts
- InlinedRoot(_) => {
- InternedString::new("{{inlined-root}}")
- }
-
- Misc => {
- InternedString::new("{{?}}")
- }
-
- ClosureExpr => {
- InternedString::new("{{closure}}")
- }
-
- StructCtor => {
- InternedString::new("{{constructor}}")
- }
-
- Initializer => {
- InternedString::new("{{initializer}}")
- }
+ InlinedRoot(_) => "{{inlined-root}}",
+
+ Impl => "{{impl}}",
+ Misc => "{{?}}",
+ ClosureExpr => "{{closure}}",
+ StructCtor => "{{constructor}}",
+ Initializer => "{{initializer}}",
+ ImplTrait => "{{impl-Trait}}",
+ };
- ImplTrait => {
- InternedString::new("{{impl-Trait}}")
- }
- }
+ Symbol::intern(s).as_str()
}
pub fn to_string(&self) -> String {
None => return false,
Some((node_id, name)) => (node_id, name),
};
- if &part[..] != mod_name.as_str() {
+ if mod_name != &**part {
return false;
}
cursor = self.map.get_parent(mod_id);
// We are looking at some node `n` with a given name and parent
// id; do their names match what I am seeking?
fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool {
- name.as_str() == &self.item_name[..] &&
- self.suffix_matches(parent_of_n)
+ name == &**self.item_name && self.suffix_matches(parent_of_n)
}
}
use syntax::abi::Abi;
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
-use syntax::parse::token::{keywords, InternedString};
use syntax::ptr::P;
+use syntax::symbol::{Symbol, keywords};
use syntax::tokenstream::TokenTree;
use syntax::util::ThinVec;
/// A `box x` expression.
ExprBox(P<Expr>),
/// An array (`[a, b, c, d]`)
- ExprArray(HirVec<P<Expr>>),
+ ExprArray(HirVec<Expr>),
/// A function call
///
/// The first field resolves to the function itself (usually an `ExprPath`),
/// and the second field is the list of arguments
- ExprCall(P<Expr>, HirVec<P<Expr>>),
+ ExprCall(P<Expr>, HirVec<Expr>),
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
///
/// The `Spanned<Name>` is the identifier for the method name.
///
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
- ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<P<Expr>>),
+ ExprMethodCall(Spanned<Name>, HirVec<P<Ty>>, HirVec<Expr>),
/// A tuple (`(a, b, c ,d)`)
- ExprTup(HirVec<P<Expr>>),
+ ExprTup(HirVec<Expr>),
/// A binary operation (For example: `a + b`, `a * b`)
ExprBinary(BinOp, P<Expr>, P<Expr>),
/// A unary operation (For example: `!x`, `*x`)
/// Conditionless loop (can be exited with break, continue, or return)
///
/// `'label: loop { block }`
- ExprLoop(P<Block>, Option<Spanned<Name>>),
+ ExprLoop(P<Block>, Option<Spanned<Name>>, LoopSource),
/// A `match` block, with a source that indicates whether or not it is
/// the result of a desugaring, and if so, which kind.
ExprMatch(P<Expr>, HirVec<Arm>, MatchSource),
/// A referencing operation (`&a` or `&mut a`)
ExprAddrOf(Mutability, P<Expr>),
/// A `break`, with an optional label to break
- ExprBreak(Option<Spanned<Name>>),
+ ExprBreak(Option<Spanned<Name>>, Option<P<Expr>>),
/// A `continue`, with an optional label
ExprAgain(Option<Spanned<Name>>),
/// A `return`, with an optional value to be returned
ExprRet(Option<P<Expr>>),
/// Inline assembly (from `asm!`), with its outputs and inputs.
- ExprInlineAsm(P<InlineAsm>, HirVec<P<Expr>>, HirVec<P<Expr>>),
+ ExprInlineAsm(P<InlineAsm>, HirVec<Expr>, HirVec<Expr>),
/// A struct or struct-like variant literal expression.
///
TryDesugar,
}
+/// The loop type that yielded an ExprLoop
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+pub enum LoopSource {
+ /// A `loop { .. }` loop
+ Loop,
+ /// A `while let _ = _ { .. }` loop
+ WhileLet,
+ /// A `for _ in _ { .. }` loop
+ ForLoop,
+}
+
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum CaptureClause {
CaptureByValue,
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsmOutput {
- pub constraint: InternedString,
+ pub constraint: Symbol,
pub is_rw: bool,
pub is_indirect: bool,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
- pub asm: InternedString,
+ pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: HirVec<InlineAsmOutput>,
- pub inputs: HirVec<InternedString>,
- pub clobbers: HirVec<InternedString>,
+ pub inputs: HirVec<Symbol>,
+ pub clobbers: HirVec<Symbol>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
use syntax::abi::Abi;
use syntax::ast;
use syntax::codemap::{CodeMap, Spanned};
-use syntax::parse::token::{self, keywords, BinOpToken};
+use syntax::parse::token::{self, BinOpToken};
use syntax::parse::lexer::comments;
use syntax::print::pp::{self, break_offset, word, space, hardbreak};
use syntax::print::pp::{Breaks, eof};
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
use syntax::print::pprust::{self as ast_pp, PrintState};
use syntax::ptr::P;
+use syntax::symbol::keywords;
use syntax_pos::{self, BytePos};
use errors;
self.end()
}
- pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<hir::Expr>]) -> io::Result<()> {
+ pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) -> io::Result<()> {
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
}
}
- fn print_call_post(&mut self, args: &[P<hir::Expr>]) -> io::Result<()> {
+ fn print_call_post(&mut self, args: &[hir::Expr]) -> io::Result<()> {
self.popen()?;
self.commasep_exprs(Inconsistent, args)?;
self.pclose()
Ok(())
}
- fn print_expr_vec(&mut self, exprs: &[P<hir::Expr>]) -> io::Result<()> {
+ fn print_expr_vec(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
self.ibox(indent_unit)?;
word(&mut self.s, "[")?;
- self.commasep_exprs(Inconsistent, &exprs[..])?;
+ self.commasep_exprs(Inconsistent, exprs)?;
word(&mut self.s, "]")?;
self.end()
}
Ok(())
}
- fn print_expr_tup(&mut self, exprs: &[P<hir::Expr>]) -> io::Result<()> {
+ fn print_expr_tup(&mut self, exprs: &[hir::Expr]) -> io::Result<()> {
self.popen()?;
- self.commasep_exprs(Inconsistent, &exprs[..])?;
+ self.commasep_exprs(Inconsistent, exprs)?;
if exprs.len() == 1 {
word(&mut self.s, ",")?;
}
self.pclose()
}
- fn print_expr_call(&mut self, func: &hir::Expr, args: &[P<hir::Expr>]) -> io::Result<()> {
+ fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) -> io::Result<()> {
self.print_expr_maybe_paren(func)?;
self.print_call_post(args)
}
fn print_expr_method_call(&mut self,
name: Spanned<ast::Name>,
tys: &[P<hir::Ty>],
- args: &[P<hir::Expr>])
+ args: &[hir::Expr])
-> io::Result<()> {
let base_args = &args[1..];
self.print_expr(&args[0])?;
self.print_expr(expr)?;
}
hir::ExprArray(ref exprs) => {
- self.print_expr_vec(&exprs[..])?;
+ self.print_expr_vec(exprs)?;
}
hir::ExprRepeat(ref element, ref count) => {
self.print_expr_repeat(&element, &count)?;
self.print_expr_struct(path, &fields[..], wth)?;
}
hir::ExprTup(ref exprs) => {
- self.print_expr_tup(&exprs[..])?;
+ self.print_expr_tup(exprs)?;
}
hir::ExprCall(ref func, ref args) => {
- self.print_expr_call(&func, &args[..])?;
+ self.print_expr_call(&func, args)?;
}
hir::ExprMethodCall(name, ref tys, ref args) => {
- self.print_expr_method_call(name, &tys[..], &args[..])?;
+ self.print_expr_method_call(name, &tys[..], args)?;
}
hir::ExprBinary(op, ref lhs, ref rhs) => {
self.print_expr_binary(op, &lhs, &rhs)?;
space(&mut self.s)?;
self.print_block(&blk)?;
}
- hir::ExprLoop(ref blk, opt_sp_name) => {
+ hir::ExprLoop(ref blk, opt_sp_name, _) => {
if let Some(sp_name) = opt_sp_name {
self.print_name(sp_name.node)?;
self.word_space(":")?;
hir::ExprPath(Some(ref qself), ref path) => {
self.print_qpath(path, qself, true)?
}
- hir::ExprBreak(opt_name) => {
+ hir::ExprBreak(opt_name, ref opt_expr) => {
word(&mut self.s, "break")?;
space(&mut self.s)?;
if let Some(name) = opt_name {
self.print_name(name.node)?;
space(&mut self.s)?;
}
+ if let Some(ref expr) = *opt_expr {
+ self.print_expr(expr)?;
+ space(&mut self.s)?;
+ }
}
hir::ExprAgain(opt_name) => {
word(&mut self.s, "continue")?;
hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => {
word(&mut self.s, "asm!")?;
self.popen()?;
- self.print_string(&a.asm, a.asm_str_style)?;
+ self.print_string(&a.asm.as_str(), a.asm_str_style)?;
self.word_space(":")?;
let mut out_idx = 0;
self.commasep(Inconsistent, &a.outputs, |s, out| {
- let mut ch = out.constraint.chars();
+ let constraint = out.constraint.as_str();
+ let mut ch = constraint.chars();
match ch.next() {
Some('=') if out.is_rw => {
s.print_string(&format!("+{}", ch.as_str()),
ast::StrStyle::Cooked)?
}
- _ => s.print_string(&out.constraint,
- ast::StrStyle::Cooked)?,
+ _ => s.print_string(&constraint, ast::StrStyle::Cooked)?,
}
s.popen()?;
s.print_expr(&outputs[out_idx])?;
let mut in_idx = 0;
self.commasep(Inconsistent, &a.inputs, |s, co| {
- s.print_string(&co, ast::StrStyle::Cooked)?;
+ s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
s.popen()?;
s.print_expr(&inputs[in_idx])?;
s.pclose()?;
self.word_space(":")?;
self.commasep(Inconsistent, &a.clobbers, |s, co| {
- s.print_string(&co, ast::StrStyle::Cooked)?;
+ s.print_string(&co.as_str(), ast::StrStyle::Cooked)?;
Ok(())
})?;
use std::char::from_u32;
use std::fmt;
use syntax::ast;
-use syntax::parse::token;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::{self, Pos, Span};
use errors::DiagnosticBuilder;
names.push(lt_name);
}
names.sort();
- let name = token::intern(&names[0]);
+ let name = Symbol::intern(&names[0]);
return (name_to_dummy_lifetime(name), Kept);
}
return (self.life_giver.give_lifetime(), Fresh);
let mut s = String::from("'");
s.push_str(&num_to_string(self.counter.get()));
if !self.taken.contains(&s) {
- lifetime = name_to_dummy_lifetime(token::intern(&s[..]));
+ lifetime = name_to_dummy_lifetime(Symbol::intern(&s));
self.generated.borrow_mut().push(lifetime);
break;
}
#![feature(core_intrinsics)]
#![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))]
#![feature(enumset)]
+#![cfg_attr(stage0, feature(item_like_imports))]
#![feature(libc)]
#![feature(nonzero)]
#![feature(quote)]
declare_lint! {
pub HR_LIFETIME_IN_ASSOC_TYPE,
- Warn,
+ Deny,
"binding for associated type references higher-ranked lifetime \
that does not appear in the trait input types"
}
"detects extra requirements in impls that were erroneously allowed"
}
+declare_lint! {
+ pub LEGACY_DIRECTORY_OWNERSHIP,
+ Warn,
+ "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
+ not named `mod.rs`"
+}
+
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
LIFETIME_UNDERSCORE,
SAFE_EXTERN_STATICS,
PATTERNS_IN_FNS_WITHOUT_BODY,
- EXTRA_REQUIREMENT_IN_IMPL
+ EXTRA_REQUIREMENT_IN_IMPL,
+ LEGACY_DIRECTORY_OWNERSHIP
)
}
}
use std::mem;
use std::fmt;
use syntax::attr;
-use syntax::parse::token::InternedString;
use syntax::ast;
use syntax_pos::{MultiSpan, Span};
use errors::{self, Diagnostic, DiagnosticBuilder};
/// Parse the lint attributes into a vector, with `Err`s for malformed lint
/// attributes. Writing this as an iterator is an enormous mess.
// See also the hir version just below.
-pub fn gather_attrs(attrs: &[ast::Attribute])
- -> Vec<Result<(InternedString, Level, Span), Span>> {
+pub fn gather_attrs(attrs: &[ast::Attribute]) -> Vec<Result<(ast::Name, Level, Span), Span>> {
let mut out = vec![];
for attr in attrs {
let r = gather_attr(attr);
out
}
-pub fn gather_attr(attr: &ast::Attribute)
- -> Vec<Result<(InternedString, Level, Span), Span>> {
+pub fn gather_attr(attr: &ast::Attribute) -> Vec<Result<(ast::Name, Level, Span), Span>> {
let mut out = vec![];
- let level = match Level::from_str(&attr.name()) {
+ let level = match Level::from_str(&attr.name().as_str()) {
None => return out,
Some(lvl) => lvl,
};
attr::mark_used(attr);
- let meta = &attr.node.value;
+ let meta = &attr.value;
let metas = if let Some(metas) = meta.meta_item_list() {
metas
} else {
};
for li in metas {
- out.push(li.word().map_or(Err(li.span), |word| {
- Ok((word.name().clone(), level, word.span))
- }));
+ out.push(li.word().map_or(Err(li.span), |word| Ok((word.name(), level, word.span))));
}
out
continue;
}
Ok((lint_name, level, span)) => {
- match self.lints().find_lint(&lint_name, &self.sess(), Some(span)) {
+ match self.lints().find_lint(&lint_name.as_str(), &self.sess(), Some(span)) {
Ok(lint_id) => vec![(lint_id, level, span)],
Err(FindLintError::NotFound) => {
- match self.lints().lint_groups.get(&lint_name[..]) {
+ match self.lints().lint_groups.get(&*lint_name.as_str()) {
Some(&(ref v, _)) => v.iter()
.map(|lint_id: &LintId|
(*lint_id, level, span))
continue;
}
Ok((lint_name, _, span)) => {
- match check_lint_name(&cx.lints,
- &lint_name[..]) {
+ match check_lint_name(&cx.lints, &lint_name.as_str()) {
CheckLintNameResult::Ok => (),
CheckLintNameResult::Warning(ref msg) => {
cx.span_lint(builtin::RENAMED_AND_REMOVED_LINTS,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use syntax::parse::token::InternedString;
+use syntax::symbol::InternedString;
use syntax::ast;
use std::rc::Rc;
use hir::def_id::DefId;
use syntax::attr;
use syntax::ext::base::SyntaxExtension;
use syntax::ptr::P;
-use syntax::parse::token::InternedString;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_back::target::Target;
use hir;
#[derive(Clone, Debug)]
pub struct LinkMeta {
- pub crate_name: String,
+ pub crate_name: Symbol,
pub crate_hash: Svh,
}
-// Where a crate came from on the local filesystem. One of these two options
+// Where a crate came from on the local filesystem. One of these three options
// must be non-None.
#[derive(PartialEq, Clone, Debug)]
pub struct CrateSource {
pub dylib: Option<(PathBuf, PathKind)>,
pub rlib: Option<(PathBuf, PathKind)>,
+ pub rmeta: Option<(PathBuf, PathKind)>,
}
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
Explicit,
}
+#[derive(PartialEq, Clone, Debug)]
+pub enum LibSource {
+ Some(PathBuf),
+ MetadataOnly,
+ None,
+}
+
+impl LibSource {
+ pub fn is_some(&self) -> bool {
+ if let LibSource::Some(_) = *self {
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn option(&self) -> Option<PathBuf> {
+ match *self {
+ LibSource::Some(ref p) => Some(p.clone()),
+ LibSource::MetadataOnly | LibSource::None => None,
+ }
+ }
+}
+
#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
pub enum LinkagePreference {
RequireDynamic,
#[derive(Clone, Hash, RustcEncodable, RustcDecodable)]
pub struct NativeLibrary {
pub kind: NativeLibraryKind,
- pub name: String,
- pub cfg: Option<P<ast::MetaItem>>,
+ pub name: Symbol,
+ pub cfg: Option<ast::MetaItem>,
}
/// The data we save and restore about an inlined item or method. This is not
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
/// The name of the crate as it is referred to in source code of the current
/// crate.
- fn crate_name(&self, cnum: CrateNum) -> InternedString;
+ fn crate_name(&self, cnum: CrateNum) -> Symbol;
/// The name of the crate as it is stored in the crate's metadata.
- fn original_crate_name(&self, cnum: CrateNum) -> InternedString;
+ fn original_crate_name(&self, cnum: CrateNum) -> Symbol;
fn crate_hash(&self, cnum: CrateNum) -> Svh;
- fn crate_disambiguator(&self, cnum: CrateNum) -> InternedString;
+ fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol;
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>;
fn reachable_ids(&self, cnum: CrateNum) -> Vec<DefId>;
// utility functions
fn metadata_filename(&self) -> &str;
fn metadata_section_name(&self, target: &Target) -> &str;
- fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
+ fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
bug!("panic_strategy")
}
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate> { bug!("extern_crate") }
- fn crate_name(&self, cnum: CrateNum) -> InternedString { bug!("crate_name") }
- fn original_crate_name(&self, cnum: CrateNum) -> InternedString {
+ fn crate_name(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
+ fn original_crate_name(&self, cnum: CrateNum) -> Symbol {
bug!("original_crate_name")
}
fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
fn crate_disambiguator(&self, cnum: CrateNum)
- -> InternedString { bug!("crate_disambiguator") }
+ -> Symbol { bug!("crate_disambiguator") }
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
{ bug!("plugin_registrar_fn") }
fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>
// utility functions
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
- fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
+ fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{ vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
let dead_code = lint::builtin::DEAD_CODE.name_lower();
for attr in lint::gather_attrs(attrs) {
match attr {
- Ok((ref name, lint::Allow, _))
- if &name[..] == dead_code => return true,
+ Ok((name, lint::Allow, _)) if name == &*dead_code => return true,
_ => (),
}
}
span: syntax_pos::Span,
name: ast::Name,
node_type: &str) {
- let name = name.as_str();
- if !name.starts_with("_") {
+ if !name.as_str().starts_with("_") {
self.tcx
.sess
.add_lint(lint::builtin::DEAD_CODE,
// No linkage happens with rlibs, we just needed the metadata (which we
// got long ago), so don't bother with anything.
- config::CrateTypeRlib => return Vec::new(),
+ config::CrateTypeRlib | config::CrateTypeMetadata => return Vec::new(),
// Staticlibs and cdylibs must have all static dependencies. If any fail
// to be found, we generate some nice pretty errors.
if src.dylib.is_none() &&
!formats.contains_key(&cnum) &&
sess.cstore.dep_kind(cnum) == DepKind::Explicit {
- assert!(src.rlib.is_some());
+ assert!(src.rlib.is_some() || src.rmeta.is_some());
info!("adding staticlib: {}", sess.cstore.crate_name(cnum));
add_library(sess, cnum, RequireStatic, &mut formats);
ret[cnum.as_usize() - 1] = Linkage::Static;
EntryPointType::Start
} else if attr::contains_name(&item.attrs, "main") {
EntryPointType::MainAttr
- } else if item.name.as_str() == "main" {
+ } else if item.name == "main" {
if at_root {
// This is a top-level function so can be 'main'
EntryPointType::MainNamed
self.delegate.consume(consume_id, consume_span, cmt, mode);
}
- fn consume_exprs(&mut self, exprs: &[P<hir::Expr>]) {
+ fn consume_exprs(&mut self, exprs: &[hir::Expr]) {
for expr in exprs {
self.consume_expr(&expr);
}
self.consume_exprs(inputs);
}
- hir::ExprBreak(..) |
hir::ExprAgain(..) |
hir::ExprLit(..) => {}
- hir::ExprLoop(ref blk, _) => {
+ hir::ExprLoop(ref blk, _, _) => {
self.walk_block(&blk);
}
self.walk_block(&blk);
}
- hir::ExprRet(ref opt_expr) => {
+ hir::ExprBreak(_, ref opt_expr) | hir::ExprRet(ref opt_expr) => {
if let Some(ref expr) = *opt_expr {
self.consume_expr(&expr);
}
ty::TyFnDef(.., ref bfty) => bfty.abi == RustIntrinsic,
_ => return false
};
- intrinsic && self.infcx.tcx.item_name(def_id).as_str() == "transmute"
+ intrinsic && self.infcx.tcx.item_name(def_id) == "transmute"
}
fn check_transmute(&self, span: Span, from: Ty<'gcx>, to: Ty<'gcx>, id: ast::NodeId) {
use util::nodemap::FxHashMap;
use syntax::ast;
-use syntax::parse::token::InternedString;
+use syntax::symbol::Symbol;
use hir::itemlikevisit::ItemLikeVisitor;
use hir;
impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
if let Some(value) = extract(&item.attrs) {
- let item_index = self.item_refs.get(&value[..]).cloned();
+ let item_index = self.item_refs.get(&*value.as_str()).cloned();
if let Some(item_index) = item_index {
self.collect_item(item_index, self.ast_map.local_def_id(item.id))
let span = self.ast_map.span(item.id);
span_err!(self.session, span, E0522,
"definition of an unknown language item: `{}`.",
- &value[..]);
+ value);
}
}
}
}
}
-pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
+pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
for attribute in attrs {
match attribute.value_str() {
- Some(ref value) if attribute.check_name("lang") => {
- return Some(value.clone());
- }
+ Some(value) if attribute.check_name("lang") => return Some(value),
_ => {}
}
}
use std::io;
use std::rc::Rc;
use syntax::ast::{self, NodeId};
-use syntax::parse::token::keywords;
-use syntax::ptr::P;
+use syntax::symbol::keywords;
use syntax_pos::Span;
use hir::Expr;
hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprTupField(..) |
hir::ExprArray(..) | hir::ExprCall(..) | hir::ExprMethodCall(..) |
hir::ExprTup(..) | hir::ExprBinary(..) | hir::ExprAddrOf(..) |
- hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(_) |
+ hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprBreak(..) |
hir::ExprAgain(_) | hir::ExprLit(_) | hir::ExprRet(..) |
hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
hir::ExprStruct(..) | hir::ExprRepeat(..) |
self.define_bindings_in_pat(&local.pat, succ)
}
- fn propagate_through_exprs(&mut self, exprs: &[P<Expr>], succ: LiveNode)
+ fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode)
-> LiveNode {
exprs.iter().rev().fold(succ, |succ, expr| {
self.propagate_through_expr(&expr, succ)
// Note that labels have been resolved, so we don't need to look
// at the label ident
- hir::ExprLoop(ref blk, _) => {
+ hir::ExprLoop(ref blk, _, _) => {
self.propagate_through_loop(expr, LoopLoop, &blk, succ)
}
self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
}
- hir::ExprBreak(opt_label) => {
+ hir::ExprBreak(opt_label, ref opt_expr) => {
// Find which label this break jumps to
let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span);
// look it up in the break loop nodes table
match self.break_ln.get(&sc) {
- Some(&b) => b,
+ Some(&b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b),
None => span_bug!(expr.span, "break to unknown label")
}
}
match self.cont_ln.get(&sc) {
Some(&b) => b,
- None => span_bug!(expr.span, "loop to unknown label")
+ None => span_bug!(expr.span, "continue to unknown label")
}
}
// Uninteresting cases: just propagate in rev exec order
hir::ExprArray(ref exprs) => {
- self.propagate_through_exprs(&exprs[..], succ)
+ self.propagate_through_exprs(exprs, succ)
}
hir::ExprRepeat(ref element, ref count) => {
} else {
succ
};
- let succ = self.propagate_through_exprs(&args[..], succ);
+ let succ = self.propagate_through_exprs(args, succ);
self.propagate_through_expr(&f, succ)
}
} else {
succ
};
- self.propagate_through_exprs(&args[..], succ)
+ self.propagate_through_exprs(args, succ)
}
hir::ExprTup(ref exprs) => {
- self.propagate_through_exprs(&exprs[..], succ)
+ self.propagate_through_exprs(exprs, succ)
}
hir::ExprBinary(op, ref l, ref r) if op.node.is_lazy() => {
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ReachableContext<'a, 'tcx> {
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
- *ty == config::CrateTypeProcMacro
+ *ty == config::CrateTypeProcMacro || *ty == config::CrateTypeMetadata
});
ReachableContext {
tcx: tcx,
}
if let Some(s) = attr.value_str() {
- if let Some(n) = s.parse().ok() {
+ if let Some(n) = s.as_str().parse().ok() {
sess.recursion_limit.set(n);
return;
}
terminating(then.id);
}
- hir::ExprLoop(ref body, _) => {
+ hir::ExprLoop(ref body, _, _) => {
terminating(body.id);
}
use ty;
use std::mem::replace;
use syntax::ast;
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use syntax_pos::Span;
use util::nodemap::NodeMap;
fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> {
match ex.node {
hir::ExprWhile(.., Some(label)) |
- hir::ExprLoop(_, Some(label)) => Some((label.node, label.span)),
+ hir::ExprLoop(_, Some(label), _) => Some((label.node, label.span)),
_ => None,
}
}
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, DefIndex, LOCAL_CRATE};
use ty::{self, TyCtxt, AdtKind};
use middle::privacy::AccessLevels;
-use syntax::parse::token::InternedString;
+use syntax::symbol::Symbol;
use syntax_pos::{Span, DUMMY_SP};
use syntax::ast;
use syntax::ast::{NodeId, Attribute};
use std::mem::replace;
use std::cmp::Ordering;
-use std::ops::Deref;
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Copy, Debug, Eq, Hash)]
pub enum StabilityLevel {
// Check if deprecated_since < stable_since. If it is,
// this is *almost surely* an accident.
- if let (&Some(attr::RustcDeprecation {since: ref dep_since, ..}),
- &attr::Stable {since: ref stab_since}) = (&stab.rustc_depr, &stab.level) {
+ if let (&Some(attr::RustcDeprecation {since: dep_since, ..}),
+ &attr::Stable {since: stab_since}) = (&stab.rustc_depr, &stab.level) {
// Explicit version of iter::order::lt to handle parse errors properly
- for (dep_v, stab_v) in dep_since.split(".").zip(stab_since.split(".")) {
+ for (dep_v, stab_v) in
+ dep_since.as_str().split(".").zip(stab_since.as_str().split(".")) {
if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
match dep_v.cmp(&stab_v) {
Ordering::Less => {
/// features and possibly prints errors. Returns a list of all
/// features used.
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
- -> FxHashMap<InternedString, attr::StabilityLevel> {
+ -> FxHashMap<Symbol, attr::StabilityLevel> {
let _task = tcx.dep_graph.in_task(DepNode::StabilityCheck);
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
struct Checker<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- active_features: FxHashSet<InternedString>,
- used_features: FxHashMap<InternedString, attr::StabilityLevel>,
+ active_features: FxHashSet<Symbol>,
+ used_features: FxHashMap<Symbol, attr::StabilityLevel>,
// Within a block where feature gate checking can be skipped.
in_skip_block: u32,
}
if !self.active_features.contains(feature) {
let msg = match *reason {
Some(ref r) => format!("use of unstable library feature '{}': {}",
- &feature, &r),
+ &feature.as_str(), &r),
None => format!("use of unstable library feature '{}'", &feature)
};
- emit_feature_err(&self.tcx.sess.parse_sess, &feature, span,
+ emit_feature_err(&self.tcx.sess.parse_sess, &feature.as_str(), span,
GateIssue::Library(Some(issue)), &msg);
}
}
// When compiling with --test we don't enforce stability on the
// compiler-generated test module, demarcated with `DUMMY_SP` plus the
// name `__test`
- if item.span == DUMMY_SP && item.name.as_str() == "__test" { return }
+ if item.span == DUMMY_SP && item.name == "__test" { return }
check_item(self.tcx, item, true,
&mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
/// were expected to be library features), and the list of features used from
/// libraries, identify activated features that don't exist and error about them.
pub fn check_unused_or_stable_features(sess: &Session,
- lib_features_used: &FxHashMap<InternedString,
+ lib_features_used: &FxHashMap<Symbol,
attr::StabilityLevel>) {
let ref declared_lib_features = sess.features.borrow().declared_lib_features;
- let mut remaining_lib_features: FxHashMap<InternedString, Span>
+ let mut remaining_lib_features: FxHashMap<Symbol, Span>
= declared_lib_features.clone().into_iter().collect();
fn format_stable_since_msg(version: &str) -> String {
}
for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
- let version = find_lang_feature_accepted_version(stable_lang_feature.deref())
+ let version = find_lang_feature_accepted_version(&stable_lang_feature.as_str())
.expect("unexpectedly couldn't find version feature was stabilized");
sess.add_lint(lint::builtin::STABLE_FEATURES,
ast::CRATE_NODE_ID,
sess.add_lint(lint::builtin::STABLE_FEATURES,
ast::CRATE_NODE_ID,
span,
- format_stable_since_msg(version.deref()));
+ format_stable_since_msg(&version.as_str()));
}
}
None => ( /* used but undeclared, handled during the previous ast visit */ )
use rustc_back::PanicStrategy;
use syntax::ast;
-use syntax::parse::token::InternedString;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use hir::intravisit::Visitor;
use hir::intravisit;
verify(sess, items);
}
-pub fn link_name(attrs: &[ast::Attribute]) -> Option<InternedString> {
+pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
lang_items::extract(attrs).and_then(|name| {
- $(if &name[..] == stringify!($name) {
- Some(InternedString::new(stringify!($sym)))
+ $(if name == stringify!($name) {
+ Some(Symbol::intern(stringify!($sym)))
} else)* {
None
}
config::CrateTypeCdylib |
config::CrateTypeExecutable |
config::CrateTypeStaticlib => true,
- config::CrateTypeRlib => false,
+ config::CrateTypeRlib |
+ config::CrateTypeMetadata => false,
}
});
if !needs_check {
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
if let Some(lang_item) = lang_items::extract(&i.attrs) {
- self.register(&lang_item, i.span);
+ self.register(&lang_item.as_str(), i.span);
}
intravisit::walk_foreign_item(self, i)
}
use middle::cstore;
use syntax::ast::{self, IntTy, UintTy};
-use syntax::attr;
use syntax::parse;
-use syntax::parse::token::InternedString;
+use syntax::symbol::Symbol;
use syntax::feature_gate::UnstableFeatures;
use errors::{ColorConfig, FatalError, Handler};
use std::fmt;
use std::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
+use std::collections::HashSet;
use std::iter::FromIterator;
use std::path::PathBuf;
DepInfo,
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum ErrorOutputType {
- HumanReadable(ColorConfig),
- Json,
-}
-
-impl Default for ErrorOutputType {
- fn default() -> ErrorOutputType {
- ErrorOutputType::HumanReadable(ColorConfig::Auto)
- }
-}
-
impl OutputType {
fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
match *self {
}
}
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum ErrorOutputType {
+ HumanReadable(ColorConfig),
+ Json,
+}
+
+impl Default for ErrorOutputType {
+ fn default() -> ErrorOutputType {
+ ErrorOutputType::HumanReadable(ColorConfig::Auto)
+ }
+}
+
// Use tree-based collections to cheaply get a deterministic Hash implementation.
// DO NOT switch BTreeMap out for an unsorted container type! That would break
// dependency tracking for commandline arguments.
CrateTypeStaticlib,
CrateTypeCdylib,
CrateTypeProcMacro,
+ CrateTypeMetadata,
}
#[derive(Clone, Hash)]
}
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
- use syntax::parse::token::intern_and_get_ident as intern;
-
let end = &sess.target.target.target_endian;
let arch = &sess.target.target.arch;
let wordsz = &sess.target.target.target_pointer_width;
let max_atomic_width = sess.target.target.max_atomic_width();
let fam = if let Some(ref fam) = sess.target.target.options.target_family {
- intern(fam)
+ Symbol::intern(fam)
} else if sess.target.target.options.is_like_windows {
- InternedString::new("windows")
+ Symbol::intern("windows")
} else {
- InternedString::new("unix")
+ Symbol::intern("unix")
};
- let mk = attr::mk_name_value_item_str;
- let mut ret = vec![ // Target bindings.
- mk(InternedString::new("target_os"), intern(os)),
- mk(InternedString::new("target_family"), fam.clone()),
- mk(InternedString::new("target_arch"), intern(arch)),
- mk(InternedString::new("target_endian"), intern(end)),
- mk(InternedString::new("target_pointer_width"), intern(wordsz)),
- mk(InternedString::new("target_env"), intern(env)),
- mk(InternedString::new("target_vendor"), intern(vendor)),
- ];
- match &fam[..] {
- "windows" | "unix" => ret.push(attr::mk_word_item(fam)),
- _ => (),
+ let mut ret = HashSet::new();
+ // Target bindings.
+ ret.insert((Symbol::intern("target_os"), Some(Symbol::intern(os))));
+ ret.insert((Symbol::intern("target_family"), Some(fam)));
+ ret.insert((Symbol::intern("target_arch"), Some(Symbol::intern(arch))));
+ ret.insert((Symbol::intern("target_endian"), Some(Symbol::intern(end))));
+ ret.insert((Symbol::intern("target_pointer_width"), Some(Symbol::intern(wordsz))));
+ ret.insert((Symbol::intern("target_env"), Some(Symbol::intern(env))));
+ ret.insert((Symbol::intern("target_vendor"), Some(Symbol::intern(vendor))));
+ if fam == "windows" || fam == "unix" {
+ ret.insert((fam, None));
}
if sess.target.target.options.has_elf_tls {
- ret.push(attr::mk_word_item(InternedString::new("target_thread_local")));
+ ret.insert((Symbol::intern("target_thread_local"), None));
}
for &i in &[8, 16, 32, 64, 128] {
if i <= max_atomic_width {
let s = i.to_string();
- ret.push(mk(InternedString::new("target_has_atomic"), intern(&s)));
+ ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern(&s))));
if &s == wordsz {
- ret.push(mk(InternedString::new("target_has_atomic"), intern("ptr")));
+ ret.insert((Symbol::intern("target_has_atomic"), Some(Symbol::intern("ptr"))));
}
}
}
if sess.opts.debug_assertions {
- ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
+ ret.insert((Symbol::intern("debug_assertions"), None));
}
if sess.opts.crate_types.contains(&CrateTypeProcMacro) {
- ret.push(attr::mk_word_item(InternedString::new("proc_macro")));
+ ret.insert((Symbol::intern("proc_macro"), None));
}
return ret;
}
-pub fn append_configuration(cfg: &mut ast::CrateConfig,
- name: InternedString) {
- if !cfg.iter().any(|mi| mi.name() == name) {
- cfg.push(attr::mk_word_item(name))
- }
-}
-
pub fn build_configuration(sess: &Session,
mut user_cfg: ast::CrateConfig)
-> ast::CrateConfig {
let default_cfg = default_configuration(sess);
// If the user wants a test runner, then add the test cfg
if sess.opts.test {
- append_configuration(&mut user_cfg, InternedString::new("test"))
+ user_cfg.insert((Symbol::intern("test"), None));
}
- let mut v = user_cfg.into_iter().collect::<Vec<_>>();
- v.extend_from_slice(&default_cfg[..]);
- v
+ user_cfg.extend(default_cfg.iter().cloned());
+ user_cfg
}
pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
assumed.", "[KIND=]NAME"),
opt::multi_s("", "crate-type", "Comma separated list of types of crates
for the compiler to emit",
- "[bin|lib|rlib|dylib|cdylib|staticlib]"),
+ "[bin|lib|rlib|dylib|cdylib|staticlib|metadata]"),
opt::opt_s("", "crate-name", "Specify the name of the crate being built",
"NAME"),
opt::multi_s("", "emit", "Comma separated list of types of output for \
let meta_item = panictry!(parser.parse_meta_item());
if !parser.reader.is_eof() {
- early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}",
- s))
+ early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}", s))
+ } else if meta_item.is_meta_item_list() {
+ let msg =
+ format!("invalid predicate in --cfg command line argument: `{}`", meta_item.name());
+ early_error(ErrorOutputType::default(), &msg)
}
- meta_item
+ (meta_item.name(), meta_item.value_str())
}).collect::<ast::CrateConfig>()
}
"cdylib" => CrateTypeCdylib,
"bin" => CrateTypeExecutable,
"proc-macro" => CrateTypeProcMacro,
+ "metadata" => CrateTypeMetadata,
_ => {
return Err(format!("unknown crate type: `{}`",
part));
CrateTypeStaticlib => "staticlib".fmt(f),
CrateTypeCdylib => "cdylib".fmt(f),
CrateTypeProcMacro => "proc-macro".fmt(f),
+ CrateTypeMetadata => "metadata".fmt(f),
}
}
}
use std::rc::Rc;
use super::{OutputType, OutputTypes, Externs};
use rustc_back::PanicStrategy;
- use syntax::{ast, attr};
- use syntax::parse::token::InternedString;
- use syntax::codemap::dummy_spanned;
+ use syntax::symbol::Symbol;
fn optgroups() -> Vec<OptGroup> {
super::rustc_optgroups().into_iter()
let (sessopts, cfg) = build_session_options_and_crate_config(matches);
let sess = build_session(sessopts, &dep_graph, None, registry, Rc::new(DummyCrateStore));
let cfg = build_configuration(&sess, cfg);
- assert!(attr::contains(&cfg, &dummy_spanned(ast::MetaItemKind::Word({
- InternedString::new("test")
- }))));
+ assert!(cfg.contains(&(Symbol::intern("test"), None)));
}
// When the user supplies --test and --cfg test, don't implicitly add
let sess = build_session(sessopts, &dep_graph, None, registry,
Rc::new(DummyCrateStore));
let cfg = build_configuration(&sess, cfg);
- let mut test_items = cfg.iter().filter(|m| m.name() == "test");
+ let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test");
assert!(test_items.next().is_some());
assert!(test_items.next().is_none());
}
use syntax::feature_gate;
use syntax::parse;
use syntax::parse::ParseSess;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax::{ast, codemap};
use syntax::feature_gate::AttributeType;
use syntax_pos::{Span, MultiSpan};
// forms a unique global identifier for the crate. It is used to allow
// multiple crates with the same name to coexist. See the
// trans::back::symbol_names module for more information.
- pub crate_disambiguator: RefCell<token::InternedString>,
+ pub crate_disambiguator: RefCell<Symbol>,
pub features: RefCell<feature_gate::Features>,
/// The maximum recursion limit for potentially infinitely recursive
}
impl Session {
- pub fn local_crate_disambiguator(&self) -> token::InternedString {
- self.crate_disambiguator.borrow().clone()
+ pub fn local_crate_disambiguator(&self) -> Symbol {
+ *self.crate_disambiguator.borrow()
}
pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
sp: S,
plugin_attributes: RefCell::new(Vec::new()),
crate_types: RefCell::new(Vec::new()),
dependency_formats: RefCell::new(FxHashMap()),
- crate_disambiguator: RefCell::new(token::intern("").as_str()),
+ crate_disambiguator: RefCell::new(Symbol::intern("")),
features: RefCell::new(feature_gate::Features::new()),
recursion_limit: Cell::new(64),
next_node_id: Cell::new(NodeId::new(1)),
let err_sp = item.meta().span.substitute_dummy(span);
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
let trait_str = def.trait_ref.to_string();
- if let Some(ref istring) = item.value_str() {
+ if let Some(istring) = item.value_str() {
+ let istring = &*istring.as_str();
let generic_map = def.generics.types.iter().map(|param| {
(param.name.as_str().to_string(),
trait_ref.substs.type_for_def(param).to_string())
}).collect::<FxHashMap<String, String>>();
- let parser = Parser::new(&istring);
+ let parser = Parser::new(istring);
let mut errored = false;
let err: String = parser.filter_map(|p| {
match p {
use hir::def_id::DefId;
use infer::InferOk;
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
-use syntax::parse::token;
use syntax::ast;
+use syntax::symbol::Symbol;
use ty::subst::Subst;
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
let predicate = ty::Binder(ty::ProjectionPredicate { // (1) recreate binder here
projection_ty: ty::ProjectionTy {
trait_ref: trait_ref,
- item_name: token::intern(FN_OUTPUT_NAME),
+ item_name: Symbol::intern(FN_OUTPUT_NAME),
},
ty: ret_type
});
use std::iter;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
-use syntax::parse::token::{self, keywords};
+use syntax::symbol::{Symbol, keywords};
use hir;
/// The definite name of the current crate after taking into account
/// attributes, commandline parameters, etc.
- pub crate_name: token::InternedString,
+ pub crate_name: Symbol,
/// Data layout specification for the current target.
pub data_layout: TargetDataLayout,
/// Map from function to the `#[derive]` mode that it's defining. Only used
/// by `proc-macro` crates.
- pub derive_macros: RefCell<NodeMap<token::InternedString>>,
+ pub derive_macros: RefCell<NodeMap<Symbol>>,
}
impl<'tcx> GlobalCtxt<'tcx> {
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
- pub fn crate_name(self, cnum: CrateNum) -> token::InternedString {
+ pub fn crate_name(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
- self.crate_name.clone()
+ self.crate_name
} else {
self.sess.cstore.crate_name(cnum)
}
}
- pub fn original_crate_name(self, cnum: CrateNum) -> token::InternedString {
+ pub fn original_crate_name(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
self.crate_name.clone()
} else {
}
}
- pub fn crate_disambiguator(self, cnum: CrateNum) -> token::InternedString {
+ pub fn crate_disambiguator(self, cnum: CrateNum) -> Symbol {
if cnum == LOCAL_CRATE {
self.sess.local_crate_disambiguator()
} else {
custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
cast_kinds: RefCell::new(NodeMap()),
fragment_infos: RefCell::new(DefIdMap()),
- crate_name: token::intern_and_get_ident(crate_name),
+ crate_name: Symbol::intern(crate_name),
data_layout: data_layout,
layout_cache: RefCell::new(FxHashMap()),
layout_depth: Cell::new(0),
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use ty::{self, Ty, TyCtxt};
use syntax::ast;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use std::cell::Cell;
if let Some(extern_crate_def_id) = opt_extern_crate {
self.push_item_path(buffer, extern_crate_def_id);
} else {
- buffer.push(&self.crate_name(cnum));
+ buffer.push(&self.crate_name(cnum).as_str());
}
}
}
RootMode::Absolute => {
// In absolute mode, just write the crate name
// unconditionally.
- buffer.push(&self.original_crate_name(cnum));
+ buffer.push(&self.original_crate_name(cnum).as_str());
}
}
}
return true;
}
None => {
- buffer.push(&self.crate_name(cur_def.krate));
+ buffer.push(&self.crate_name(cur_def.krate).as_str());
cur_path.iter().rev().map(|segment| buffer.push(&segment.as_str())).count();
return true;
}
cur_path.push(self.sess.cstore.def_key(cur_def)
.disambiguated_data.data.get_opt_name().unwrap_or_else(||
- token::intern("<unnamed>")));
+ Symbol::intern("<unnamed>")));
match visible_parent_map.get(&cur_def) {
Some(&def) => cur_def = def,
None => return false,
use ty::walk::TypeWalker;
use util::common::MemoizationMap;
use util::nodemap::NodeSet;
-use util::nodemap::FxHashMap;
+use util::nodemap::{FxHashMap, FxHashSet};
use serialize::{self, Encodable, Encoder};
use std::borrow::Cow;
use std::mem;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
-use syntax::parse::token::{self, InternedString};
+use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{DUMMY_SP, Span};
use rustc_const_math::ConstInt;
+use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
use hir;
use hir::itemlikevisit::ItemLikeVisitor;
impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {}
+impl<'a, 'gcx, 'tcx> AdtDefData<'tcx, 'static> {
+ #[inline]
+ pub fn is_uninhabited_recurse(&'tcx self,
+ visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
+ block: Option<NodeId>,
+ cx: TyCtxt<'a, 'gcx, 'tcx>,
+ substs: &'tcx Substs<'tcx>) -> bool {
+ if !visited.insert((self.did, substs)) {
+ return false;
+ };
+ self.variants.iter().all(|v| {
+ v.is_uninhabited_recurse(visited, block, cx, substs, self.is_union())
+ })
+ }
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum AdtKind { Struct, Union, Enum }
self.variants.iter().flat_map(VariantDefData::fields_iter)
}
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.variants.is_empty()
- }
-
#[inline]
pub fn is_univariant(&self) -> bool {
self.variants.len() == 1
}
}
+impl<'a, 'gcx, 'tcx> VariantDefData<'tcx, 'static> {
+ #[inline]
+ pub fn is_uninhabited_recurse(&'tcx self,
+ visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
+ block: Option<NodeId>,
+ cx: TyCtxt<'a, 'gcx, 'tcx>,
+ substs: &'tcx Substs<'tcx>,
+ is_union: bool) -> bool {
+ if is_union {
+ self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
+ } else {
+ self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
+ }
+ }
+}
+
impl<'a, 'gcx, 'tcx, 'container> FieldDefData<'tcx, 'container> {
pub fn new(did: DefId,
name: Name,
}
}
+impl<'a, 'gcx, 'tcx> FieldDefData<'tcx, 'static> {
+ #[inline]
+ pub fn is_uninhabited_recurse(&'tcx self,
+ visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
+ block: Option<NodeId>,
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ substs: &'tcx Substs<'tcx>) -> bool {
+ block.map_or(true, |b| self.vis.is_accessible_from(b, &tcx.map)) &&
+ self.ty(tcx, substs).is_uninhabited_recurse(visited, block, tcx)
+ }
+}
+
/// Records the substitutions used to translate the polytype for an
/// item into the monotype of an item reference.
#[derive(Clone, RustcEncodable, RustcDecodable)]
/// Iterator that walks the immediate children of `self`. Hence
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
/// (but not `i32`, like `walk`).
- pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
+ pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> {
walk::walk_shallow(self)
}
if let Some(id) = self.map.as_local_node_id(id) {
self.map.name(id)
} else if id.index == CRATE_DEF_INDEX {
- token::intern(&self.sess.cstore.original_crate_name(id.krate))
+ self.sess.cstore.original_crate_name(id.krate)
} else {
let def_key = self.sess.cstore.def_key(id);
// The name of a StructCtor is that of its struct parent.
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
/// with the name of the crate containing the impl.
- pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, InternedString> {
+ pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
if impl_did.is_local() {
let node_id = self.map.as_local_node_id(impl_did).unwrap();
Ok(self.map.span(node_id))
use std::fmt;
use std::ops;
use syntax::abi;
-use syntax::ast::{self, Name};
-use syntax::parse::token::{keywords, InternedString};
+use syntax::ast::{self, Name, NodeId};
+use syntax::symbol::{keywords, InternedString};
+use util::nodemap::FxHashSet;
use serialize;
}
}
- pub fn is_uninhabited(&self, _cx: TyCtxt) -> bool {
- // FIXME(#24885): be smarter here, the AdtDefData::is_empty method could easily be made
- // more complete.
+ /// Checks whether a type is uninhabited.
+ /// If `block` is `Some(id)` it also checks that the uninhabited-ness is visible from `id`.
+ pub fn is_uninhabited(&self, block: Option<NodeId>, cx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
+ let mut visited = FxHashSet::default();
+ self.is_uninhabited_recurse(&mut visited, block, cx)
+ }
+
+ pub fn is_uninhabited_recurse(&self,
+ visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
+ block: Option<NodeId>,
+ cx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
match self.sty {
- TyAdt(def, _) => def.is_empty(),
+ TyAdt(def, substs) => {
+ def.is_uninhabited_recurse(visited, block, cx, substs)
+ },
- // FIXME(canndrew): There's no reason why these can't be uncommented, they're tested
- // and they don't break anything. But I'm keeping my changes small for now.
- //TyNever => true,
- //TyTuple(ref tys) => tys.iter().any(|ty| ty.is_uninhabited(cx)),
+ TyNever => true,
+ TyTuple(ref tys) => tys.iter().any(|ty| ty.is_uninhabited_recurse(visited, block, cx)),
+ TyArray(ty, len) => len > 0 && ty.is_uninhabited_recurse(visited, block, cx),
+ TyRef(_, ref tm) => tm.ty.is_uninhabited_recurse(visited, block, cx),
- // FIXME(canndrew): this line breaks core::fmt
- //TyRef(_, ref tm) => tm.ty.is_uninhabited(cx),
_ => false,
}
}
//! WARNING: this does not keep track of the region depth.
use ty::{self, Ty};
-use std::iter::Iterator;
-use std::vec::IntoIter;
+use rustc_data_structures::small_vec::SmallVec;
+use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
+
+// The TypeWalker's stack is hot enough that it's worth going to some effort to
+// avoid heap allocations.
+pub type TypeWalkerArray<'tcx> = [Ty<'tcx>; 8];
+pub type TypeWalkerStack<'tcx> = SmallVec<TypeWalkerArray<'tcx>>;
pub struct TypeWalker<'tcx> {
- stack: Vec<Ty<'tcx>>,
+ stack: TypeWalkerStack<'tcx>,
last_subtree: usize,
}
impl<'tcx> TypeWalker<'tcx> {
pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
- TypeWalker { stack: vec![ty], last_subtree: 1, }
+ TypeWalker { stack: SmallVec::one(ty), last_subtree: 1, }
}
/// Skips the subtree of types corresponding to the last type
}
}
-pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
- let mut stack = vec![];
+pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter<TypeWalkerArray<'tcx>> {
+ let mut stack = SmallVec::new();
push_subtypes(&mut stack, ty);
stack.into_iter()
}
// known to be significant to any code, but it seems like the
// natural order one would expect (basically, the order of the
// types as they are written).
-fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
+fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
match parent_ty.sty {
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => {
}
}
-fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
+fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
stack.push(sig.0.output);
stack.extend(sig.0.inputs.iter().cloned().rev());
}
use std::path::Path;
use std::time::{Duration, Instant};
-use hir;
-use hir::intravisit;
-use hir::intravisit::Visitor;
-
// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";
Indenter { _cannot_construct_outside_of_this_module: () }
}
-struct LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
- p: P,
- flag: bool,
-}
-
-impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&hir::Expr_) -> bool {
- fn visit_expr(&mut self, e: &hir::Expr) {
- self.flag |= (self.p)(&e.node);
- match e.node {
- // Skip inner loops, since a break in the inner loop isn't a
- // break inside the outer loop
- hir::ExprLoop(..) | hir::ExprWhile(..) => {}
- _ => intravisit::walk_expr(self, e)
- }
- }
-}
-
-// Takes a predicate p, returns true iff p is true for any subexpressions
-// of b -- skipping any inner loops (loop, while, loop_body)
-pub fn loop_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr_) -> bool {
- let mut v = LoopQueryVisitor {
- p: p,
- flag: false,
- };
- intravisit::walk_block(&mut v, b);
- return v.flag;
-}
-
-struct BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
- p: P,
- flag: bool,
-}
-
-impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&hir::Expr) -> bool {
- fn visit_expr(&mut self, e: &hir::Expr) {
- self.flag |= (self.p)(e);
- intravisit::walk_expr(self, e)
- }
-}
-
-// Takes a predicate p, returns true iff p is true for any subexpressions
-// of b -- skipping any inner loops (loop, while, loop_body)
-pub fn block_query<P>(b: &hir::Block, p: P) -> bool where P: FnMut(&hir::Expr) -> bool {
- let mut v = BlockQueryVisitor {
- p: p,
- flag: false,
- };
- intravisit::walk_block(&mut v, &b);
- return v.flag;
-}
-
pub trait MemoizationMap {
type Key: Clone;
type Value: Clone;
use std::usize;
use syntax::abi::Abi;
-use syntax::parse::token;
use syntax::ast::CRATE_NODE_ID;
+use syntax::symbol::Symbol;
use hir;
pub fn verbose() -> bool {
ty::BrAnon(_) |
ty::BrFresh(_) |
ty::BrEnv => {
- let name = token::intern("'r");
+ let name = Symbol::intern("'r");
let _ = write!(f, "{}", name);
ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID),
name,
{
let name = tcx.item_name(def_id);
if abi == Abi::RustIntrinsic || abi == Abi::PlatformIntrinsic {
- if name.as_str() == "rustc_peek" {
+ if name == "rustc_peek" {
return Some((args, source_info.span));
}
}
use borrowck::BorrowckCtxt;
use syntax::ast::{self, MetaItem};
-use syntax::ptr::P;
use syntax_pos::{Span, DUMMY_SP};
use rustc::hir;
use self::dataflow::{DefinitelyInitializedLvals};
use self::gather_moves::{MoveData, MovePathIndex, LookupResult};
-fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<P<MetaItem>> {
+fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
for attr in attrs {
if attr.check_name("rustc_mir") {
let items = attr.meta_item_list();
// Check for empty enum, because is_useful only works on inhabited types.
let pat_ty = self.tcx.tables().node_id_to_type(scrut.id);
if inlined_arms.is_empty() {
- if !pat_ty.is_uninhabited(self.tcx) {
+ if !pat_ty.is_uninhabited(Some(scrut.id), self.tcx) {
// We know the type is inhabited, so this must be wrong
let mut err = create_e0004(self.tcx.sess, span,
format!("non-exhaustive patterns: type {} \
_ => bug!()
};
let pats = args.iter()
- .map(|expr| const_expr_to_pat(tcx, &**expr, pat_id, span))
+ .map(|expr| const_expr_to_pat(tcx, &*expr, pat_id, span))
.collect::<Result<_, _>>()?;
PatKind::TupleStruct(path, pats, None)
}
use syntax::ast::*;
use syntax::ast::LitIntType::*;
match *lit {
- LitKind::Str(ref s, _) => Ok(Str((*s).clone())),
+ LitKind::Str(ref s, _) => Ok(Str(s.as_str())),
LitKind::ByteStr(ref data) => Ok(ByteStr(data.clone())),
LitKind::Byte(n) => Ok(Integral(U8(n))),
LitKind::Int(n, Signed(ity)) => {
infer(Infer(n), tcx, &ty::TyUint(ity)).map(Integral)
},
- LitKind::Float(ref n, fty) => {
- parse_float(n, Some(fty)).map(Float)
+ LitKind::Float(n, fty) => {
+ parse_float(&n.as_str(), Some(fty)).map(Float)
}
- LitKind::FloatUnsuffixed(ref n) => {
+ LitKind::FloatUnsuffixed(n) => {
let fty_hint = match ty_hint.map(|t| &t.sty) {
Some(&ty::TyFloat(fty)) => Some(fty),
_ => None
};
- parse_float(n, fty_hint).map(Float)
+ parse_float(&n.as_str(), fty_hint).map(Float)
}
LitKind::Bool(b) => Ok(Bool(b)),
LitKind::Char(c) => Ok(Char(c)),
self.set_len(len + 1);
}
}
+
+ pub fn truncate(&mut self, len: usize) {
+ unsafe {
+ while len < self.len() {
+ // Decrement len before the drop_in_place(), so a panic on Drop
+ // doesn't re-drop the just-failed value.
+ let newlen = self.len() - 1;
+ self.set_len(newlen);
+ ::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
+ }
+ }
+ }
}
impl<A: Array> Deref for SmallVec<A> {
use syntax::{ast, diagnostics, visit};
use syntax::attr;
use syntax::ext::base::ExtCtxt;
-use syntax::parse::{self, PResult, token};
+use syntax::parse::{self, PResult};
+use syntax::symbol::Symbol;
use syntax::util::node_count::NodeCounter;
use syntax;
use syntax_ext;
tcx.print_debug_stats();
}
- // Discard interned strings as they are no longer required.
- token::clear_ident_interner();
-
Ok((outputs, trans))
})??
};
*sess.features.borrow_mut() = features;
*sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
- *sess.crate_disambiguator.borrow_mut() =
- token::intern(&compute_crate_disambiguator(sess)).as_str();
+ *sess.crate_disambiguator.borrow_mut() = Symbol::intern(&compute_crate_disambiguator(sess));
time(time_passes, "recursion limit", || {
middle::recursion_limit::update_recursion_limit(sess, &krate);
time(time_passes,
"loop checking",
- || loops::check_crate(sess, &hir_map));
+ || loops::check_crate(sess, &resolutions.def_map, &hir_map));
time(time_passes,
"static item recursion checking",
outputs: &OutputFilenames) {
time(sess.time_passes(),
"linking",
- || link::link_binary(sess, trans, outputs, &trans.link.crate_name));
+ || link::link_binary(sess, trans, outputs, &trans.link.crate_name.as_str()));
}
fn escape_dep_filename(filename: &str) -> String {
Some(ref n) if *n == "rlib" => {
Some(config::CrateTypeRlib)
}
+ Some(ref n) if *n == "metadata" => {
+ Some(config::CrateTypeMetadata)
+ }
Some(ref n) if *n == "dylib" => {
Some(config::CrateTypeDylib)
}
}
}
}
-
-// For use by the `rusti` project (https://github.com/murarth/rusti).
-pub fn reset_thread_local_state() {
- // These may be left in an incoherent state after a previous compile.
- syntax::ext::hygiene::reset_hygiene_data();
- // `clear_ident_interner` can be used to free memory, but it does not restore the initial state.
- token::reset_ident_interner();
-}
use std::sync::{Arc, Mutex};
use std::thread;
-use syntax::{ast, json};
+use syntax::ast;
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
use syntax::feature_gate::{GatedCfg, UnstableFeatures};
use syntax::parse::{self, PResult};
-use syntax_pos::MultiSpan;
-use errors::emitter::Emitter;
+use syntax_pos::{DUMMY_SP, MultiSpan};
#[cfg(test)]
pub mod test;
}
}
-fn check_cfg(cfg: &ast::CrateConfig,
- output: ErrorOutputType) {
- let emitter: Box<Emitter> = match output {
- config::ErrorOutputType::HumanReadable(color_config) => {
- Box::new(errors::emitter::EmitterWriter::stderr(color_config, None))
- }
- config::ErrorOutputType::Json => Box::new(json::JsonEmitter::basic()),
- };
- let handler = errors::Handler::with_emitter(true, false, emitter);
-
- let mut saw_invalid_predicate = false;
- for item in cfg.iter() {
- if item.is_meta_item_list() {
- saw_invalid_predicate = true;
- handler.emit(&MultiSpan::new(),
- &format!("invalid predicate in --cfg command line argument: `{}`",
- item.name()),
- errors::Level::Fatal);
- }
- }
-
- if saw_invalid_predicate {
- panic!(errors::FatalError);
- }
-}
-
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
fn early_callback(&mut self,
matches: &getopts::Matches,
_: &config::Options,
- cfg: &ast::CrateConfig,
+ _: &ast::CrateConfig,
descriptions: &errors::registry::Registry,
output: ErrorOutputType)
-> Compilation {
return Compilation::Stop;
}
- check_cfg(cfg, output);
Compilation::Continue
}
let allow_unstable_cfg = UnstableFeatures::from_environment()
.is_nightly_build();
- for cfg in &sess.parse_sess.config {
- if !allow_unstable_cfg && GatedCfg::gate(cfg).is_some() {
+ let mut cfgs = Vec::new();
+ for &(name, ref value) in sess.parse_sess.config.iter() {
+ let gated_cfg = GatedCfg::gate(&ast::MetaItem {
+ name: name,
+ node: ast::MetaItemKind::Word,
+ span: DUMMY_SP,
+ });
+ if !allow_unstable_cfg && gated_cfg.is_some() {
continue;
}
- if cfg.is_word() {
- println!("{}", cfg.name());
- } else if let Some(s) = cfg.value_str() {
- println!("{}=\"{}\"", cfg.name(), s);
- } else if cfg.is_meta_item_list() {
- // Right now there are not and should not be any
- // MetaItemKind::List items in the configuration returned by
- // `build_configuration`.
- panic!("Found an unexpected list in cfg attribute '{}'!", cfg.name())
+ cfgs.push(if let &Some(ref value) = value {
+ format!("{}=\"{}\"", name, value)
} else {
- // There also shouldn't be literals.
- panic!("Found an unexpected literal in cfg attribute '{}'!", cfg.name())
- }
+ format!("{}", name)
+ });
+ }
+
+ cfgs.sort();
+ for cfg in cfgs {
+ println!("{}", cfg);
}
}
PrintRequest::TargetCPUs => {
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
fn post(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> {
match node {
- pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => {
+ pprust::NodeIdent(&ast::Ident { name, ctxt }) => {
pp::space(&mut s.s)?;
// FIXME #16420: this doesn't display the connections
// between syntax contexts
- s.synth_comment(format!("{}{:?}", nm, ctxt))
+ s.synth_comment(format!("{}{:?}", name.as_u32(), ctxt))
}
- pprust::NodeName(&ast::Name(nm)) => {
+ pprust::NodeName(&name) => {
pp::space(&mut s.s)?;
- s.synth_comment(nm.to_string())
+ s.synth_comment(name.as_u32().to_string())
}
_ => Ok(()),
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use syntax::{ast, attr};
+use syntax::ast;
use llvm::LLVMRustHasFeature;
use rustc::session::Session;
use rustc_trans::back::write::create_target_machine;
use syntax::feature_gate::UnstableFeatures;
-use syntax::parse::token::InternedString;
-use syntax::parse::token::intern_and_get_ident as intern;
+use syntax::symbol::Symbol;
use libc::c_char;
// WARNING: the features must be known to LLVM or the feature
_ => &[],
};
- let tf = InternedString::new("target_feature");
+ let tf = Symbol::intern("target_feature");
for feat in whitelist {
assert_eq!(feat.chars().last(), Some('\0'));
if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
- cfg.push(attr::mk_name_value_item_str(tf.clone(), intern(&feat[..feat.len() - 1])))
+ cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1]))));
}
}
}
if crt_static {
- cfg.push(attr::mk_name_value_item_str(tf.clone(), intern("crt-static")));
+ cfg.insert((tf, Some(Symbol::intern("crt-static"))));
}
}
use errors;
use errors::emitter::Emitter;
use errors::{Level, DiagnosticBuilder};
-use syntax::parse::token;
use syntax::feature_gate::UnstableFeatures;
+use syntax::symbol::Symbol;
use rustc::hir;
pub fn t_param(&self, index: u32) -> Ty<'tcx> {
let name = format!("T{}", index);
- self.infcx.tcx.mk_param(index, token::intern(&name[..]))
+ self.infcx.tcx.mk_param(index, Symbol::intern(&name[..]))
}
pub fn re_early_bound(&self, index: u32, name: &'static str) -> &'tcx ty::Region {
- let name = token::intern(name);
+ let name = Symbol::intern(name);
self.infcx.tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
index: index,
name: name,
use std::fs::File;
use std::io::Write;
use syntax::ast;
-use syntax::parse::token::InternedString;
use syntax_pos::Span;
use {ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
}
type Sources = Vec<(Span, DefId, DepNode<DefId>)>;
-type Targets = Vec<(Span, InternedString, ast::NodeId, DepNode<DefId>)>;
+type Targets = Vec<(Span, ast::Name, ast::NodeId, DepNode<DefId>)>;
struct IfThisChanged<'a, 'tcx:'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
impl<'a, 'tcx> IfThisChanged<'a, 'tcx> {
- fn argument(&self, attr: &ast::Attribute) -> Option<InternedString> {
+ fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
let mut value = None;
for list_item in attr.meta_item_list().unwrap_or_default() {
match list_item.word() {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
None => DepNode::Hir(def_id),
- Some(ref n) => {
- match DepNode::from_label_string(&n[..], def_id) {
+ Some(n) => {
+ match DepNode::from_label_string(&n.as_str(), def_id) {
Ok(n) => n,
Err(()) => {
self.tcx.sess.span_fatal(
} else if attr.check_name(ATTR_THEN_THIS_WOULD_NEED) {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
- Some(ref n) => {
- match DepNode::from_label_string(&n[..], def_id) {
+ Some(n) => {
+ match DepNode::from_label_string(&n.as_str(), def_id) {
Ok(n) => n,
Err(()) => {
self.tcx.sess.span_fatal(
}
};
self.then_this_would_need.push((attr.span,
- dep_node_interned.clone().unwrap(),
+ dep_node_interned.unwrap(),
node_id,
dep_node));
}
let crate_disambiguator = self.tcx.sess.local_crate_disambiguator();
"crate_disambiguator".hash(&mut crate_state);
- crate_disambiguator.len().hash(&mut crate_state);
- crate_disambiguator.hash(&mut crate_state);
+ crate_disambiguator.as_str().len().hash(&mut crate_state);
+ crate_disambiguator.as_str().hash(&mut crate_state);
// add each item (in some deterministic order) to the overall
// crate hash.
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
use syntax::parse::token;
+use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
use syntax::tokenstream;
use rustc::hir;
// FIXME (#14132): should we include (some function of)
// ident.ctxt as well?
- SawIdent(token::InternedString),
- SawStructDef(token::InternedString),
+ SawIdent(InternedString),
+ SawStructDef(InternedString),
SawLifetime,
SawLifetimeDef(usize),
#[derive(Hash)]
enum SawExprComponent<'a> {
- SawExprLoop(Option<token::InternedString>),
- SawExprField(token::InternedString),
+ SawExprLoop(Option<InternedString>),
+ SawExprField(InternedString),
SawExprTupField(usize),
- SawExprBreak(Option<token::InternedString>),
- SawExprAgain(Option<token::InternedString>),
+ SawExprBreak(Option<InternedString>),
+ SawExprAgain(Option<InternedString>),
SawExprBox,
SawExprArray,
SawExprBinary(hir::BinOp_),
SawExprUnary(hir::UnOp),
SawExprLit(ast::LitKind),
+ SawExprLitStr(InternedString, ast::StrStyle),
+ SawExprLitFloat(InternedString, Option<ast::FloatTy>),
SawExprCast,
SawExprType,
SawExprIf,
ExprUnary(op, _) => {
(SawExprUnary(op), unop_can_panic_at_runtime(op))
}
- ExprLit(ref lit) => (SawExprLit(lit.node.clone()), false),
+ ExprLit(ref lit) => (saw_lit(lit), false),
ExprCast(..) => (SawExprCast, false),
ExprType(..) => (SawExprType, false),
ExprIf(..) => (SawExprIf, false),
ExprWhile(..) => (SawExprWhile, false),
- ExprLoop(_, id) => (SawExprLoop(id.map(|id| id.node.as_str())), false),
+ ExprLoop(_, id, _) => (SawExprLoop(id.map(|id| id.node.as_str())), false),
ExprMatch(..) => (SawExprMatch, false),
ExprClosure(cc, _, _, _) => (SawExprClosure(cc), false),
ExprBlock(..) => (SawExprBlock, false),
ExprIndex(..) => (SawExprIndex, true),
ExprPath(ref qself, _) => (SawExprPath(qself.as_ref().map(|q| q.position)), false),
ExprAddrOf(m, _) => (SawExprAddrOf(m), false),
- ExprBreak(id) => (SawExprBreak(id.map(|id| id.node.as_str())), false),
+ ExprBreak(id, _) => (SawExprBreak(id.map(|id| id.node.as_str())), false),
ExprAgain(id) => (SawExprAgain(id.map(|id| id.node.as_str())), false),
ExprRet(..) => (SawExprRet, false),
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false),
}
}
+fn saw_lit(lit: &ast::Lit) -> SawExprComponent<'static> {
+ match lit.node {
+ ast::LitKind::Str(s, style) => SawExprLitStr(s.as_str(), style),
+ ast::LitKind::Float(s, ty) => SawExprLitFloat(s.as_str(), Some(ty)),
+ ast::LitKind::FloatUnsuffixed(s) => SawExprLitFloat(s.as_str(), None),
+ ref node @ _ => SawExprLit(node.clone()),
+ }
+}
+
#[derive(Hash)]
enum SawItemComponent {
SawItemExternCrate,
// ignoring span information, it doesn't matter here
self.hash_discriminant(&meta_item.node);
+ meta_item.name.as_str().len().hash(self.st);
+ meta_item.name.as_str().hash(self.st);
+
match meta_item.node {
- ast::MetaItemKind::Word(ref s) => {
- s.len().hash(self.st);
- s.hash(self.st);
- }
- ast::MetaItemKind::NameValue(ref s, ref lit) => {
- s.len().hash(self.st);
- s.hash(self.st);
- lit.node.hash(self.st);
- }
- ast::MetaItemKind::List(ref s, ref items) => {
- s.len().hash(self.st);
- s.hash(self.st);
+ ast::MetaItemKind::Word => {}
+ ast::MetaItemKind::NameValue(ref lit) => saw_lit(lit).hash(self.st),
+ ast::MetaItemKind::List(ref items) => {
// Sort subitems so the hash does not depend on their order
let indices = self.indices_sorted_by(&items, |p| {
- (p.name(), fnv::hash(&p.literal().map(|i| &i.node)))
+ (p.name().map(Symbol::as_str), fnv::hash(&p.literal().map(saw_lit)))
});
items.len().hash(self.st);
for (index, &item_index) in indices.iter().enumerate() {
self.hash_meta_item(meta_item);
}
ast::NestedMetaItemKind::Literal(ref lit) => {
- lit.node.hash(self.st);
+ saw_lit(lit).hash(self.st);
}
}
}
let indices = self.indices_sorted_by(attributes, |attr| attr.name());
for i in indices {
- let attr = &attributes[i].node;
+ let attr = &attributes[i];
if !attr.is_sugared_doc &&
- !IGNORED_ATTRIBUTES.contains(&&*attr.value.name()) {
+ !IGNORED_ATTRIBUTES.contains(&&*attr.value.name().as_str()) {
SawAttribute(attr.style).hash(self.st);
- self.hash_meta_item(&*attr.value);
+ self.hash_meta_item(&attr.value);
}
}
}
assert_eq!(old_info.krate, krate);
let old_name: &str = &old_info.name;
let old_disambiguator: &str = &old_info.disambiguator;
- let new_name: &str = &tcx.crate_name(krate);
- let new_disambiguator: &str = &tcx.crate_disambiguator(krate);
+ let new_name: &str = &tcx.crate_name(krate).as_str();
+ let new_disambiguator: &str = &tcx.crate_disambiguator(krate).as_str();
old_name == new_name && old_disambiguator == new_disambiguator
}
}
let new_krates: HashMap<_, _> =
once(LOCAL_CRATE)
.chain(tcx.sess.cstore.crates())
- .map(|krate| (make_key(&tcx.crate_name(krate),
- &tcx.crate_disambiguator(krate)), krate))
+ .map(|krate| (make_key(&tcx.crate_name(krate).as_str(),
+ &tcx.crate_disambiguator(krate).as_str()), krate))
.collect();
let ids = self.paths.iter()
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use syntax::ast::{self, Attribute, NestedMetaItem};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use syntax::parse::token::InternedString;
use syntax_pos::Span;
use rustc::ty::TyCtxt;
use ich::Fingerprint;
}
impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
-
fn dep_node(&self, attr: &Attribute, def_id: DefId) -> DepNode<DefId> {
for item in attr.meta_item_list().unwrap_or(&[]) {
if item.check_name(LABEL) {
let value = expect_associated_value(self.tcx, item);
- match DepNode::from_label_string(&value[..], def_id) {
+ match DepNode::from_label_string(&value.as_str(), def_id) {
Ok(def_id) => return def_id,
Err(()) => {
self.tcx.sess.span_fatal(
if item.check_name(CFG) {
let value = expect_associated_value(tcx, item);
debug!("check_config: searching for cfg {:?}", value);
- for cfg in &config[..] {
- if cfg.check_name(&value[..]) {
- debug!("check_config: matched {:?}", cfg);
- return true;
- }
- }
- return false;
+ return config.contains(&(value, None));
}
}
&format!("no cfg attribute"));
}
-fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> InternedString {
+fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name {
if let Some(value) = item.value_str() {
value
} else {
}
fn crate_path_tcx(tcx: TyCtxt, cnum: CrateNum) -> PathBuf {
- crate_path(tcx.sess, &tcx.crate_name(cnum), &tcx.crate_disambiguator(cnum))
+ crate_path(tcx.sess, &tcx.crate_name(cnum).as_str(), &tcx.crate_disambiguator(cnum).as_str())
}
/// Finds the session directory containing the correct metadata hashes file for
.concat()
}
- let s = name.as_str();
-
if !is_camel_case(name) {
- let c = to_camel_case(&s);
+ let c = to_camel_case(&name.as_str());
let m = if c.is_empty() {
- format!("{} `{}` should have a camel case name such as `CamelCase`",
- sort,
- s)
+ format!("{} `{}` should have a camel case name such as `CamelCase`", sort, name)
} else {
- format!("{} `{}` should have a camel case name such as `{}`",
- sort,
- s,
- c)
+ format!("{} `{}` should have a camel case name such as `{}`", sort, name, c)
};
cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
}
.and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(ref name) = cx.tcx.sess.opts.crate_name {
self.check_snake_case(cx, "crate", name, None);
- } else if let Some((attr, ref name)) = attr_crate_name {
- self.check_snake_case(cx, "crate", name, Some(attr.span));
+ } else if let Some((attr, name)) = attr_crate_name {
+ self.check_snake_case(cx, "crate", &name.as_str(), Some(attr.span));
}
}
impl NonUpperCaseGlobals {
fn check_upper_case(cx: &LateContext, sort: &str, name: ast::Name, span: Span) {
- let s = name.as_str();
-
- if s.chars().any(|c| c.is_lowercase()) {
- let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
- if uc != &s[..] {
+ if name.as_str().chars().any(|c| c.is_lowercase()) {
+ let uc = NonSnakeCase::to_snake_case(&name.as_str()).to_uppercase();
+ if name != &*uc {
cx.span_lint(NON_UPPER_CASE_GLOBALS,
span,
&format!("{} `{}` should have an upper case name such as `{}`",
sort,
- s,
+ name,
uc));
} else {
cx.span_lint(NON_UPPER_CASE_GLOBALS,
span,
- &format!("{} `{}` should have an upper case name", sort, s));
+ &format!("{} `{}` should have an upper case name", sort, name));
}
}
}
use syntax::ast;
use syntax::attr;
use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes};
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc::hir::{self, PatKind};
stability: &Option<&attr::Stability>,
deprecation: &Option<stability::DeprecationEntry>) {
// Deprecated attributes apply in-crate and cross-crate.
- if let Some(&attr::Stability{rustc_depr: Some(attr::RustcDeprecation{ref reason, ..}), ..})
+ if let Some(&attr::Stability{rustc_depr: Some(attr::RustcDeprecation{reason, ..}), ..})
= *stability {
- output(cx, DEPRECATED, span, Some(&reason))
+ output(cx, DEPRECATED, span, Some(reason))
} else if let Some(ref depr_entry) = *deprecation {
if let Some(parent_depr) = cx.tcx.lookup_deprecation_entry(self.parent_def(cx)) {
if parent_depr.same_origin(depr_entry) {
}
}
- output(cx, DEPRECATED, span, depr_entry.attr.note.as_ref().map(|x| &**x))
+ output(cx, DEPRECATED, span, depr_entry.attr.note)
}
- fn output(cx: &LateContext, lint: &'static Lint, span: Span, note: Option<&str>) {
+ fn output(cx: &LateContext, lint: &'static Lint, span: Span, note: Option<Symbol>) {
let msg = if let Some(note) = note {
format!("use of deprecated item: {}", note)
} else {
impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
- let name = &*attr.name();
+ let name = attr.name();
for &&(n, _, ref g) in &self.depr_attrs {
- if n == name {
+ if name == n {
if let &AttributeGate::Gated(Stability::Deprecated(link),
ref name,
ref reason,
ty::TyFnDef(.., ref bfty) if bfty.abi == RustIntrinsic => (),
_ => return false,
}
- cx.tcx.item_name(def_id).as_str() == "transmute"
+ cx.tcx.item_name(def_id) == "transmute"
}
}
}
id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL),
reference: "issue #37166 <https://github.com/rust-lang/rust/issues/37166>",
},
+ FutureIncompatibleInfo {
+ id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP),
+ reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
+ },
]);
// Register renamed and removed lints
ty::TyFloat(t) => {
let (min, max) = float_ty_range(t);
let lit_val: f64 = match lit.node {
- ast::LitKind::Float(ref v, _) |
- ast::LitKind::FloatUnsuffixed(ref v) => {
- match v.parse() {
+ ast::LitKind::Float(v, _) |
+ ast::LitKind::FloatUnsuffixed(v) => {
+ match v.as_str().parse() {
Ok(f) => f,
Err(_) => return,
}
use syntax::ast;
use syntax::attr;
use syntax::feature_gate::{BUILTIN_ATTRIBUTES, AttributeType};
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use syntax::ptr::P;
use syntax_pos::Span;
let name = path1.node;
if let hir::BindByValue(hir::MutMutable) = mode {
if !name.as_str().starts_with("_") {
- match mutables.entry(name.0 as usize) {
+ match mutables.entry(name) {
Vacant(entry) => {
entry.insert(vec![id]);
}
// check for #[must_use="..."]
if let Some(s) = attr.value_str() {
msg.push_str(": ");
- msg.push_str(&s);
+ msg.push_str(&s.as_str());
}
cx.span_lint(UNUSED_MUST_USE, sp, &msg);
return true;
// Has a plugin registered this attribute as one which must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
- .find(|&&(ref x, t)| &*attr.name() == x && AttributeType::CrateLevel == t)
+ .find(|&&(ref x, t)| attr.name() == &**x && AttributeType::CrateLevel == t)
.is_some();
if known_crate || plugin_crate {
- let msg = match attr.node.style {
+ let msg = match attr.style {
ast::AttrStyle::Outer => {
"crate-level attribute should be an inner attribute: add an exclamation \
mark: #![foo]"
#[allow(missing_copy_implementations)]
pub enum OperandBundleDef_opaque {}
pub type OperandBundleDefRef = *mut OperandBundleDef_opaque;
-#[allow(missing_copy_implementations)]
-pub enum Attribute_opaque {}
-pub type AttributeRef = *mut Attribute_opaque;
pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void);
pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);
Name: *const c_char)
-> ValueRef;
- pub fn LLVMRustCreateAttribute(C: ContextRef, kind: Attribute, val: u64) -> AttributeRef;
-
// Operations on functions
pub fn LLVMAddFunction(M: ModuleRef, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef;
pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
pub fn LLVMRustAddDereferenceableAttr(Fn: ValueRef, index: c_uint, bytes: u64);
- pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: AttributeRef);
+ pub fn LLVMRustAddFunctionAttribute(Fn: ValueRef, index: c_uint, attr: Attribute);
pub fn LLVMRustAddFunctionAttrStringValue(Fn: ValueRef,
index: c_uint,
Name: *const c_char,
Value: *const c_char);
- pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: AttributeRef);
+ pub fn LLVMRustRemoveFunctionAttributes(Fn: ValueRef, index: c_uint, attr: Attribute);
// Operations on parameters
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
- pub fn LLVMAddAttribute(Arg: ValueRef, attr: AttributeRef);
- pub fn LLVMRemoveAttribute(Arg: ValueRef, attr: AttributeRef);
pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
// Operations on basic blocks
pub fn LLVMAddInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
pub fn LLVMRemoveInstrAttribute(Instr: ValueRef, index: c_uint, IA: c_uint);
pub fn LLVMSetInstrParamAlignment(Instr: ValueRef, index: c_uint, align: c_uint);
- pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: AttributeRef);
+ pub fn LLVMRustAddCallSiteAttribute(Instr: ValueRef, index: c_uint, attr: Attribute);
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: ValueRef, index: c_uint, bytes: u64);
// Operations on call instructions (only)
}
impl Attribute {
- fn as_object(&self, value: ValueRef) -> AttributeRef {
- unsafe { LLVMRustCreateAttribute(LLVMRustGetValueContext(value), *self, 0) }
- }
-
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
- unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.as_object(llfn)) }
+ unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
}
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
- unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.as_object(callsite)) }
+ unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
}
pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
- unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.as_object(llfn)) }
+ unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
}
pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
use syntax::attr;
use syntax::ext::base::SyntaxExtension;
use syntax::feature_gate::{self, GateIssue};
-use syntax::parse::token::{InternedString, intern};
+use syntax::symbol::Symbol;
use syntax_pos::{Span, DUMMY_SP};
use log;
pub struct Library {
pub dylib: Option<(PathBuf, PathKind)>,
pub rlib: Option<(PathBuf, PathKind)>,
+ pub rmeta: Option<(PathBuf, PathKind)>,
pub metadata: MetadataBlob,
}
cstore: &'a CStore,
next_crate_num: CrateNum,
foreign_item_map: FxHashMap<String, Vec<ast::NodeId>>,
- local_crate_name: String,
+ local_crate_name: Symbol,
}
fn dump_crates(cstore: &CStore) {
info!(" cnum: {}", data.cnum);
info!(" hash: {}", data.hash());
info!(" reqd: {:?}", data.dep_kind.get());
- let CrateSource { dylib, rlib } = data.source.clone();
+ let CrateSource { dylib, rlib, rmeta } = data.source.clone();
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
- })
+ rmeta.map(|rl| info!(" rmeta: {}", rl.0.display()));
+ });
}
#[derive(Debug)]
struct ExternCrateInfo {
- ident: String,
- name: String,
+ ident: Symbol,
+ name: Symbol,
id: ast::NodeId,
dep_kind: DepKind,
}
cstore: &CStore,
span: Option<Span>,
lib: NativeLibrary) {
- if lib.name.is_empty() {
+ if lib.name.as_str().is_empty() {
match span {
Some(span) => {
struct_span_err!(sess, span, E0454,
cstore: cstore,
next_crate_num: cstore.next_crate_num(),
foreign_item_map: FxHashMap(),
- local_crate_name: local_crate_name.to_owned(),
+ local_crate_name: Symbol::intern(local_crate_name),
}
}
Some(name) => {
validate_crate_name(Some(self.sess), &name.as_str(),
Some(i.span));
- name.to_string()
+ name
}
- None => i.ident.to_string(),
+ None => i.ident.name,
};
Some(ExternCrateInfo {
- ident: i.ident.to_string(),
+ ident: i.ident.name,
name: name,
id: i.id,
dep_kind: if attr::contains_name(&i.attrs, "no_link") {
}
}
- fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind)
+ fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
-> Option<CrateNum> {
let mut ret = None;
self.cstore.iter_crate_data(|cnum, data| {
// `source` stores paths which are normalized which may be different
// from the strings on the command line.
let source = self.cstore.used_crate_source(cnum);
- if let Some(locs) = self.sess.opts.externs.get(name) {
+ if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
let found = locs.iter().any(|l| {
let l = fs::canonicalize(l).ok();
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
root: &CrateRoot) {
// Check for (potential) conflicts with the local crate
if self.local_crate_name == root.name &&
- self.sess.local_crate_disambiguator() == &root.disambiguator[..] {
+ self.sess.local_crate_disambiguator() == root.disambiguator {
span_fatal!(self.sess, span, E0519,
"the current crate is indistinguishable from one of its \
dependencies: it has the same crate-name `{}` and was \
fn register_crate(&mut self,
root: &Option<CratePaths>,
- ident: &str,
- name: &str,
+ ident: Symbol,
+ name: Symbol,
span: Span,
lib: Library,
dep_kind: DepKind)
ident: ident.to_string(),
dylib: lib.dylib.clone().map(|p| p.0),
rlib: lib.rlib.clone().map(|p| p.0),
+ rmeta: lib.rmeta.clone().map(|p| p.0),
})
} else {
None
// Maintain a reference to the top most crate.
let root = if root.is_some() { root } else { &crate_paths };
- let Library { dylib, rlib, metadata } = lib;
+ let Library { dylib, rlib, rmeta, metadata } = lib;
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
let cmeta = Rc::new(cstore::CrateMetadata {
- name: name.to_string(),
+ name: name,
extern_crate: Cell::new(None),
key_map: metadata.load_key_map(crate_root.index),
proc_macros: crate_root.macro_derive_registrar.map(|_| {
source: cstore::CrateSource {
dylib: dylib,
rlib: rlib,
+ rmeta: rmeta,
},
});
fn resolve_crate(&mut self,
root: &Option<CratePaths>,
- ident: &str,
- name: &str,
+ ident: Symbol,
+ name: Symbol,
hash: Option<&Svh>,
span: Span,
path_kind: PathKind,
match result {
LoadResult::Previous(cnum) => {
let data = self.cstore.get_crate_data(cnum);
+ if data.root.macro_derive_registrar.is_some() {
+ dep_kind = DepKind::MacrosOnly;
+ }
data.dep_kind.set(cmp::max(data.dep_kind.get(), dep_kind));
(cnum, data)
}
let deps = crate_root.crate_deps.decode(metadata);
let map: FxHashMap<_, _> = deps.enumerate().map(|(crate_num, dep)| {
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
- let dep_name = &dep.name.as_str();
let dep_kind = match dep_kind {
DepKind::MacrosOnly => DepKind::MacrosOnly,
_ => dep.kind,
};
let (local_cnum, ..) = self.resolve_crate(
- root, dep_name, dep_name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
+ root, dep.name, dep.name, Some(&dep.hash), span, PathKind::Dependency, dep_kind,
);
(CrateNum::new(crate_num + 1), local_cnum)
}).collect();
let target_triple = &self.sess.opts.target_triple[..];
let is_cross = target_triple != config::host_triple();
let mut target_only = false;
- let ident = info.ident.clone();
- let name = info.name.clone();
let mut locate_ctxt = locator::Context {
sess: self.sess,
span: span,
- ident: &ident[..],
- crate_name: &name[..],
+ ident: info.ident,
+ crate_name: info.name,
hash: None,
filesearch: self.sess.host_filesearch(PathKind::Crate),
target: &self.sess.host,
trait_name: &str,
expand: fn(TokenStream) -> TokenStream,
attributes: &[&'static str]) {
- let attrs = attributes.iter().map(|s| InternedString::new(s)).collect();
+ let attrs = attributes.iter().cloned().map(Symbol::intern).collect();
let derive = SyntaxExtension::CustomDerive(
Box::new(CustomDerive::new(expand, attrs))
);
- self.0.push((intern(trait_name), Rc::new(derive)));
+ self.0.push((Symbol::intern(trait_name), Rc::new(derive)));
}
}
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
-> Option<(PathBuf, Svh, DefIndex)> {
let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
- name: name.to_string(),
- ident: name.to_string(),
+ name: Symbol::intern(name),
+ ident: Symbol::intern(name),
id: ast::DUMMY_NODE_ID,
dep_kind: DepKind::MacrosOnly,
});
let libs = self.cstore.get_used_libraries();
for (foreign_lib, list) in self.foreign_item_map.iter() {
let is_static = libs.borrow().iter().any(|lib| {
- *foreign_lib == lib.name && lib.kind == cstore::NativeStatic
+ lib.name == &**foreign_lib && lib.kind == cstore::NativeStatic
});
if is_static {
for id in list {
// in terms of everyone has a compatible panic runtime format, that's
// performed later as part of the `dependency_format` module.
let name = match desired_strategy {
- PanicStrategy::Unwind => "panic_unwind",
- PanicStrategy::Abort => "panic_abort",
+ PanicStrategy::Unwind => Symbol::intern("panic_unwind"),
+ PanicStrategy::Abort => Symbol::intern("panic_abort"),
};
info!("panic runtime not found -- loading {}", name);
config::CrateTypeProcMacro |
config::CrateTypeCdylib |
config::CrateTypeStaticlib => need_lib_alloc = true,
- config::CrateTypeRlib => {}
+ config::CrateTypeRlib |
+ config::CrateTypeMetadata => {}
}
}
if !need_lib_alloc && !need_exe_alloc { return }
// * Staticlibs and Rust dylibs use system malloc
// * Rust dylibs used as dependencies to rust use jemalloc
let name = if need_lib_alloc && !self.sess.opts.cg.prefer_dynamic {
- &self.sess.target.target.options.lib_allocation_crate
+ Symbol::intern(&self.sess.target.target.options.lib_allocation_crate)
} else {
- &self.sess.target.target.options.exe_allocation_crate
+ Symbol::intern(&self.sess.target.target.options.exe_allocation_crate)
};
let dep_kind = DepKind::Implicit;
let (cnum, data) =
impl<'a> CrateLoader<'a> {
pub fn preprocess(&mut self, krate: &ast::Crate) {
for attr in krate.attrs.iter().filter(|m| m.name() == "link_args") {
- if let Some(ref linkarg) = attr.value_str() {
- self.cstore.add_used_link_args(&linkarg);
+ if let Some(linkarg) = attr.value_str() {
+ self.cstore.add_used_link_args(&linkarg.as_str());
}
}
}
// First, add all of the custom #[link_args] attributes
for m in i.attrs.iter().filter(|a| a.check_name("link_args")) {
if let Some(linkarg) = m.value_str() {
- self.cstore.add_used_link_args(&linkarg);
+ self.cstore.add_used_link_args(&linkarg.as_str());
}
}
};
let kind = items.iter().find(|k| {
k.check_name("kind")
- }).and_then(|a| a.value_str());
+ }).and_then(|a| a.value_str()).map(Symbol::as_str);
let kind = match kind.as_ref().map(|s| &s[..]) {
Some("static") => cstore::NativeStatic,
Some("dylib") => cstore::NativeUnknown,
struct_span_err!(self.sess, m.span, E0459,
"#[link(...)] specified without `name = \"foo\"`")
.span_label(m.span, &format!("missing `name` argument")).emit();
- InternedString::new("foo")
+ Symbol::intern("foo")
}
};
let cfg = items.iter().find(|k| {
list[0].meta_item().unwrap().clone()
});
let lib = NativeLibrary {
- name: n.to_string(),
+ name: n,
kind: kind,
cfg: cfg,
};
for &(ref name, kind) in &self.sess.opts.libs {
let lib = NativeLibrary {
- name: name.clone(),
+ name: Symbol::intern(name),
kind: kind,
cfg: None,
};
let info = self.extract_crate_info(item).unwrap();
let (cnum, ..) = self.resolve_crate(
- &None, &info.ident, &info.name, None, item.span, PathKind::Crate, info.dep_kind,
+ &None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind,
);
let def_id = definitions.opt_local_def_id(item.id).unwrap();
use std::cell::{RefCell, Cell};
use std::rc::Rc;
-use std::path::PathBuf;
use flate::Bytes;
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
+use syntax::symbol::Symbol;
use syntax_pos;
pub use rustc::middle::cstore::{NativeLibrary, LinkagePreference};
pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown};
-pub use rustc::middle::cstore::{CrateSource, LinkMeta};
+pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource};
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
pub enum MetadataBlob {
Inflated(Bytes),
Archive(locator::ArchiveMetadata),
+ Raw(Vec<u8>),
}
/// Holds information about a syntax_pos::FileMap imported from another crate.
}
pub struct CrateMetadata {
- pub name: String,
+ pub name: Symbol,
/// Information about the extern crate that caused this crate to
/// be loaded. If this is `None`, then the crate was injected
// positions.
pub fn do_get_used_crates(&self,
prefer: LinkagePreference)
- -> Vec<(CrateNum, Option<PathBuf>)> {
+ -> Vec<(CrateNum, LibSource)> {
let mut ordering = Vec::new();
for (&num, _) in self.metas.borrow().iter() {
self.push_dependencies_in_postorder(&mut ordering, num);
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
};
+ let path = match path {
+ Some(p) => LibSource::Some(p),
+ None => {
+ if data.source.rmeta.is_some() {
+ LibSource::MetadataOnly
+ } else {
+ LibSource::None
+ }
+ }
+ };
Some((cnum, path))
})
.collect::<Vec<_>>();
}
pub fn add_used_library(&self, lib: NativeLibrary) {
- assert!(!lib.name.is_empty());
+ assert!(!lib.name.as_str().is_empty());
self.used_libraries.borrow_mut().push(lib);
}
}
impl CrateMetadata {
- pub fn name(&self) -> &str {
- &self.root.name
+ pub fn name(&self) -> Symbol {
+ self.root.name
}
pub fn hash(&self) -> Svh {
self.root.hash
}
- pub fn disambiguator(&self) -> &str {
- &self.root.disambiguator
+ pub fn disambiguator(&self) -> Symbol {
+ self.root.disambiguator
}
pub fn is_staged_api(&self) -> bool {
use locator;
use schema;
-use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, DepKind, ExternCrate};
+use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, LibSource, DepKind, ExternCrate};
use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro};
use rustc::hir::def::{self, Def};
use rustc::middle::lang_items;
use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc_back::PanicStrategy;
-use std::path::PathBuf;
use syntax::ast;
use syntax::attr;
-use syntax::parse::{token, new_parser_from_source_str};
+use syntax::parse::new_parser_from_source_str;
+use syntax::symbol::Symbol;
use syntax_pos::mk_sp;
use rustc::hir::svh::Svh;
use rustc_back::target::Target;
self.get_crate_data(cnum).panic_strategy()
}
- fn crate_name(&self, cnum: CrateNum) -> token::InternedString
+ fn crate_name(&self, cnum: CrateNum) -> Symbol
{
- token::intern_and_get_ident(&self.get_crate_data(cnum).name[..])
+ self.get_crate_data(cnum).name
}
- fn original_crate_name(&self, cnum: CrateNum) -> token::InternedString
+ fn original_crate_name(&self, cnum: CrateNum) -> Symbol
{
- token::intern_and_get_ident(&self.get_crate_data(cnum).name())
+ self.get_crate_data(cnum).name()
}
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>
self.get_crate_hash(cnum)
}
- fn crate_disambiguator(&self, cnum: CrateNum) -> token::InternedString
+ fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol
{
- token::intern_and_get_ident(&self.get_crate_data(cnum).disambiguator())
+ self.get_crate_data(cnum).disambiguator()
}
fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
locator::meta_section_name(target)
}
- fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
+ fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{
self.do_get_used_crates(prefer)
}
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
fn raw_bytes(self) -> &'a [u8] {
match *self {
- MetadataBlob::Inflated(ref vec) => &vec[..],
+ MetadataBlob::Inflated(ref vec) => vec,
MetadataBlob::Archive(ref ar) => ar.as_slice(),
+ MetadataBlob::Raw(ref vec) => vec,
}
}
}
.decode(self)
.map(|mut attr| {
// Need new unique IDs: old thread-local IDs won't map to new threads.
- attr.node.id = attr::mk_attr_id();
+ attr.id = attr::mk_attr_id();
attr
})
.collect()
use std::u32;
use syntax::ast::{self, CRATE_NODE_ID};
use syntax::attr;
-use syntax;
+use syntax::symbol::Symbol;
use syntax_pos;
use rustc::hir::{self, PatKind};
if let PatKind::Binding(_, ref path1, _) = arg.pat.node {
path1.node
} else {
- syntax::parse::token::intern("")
+ Symbol::intern("")
}
}))
}
let deps = get_ordered_deps(self.cstore);
self.lazy_seq(deps.iter().map(|&(_, ref dep)| {
CrateDep {
- name: syntax::parse::token::intern(dep.name()),
+ name: dep.name(),
hash: dep.hash(),
kind: dep.dep_kind.get(),
}
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
let root = self.lazy(&CrateRoot {
rustc_version: rustc_version(),
- name: link_meta.crate_name.clone(),
+ name: link_meta.crate_name,
triple: tcx.sess.opts.target_triple.clone(),
hash: link_meta.crate_hash,
- disambiguator: tcx.sess.local_crate_disambiguator().to_string(),
+ disambiguator: tcx.sess.local_crate_disambiguator(),
panic_strategy: tcx.sess.panic_strategy(),
plugin_registrar_fn: tcx.sess
.plugin_registrar_fn
//! is a platform-defined dynamic library. Each library has a metadata somewhere
//! inside of it.
//!
+//! A third kind of dependency is an rmeta file. These are metadata files and do
+//! not contain any code, etc. To a first approximation, these are treated in the
+//! same way as rlibs. Where there is both an rlib and an rmeta file, the rlib
+//! gets priority (even if the rmeta file is newer). An rmeta file is only
+//! useful for checking a downstream crate, attempting to link one will cause an
+//! error.
+//!
//! When translating a crate name to a crate on the filesystem, we all of a
//! sudden need to take into account both rlibs and dylibs! Linkage later on may
//! use either one of these files, as each has their pros/cons. The job of crate
use rustc_llvm::{False, ObjectFile, mk_section_iter};
use rustc_llvm::archive_ro::ArchiveRO;
use errors::DiagnosticBuilder;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_back::target::Target;
use std::cmp;
use std::fmt;
-use std::fs;
-use std::io;
+use std::fs::{self, File};
+use std::io::{self, Read};
use std::path::{Path, PathBuf};
use std::ptr;
use std::slice;
pub struct Context<'a> {
pub sess: &'a Session,
pub span: Span,
- pub ident: &'a str,
- pub crate_name: &'a str,
+ pub ident: Symbol,
+ pub crate_name: Symbol,
pub hash: Option<&'a Svh>,
// points to either self.sess.target.target or self.sess.host, must match triple
pub target: &'a Target,
pub ident: String,
pub dylib: Option<PathBuf>,
pub rlib: Option<PathBuf>,
+ pub rmeta: Option<PathBuf>,
}
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
#[derive(Copy, Clone, PartialEq)]
enum CrateFlavor {
Rlib,
+ Rmeta,
Dylib,
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
CrateFlavor::Rlib => "rlib",
+ CrateFlavor::Rmeta => "rmeta",
CrateFlavor::Dylib => "dylib",
})
}
impl CratePaths {
fn paths(&self) -> Vec<PathBuf> {
- match (&self.dylib, &self.rlib) {
- (&None, &None) => vec![],
- (&Some(ref p), &None) |
- (&None, &Some(ref p)) => vec![p.clone()],
- (&Some(ref p1), &Some(ref p2)) => vec![p1.clone(), p2.clone()],
- }
+ self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).cloned().collect()
}
}
// must be loaded via -L plus some filtering.
if self.hash.is_none() {
self.should_match_name = false;
- if let Some(s) = self.sess.opts.externs.get(self.crate_name) {
+ if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
return self.find_commandline_library(s.iter());
}
self.should_match_name = true;
None => return FileDoesntMatch,
Some(file) => file,
};
- let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
- (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], true)
- } else if file.starts_with(&dylib_prefix) &&
- file.ends_with(&dypair.1) {
- (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], false)
- } else {
- if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
- staticlibs.push(CrateMismatch {
- path: path.to_path_buf(),
- got: "static".to_string(),
- });
- }
- return FileDoesntMatch;
- };
+ let (hash, found_kind) =
+ if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
+ (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib)
+ } else if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rmeta") {
+ (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta)
+ } else if file.starts_with(&dylib_prefix) &&
+ file.ends_with(&dypair.1) {
+ (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib)
+ } else {
+ if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
+ staticlibs.push(CrateMismatch {
+ path: path.to_path_buf(),
+ got: "static".to_string(),
+ });
+ }
+ return FileDoesntMatch;
+ };
info!("lib candidate: {}", path.display());
let hash_str = hash.to_string();
let slot = candidates.entry(hash_str)
- .or_insert_with(|| (FxHashMap(), FxHashMap()));
- let (ref mut rlibs, ref mut dylibs) = *slot;
+ .or_insert_with(|| (FxHashMap(), FxHashMap(), FxHashMap()));
+ let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot;
fs::canonicalize(path)
.map(|p| {
- if rlib {
- rlibs.insert(p, kind);
- } else {
- dylibs.insert(p, kind);
+ match found_kind {
+ CrateFlavor::Rlib => { rlibs.insert(p, kind); }
+ CrateFlavor::Rmeta => { rmetas.insert(p, kind); }
+ CrateFlavor::Dylib => { dylibs.insert(p, kind); }
}
FileMatches
})
// libraries corresponds to the crate id and hash criteria that this
// search is being performed for.
let mut libraries = FxHashMap();
- for (_hash, (rlibs, dylibs)) in candidates {
+ for (_hash, (rlibs, rmetas, dylibs)) in candidates {
let mut slot = None;
let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
+ let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
if let Some((h, m)) = slot {
libraries.insert(h,
Library {
dylib: dylib,
rlib: rlib,
+ rmeta: rmeta,
metadata: m,
});
}
if let Some((ref p, _)) = lib.rlib {
err.note(&format!("path: {}", p.display()));
}
- note_crate_name(&mut err, &lib.metadata.get_root().name);
+ note_crate_name(&mut err, &lib.metadata.get_root().name.as_str());
}
err.emit();
None
let sess = self.sess;
let dylibname = self.dylibname();
let mut rlibs = FxHashMap();
+ let mut rmetas = FxHashMap();
let mut dylibs = FxHashMap();
{
let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
return false;
}
};
- if file.starts_with("lib") && file.ends_with(".rlib") {
+ if file.starts_with("lib") &&
+ (file.ends_with(".rlib") || file.ends_with(".rmeta")) {
return true;
} else {
let (ref prefix, ref suffix) = dylibname;
for loc in locs {
if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
+ } else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") {
+ rmetas.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
} else {
dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
}
// Extract the rlib/dylib pair.
let mut slot = None;
let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
+ let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
- if rlib.is_none() && dylib.is_none() {
+ if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
return None;
}
match slot {
Some(Library {
dylib: dylib,
rlib: rlib,
+ rmeta: rmeta,
metadata: metadata,
})
}
Ok(blob)
}
};
+ } else if flavor == CrateFlavor::Rmeta {
+ let mut file = File::open(filename).map_err(|_|
+ format!("could not open file: '{}'", filename.display()))?;
+ let mut buf = vec![];
+ file.read_to_end(&mut buf).map_err(|_|
+ format!("failed to read rlib metadata: '{}'", filename.display()))?;
+ let blob = MetadataBlob::Raw(buf);
+ verify_decompressed_encoding_version(&blob, filename)?;
+ return Ok(blob);
}
unsafe {
let buf = common::path2cstr(filename);
let filename = path.file_name().unwrap().to_str().unwrap();
let flavor = if filename.ends_with(".rlib") {
CrateFlavor::Rlib
+ } else if filename.ends_with(".rmeta") {
+ CrateFlavor::Rmeta
} else {
CrateFlavor::Dylib
};
use rustc_serialize as serialize;
use syntax::{ast, attr};
+use syntax::symbol::Symbol;
use syntax_pos::{self, Span};
use std::marker::PhantomData;
#[derive(RustcEncodable, RustcDecodable)]
pub struct CrateRoot {
pub rustc_version: String,
- pub name: String,
+ pub name: Symbol,
pub triple: String,
pub hash: hir::svh::Svh,
- pub disambiguator: String,
+ pub disambiguator: Symbol,
pub panic_strategy: PanicStrategy,
pub plugin_registrar_fn: Option<DefIndex>,
pub macro_derive_registrar: Option<DefIndex>,
this.cfg.terminate(block, source_info,
TerminatorKind::Goto { target: loop_block });
- let might_break = this.in_loop_scope(loop_block, exit_block, move |this| {
- // conduct the test, if necessary
- let body_block;
- if let Some(cond_expr) = opt_cond_expr {
- // This loop has a condition, ergo its exit_block is reachable.
- this.find_loop_scope(expr_span, None).might_break = true;
+ this.in_loop_scope(
+ loop_block, exit_block, destination.clone(),
+ move |this| {
+ // conduct the test, if necessary
+ let body_block;
+ if let Some(cond_expr) = opt_cond_expr {
+ let loop_block_end;
+ let cond = unpack!(
+ loop_block_end = this.as_operand(loop_block, cond_expr));
+ body_block = this.cfg.start_new_block();
+ this.cfg.terminate(loop_block_end, source_info,
+ TerminatorKind::If {
+ cond: cond,
+ targets: (body_block, exit_block)
+ });
- let loop_block_end;
- let cond = unpack!(loop_block_end = this.as_operand(loop_block, cond_expr));
- body_block = this.cfg.start_new_block();
- this.cfg.terminate(loop_block_end, source_info,
- TerminatorKind::If {
- cond: cond,
- targets: (body_block, exit_block)
- });
- } else {
- body_block = loop_block;
- }
+ // if the test is false, there's no `break` to assign `destination`, so
+ // we have to do it; this overwrites any `break`-assigned value but it's
+ // always `()` anyway
+ this.cfg.push_assign_unit(exit_block, source_info, destination);
+ } else {
+ body_block = loop_block;
+ }
- // The “return” value of the loop body must always be an unit, but we cannot
- // reuse that as a “return” value of the whole loop expressions, because some
- // loops are diverging (e.g. `loop {}`). Thus, we introduce a unit temporary as
- // the destination for the loop body and assign the loop’s own “return” value
- // immediately after the iteration is finished.
- let tmp = this.get_unit_temp();
- // Execute the body, branching back to the test.
- let body_block_end = unpack!(this.into(&tmp, body_block, body));
- this.cfg.terminate(body_block_end, source_info,
- TerminatorKind::Goto { target: loop_block });
- });
- // If the loop may reach its exit_block, we assign an empty tuple to the
- // destination to keep the MIR well-formed.
- if might_break {
- this.cfg.push_assign_unit(exit_block, source_info, destination);
- }
+ // The “return” value of the loop body must always be an unit. We therefore
+ // introduce a unit temporary as the destination for the loop body.
+ let tmp = this.get_unit_temp();
+ // Execute the body, branching back to the test.
+ let body_block_end = unpack!(this.into(&tmp, body_block, body));
+ this.cfg.terminate(body_block_end, source_info,
+ TerminatorKind::Goto { target: loop_block });
+ }
+ );
exit_block.unit()
}
ExprKind::Call { ty, fun, args } => {
use build::{BlockAnd, BlockAndExtension, Builder};
use build::scope::LoopScope;
use hair::*;
-use rustc::middle::region::CodeExtent;
use rustc::mir::*;
-use syntax_pos::Span;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
block.unit()
}
ExprKind::Continue { label } => {
- this.break_or_continue(expr_span, label, block,
- |loop_scope| loop_scope.continue_block)
+ let LoopScope { continue_block, extent, .. } =
+ *this.find_loop_scope(expr_span, label);
+ this.exit_scope(expr_span, extent, block, continue_block);
+ this.cfg.start_new_block().unit()
}
- ExprKind::Break { label } => {
- this.break_or_continue(expr_span, label, block, |loop_scope| {
- loop_scope.might_break = true;
- loop_scope.break_block
- })
+ ExprKind::Break { label, value } => {
+ let (break_block, extent, destination) = {
+ let LoopScope {
+ break_block,
+ extent,
+ ref break_destination,
+ ..
+ } = *this.find_loop_scope(expr_span, label);
+ (break_block, extent, break_destination.clone())
+ };
+ if let Some(value) = value {
+ unpack!(block = this.into(&destination, block, value))
+ } else {
+ this.cfg.push_assign_unit(block, source_info, &destination)
+ }
+ this.exit_scope(expr_span, extent, block, break_block);
+ this.cfg.start_new_block().unit()
}
ExprKind::Return { value } => {
block = match value {
}
}
- fn break_or_continue<F>(&mut self,
- span: Span,
- label: Option<CodeExtent>,
- block: BasicBlock,
- exit_selector: F)
- -> BlockAnd<()>
- where F: FnOnce(&mut LoopScope) -> BasicBlock
- {
- let (exit_block, extent) = {
- let loop_scope = self.find_loop_scope(span, label);
- (exit_selector(loop_scope), loop_scope.extent)
- };
- self.exit_scope(span, extent, block, exit_block);
- self.cfg.start_new_block().unit()
- }
-
}
use rustc::hir;
use syntax::abi::Abi;
use syntax::ast;
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use syntax_pos::Span;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
/// the current set of loops; see the `scope` module for more
/// details
- loop_scopes: Vec<scope::LoopScope>,
+ loop_scopes: Vec<scope::LoopScope<'tcx>>,
/// the vector of all scopes that we have created thus far;
/// we track this for debuginfo later
}
#[derive(Clone, Debug)]
-pub struct LoopScope {
+pub struct LoopScope<'tcx> {
/// Extent of the loop
pub extent: CodeExtent,
/// Where the body of the loop begins
/// Block to branch into when the loop terminates (either by being `break`-en out from, or by
/// having its condition to become false)
pub break_block: BasicBlock,
- /// Indicates the reachability of the break_block for this loop
- pub might_break: bool
+ /// The destination of the loop expression itself (i.e. where to put the result of a `break`
+ /// expression)
+ pub break_destination: Lvalue<'tcx>,
}
impl<'tcx> Scope<'tcx> {
///
/// Returns the might_break attribute of the LoopScope used.
pub fn in_loop_scope<F>(&mut self,
- loop_block: BasicBlock,
- break_block: BasicBlock,
- f: F)
- -> bool
+ loop_block: BasicBlock,
+ break_block: BasicBlock,
+ break_destination: Lvalue<'tcx>,
+ f: F)
where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>)
{
let extent = self.extent_of_innermost_scope();
extent: extent.clone(),
continue_block: loop_block,
break_block: break_block,
- might_break: false
+ break_destination: break_destination,
};
self.loop_scopes.push(loop_scope);
f(self);
let loop_scope = self.loop_scopes.pop().unwrap();
assert!(loop_scope.extent == extent);
- loop_scope.might_break
}
/// Convenience wrapper that pushes a scope and then executes `f`
pub fn find_loop_scope(&mut self,
span: Span,
label: Option<CodeExtent>)
- -> &mut LoopScope {
+ -> &mut LoopScope<'tcx> {
let loop_scopes = &mut self.loop_scopes;
match label {
None => {
use rustc::middle::region::CodeExtent;
use rustc::ty::{self, AdtKind, VariantDef, Ty};
use rustc::ty::cast::CastKind as TyCastKind;
-use rustc::mir::*;
use rustc::hir;
use syntax::ptr::P;
},
hir::ExprRet(ref v) =>
ExprKind::Return { value: v.to_ref() },
- hir::ExprBreak(label) =>
- ExprKind::Break { label: label.map(|_| loop_label(cx, expr)) },
+ hir::ExprBreak(label, ref value) =>
+ ExprKind::Break { label: label.map(|_| loop_label(cx, expr)),
+ value: value.to_ref() },
hir::ExprAgain(label) =>
ExprKind::Continue { label: label.map(|_| loop_label(cx, expr)) },
hir::ExprMatch(ref discr, ref arms, _) =>
hir::ExprWhile(ref cond, ref body, _) =>
ExprKind::Loop { condition: Some(cond.to_ref()),
body: block::to_expr_ref(cx, body) },
- hir::ExprLoop(ref body, _) =>
+ hir::ExprLoop(ref body, _, _) =>
ExprKind::Loop { condition: None,
body: block::to_expr_ref(cx, body) },
hir::ExprField(ref source, name) => {
*/
use hair::*;
-use rustc::mir::*;
use rustc::mir::transform::MirSource;
use rustc::middle::const_val::ConstVal;
use rustc::infer::InferCtxt;
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt};
-use syntax::parse::token;
+use syntax::symbol::{Symbol, InternedString};
use rustc::hir;
use rustc_const_math::{ConstInt, ConstUsize};
self.tcx.mk_nil()
}
- pub fn str_literal(&mut self, value: token::InternedString) -> Literal<'tcx> {
+ pub fn str_literal(&mut self, value: InternedString) -> Literal<'tcx> {
Literal::Value { value: ConstVal::Str(value) }
}
self_ty: Ty<'tcx>,
params: &[Ty<'tcx>])
-> (Ty<'tcx>, Literal<'tcx>) {
- let method_name = token::intern(method_name);
+ let method_name = Symbol::intern(method_name);
let substs = self.tcx.mk_substs_trait(self_ty, params);
for item in self.tcx.associated_items(trait_def_id) {
if item.kind == ty::AssociatedKind::Method && item.name == method_name {
},
Break {
label: Option<CodeExtent>,
+ value: Option<ExprRef<'tcx>>,
},
Continue {
label: Option<CodeExtent>,
#![feature(associated_consts)]
#![feature(box_patterns)]
#![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))]
+#![cfg_attr(stage0, feature(item_like_imports))]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
use syntax::ast::*;
use syntax::attr;
use syntax::codemap::Spanned;
-use syntax::parse::token::{self, keywords};
+use syntax::parse::token;
+use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};
use syntax_pos::Span;
use errors;
if label.name == keywords::StaticLifetime.name() {
self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
}
- if label.name.as_str() == "'_" {
+ if label.name == "'_" {
self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
id,
span,
impl<'a> Visitor for AstValidator<'a> {
fn visit_lifetime(&mut self, lt: &Lifetime) {
- if lt.name.as_str() == "'_" {
+ if lt.name == "'_" {
self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
lt.id,
lt.span,
ExprKind::Loop(_, Some(ident)) |
ExprKind::WhileLet(.., Some(ident)) |
ExprKind::ForLoop(.., Some(ident)) |
- ExprKind::Break(Some(ident)) |
+ ExprKind::Break(Some(ident), _) |
ExprKind::Continue(Some(ident)) => {
self.check_label(ident.node, ident.span, expr.id);
}
ItemKind::Mod(_) => {
// Ensure that `path` attributes on modules are recorded as used (c.f. #35584).
attr::first_attr_value_str_by_name(&item.attrs, "path");
+ if let Some(attr) =
+ item.attrs.iter().find(|attr| attr.name() == "warn_directory_ownership") {
+ let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
+ let msg = "cannot declare a new module at this location";
+ self.session.add_lint(lint, item.id, item.span, msg.to_string());
+ attr::mark_used(attr);
+ }
}
ItemKind::Union(ref vdata, _) => {
if !vdata.is_struct() {
hir::ExprLoop(..) |
// More control flow (also not very meaningful).
- hir::ExprBreak(_) |
+ hir::ExprBreak(..) |
hir::ExprAgain(_) |
hir::ExprRet(_) |
register_diagnostics! {
E0472, // asm! is unsupported on this target
E0561, // patterns aren't allowed in function pointer types
+ E0571, // `break` with a value in a non-`loop`-loop
}
hir_visit::walk_assoc_type_binding(self, type_binding)
}
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
- self.record("Attribute", Id::Attr(attr.node.id), attr);
+ self.record("Attribute", Id::Attr(attr.id), attr);
}
fn visit_macro_def(&mut self, macro_def: &'v hir::MacroDef) {
self.record("MacroDef", Id::Node(macro_def.id), macro_def);
use rustc::session::Session;
use rustc::dep_graph::DepNode;
+use rustc::hir::def::{Def, DefMap};
use rustc::hir::map::Map;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir;
use syntax_pos::Span;
+#[derive(Clone, Copy, PartialEq)]
+enum LoopKind {
+ Loop(hir::LoopSource),
+ WhileLoop,
+}
+
+impl LoopKind {
+ fn name(self) -> &'static str {
+ match self {
+ LoopKind::Loop(hir::LoopSource::Loop) => "loop",
+ LoopKind::Loop(hir::LoopSource::WhileLet) => "while let",
+ LoopKind::Loop(hir::LoopSource::ForLoop) => "for",
+ LoopKind::WhileLoop => "while",
+ }
+ }
+}
+
#[derive(Clone, Copy, PartialEq)]
enum Context {
Normal,
- Loop,
+ Loop(LoopKind),
Closure,
}
#[derive(Copy, Clone)]
-struct CheckLoopVisitor<'a> {
+struct CheckLoopVisitor<'a, 'ast: 'a> {
sess: &'a Session,
+ def_map: &'a DefMap,
+ hir_map: &'a Map<'ast>,
cx: Context,
}
-pub fn check_crate(sess: &Session, map: &Map) {
+pub fn check_crate(sess: &Session, def_map: &DefMap, map: &Map) {
let _task = map.dep_graph.in_task(DepNode::CheckLoops);
let krate = map.krate();
krate.visit_all_item_likes(&mut CheckLoopVisitor {
sess: sess,
+ def_map: def_map,
+ hir_map: map,
cx: Normal,
}.as_deep_visitor());
}
-impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
+impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> {
fn visit_item(&mut self, i: &hir::Item) {
self.with_context(Normal, |v| intravisit::walk_item(v, i));
}
fn visit_expr(&mut self, e: &hir::Expr) {
match e.node {
hir::ExprWhile(ref e, ref b, _) => {
- self.visit_expr(&e);
- self.with_context(Loop, |v| v.visit_block(&b));
+ self.with_context(Loop(LoopKind::WhileLoop), |v| {
+ v.visit_expr(&e);
+ v.visit_block(&b);
+ });
}
- hir::ExprLoop(ref b, _) => {
- self.with_context(Loop, |v| v.visit_block(&b));
+ hir::ExprLoop(ref b, _, source) => {
+ self.with_context(Loop(LoopKind::Loop(source)), |v| v.visit_block(&b));
}
hir::ExprClosure(.., ref b, _) => {
self.with_context(Closure, |v| v.visit_expr(&b));
}
- hir::ExprBreak(_) => self.require_loop("break", e.span),
+ hir::ExprBreak(ref opt_label, ref opt_expr) => {
+ if opt_expr.is_some() {
+ let loop_kind = if opt_label.is_some() {
+ let loop_def = self.def_map.get(&e.id).unwrap().full_def();
+ if loop_def == Def::Err {
+ None
+ } else if let Def::Label(loop_id) = loop_def {
+ Some(match self.hir_map.expect_expr(loop_id).node {
+ hir::ExprWhile(..) => LoopKind::WhileLoop,
+ hir::ExprLoop(_, _, source) => LoopKind::Loop(source),
+ ref r => span_bug!(e.span,
+ "break label resolved to a non-loop: {:?}", r),
+ })
+ } else {
+ span_bug!(e.span, "break resolved to a non-label")
+ }
+ } else if let Loop(kind) = self.cx {
+ Some(kind)
+ } else {
+ // `break` outside a loop - caught below
+ None
+ };
+ match loop_kind {
+ None | Some(LoopKind::Loop(hir::LoopSource::Loop)) => (),
+ Some(kind) => {
+ struct_span_err!(self.sess, e.span, E0571,
+ "`break` with value from a `{}` loop",
+ kind.name())
+ .span_label(e.span,
+ &format!("can only break with a value inside `loop`"))
+ .emit();
+ }
+ }
+ }
+ self.require_loop("break", e.span);
+ }
hir::ExprAgain(_) => self.require_loop("continue", e.span),
_ => intravisit::walk_expr(self, e),
}
}
}
-impl<'a> CheckLoopVisitor<'a> {
+impl<'a, 'ast> CheckLoopVisitor<'a, 'ast> {
fn with_context<F>(&mut self, cx: Context, f: F)
- where F: FnOnce(&mut CheckLoopVisitor<'a>)
+ where F: FnOnce(&mut CheckLoopVisitor<'a, 'ast>)
{
let old_cx = self.cx;
self.cx = cx;
fn require_loop(&self, name: &str, span: Span) {
match self.cx {
- Loop => {}
+ Loop(_) => {}
Closure => {
struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name)
.span_label(span, &format!("cannot break inside of a closure"))
for plugin in plugins {
// plugins must have a name and can't be key = value
match plugin.name() {
- Some(ref name) if !plugin.is_value_str() => {
+ Some(name) if !plugin.is_value_str() => {
let args = plugin.meta_item_list().map(ToOwned::to_owned);
- loader.load_plugin(plugin.span, name, args.unwrap_or_default());
+ loader.load_plugin(plugin.span, &name.as_str(), args.unwrap_or_default());
},
_ => call_malformed_plugin_attribute(sess, attr.span),
}
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT};
use syntax::ext::base::MacroExpanderFn;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax::ast;
use syntax::feature_gate::AttributeType;
use syntax_pos::Span;
///
/// This is the most general hook into `libsyntax`'s expansion behavior.
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
- if name.as_str() == "macro_rules" {
+ if name == "macro_rules" {
panic!("user-defined macros may not be named `macro_rules`");
}
self.syntax_exts.push((name, match extension {
/// It builds for you a `NormalTT` that calls `expander`,
/// and also takes care of interning the macro's name.
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
- self.register_syntax_extension(token::intern(name),
+ self.register_syntax_extension(Symbol::intern(name),
NormalTT(Box::new(expander), None, false));
}
use syntax::ast::Name;
use syntax::attr;
-use syntax::parse::token;
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
use syntax::ext::expand::mark_tts;
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
match view_path.node {
ViewPathSimple(binding, ref full_path) => {
let mut source = full_path.segments.last().unwrap().identifier;
- let source_name = source.name.as_str();
+ let source_name = source.name;
if source_name == "mod" || source_name == "self" {
resolve_error(self,
view_path.span,
});
} else {
for (name, span) in legacy_imports.imports {
- let result = self.resolve_name_in_module(module, name, MacroNS, false, false, None);
+ let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
if let Success(binding) = result {
self.legacy_import_macro(name, binding, span, allow_shadowing);
} else {
}
for (name, span) in legacy_imports.reexports {
self.used_crates.insert(module.def_id().unwrap().krate);
- let result = self.resolve_name_in_module(module, name, MacroNS, false, false, None);
+ let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
if let Success(binding) = result {
self.macro_exports.push(Export { name: name, def: binding.def() });
} else {
if attr.check_name("macro_escape") {
let msg = "macro_escape is a deprecated synonym for macro_use";
let mut err = self.session.struct_span_warn(attr.span, msg);
- if let ast::AttrStyle::Inner = attr.node.style {
+ if let ast::AttrStyle::Inner = attr.style {
err.help("consider an outer attribute, #[macro_use] mod ...").emit();
} else {
err.emit();
match attr.meta_item_list() {
Some(names) => for attr in names {
if let Some(word) = attr.word() {
- imports.imports.push((token::intern(&word.name()), attr.span()));
+ imports.imports.push((word.name(), attr.span()));
} else {
span_err!(self.session, attr.span(), E0466, "bad macro import");
}
if let Some(names) = attr.meta_item_list() {
for attr in names {
if let Some(word) = attr.word() {
- imports.reexports.push((token::intern(&word.name()), attr.span()));
+ imports.reexports.push((word.name(), attr.span()));
} else {
bad_macro_reexport(self, attr.span());
}
An example of this error:
-```compile_fail
+```ignore
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line
use syntax::ast::{self, FloatTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, Ident, SpannedIdent, IntTy, UintTy};
use syntax::ext::base::SyntaxExtension;
-use syntax::parse::token::{self, keywords};
+use syntax::symbol::{Symbol, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::visit::{self, FnKind, Visitor};
enum SuggestionType {
Macro(String),
- Function(token::InternedString),
+ Function(Symbol),
NotFound,
}
}
fn intern(&mut self, string: &str, primitive_type: PrimTy) {
- self.primitive_types.insert(token::intern(string), primitive_type);
+ self.primitive_types.insert(Symbol::intern(string), primitive_type);
}
}
arenas: &'a ResolverArenas<'a>,
dummy_binding: &'a NameBinding<'a>,
- new_import_semantics: bool, // true if `#![feature(item_like_imports)]`
use_extern_macros: bool, // true if `#![feature(use_extern_macros)]`
pub exported_macros: Vec<ast::MacroDef>,
span: DUMMY_SP,
vis: ty::Visibility::Public,
}),
- new_import_semantics: session.features.borrow().item_like_imports,
use_extern_macros: session.features.borrow().use_extern_macros,
exported_macros: Vec::new(),
-> ResolveResult<Module<'a>> {
fn search_parent_externals<'a>(this: &mut Resolver<'a>, needle: Name, module: Module<'a>)
-> Option<Module<'a>> {
- match this.resolve_name_in_module(module, needle, TypeNS, false, false, None) {
+ match this.resolve_name_in_module(module, needle, TypeNS, false, None) {
Success(binding) if binding.is_extern_crate() => Some(module),
_ => if let (&ModuleKind::Def(..), Some(parent)) = (&module.kind, module.parent) {
search_parent_externals(this, needle, parent)
// modules as we go.
while index < module_path_len {
let name = module_path[index].name;
- match self.resolve_name_in_module(search_module, name, TypeNS, false, false, span) {
+ match self.resolve_name_in_module(search_module, name, TypeNS, false, span) {
Failed(_) => {
- let segment_name = name.as_str();
let module_name = module_to_string(search_module);
let msg = if "???" == &module_name {
let current_module = self.current_module;
format!("Did you mean `{}{}`?", prefix, path_str)
}
- None => format!("Maybe a missing `extern crate {};`?", segment_name),
+ None => format!("Maybe a missing `extern crate {};`?", name),
}
} else {
- format!("Could not find `{}` in `{}`", segment_name, module_name)
+ format!("Could not find `{}` in `{}`", name, module_name)
};
return Failed(span.map(|span| (span, msg)));
if let ModuleRibKind(module) = self.ribs[ns][i].kind {
let name = ident.name;
- let item = self.resolve_name_in_module(module, name, ns, true, false, record_used);
+ let item = self.resolve_name_in_module(module, name, ns, false, record_used);
if let Success(binding) = item {
// The ident resolves to an item.
return Some(LexicalScopeBinding::Item(binding));
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_prelude {
return self.prelude.and_then(|prelude| {
- self.resolve_name_in_module(prelude, name, ns, false, false, None).success()
+ self.resolve_name_in_module(prelude, name, ns, false, None).success()
}).map(LexicalScopeBinding::Item)
} else {
return None;
/// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
fn resolve_module_prefix(&mut self, module_path: &[Ident], span: Option<Span>)
-> ResolveResult<ModulePrefixResult<'a>> {
- if &*module_path[0].name.as_str() == "$crate" {
+ if module_path[0].name == "$crate" {
return Success(PrefixFound(self.resolve_crate_var(module_path[0].ctxt), 1));
}
self.module_map[&self.current_module.normal_ancestor_id.unwrap()];
// Now loop through all the `super`s we find.
- while i < module_path.len() && "super" == module_path[i].name.as_str() {
+ while i < module_path.len() && module_path[i].name == "super" {
debug!("(resolving module prefix) resolving `super` at {}",
module_to_string(&containing_module));
if let Some(parent) = containing_module.parent {
let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
match (qualified_binding, unqualified_def) {
(Ok(binding), Some(ref ud)) if binding.def() == ud.def &&
- segments[0].identifier.name.as_str() != "$crate" => {
+ segments[0].identifier.name != "$crate" => {
self.session
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
id,
};
let name = segments.last().unwrap().identifier.name;
- let result = self.resolve_name_in_module(module, name, namespace, false, false, Some(span));
+ let result = self.resolve_name_in_module(module, name, namespace, false, Some(span));
result.success().ok_or(false)
}
};
let name = segments.last().unwrap().ident().name;
- let result = self.resolve_name_in_module(module, name, namespace, false, false, Some(span));
+ let result = self.resolve_name_in_module(module, name, namespace, false, Some(span));
result.success().ok_or(false)
}
}
fn find_best_match(&mut self, name: &str) -> SuggestionType {
- if let Some(macro_name) = self.macro_names.iter().find(|n| n.as_str() == name) {
+ if let Some(macro_name) = self.macro_names.iter().find(|&n| n == &name) {
return SuggestionType::Macro(format!("{}!", macro_name));
}
.flat_map(|rib| rib.bindings.keys().map(|ident| &ident.name));
if let Some(found) = find_best_match_for_name(names, name, None) {
- if name != found {
+ if found != name {
return SuggestionType::Function(found);
}
} SuggestionType::NotFound
false // Stop advancing
});
- if method_scope &&
- &path_name[..] == keywords::SelfValue.name().as_str() {
+ if method_scope && keywords::SelfValue.name() == &*path_name {
resolve_error(self,
expr.span,
ResolutionError::SelfNotAvailableInStaticMethod);
visit::walk_expr(self, expr);
}
- ExprKind::Break(Some(label)) | ExprKind::Continue(Some(label)) => {
+ ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
match self.search_label(label.node) {
None => {
self.record_def(expr.id, err_path_resolution());
resolve_error(self,
label.span,
- ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
+ ResolutionError::UndeclaredLabel(&label.node.name.as_str()));
}
Some(def @ Def::Label(_)) => {
// Since this def is a label, it is never read.
- self.record_def(expr.id, PathResolution::new(def))
+ self.record_def(expr.id, PathResolution::new(def));
}
Some(_) => {
- span_bug!(expr.span, "label wasn't mapped to a label def!")
+ span_bug!(expr.span, "label wasn't mapped to a label def!");
}
}
+
+ // visit `break` argument if any
+ visit::walk_expr(self, expr);
}
ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => {
}
} else {
// danger, shouldn't be ident?
- names.push(token::str_to_ident("<opaque>"));
+ names.push(Ident::from_str("<opaque>"));
collect_mod(names, module.parent.unwrap());
}
}
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::fold::Folder;
-use syntax::parse::token::intern;
use syntax::ptr::P;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::visit::Visitor;
impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
let ident = path.segments[0].identifier;
- if &ident.name.as_str() == "$crate" {
+ if ident.name == "$crate" {
path.global = true;
let module = self.0.resolve_crate_var(ident.ctxt);
if module.is_local() {
}
fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef, export: bool) {
- if &def.ident.name.as_str() == "macro_rules" {
+ if def.ident.name == "macro_rules" {
self.session.span_err(def.span, "user-defined macros may not be named `macro_rules`");
}
fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
for i in 0..attrs.len() {
- let name = intern(&attrs[i].name());
- match self.builtin_macros.get(&name).cloned() {
+ match self.builtin_macros.get(&attrs[i].name()).cloned() {
Some(binding) => match *self.get_macro(binding) {
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
return Some(attrs.remove(i))
loop {
// Since expanded macros may not shadow the lexical scope (enforced below),
// we can ignore unresolved invocations (indicated by the penultimate argument).
- match self.resolve_name_in_module(module, name, ns, true, true, record_used) {
+ match self.resolve_name_in_module(module, name, ns, true, record_used) {
Success(binding) => {
let span = match record_used {
Some(span) => span,
single_imports: SingleImports<'a>,
/// The least shadowable known binding for this name, or None if there are no known bindings.
pub binding: Option<&'a NameBinding<'a>>,
- duplicate_globs: Vec<&'a NameBinding<'a>>,
}
#[derive(Clone, Debug)]
module: Module<'a>,
name: Name,
ns: Namespace,
- allow_private_imports: bool,
ignore_unresolved_invocations: bool,
record_used: Option<Span>)
-> ResolveResult<&'a NameBinding<'a>> {
_ => return Failed(None), // This happens when there is a cycle of imports
};
- let new_import_semantics = self.new_import_semantics;
- let is_disallowed_private_import = |binding: &NameBinding| {
- !new_import_semantics && !allow_private_imports && // disallowed
- binding.vis != ty::Visibility::Public && binding.is_import() && // non-`pub` import
- !binding.is_extern_crate() // not an `extern crate`
- };
-
if let Some(span) = record_used {
if let Some(binding) = resolution.binding {
- if is_disallowed_private_import(binding) {
- return Failed(None);
- }
if self.record_use(name, ns, binding, span) {
return Success(self.dummy_binding);
}
}
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
- let usable =
- this.is_accessible(binding.vis) && !is_disallowed_private_import(binding) ||
- binding.is_extern_crate(); // c.f. issue #37020
+ // `extern crate` are always usable for backwards compatability, see issue #37020.
+ let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
if usable { Success(binding) } else { Failed(None) }
};
SingleImport { source, .. } => source,
_ => unreachable!(),
};
- match self.resolve_name_in_module(module, name, ns, true, false, None) {
+ match self.resolve_name_in_module(module, name, ns, false, None) {
Failed(_) => {}
_ => return Indeterminate,
}
for directive in module.globs.borrow().iter() {
if self.is_accessible(directive.vis.get()) {
if let Some(module) = directive.imported_module.get() {
- let result = self.resolve_name_in_module(module, name, ns, true, false, None);
+ let result = self.resolve_name_in_module(module, name, ns, false, None);
if let Indeterminate = result {
return Indeterminate;
}
self.update_resolution(module, name, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if binding.is_glob_import() {
- if !this.new_import_semantics {
- resolution.duplicate_globs.push(binding);
- } else if !old_binding.is_glob_import() &&
- !(ns == MacroNS && old_binding.expansion != Mark::root()) {
+ if !old_binding.is_glob_import() &&
+ !(ns == MacroNS && old_binding.expansion != Mark::root()) {
} else if binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(old_binding, binding));
} else if !old_binding.vis.is_at_least(binding.vis, this) {
resolution.binding = Some(binding);
}
} else if old_binding.is_glob_import() {
- if !this.new_import_semantics {
- resolution.duplicate_globs.push(old_binding);
- resolution.binding = Some(binding);
- } else if ns == MacroNS && binding.expansion != Mark::root() &&
- binding.def() != old_binding.def() {
+ if ns == MacroNS && binding.expansion != Mark::root() &&
+ binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(binding, old_binding));
} else {
resolution.binding = Some(binding);
let t = f(self, resolution);
match resolution.binding() {
- _ if !self.new_import_semantics && old_binding.is_some() => return t,
+ _ if old_binding.is_some() => return t,
None => return t,
Some(binding) => match old_binding {
Some(old_binding) if old_binding as *const _ == binding as *const _ => return t,
// Define `binding` in `module`s glob importers.
for directive in module.glob_importers.borrow_mut().iter() {
- if match self.new_import_semantics {
- true => self.is_accessible_from(binding.vis, directive.parent),
- false => binding.vis == ty::Visibility::Public,
- } {
+ if self.is_accessible_from(binding.vis, directive.parent) {
let imported_binding = self.import(binding, directive);
let _ = self.try_define(directive.parent, name, ns, imported_binding);
}
self.per_ns(|this, ns| {
if let Err(Undetermined) = result[ns].get() {
result[ns].set({
- match this.resolve_name_in_module(module, source, ns, false, false, None) {
+ match this.resolve_name_in_module(module, source, ns, false, None) {
Success(binding) => Ok(binding),
Indeterminate => Err(Undetermined),
Failed(_) => Err(Determined),
if all_ns_err {
let mut all_ns_failed = true;
self.per_ns(|this, ns| {
- match this.resolve_name_in_module(module, name, ns, false, false, Some(span)) {
+ match this.resolve_name_in_module(module, name, ns, false, Some(span)) {
Success(_) => all_ns_failed = false,
_ => {}
}
resolution.borrow().binding().map(|binding| (*name, binding))
}).collect::<Vec<_>>();
for ((name, ns), binding) in bindings {
- if binding.pseudo_vis() == ty::Visibility::Public ||
- self.new_import_semantics && self.is_accessible(binding.vis) {
+ if binding.pseudo_vis() == ty::Visibility::Public || self.is_accessible(binding.vis) {
let imported_binding = self.import(binding, directive);
let _ = self.try_define(directive.parent, name, ns, imported_binding);
}
None => continue,
};
- // Report conflicts
- if !self.new_import_semantics {
- for duplicate_glob in resolution.duplicate_globs.iter() {
- // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
- if !binding.is_import() {
- if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
- if binding.is_import() { continue }
- }
- }
-
- self.report_conflict(module, name, ns, duplicate_glob, binding);
- }
- }
-
if binding.vis == ty::Visibility::Public &&
(binding.is_import() || binding.is_extern_crate()) {
let def = binding.def();
use std::hash::*;
use syntax::ast::{self, NodeId, PatKind, Attribute, CRATE_NODE_ID};
-use syntax::parse::token::{self, keywords};
+use syntax::parse::token;
+use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};
use syntax::print::pprust::{path_to_string, ty_to_string, bounds_to_string, generics_to_string};
use syntax::ptr::P;
use syntax::ast::{self, NodeId, PatKind, Attribute, CRATE_NODE_ID};
use syntax::parse::lexer::comments::strip_doc_comment_decoration;
-use syntax::parse::token::{self, keywords, InternedString};
+use syntax::parse::token;
+use syntax::symbol::{Symbol, keywords};
use syntax::visit::{self, Visitor};
use syntax::print::pprust::{ty_to_string, arg_to_string};
use syntax::codemap::MacroAttribute;
}
};
result.push(CrateData {
- name: (&self.tcx.sess.cstore.crate_name(n)[..]).to_owned(),
+ name: self.tcx.sess.cstore.crate_name(n).to_string(),
number: n.as_u32(),
span: span,
});
}
fn docs_for_attrs(attrs: &[Attribute]) -> String {
- let doc = InternedString::new("doc");
+ let doc = Symbol::intern("doc");
let mut result = String::new();
for attr in attrs {
if attr.name() == doc {
- if let Some(ref val) = attr.value_str() {
- if attr.node.is_sugared_doc {
- result.push_str(&strip_doc_comment_decoration(val));
+ if let Some(val) = attr.value_str() {
+ if attr.is_sugared_doc {
+ result.push_str(&strip_doc_comment_decoration(&val.as_str()));
} else {
- result.push_str(val);
+ result.push_str(&val.as_str());
}
result.push('\n');
}
use syntax::ast;
use syntax::parse::lexer::{self, Reader, StringReader};
-use syntax::parse::token::{self, keywords, Token};
+use syntax::parse::token::{self, Token};
+use syntax::symbol::keywords;
use syntax_pos::*;
#[derive(Clone)]
AsmDialect::Intel => llvm::AsmDialect::Intel,
};
- let asm = CString::new(ia.asm.as_bytes()).unwrap();
+ let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap();
let constraint_cstr = CString::new(all_constraints).unwrap();
let r = InlineAsmCall(bcx,
asm.as_ptr(),
use rustc::ty::TyCtxt;
use syntax::ast;
-use syntax::parse::token::InternedString;
use {ModuleSource, ModuleTranslation};
}
let mname = self.field(attr, MODULE);
- let mtrans = self.modules.iter().find(|mtrans| &mtrans.name[..] == &mname[..]);
+ let mtrans = self.modules.iter().find(|mtrans| *mtrans.name == *mname.as_str());
let mtrans = match mtrans {
Some(m) => m,
None => {
}
}
- fn field(&self, attr: &ast::Attribute, name: &str) -> InternedString {
+ fn field(&self, attr: &ast::Attribute, name: &str) -> ast::Name {
for item in attr.meta_item_list().unwrap_or(&[]) {
if item.check_name(name) {
if let Some(value) = item.value_str() {
let config = &self.tcx.sess.parse_sess.config;
let value = self.field(attr, CFG);
debug!("check_config(config={:?}, value={:?})", config, value);
- if config.iter().any(|c| c.check_name(&value[..])) {
+ if config.iter().any(|&(name, _)| name == value) {
debug!("check_config: matched");
return true;
}
}
fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
- let kind = &self.config.sess.target.target.options.archive_format[..];
+ let kind = &*self.config.sess.target.target.options.archive_format;
kind.parse().map_err(|_| kind)
}
use session::filesearch;
use session::search_paths::PathKind;
use session::Session;
-use middle::cstore::{self, LinkMeta, NativeLibrary};
+use middle::cstore::{self, LinkMeta, NativeLibrary, LibSource};
use middle::cstore::{LinkagePreference, NativeLibraryKind};
use middle::dependency_format::Linkage;
use CrateTranslation;
use flate;
use syntax::ast;
use syntax::attr;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
// RLIB LLVM-BYTECODE OBJECT LAYOUT
if let Some(sess) = sess {
if let Some(ref s) = sess.opts.crate_name {
- if let Some((attr, ref name)) = attr_crate_name {
- if *s != &name[..] {
+ if let Some((attr, name)) = attr_crate_name {
+ if name != &**s {
let msg = format!("--crate-name and #[crate_name] are \
required to match, but `{}` != `{}`",
s, name);
}
"rust_out".to_string()
-
}
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap,
name: &str)
-> LinkMeta {
let r = LinkMeta {
- crate_name: name.to_owned(),
+ crate_name: Symbol::intern(name),
crate_hash: Svh::new(incremental_hashes_map[&DepNode::Krate].to_smaller_hash()),
};
info!("{:?}", r);
config::CrateTypeRlib => {
outputs.out_directory.join(&format!("lib{}.rlib", libname))
}
+ config::CrateTypeMetadata => {
+ outputs.out_directory.join(&format!("lib{}.rmeta", libname))
+ }
config::CrateTypeCdylib |
config::CrateTypeProcMacro |
config::CrateTypeDylib => {
.or_else(|| fmts.get(&config::CrateTypeCdylib))
.or_else(|| fmts.get(&config::CrateTypeProcMacro));
let fmts = fmts.unwrap_or_else(|| {
- bug!("could not find formats for rlibs")
+ bug!("could not find formats for rlibs");
});
for (cnum, path) in crates {
match fmts[cnum.as_usize() - 1] {
}
let name = sess.cstore.crate_name(cnum).clone();
let path = match path {
- Some(p) => p,
- None => {
+ LibSource::Some(p) => p,
+ LibSource::MetadataOnly => {
+ sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file",
+ name));
+ }
+ LibSource::None => {
sess.fatal(&format!("could not find rlib for: `{}`", name));
}
};
config::CrateTypeStaticlib => {
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
}
+ config::CrateTypeMetadata => {
+ emit_metadata(sess, trans, &out_filename);
+ }
_ => {
link_natively(sess, crate_type, &objects, &out_filename, trans,
outputs, tmpdir.path());
}
}
+fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, out_filename: &Path) {
+ let result = fs::File::create(out_filename).and_then(|mut f| f.write_all(&trans.metadata));
+ if let Err(e) = result {
+ sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
+ }
+}
+
// Create an 'rlib'
//
// An rlib in its current incarnation is essentially a renamed .a file. The
tmpdir: &Path) -> ArchiveBuilder<'a> {
info!("preparing rlib from {:?} to {:?}", objects, out_filename);
let mut ab = ArchiveBuilder::new(archive_config(sess, out_filename, None));
+
for obj in objects {
ab.add_file(obj);
}
NativeLibraryKind::NativeFramework |
NativeLibraryKind::NativeUnknown => continue,
}
- ab.add_native_library(&lib.name);
+ ab.add_native_library(&lib.name.as_str());
}
// After adding all files to the archive, we need to update the
// here so concurrent builds in the same directory don't try to use
// the same filename for metadata (stomping over one another)
let metadata = tmpdir.join(sess.cstore.metadata_filename());
- match fs::File::create(&metadata).and_then(|mut f| {
- f.write_all(&trans.metadata)
- }) {
- Ok(..) => {}
- Err(e) => {
- sess.fatal(&format!("failed to write {}: {}",
- metadata.display(), e));
- }
- }
+ emit_metadata(sess, trans, &metadata);
ab.add_file(&metadata);
// For LTO purposes, the bytecode of this library is also inserted
let skip_object_files = native_libs.iter().any(|lib| {
lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
});
- ab.add_rlib(path, &name, sess.lto(), skip_object_files).unwrap();
+ ab.add_rlib(path, &name.as_str(), sess.lto(), skip_object_files).unwrap();
all_native_libs.extend(sess.cstore.native_libraries(cnum));
});
// don't otherwise explicitly reference them. This can occur for
// libraries which are just providing bindings, libraries with generic
// functions, etc.
- cmd.link_whole_staticlib(&l.name, &search_path);
+ cmd.link_whole_staticlib(&l.name.as_str(), &search_path);
}
cmd.hint_dynamic();
for lib in others {
match lib.kind {
- NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name),
- NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name),
+ NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
+ NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
NativeLibraryKind::NativeStatic => bug!(),
}
}
continue
}
match lib.kind {
- NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name),
- NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name),
+ NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
+ NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
// ignore statically included native libraries here as we've
// already included them when we included the rust library
use std::fs;
use rustc::hir::def_id::CrateNum;
+use rustc::middle::cstore::LibSource;
pub struct RPathConfig<'a> {
- pub used_crates: Vec<(CrateNum, Option<PathBuf>)>,
+ pub used_crates: Vec<(CrateNum, LibSource)>,
pub out_filename: PathBuf,
pub is_like_osx: bool,
pub has_rpath: bool,
debug!("preparing the RPATH!");
let libs = config.used_crates.clone();
- let libs = libs.into_iter().filter_map(|(_, l)| l).collect::<Vec<_>>();
+ let libs = libs.into_iter().filter_map(|(_, l)| l.option()).collect::<Vec<_>>();
let rpaths = get_rpaths(config, &libs[..]);
flags.extend_from_slice(&rpaths_to_flags(&rpaths[..]));
use rustc::util::common::record_time;
use syntax::attr;
-use syntax::parse::token::{self, InternedString};
+use syntax::symbol::{Symbol, InternedString};
fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
}
fn push(&mut self, text: &str) {
- self.names.push(token::intern(text).as_str());
+ self.names.push(Symbol::intern(text).as_str());
}
}
krate: LOCAL_CRATE,
};
let hash = get_symbol_hash(scx, &empty_def_path, t, None);
- let path = [token::intern_and_get_ident(prefix)];
+ let path = [Symbol::intern(prefix).as_str()];
mangle(path.iter().cloned(), &hash)
}
llval: ValueRef,
attrs: &[ast::Attribute]) {
if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") {
- if contains_null(§) {
+ if contains_null(§.as_str()) {
ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", §));
}
unsafe {
- let buf = CString::new(sect.as_bytes()).unwrap();
+ let buf = CString::new(sect.as_str().as_bytes()).unwrap();
llvm::LLVMSetSection(llval, buf.as_ptr());
}
}
config::CrateTypeStaticlib |
config::CrateTypeCdylib => MetadataKind::None,
- config::CrateTypeRlib => MetadataKind::Uncompressed,
+ config::CrateTypeRlib |
+ config::CrateTypeMetadata => MetadataKind::Uncompressed,
config::CrateTypeDylib |
config::CrateTypeProcMacro => MetadataKind::Compressed,
assert_module_sources::assert_module_sources(tcx, &modules);
// Skip crate items and just output metadata in -Z no-trans mode.
- if tcx.sess.opts.debugging_opts.no_trans {
+ if tcx.sess.opts.debugging_opts.no_trans ||
+ tcx.sess.crate_types.borrow().iter().all(|ct| ct == &config::CrateTypeMetadata) {
let linker_info = LinkerInfo::new(&shared_ccx, &[]);
return CrateTranslation {
modules: modules,
-> bool {
(bare_fn_ty.abi == Abi::RustIntrinsic ||
bare_fn_ty.abi == Abi::PlatformIntrinsic) &&
- tcx.item_name(def_id).as_str() == "drop_in_place"
+ tcx.item_name(def_id) == "drop_in_place"
}
}
}
use std::cell::{Cell, RefCell, Ref};
use syntax::ast;
-use syntax::parse::token::InternedString;
-use syntax::parse::token;
+use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{DUMMY_SP, Span};
pub use context::{CrateContext, SharedCrateContext};
VariantInfo {
discr: Disr(0),
fields: v.iter().enumerate().map(|(i, &t)| {
- Field(token::intern(&i.to_string()), t)
+ Field(Symbol::intern(&i.to_string()), t)
}).collect()
}
}
// extern "C" fn() from being non-null, so we can't just declare a
// static and call it a day. Some linkages (like weak) will make it such
// that the static actually has a null value.
- let linkage = match base::llvm_linkage_by_name(&name) {
+ let linkage = match base::llvm_linkage_by_name(&name.as_str()) {
Some(linkage) => linkage,
None => {
ccx.sess().span_fatal(span, "invalid linkage specified");
use std::rc::Rc;
use std::str;
use syntax::ast;
-use syntax::parse::token::InternedString;
+use syntax::symbol::InternedString;
use abi::FnType;
pub struct Stats {
use std::fmt::Write;
use std::path::Path;
use std::ptr;
-use std::rc::Rc;
-use syntax::util::interner::Interner;
use syntax::ast;
-use syntax::parse::token;
+use syntax::symbol::{Interner, InternedString};
use syntax_pos::{self, Span};
unique_type_id: UniqueTypeId,
metadata: DIType) {
if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
- let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
bug!("Type metadata for unique id '{}' is already in the TypeMap!",
- &unique_type_id_str[..]);
+ self.get_unique_type_id_as_string(unique_type_id));
}
}
// Get the string representation of a UniqueTypeId. This method will fail if
// the id is unknown.
- fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<str> {
+ fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
let UniqueTypeId(interner_key) = unique_type_id;
self.unique_id_interner.get(interner_key)
}
-> UniqueTypeId {
let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
let enum_variant_type_id = format!("{}::{}",
- &self.get_unique_type_id_as_string(enum_type_id),
+ self.get_unique_type_id_as_string(enum_type_id),
variant_name);
let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
UniqueTypeId(interner_key)
let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => metadata,
None => {
- let unique_type_id_str =
- type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Expected type metadata for unique \
type id '{}' to already be in \
the debuginfo::TypeMap but it \
was not. (Ty = {})",
- &unique_type_id_str[..],
+ type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
};
match type_map.find_metadata_for_type(t) {
Some(metadata) => {
if metadata != metadata_for_uid {
- let unique_type_id_str =
- type_map.get_unique_type_id_as_string(unique_type_id);
span_bug!(usage_site_span,
"Mismatch between Ty and \
UniqueTypeId maps in \
debuginfo::TypeMap. \
UniqueTypeId={}, Ty={}",
- &unique_type_id_str[..],
+ type_map.get_unique_type_id_as_string(unique_type_id),
t);
}
}
};
fn fallback_path(scc: &SharedCrateContext) -> CString {
- CString::new(scc.link_meta().crate_name.clone()).unwrap()
+ CString::new(scc.link_meta().crate_name.to_string()).unwrap()
}
}
let enum_llvm_type = type_of::type_of(cx, enum_type);
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
- let unique_type_id_str = debug_context(cx)
- .type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
-
let enum_name = CString::new(enum_name).unwrap();
- let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id_str = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let enum_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateUnionType(
DIB(cx),
fn get_enum_discriminant_name(cx: &CrateContext,
def_id: DefId)
- -> token::InternedString {
+ -> InternedString {
cx.tcx().item_name(def_id).as_str()
}
}
-> DICompositeType {
let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
- let unique_type_id_str = debug_context(cx).type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
let name = CString::new(struct_type_name).unwrap();
- let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
-> DICompositeType {
let (union_size, union_align) = size_and_align_of(cx, union_llvm_type);
- let unique_type_id_str = debug_context(cx).type_map
- .borrow()
- .get_unique_type_id_as_string(unique_type_id);
let name = CString::new(union_type_name).unwrap();
- let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
+ let unique_type_id = CString::new(
+ debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
+ ).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
}
let name = match def_key.disambiguated_data.data {
- DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
+ DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate).as_str(),
data => data.as_interned_str()
};
});
let namespace_name = match def_key.disambiguated_data.data {
- DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate),
+ DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate).as_str(),
data => data.as_interned_str()
};
qualified: bool,
output: &mut String) {
if qualified {
- output.push_str(&cx.tcx().crate_name(def_id.krate));
+ output.push_str(&cx.tcx().crate_name(def_id.krate).as_str());
for path_element in cx.tcx().def_path(def_id).data {
output.push_str("::");
output.push_str(&path_element.data.as_interned_str());
use Disr;
use rustc::hir;
use syntax::ast;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use rustc::session::Session;
use syntax_pos::{Span, DUMMY_SP};
let sig = tcx.erase_late_bound_regions_and_normalize(&fty.sig);
let arg_tys = sig.inputs;
let ret_ty = sig.output;
- let name = tcx.item_name(def_id).as_str();
+ let name = &*tcx.item_name(def_id).as_str();
let span = match call_debug_location {
DebugLoc::ScopeAt(_, span) => span,
Call(bcx, llfn, &[], call_debug_location);
Unreachable(bcx);
return Result::new(bcx, C_undef(Type::nil(ccx).ptr_to()));
- } else if &name[..] == "unreachable" {
+ } else if name == "unreachable" {
Unreachable(bcx);
return Result::new(bcx, C_nil(ccx));
}
let llret_ty = type_of::type_of(ccx, ret_ty);
- let simple = get_simple_intrinsic(ccx, &name);
- let llval = match (simple, &name[..]) {
+ let simple = get_simple_intrinsic(ccx, name);
+ let llval = match (simple, name) {
(Some(llfn), _) => {
Call(bcx, llfn, &llargs, call_debug_location)
}
}
(_, "type_name") => {
let tp_ty = substs.type_at(0);
- let ty_name = token::intern_and_get_ident(&tp_ty.to_string());
+ let ty_name = Symbol::intern(&tp_ty.to_string()).as_str();
C_str_slice(ccx, ty_name)
}
(_, "type_id") => {
let sty = &arg_tys[0].sty;
match int_type_width_signed(sty, ccx) {
Some((width, signed)) =>
- match &*name {
+ match name {
"ctlz" => count_zeros_intrinsic(bcx, &format!("llvm.ctlz.i{}", width),
llargs[0], call_debug_location),
"cttz" => count_zeros_intrinsic(bcx, &format!("llvm.cttz.i{}", width),
let sty = &arg_tys[0].sty;
match float_type_width(sty) {
Some(_width) =>
- match &*name {
+ match name {
"fadd_fast" => FAddFast(bcx, llargs[0], llargs[1], call_debug_location),
"fsub_fast" => FSubFast(bcx, llargs[0], llargs[1], call_debug_location),
"fmul_fast" => FMulFast(bcx, llargs[0], llargs[1], call_debug_location),
use type_::Type;
use rustc_data_structures::fx::FxHashMap;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use super::{MirContext, LocalRef};
use super::analyze::CleanupKind;
// Get the location information.
let loc = bcx.sess().codemap().lookup_char_pos(span.lo);
- let filename = token::intern_and_get_ident(&loc.file.name);
+ let filename = Symbol::intern(&loc.file.name).as_str();
let filename = C_str_slice(bcx.ccx(), filename);
let line = C_u32(bcx.ccx(), loc.line as u32);
const_err)
}
mir::AssertMessage::Math(ref err) => {
- let msg_str = token::intern_and_get_ident(err.description());
+ let msg_str = Symbol::intern(err.description()).as_str();
let msg_str = C_str_slice(bcx.ccx(), msg_str);
let msg_file_line = C_struct(bcx.ccx(),
&[msg_str, filename, line],
use type_of;
use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use std::cell::Ref;
use std::iter;
use std::collections::hash_map::DefaultHasher;
use symbol_map::SymbolMap;
use syntax::ast::NodeId;
-use syntax::parse::token::{self, InternedString};
+use syntax::symbol::{Symbol, InternedString};
use trans_item::TransItem;
use util::nodemap::{FxHashMap, FxHashSet};
// If the partitioning should produce a fixed count of codegen units, merge
// until that count is reached.
if let PartitioningStrategy::FixedUnitCount(count) = strategy {
- merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name[..]);
+ merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name.as_str());
debug_dump(scx, "POST MERGING:", initial_partitioning.codegen_units.iter());
}
let codegen_unit_name = match characteristic_def_id {
Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
- None => InternedString::new(FALLBACK_CODEGEN_UNIT),
+ None => Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str(),
};
let make_codegen_unit = || {
// always ensure we have at least one CGU; otherwise, if we have a
// crate with just types (for example), we could wind up with no CGU
if codegen_units.is_empty() {
- let codegen_unit_name = InternedString::new(FALLBACK_CODEGEN_UNIT);
+ let codegen_unit_name = Symbol::intern(FALLBACK_CODEGEN_UNIT).as_str();
codegen_units.entry(codegen_unit_name.clone())
.or_insert_with(|| CodegenUnit::empty(codegen_unit_name.clone()));
}
let mut mod_path = String::with_capacity(64);
let def_path = tcx.def_path(def_id);
- mod_path.push_str(&tcx.crate_name(def_path.krate));
+ mod_path.push_str(&tcx.crate_name(def_path.krate).as_str());
for part in tcx.def_path(def_id)
.data
mod_path.push_str(".volatile");
}
- return token::intern_and_get_ident(&mod_path[..]);
+ return Symbol::intern(&mod_path[..]).as_str();
}
fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
- token::intern_and_get_ident(&format!("{}{}{}",
- crate_name,
- NUMBERED_CODEGEN_UNIT_MARKER,
- index)[..])
+ Symbol::intern(&format!("{}{}{}", crate_name, NUMBERED_CODEGEN_UNIT_MARKER, index)).as_str()
}
fn debug_dump<'a, 'b, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
let attributes = tcx.get_attrs(def_id);
if let Some(name) = attr::first_attr_value_str_by_name(&attributes, "linkage") {
- if let Some(linkage) = base::llvm_linkage_by_name(&name) {
+ if let Some(linkage) = base::llvm_linkage_by_name(&name.as_str()) {
Some(linkage)
} else {
let span = tcx.map.span_if_local(def_id);
// some_crate::
if !(self.omit_local_crate_name && def_id.is_local()) {
- output.push_str(&self.tcx.crate_name(def_path.krate));
+ output.push_str(&self.tcx.crate_name(def_path.krate).as_str());
output.push_str("::");
}
use std::cell::RefCell;
use syntax::{abi, ast};
use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::parse::token::{self, keywords};
+use syntax::symbol::{Symbol, keywords};
use syntax_pos::{Span, Pos};
use errors::DiagnosticBuilder;
};
let output_binding = ConvertedBinding {
- item_name: token::intern(FN_OUTPUT_NAME),
+ item_name: Symbol::intern(FN_OUTPUT_NAME),
ty: output,
span: output_span
};
if bounds.len() > 1 {
let spans = bounds.iter().map(|b| {
self.tcx().associated_items(b.def_id()).find(|item| {
- item.kind == ty::AssociatedKind::Type && item.name.as_str() == assoc_name
+ item.kind == ty::AssociatedKind::Type && item.name == assoc_name
})
.and_then(|item| self.tcx().map.as_local_node_id(item.def_id))
.and_then(|node_id| self.tcx().map.opt_span(node_id))
use rustc::hir;
use syntax_pos::Span;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
#[derive(Copy, Clone, Debug)]
enum AutoderefKind {
let normalized = traits::normalize_projection_type(&mut selcx,
ty::ProjectionTy {
trait_ref: trait_ref,
- item_name: token::intern("Target"),
+ item_name: Symbol::intern("Target"),
},
cause,
0);
(PreferMutLvalue, Some(trait_did)) => {
self.lookup_method_in_trait(span,
base_expr,
- token::intern("deref_mut"),
+ Symbol::intern("deref_mut"),
trait_did,
base_ty,
None)
(None, Some(trait_did)) => {
self.lookup_method_in_trait(span,
base_expr,
- token::intern("deref"),
+ Symbol::intern("deref"),
trait_did,
base_ty,
None)
use hir::print;
use rustc::{infer, traits};
use rustc::ty::{self, LvaluePreference, Ty};
-use syntax::parse::token;
-use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc::hir;
pub fn check_call(&self,
call_expr: &'gcx hir::Expr,
callee_expr: &'gcx hir::Expr,
- arg_exprs: &'gcx [P<hir::Expr>],
+ arg_exprs: &'gcx [hir::Expr],
expected: Expectation<'tcx>)
-> Ty<'tcx> {
let original_callee_ty = self.check_expr(callee_expr);
-> Option<ty::MethodCallee<'tcx>> {
// Try the options that are least restrictive on the caller first.
for &(opt_trait_def_id, method_name) in
- &[(self.tcx.lang_items.fn_trait(), token::intern("call")),
- (self.tcx.lang_items.fn_mut_trait(), token::intern("call_mut")),
- (self.tcx.lang_items.fn_once_trait(), token::intern("call_once"))] {
+ &[(self.tcx.lang_items.fn_trait(), Symbol::intern("call")),
+ (self.tcx.lang_items.fn_mut_trait(), Symbol::intern("call_mut")),
+ (self.tcx.lang_items.fn_once_trait(), Symbol::intern("call_once"))] {
let trait_def_id = match opt_trait_def_id {
Some(def_id) => def_id,
None => continue,
fn confirm_builtin_call(&self,
call_expr: &hir::Expr,
callee_ty: Ty<'tcx>,
- arg_exprs: &'gcx [P<hir::Expr>],
+ arg_exprs: &'gcx [hir::Expr],
expected: Expectation<'tcx>)
-> Ty<'tcx> {
let error_fn_sig;
fn confirm_deferred_closure_call(&self,
call_expr: &hir::Expr,
- arg_exprs: &'gcx [P<hir::Expr>],
+ arg_exprs: &'gcx [hir::Expr],
expected: Expectation<'tcx>,
fn_sig: ty::FnSig<'tcx>)
-> Ty<'tcx> {
fn confirm_overloaded_call(&self,
call_expr: &hir::Expr,
callee_expr: &'gcx hir::Expr,
- arg_exprs: &'gcx [P<hir::Expr>],
+ arg_exprs: &'gcx [hir::Expr],
expected: Expectation<'tcx>,
method_callee: ty::MethodCallee<'tcx>)
-> Ty<'tcx> {
/// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
SizedUnsizedCast,
IllegalCast,
+ NeedDeref,
NeedViaPtr,
NeedViaThinPtr,
NeedViaInt,
fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
match e {
+ CastError::NeedDeref => {
+ let cast_ty = fcx.ty_to_string(self.cast_ty);
+ let mut err = fcx.type_error_struct(self.cast_span,
+ |actual| {
+ format!("casting `{}` as `{}` is invalid",
+ actual,
+ cast_ty)
+ },
+ self.expr_ty);
+ err.span_label(self.expr.span,
+ &format!("cannot cast `{}` as `{}`",
+ fcx.ty_to_string(self.expr_ty),
+ cast_ty));
+ if let Ok(snippet) = fcx.sess().codemap().span_to_snippet(self.expr.span) {
+ err.span_label(self.expr.span,
+ &format!("did you mean `*{}`?", snippet));
+ }
+ err.emit();
+ }
CastError::NeedViaThinPtr |
CastError::NeedViaPtr => {
let mut err = fcx.type_error_struct(self.span,
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
(Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
(FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
- (RPtr(_), Int(_)) |
- (RPtr(_), Float) => Err(CastError::NeedViaPtr),
+ (RPtr(p), Int(_)) |
+ (RPtr(p), Float) => {
+ match p.ty.sty {
+ ty::TypeVariants::TyInt(_) |
+ ty::TypeVariants::TyUint(_) |
+ ty::TypeVariants::TyFloat(_) => {
+ Err(CastError::NeedDeref)
+ }
+ ty::TypeVariants::TyInfer(t) => {
+ match t {
+ ty::InferTy::IntVar(_) |
+ ty::InferTy::FloatVar(_) |
+ ty::InferTy::FreshIntTy(_) |
+ ty::InferTy::FreshFloatTy(_) => {
+ Err(CastError::NeedDeref)
+ }
+ _ => Err(CastError::NeedViaPtr),
+ }
+ }
+ _ => Err(CastError::NeedViaPtr),
+ }
+ }
// * -> ptr
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
use syntax::abi::Abi;
use syntax::ast;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc::hir;
/// and in libcore/intrinsics.rs
pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
- let name = token::intern(&format!("P{}", n));
+ let name = Symbol::intern(&format!("P{}", n));
ccx.tcx.mk_param(n, name)
}
pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
it: &hir::ForeignItem) {
let param = |n| {
- let name = token::intern(&format!("P{}", n));
+ let name = Symbol::intern(&format!("P{}", n));
ccx.tcx.mk_param(n, name)
};
let def = pick.item.def();
if let probe::InherentImplPick = pick.kind {
if !pick.item.vis.is_accessible_from(self.body_id, &self.tcx.map) {
- let msg = format!("{} `{}` is private", def.kind_name(), &method_name.as_str());
+ let msg = format!("{} `{}` is private", def.kind_name(), method_name);
self.tcx.sess.span_err(span, &msg);
}
}
use CrateCtxt;
use TypeAndSubsts;
use lint;
-use util::common::{block_query, ErrorReported, indenter, loop_query};
+use util::common::{ErrorReported, indenter};
use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap};
use std::cell::{Cell, Ref, RefCell};
use syntax::attr;
use syntax::codemap::{self, original_sp, Spanned};
use syntax::feature_gate::{GateIssue, emit_feature_err};
-use syntax::parse::token::{self, InternedString, keywords};
use syntax::ptr::P;
+use syntax::symbol::{Symbol, InternedString, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{self, BytePos, Span};
}
}
+#[derive(Clone)]
+pub struct LoopCtxt<'gcx, 'tcx> {
+ unified: Ty<'tcx>,
+ coerce_to: Ty<'tcx>,
+ break_exprs: Vec<&'gcx hir::Expr>,
+ may_break: bool,
+}
+
+#[derive(Clone)]
+pub struct EnclosingLoops<'gcx, 'tcx> {
+ stack: Vec<LoopCtxt<'gcx, 'tcx>>,
+ by_id: NodeMap<usize>,
+}
+
+impl<'gcx, 'tcx> EnclosingLoops<'gcx, 'tcx> {
+ fn find_loop(&mut self, id: Option<ast::NodeId>) -> Option<&mut LoopCtxt<'gcx, 'tcx>> {
+ if let Some(id) = id {
+ if let Some(ix) = self.by_id.get(&id).cloned() {
+ Some(&mut self.stack[ix])
+ } else {
+ None
+ }
+ } else {
+ self.stack.last_mut()
+ }
+ }
+}
+
#[derive(Clone)]
pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
/// Whether any child nodes have any type errors.
has_errors: Cell<bool>,
+ enclosing_loops: RefCell<EnclosingLoops<'gcx, 'tcx>>,
+
inh: &'a Inherited<'a, 'gcx, 'tcx>,
}
if let Some(ref attr) = item.attrs.iter().find(|a| {
a.check_name("rustc_on_unimplemented")
}) {
- if let Some(ref istring) = attr.value_str() {
+ if let Some(istring) = attr.value_str() {
+ let istring = istring.as_str();
let parser = Parser::new(&istring);
let types = &generics.types;
for token in parser {
Position::ArgumentNamed(s) if s == "Self" => (),
// So is `{A}` if A is a type parameter
Position::ArgumentNamed(s) => match types.iter().find(|t| {
- t.name.as_str() == s
+ t.name == s
}) {
Some(_) => (),
None => {
ast::CRATE_NODE_ID)),
diverges: Cell::new(Diverges::Maybe),
has_errors: Cell::new(false),
+ enclosing_loops: RefCell::new(EnclosingLoops {
+ stack: Vec::new(),
+ by_id: NodeMap(),
+ }),
inh: inh,
}
}
(PreferMutLvalue, Some(trait_did)) => {
self.lookup_method_in_trait_adjusted(expr.span,
Some(&base_expr),
- token::intern("index_mut"),
+ Symbol::intern("index_mut"),
trait_did,
autoderefs,
unsize,
(None, Some(trait_did)) => {
self.lookup_method_in_trait_adjusted(expr.span,
Some(&base_expr),
- token::intern("index"),
+ Symbol::intern("index"),
trait_did,
autoderefs,
unsize,
sp: Span,
method_fn_ty: Ty<'tcx>,
callee_expr: &'gcx hir::Expr,
- args_no_rcvr: &'gcx [P<hir::Expr>],
+ args_no_rcvr: &'gcx [hir::Expr],
tuple_arguments: TupleArgumentsFlag,
expected: Expectation<'tcx>)
-> Ty<'tcx> {
sp: Span,
fn_inputs: &[Ty<'tcx>],
expected_arg_tys: &[Ty<'tcx>],
- args: &'gcx [P<hir::Expr>],
+ args: &'gcx [hir::Expr],
variadic: bool,
tuple_arguments: TupleArgumentsFlag) {
let tcx = self.tcx;
fn check_method_call(&self,
expr: &'gcx hir::Expr,
method_name: Spanned<ast::Name>,
- args: &'gcx [P<hir::Expr>],
+ args: &'gcx [hir::Expr],
tps: &[P<hir::Ty>],
expected: Expectation<'tcx>,
lvalue_pref: LvaluePreference) -> Ty<'tcx> {
fn suggest_field_name(variant: ty::VariantDef<'tcx>,
field: &Spanned<ast::Name>,
skip : Vec<InternedString>)
- -> Option<InternedString> {
+ -> Option<Symbol> {
let name = field.node.as_str();
let names = variant.fields.iter().filter_map(|field| {
// ignore already set fields and private fields from non-local crates
ty::TyAdt(adt, ..) if adt.is_enum() => {
struct_span_err!(self.tcx.sess, field.name.span, E0559,
"{} `{}::{}` has no field named `{}`",
- kind_name, actual, variant.name.as_str(), field.name.node)
+ kind_name, actual, variant.name, field.name.node)
}
_ => {
struct_span_err!(self.tcx.sess, field.name.span, E0560,
match ty.sty {
ty::TyAdt(adt, ..) if adt.is_enum() => {
err.span_label(field.name.span, &format!("`{}::{}` does not have this field",
- ty, variant.name.as_str()));
+ ty, variant.name));
}
_ => {
err.span_label(field.name.span, &format!("`{}` does not have this field", ty));
}
tcx.mk_nil()
}
- hir::ExprBreak(_) => { tcx.types.never }
+ hir::ExprBreak(ref label_opt, ref expr_opt) => {
+ let loop_id = if label_opt.is_some() {
+ let loop_def = tcx.expect_def(expr.id);
+ if let Def::Label(loop_id) = loop_def {
+ Some(Some(loop_id))
+ } else if loop_def == Def::Err {
+ // an error was already printed, so just ignore it
+ None
+ } else {
+ span_bug!(expr.span, "break label resolved to a non-label");
+ }
+ } else {
+ Some(None)
+ };
+ if let Some(loop_id) = loop_id {
+ let coerce_to = {
+ let mut enclosing_loops = self.enclosing_loops.borrow_mut();
+ enclosing_loops.find_loop(loop_id).map(|ctxt| ctxt.coerce_to)
+ };
+ if let Some(coerce_to) = coerce_to {
+ let e_ty;
+ let cause;
+ if let Some(ref e) = *expr_opt {
+ // Recurse without `enclosing_loops` borrowed.
+ e_ty = self.check_expr_with_hint(e, coerce_to);
+ cause = self.misc(e.span);
+ // Notably, the recursive call may alter coerce_to - must not keep using it!
+ } else {
+ // `break` without argument acts like `break ()`.
+ e_ty = tcx.mk_nil();
+ cause = self.misc(expr.span);
+ }
+ let mut enclosing_loops = self.enclosing_loops.borrow_mut();
+ let ctxt = enclosing_loops.find_loop(loop_id).unwrap();
+
+ let result = if let Some(ref e) = *expr_opt {
+ // Special-case the first element, as it has no "previous expressions".
+ let result = if !ctxt.may_break {
+ self.try_coerce(e, e_ty, ctxt.coerce_to)
+ } else {
+ self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(),
+ ctxt.unified, e, e_ty)
+ };
+
+ ctxt.break_exprs.push(e);
+ result
+ } else {
+ self.eq_types(true, &cause, e_ty, ctxt.unified)
+ .map(|InferOk { obligations, .. }| {
+ // FIXME(#32730) propagate obligations
+ assert!(obligations.is_empty());
+ e_ty
+ })
+ };
+ match result {
+ Ok(ty) => ctxt.unified = ty,
+ Err(err) => {
+ self.report_mismatched_types(&cause, ctxt.unified, e_ty, err);
+ }
+ }
+
+ ctxt.may_break = true;
+ }
+ // Otherwise, we failed to find the enclosing loop; this can only happen if the
+ // `break` was not inside a loop at all, which is caught by the loop-checking pass.
+ }
+ tcx.types.never
+ }
hir::ExprAgain(_) => { tcx.types.never }
hir::ExprRet(ref expr_opt) => {
if let Some(ref e) = *expr_opt {
expr.span, expected)
}
hir::ExprWhile(ref cond, ref body, _) => {
- self.check_expr_has_type(&cond, tcx.types.bool);
- let cond_diverging = self.diverges.get();
- self.check_block_no_value(&body);
+ let unified = self.tcx.mk_nil();
+ let coerce_to = unified;
+ let ctxt = LoopCtxt {
+ unified: unified,
+ coerce_to: coerce_to,
+ break_exprs: vec![],
+ may_break: true,
+ };
+ self.with_loop_ctxt(expr.id, ctxt, || {
+ self.check_expr_has_type(&cond, tcx.types.bool);
+ let cond_diverging = self.diverges.get();
+ self.check_block_no_value(&body);
- // We may never reach the body so it diverging means nothing.
- self.diverges.set(cond_diverging);
+ // We may never reach the body so it diverging means nothing.
+ self.diverges.set(cond_diverging);
+ });
if self.has_errors.get() {
tcx.types.err
tcx.mk_nil()
}
}
- hir::ExprLoop(ref body, _) => {
- self.check_block_no_value(&body);
- if may_break(tcx, expr.id, &body) {
+ hir::ExprLoop(ref body, _, _) => {
+ let unified = self.next_ty_var();
+ let coerce_to = expected.only_has_type(self).unwrap_or(unified);
+ let ctxt = LoopCtxt {
+ unified: unified,
+ coerce_to: coerce_to,
+ break_exprs: vec![],
+ may_break: false,
+ };
+
+ let ctxt = self.with_loop_ctxt(expr.id, ctxt, || {
+ self.check_block_no_value(&body);
+ });
+ if ctxt.may_break {
// No way to know whether it's diverging because
// of a `break` or an outer `break` or `return.
self.diverges.set(Diverges::Maybe);
- tcx.mk_nil()
+ ctxt.unified
} else {
tcx.types.never
}
self.check_block_with_expected(&b, expected)
}
hir::ExprCall(ref callee, ref args) => {
- self.check_call(expr, &callee, &args[..], expected)
+ self.check_call(expr, &callee, args, expected)
}
hir::ExprMethodCall(name, ref tps, ref args) => {
- self.check_method_call(expr, name, &args[..], &tps[..], expected, lvalue_pref)
+ self.check_method_call(expr, name, args, &tps[..], expected, lvalue_pref)
}
hir::ExprCast(ref e, ref t) => {
if let hir::TyArray(_, ref count_expr) = t.node {
let result = if i == 0 {
self.try_coerce(e, e_ty, coerce_to)
} else {
- let prev_elems = || args[..i].iter().map(|e| &**e);
+ let prev_elems = || args[..i].iter().map(|e| &*e);
self.try_find_coercion_lub(&cause, prev_elems, unified, e, e_ty)
};
self.tcx.types.err
})
}
-}
-// Returns true if b contains a break that can exit from b
-pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool {
- // First: is there an unlabeled break immediately
- // inside the loop?
- (loop_query(&b, |e| {
- match *e {
- hir::ExprBreak(None) => true,
- _ => false
+ fn with_loop_ctxt<F: FnOnce()>(&self, id: ast::NodeId, ctxt: LoopCtxt<'gcx, 'tcx>, f: F)
+ -> LoopCtxt<'gcx, 'tcx> {
+ let index;
+ {
+ let mut enclosing_loops = self.enclosing_loops.borrow_mut();
+ index = enclosing_loops.stack.len();
+ enclosing_loops.by_id.insert(id, index);
+ enclosing_loops.stack.push(ctxt);
}
- })) ||
- // Second: is there a labeled break with label
- // <id> nested anywhere inside the loop?
- (block_query(b, |e| {
- if let hir::ExprBreak(Some(_)) = e.node {
- tcx.expect_def(e.id) == Def::Label(id)
- } else {
- false
+ f();
+ {
+ let mut enclosing_loops = self.enclosing_loops.borrow_mut();
+ debug_assert!(enclosing_loops.stack.len() == index + 1);
+ enclosing_loops.by_id.remove(&id).expect("missing loop context");
+ (enclosing_loops.stack.pop().expect("missing loop context"))
}
- }))
+ }
}
pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
use hir::def_id::DefId;
use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue};
use syntax::ast;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use rustc::hir;
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let rhs_ty_var = self.next_ty_var();
let return_ty = match self.lookup_op_method(expr, lhs_ty, vec![rhs_ty_var],
- token::intern(name), trait_def_id,
+ Symbol::intern(name), trait_def_id,
lhs_expr) {
Ok(return_ty) => return_ty,
Err(()) => {
-> Ty<'tcx>
{
assert!(op.is_by_value());
- match self.lookup_op_method(ex, operand_ty, vec![],
- token::intern(mname), trait_did,
- operand_expr) {
+ let mname = Symbol::intern(mname);
+ match self.lookup_op_method(ex, operand_ty, vec![], mname, trait_did, operand_expr) {
Ok(t) => t,
Err(()) => {
self.type_error_message(ex.span, |actual| {
hir::ExprCall(ref callee, ref args) => {
if has_method_map {
self.constrain_call(expr, Some(&callee),
- args.iter().map(|e| &**e), false);
+ args.iter().map(|e| &*e), false);
} else {
self.constrain_callee(callee.id, expr, &callee);
self.constrain_call(expr, None,
- args.iter().map(|e| &**e), false);
+ args.iter().map(|e| &*e), false);
}
intravisit::walk_expr(self, expr);
hir::ExprMethodCall(.., ref args) => {
self.constrain_call(expr, Some(&args[0]),
- args[1..].iter().map(|e| &**e), false);
+ args[1..].iter().map(|e| &*e), false);
intravisit::walk_expr(self, expr);
}
self.check_expr_fn_block(expr, &body);
}
- hir::ExprLoop(ref body, _) => {
+ hir::ExprLoop(ref body, _, _) => {
let repeating_scope = self.set_repeating_scope(body.id);
intravisit::walk_expr(self, expr);
self.set_repeating_scope(repeating_scope);
use std::cell::RefCell;
use syntax::{abi, ast, attr};
-use syntax::parse::token::{self, keywords};
+use syntax::symbol::{Symbol, keywords};
use syntax_pos::Span;
use rustc::hir::{self, map as hir_map, print as pprust};
let upvar_decls : Vec<_> = tcx.with_freevars(node_id, |fv| {
fv.iter().enumerate().map(|(i, _)| ty::TypeParameterDef {
index: (base_generics.count() as u32) + (i as u32),
- name: token::intern("<upvar>"),
+ name: Symbol::intern("<upvar>"),
def_id: def_id,
default_def_id: base_def_id,
default: None,
use syntax::ast;
use syntax::attr;
use syntax::codemap::Spanned;
-use syntax::parse::token::keywords;
use syntax::ptr::P;
use syntax::print::pprust as syntax_pprust;
+use syntax::symbol::keywords;
use syntax_pos::{self, DUMMY_SP, Pos};
use rustc_trans::back::link;
}
});
ExternalCrate {
- name: (&cx.sess().cstore.crate_name(self.0)[..]).to_owned(),
+ name: cx.sess().cstore.crate_name(self.0).to_string(),
attrs: cx.sess().cstore.item_attrs(root).clean(cx),
primitives: primitives,
}
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
- &a.name()[..] == "doc" && match a.meta_item_list() {
+ a.name() == "doc" && match a.meta_item_list() {
Some(l) => attr::list_contains_name(l, "no_inline") ||
attr::list_contains_name(l, "hidden"),
None => false,
os_imp::current_exe()
}
-/// An iterator over the arguments of a process, yielding a `String` value
+/// An iterator over the arguments of a process, yielding a [`String`] value
/// for each argument.
///
-/// This structure is created through the `std::env::args` method.
+/// This structure is created through the [`std::env::args`] method.
+///
+/// [`String`]: ../string/struct.String.html
+/// [`std::env::args`]: ./fn.args.html
#[stable(feature = "env", since = "1.0.0")]
pub struct Args { inner: ArgsOs }
-/// An iterator over the arguments of a process, yielding an `OsString` value
+/// An iterator over the arguments of a process, yielding an [`OsString`] value
/// for each argument.
///
-/// This structure is created through the `std::env::args_os` method.
+/// This structure is created through the [`std::env::args_os`] method.
+///
+/// [`OsString`]: ../ffi/struct.OsString.html
+/// [`std::env::args_os`]: ./fn.args_os.html
#[stable(feature = "env", since = "1.0.0")]
pub struct ArgsOs { inner: sys::args::Args }
///
/// The returned iterator will panic during iteration if any argument to the
/// process is not valid unicode. If this is not desired,
-/// use the `args_os` function instead.
+/// use the [`args_os`] function instead.
///
/// # Examples
///
/// println!("{}", argument);
/// }
/// ```
+///
+/// [`args_os`]: ./fn.args_os.html
#[stable(feature = "env", since = "1.0.0")]
pub fn args() -> Args {
Args { inner: args_os() }
inner: self.inner.duplicate()?
})
}
+
+ /// Changes the permissions on the underlying file.
+ ///
+ /// # Platform-specific behavior
+ ///
+ /// This function currently corresponds to the `fchmod` function on Unix and
+ /// the `SetFileInformationByHandle` function on Windows. Note that, this
+ /// [may change in the future][changes].
+ ///
+ /// [changes]: ../io/index.html#platform-specific-behavior
+ ///
+ /// # Errors
+ ///
+ /// This function will return an error if the user lacks permission change
+ /// attributes on the underlying file. It may also return an error in other
+ /// os-specific unspecified cases.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(set_permissions_atomic)]
+ /// # fn foo() -> std::io::Result<()> {
+ /// use std::fs::File;
+ ///
+ /// let file = File::open("foo.txt")?;
+ /// let mut perms = file.metadata()?.permissions();
+ /// perms.set_readonly(true);
+ /// file.set_permissions(perms)?;
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[unstable(feature = "set_permissions_atomic", issue="37916")]
+ pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
+ self.inner.set_permissions(perm.0)
+ }
}
impl AsInner<fs_imp::File> for File {
check!(fs::set_permissions(&file, p));
}
+ #[test]
+ fn fchmod_works() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("in.txt");
+
+ let file = check!(File::create(&path));
+ let attr = check!(fs::metadata(&path));
+ assert!(!attr.permissions().readonly());
+ let mut p = attr.permissions();
+ p.set_readonly(true);
+ check!(file.set_permissions(p.clone()));
+ let attr = check!(fs::metadata(&path));
+ assert!(attr.permissions().readonly());
+
+ p.set_readonly(false);
+ check!(file.set_permissions(p));
+ }
+
#[test]
fn sync_doesnt_kill_anything() {
let tmpdir = tmpdir();
impl SocketAddrV4 {
/// Creates a new socket address from the (ip, port) pair.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{SocketAddrV4, Ipv4Addr};
+ ///
+ /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
SocketAddrV4 {
}
/// Returns the IP address associated with this socket address.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{SocketAddrV4, Ipv4Addr};
+ ///
+ /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ip(&self) -> &Ipv4Addr {
unsafe {
}
/// Change the IP address associated with this socket address.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{SocketAddrV4, Ipv4Addr};
+ ///
+ /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
+ /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
+ /// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
self.inner.sin_addr = *new_ip.as_inner()
}
/// Returns the port number associated with this socket address.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{SocketAddrV4, Ipv4Addr};
+ ///
+ /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ /// assert_eq!(socket.port(), 8080);
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 {
ntoh(self.inner.sin_port)
}
/// Change the port number associated with this socket address.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{SocketAddrV4, Ipv4Addr};
+ ///
+ /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+ /// socket.set_port(4242);
+ /// assert_eq!(socket.port(), 4242);
+ /// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) {
self.inner.sin_port = hton(new_port);
pub fn fd(&self) -> &FileDesc { &self.0 }
pub fn into_fd(self) -> FileDesc { self.0 }
+
+ pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
+ cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
+ Ok(())
+ }
}
impl DirBuilder {
pub const ERROR_NO_MORE_FILES: DWORD = 18;
pub const ERROR_HANDLE_EOF: DWORD = 38;
pub const ERROR_FILE_EXISTS: DWORD = 80;
+pub const ERROR_INVALID_PARAMETER: DWORD = 87;
pub const ERROR_BROKEN_PIPE: DWORD = 109;
pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
MaximumFileInfoByHandlesClass
}
+#[repr(C)]
+pub struct FILE_BASIC_INFO {
+ pub CreationTime: LARGE_INTEGER,
+ pub LastAccessTime: LARGE_INTEGER,
+ pub LastWriteTime: LARGE_INTEGER,
+ pub ChangeTime: LARGE_INTEGER,
+ pub FileAttributes: DWORD,
+}
+
#[repr(C)]
pub struct FILE_END_OF_FILE_INFO {
pub EndOfFile: LARGE_INTEGER,
Ok(PathBuf::from(OsString::from_wide(subst)))
}
}
+
+ pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
+ let mut info = c::FILE_BASIC_INFO {
+ CreationTime: 0,
+ LastAccessTime: 0,
+ LastWriteTime: 0,
+ ChangeTime: 0,
+ FileAttributes: perm.attrs,
+ };
+ let size = mem::size_of_val(&info);
+ cvt(unsafe {
+ c::SetFileInformationByHandle(self.handle.raw(),
+ c::FileBasicInfo,
+ &mut info as *mut _ as *mut _,
+ size as c::DWORD)
+ })?;
+ Ok(())
+ }
}
impl FromInner<c::HANDLE> for File {
let reader;
let mut name;
let mut tries = 0;
+ let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
loop {
tries += 1;
let key: u64 = rand::thread_rng().gen();
let handle = c::CreateNamedPipeW(wide_name.as_ptr(),
c::PIPE_ACCESS_INBOUND |
- c::FILE_FLAG_FIRST_PIPE_INSTANCE |
- c::FILE_FLAG_OVERLAPPED,
+ c::FILE_FLAG_FIRST_PIPE_INSTANCE |
+ c::FILE_FLAG_OVERLAPPED,
c::PIPE_TYPE_BYTE |
- c::PIPE_READMODE_BYTE |
- c::PIPE_WAIT |
- c::PIPE_REJECT_REMOTE_CLIENTS,
+ c::PIPE_READMODE_BYTE |
+ c::PIPE_WAIT |
+ reject_remote_clients_flag,
1,
4096,
4096,
//
// Don't try again too much though as this could also perhaps be a
// legit error.
+ // If ERROR_INVALID_PARAMETER is returned, this probably means we're
+ // running on pre-Vista version where PIPE_REJECT_REMOTE_CLIENTS is
+ // not supported, so we continue retrying without it. This implies
+ // reduced security on Windows versions older than Vista by allowing
+ // connections to this pipe from remote machines.
+ // Proper fix would increase the number of FFI imports and introduce
+ // significant amount of Windows XP specific code with no clean
+ // testing strategy
+ // for more info see https://github.com/rust-lang/rust/pull/37677
if handle == c::INVALID_HANDLE_VALUE {
let err = io::Error::last_os_error();
- if tries < 10 &&
- err.raw_os_error() == Some(c::ERROR_ACCESS_DENIED as i32) {
- continue
+ let raw_os_err = err.raw_os_error();
+ if tries < 10 {
+ if raw_os_err == Some(c::ERROR_ACCESS_DENIED as i32) {
+ continue
+ } else if reject_remote_clients_flag != 0 &&
+ raw_os_err == Some(c::ERROR_INVALID_PARAMETER as i32) {
+ reject_remote_clients_flag = 0;
+ tries -= 1;
+ continue
+ }
}
return Err(err)
}
pub use self::UnsafeSource::*;
pub use self::ViewPath_::*;
pub use self::PathParameters::*;
+pub use symbol::Symbol as Name;
pub use util::ThinVec;
use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
use codemap::{respan, Spanned};
use abi::Abi;
use ext::hygiene::SyntaxContext;
-use parse::token::{self, keywords, InternedString};
use print::pprust;
use ptr::P;
+use symbol::{Symbol, keywords};
use tokenstream::{TokenTree};
+use std::collections::HashSet;
use std::fmt;
use std::rc::Rc;
use std::u32;
use serialize::{self, Encodable, Decodable, Encoder, Decoder};
-/// A name is a part of an identifier, representing a string or gensym. It's
-/// the result of interning.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Name(pub u32);
-
/// An identifier contains a Name (index into the interner
/// table) and a SyntaxContext to track renaming and
/// macro expansion per Flatt et al., "Macros That Work Together"
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Ident {
- pub name: Name,
+ pub name: Symbol,
pub ctxt: SyntaxContext
}
-impl Name {
- pub fn as_str(self) -> token::InternedString {
- token::InternedString::new_from_name(self)
- }
-}
-
-impl fmt::Debug for Name {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}({})", self, self.0)
- }
-}
-
-impl fmt::Display for Name {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.as_str(), f)
- }
-}
-
-impl Encodable for Name {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- s.emit_str(&self.as_str())
- }
-}
-
-impl Decodable for Name {
- fn decode<D: Decoder>(d: &mut D) -> Result<Name, D::Error> {
- Ok(token::intern(&d.read_str()?))
- }
-}
-
impl Ident {
pub const fn with_empty_ctxt(name: Name) -> Ident {
Ident { name: name, ctxt: SyntaxContext::empty() }
}
+
+ /// Maps a string to an identifier with an empty syntax context.
+ pub fn from_str(s: &str) -> Ident {
+ Ident::with_empty_ctxt(Symbol::intern(s))
+ }
}
impl fmt::Debug for Ident {
}
pub fn span_for_name(&self, name: &str) -> Option<Span> {
for t in &self.ty_params {
- if t.ident.name.as_str() == name {
+ if t.ident.name == name {
return Some(t.span);
}
}
/// The set of MetaItems that define the compilation environment of the crate,
/// used to drive conditional compilation
-pub type CrateConfig = Vec<P<MetaItem>>;
+pub type CrateConfig = HashSet<(Name, Option<Symbol>)>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Crate {
#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialEq)]
pub enum NestedMetaItemKind {
/// A full MetaItem, for recursive meta items.
- MetaItem(P<MetaItem>),
+ MetaItem(MetaItem),
/// A literal.
///
/// E.g. "foo", 64, true
/// A spanned compile-time attribute item.
///
/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-pub type MetaItem = Spanned<MetaItemKind>;
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct MetaItem {
+ pub name: Name,
+ pub node: MetaItemKind,
+ pub span: Span,
+}
/// A compile-time attribute item.
///
/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MetaItemKind {
/// Word meta item.
///
/// E.g. `test` as in `#[test]`
- Word(InternedString),
+ Word,
/// List meta item.
///
/// E.g. `derive(..)` as in `#[derive(..)]`
- List(InternedString, Vec<NestedMetaItem>),
+ List(Vec<NestedMetaItem>),
/// Name value meta item.
///
/// E.g. `feature = "foo"` as in `#[feature = "foo"]`
- NameValue(InternedString, Lit),
-}
-
-// can't be derived because the MetaItemKind::List requires an unordered comparison
-impl PartialEq for MetaItemKind {
- fn eq(&self, other: &MetaItemKind) -> bool {
- use self::MetaItemKind::*;
- match *self {
- Word(ref ns) => match *other {
- Word(ref no) => (*ns) == (*no),
- _ => false
- },
- List(ref ns, ref miss) => match *other {
- List(ref no, ref miso) => {
- ns == no &&
- miss.iter().all(|mi| {
- miso.iter().any(|x| x.node == mi.node)
- })
- }
- _ => false
- },
- NameValue(ref ns, ref vs) => match *other {
- NameValue(ref no, ref vo) => {
- (*ns) == (*no) && vs.node == vo.node
- }
- _ => false
- },
- }
- }
+ NameValue(Lit)
}
/// A Block (`{ .. }`).
/// A referencing operation (`&a` or `&mut a`)
AddrOf(Mutability, P<Expr>),
- /// A `break`, with an optional label to break
- Break(Option<SpannedIdent>),
+ /// A `break`, with an optional label to break, and an optional expression
+ Break(Option<SpannedIdent>, Option<P<Expr>>),
/// A `continue`, with an optional label
Continue(Option<SpannedIdent>),
/// A `return`, with an optional value to be returned
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum LitKind {
/// A string literal (`"foo"`)
- Str(InternedString, StrStyle),
+ Str(Symbol, StrStyle),
/// A byte string (`b"foo"`)
ByteStr(Rc<Vec<u8>>),
/// A byte char (`b'f'`)
/// An integer literal (`1`)
Int(u64, LitIntType),
/// A float literal (`1f64` or `1E10f64`)
- Float(InternedString, FloatTy),
+ Float(Symbol, FloatTy),
/// A float literal without a suffix (`1.0 or 1.0E10`)
- FloatUnsuffixed(InternedString),
+ FloatUnsuffixed(Symbol),
/// A boolean literal
Bool(bool),
}
/// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsmOutput {
- pub constraint: InternedString,
+ pub constraint: Symbol,
pub expr: P<Expr>,
pub is_rw: bool,
pub is_indirect: bool,
/// E.g. `asm!("NOP");`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsm {
- pub asm: InternedString,
+ pub asm: Symbol,
pub asm_str_style: StrStyle,
pub outputs: Vec<InlineAsmOutput>,
- pub inputs: Vec<(InternedString, P<Expr>)>,
- pub clobbers: Vec<InternedString>,
+ pub inputs: Vec<(Symbol, P<Expr>)>,
+ pub clobbers: Vec<Symbol>,
pub volatile: bool,
pub alignstack: bool,
pub dialect: AsmDialect,
}
}
-/// Meta-data associated with an item
-pub type Attribute = Spanned<Attribute_>;
/// Distinguishes between Attributes that decorate items and Attributes that
/// are contained as statements within items. These two cases need to be
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub struct AttrId(pub usize);
+/// Meta-data associated with an item
/// Doc-comments are promoted to attributes that have is_sugared_doc = true
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Attribute_ {
+pub struct Attribute {
pub id: AttrId,
pub style: AttrStyle,
- pub value: P<MetaItem>,
+ pub value: MetaItem,
pub is_sugared_doc: bool,
+ pub span: Span,
}
/// TraitRef's appear in impls.
pub use self::IntType::*;
use ast;
-use ast::{AttrId, Attribute, Attribute_};
+use ast::{AttrId, Attribute, Name};
use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
use ast::{Lit, Expr, Item, Local, Stmt, StmtKind};
-use codemap::{respan, spanned, dummy_spanned};
+use codemap::{spanned, dummy_spanned, mk_sp};
use syntax_pos::{Span, BytePos, DUMMY_SP};
use errors::Handler;
use feature_gate::{Features, GatedCfg};
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use parse::token::InternedString;
-use parse::{ParseSess, token};
+use parse::ParseSess;
use ptr::P;
+use symbol::Symbol;
use util::ThinVec;
use std::cell::{RefCell, Cell};
}
enum AttrError {
- MultipleItem(InternedString),
- UnknownMetaItem(InternedString),
+ MultipleItem(Name),
+ UnknownMetaItem(Name),
MissingSince,
MissingFeature,
MultipleStabilityLevels,
pub fn mark_used(attr: &Attribute) {
debug!("Marking {:?} as used.", attr);
- let AttrId(id) = attr.node.id;
+ let AttrId(id) = attr.id;
USED_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
}
pub fn is_used(attr: &Attribute) -> bool {
- let AttrId(id) = attr.node.id;
+ let AttrId(id) = attr.id;
USED_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
pub fn mark_known(attr: &Attribute) {
debug!("Marking {:?} as known.", attr);
- let AttrId(id) = attr.node.id;
+ let AttrId(id) = attr.id;
KNOWN_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
}
pub fn is_known(attr: &Attribute) -> bool {
- let AttrId(id) = attr.node.id;
+ let AttrId(id) = attr.id;
KNOWN_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
impl NestedMetaItem {
/// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
- pub fn meta_item(&self) -> Option<&P<MetaItem>> {
+ pub fn meta_item(&self) -> Option<&MetaItem> {
match self.node {
NestedMetaItemKind::MetaItem(ref item) => Some(&item),
_ => None
/// Returns the name of the meta item, e.g. `foo` in `#[foo]`,
/// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
- pub fn name(&self) -> Option<InternedString> {
+ pub fn name(&self) -> Option<Name> {
self.meta_item().and_then(|meta_item| Some(meta_item.name()))
}
/// Gets the string value if self is a MetaItem and the MetaItem is a
/// MetaItemKind::NameValue variant containing a string, otherwise None.
- pub fn value_str(&self) -> Option<InternedString> {
+ pub fn value_str(&self) -> Option<Symbol> {
self.meta_item().and_then(|meta_item| meta_item.value_str())
}
/// Returns a MetaItem if self is a MetaItem with Kind Word.
- pub fn word(&self) -> Option<&P<MetaItem>> {
+ pub fn word(&self) -> Option<&MetaItem> {
self.meta_item().and_then(|meta_item| if meta_item.is_word() {
Some(meta_item)
} else {
impl Attribute {
pub fn check_name(&self, name: &str) -> bool {
- let matches = name == &self.name()[..];
+ let matches = self.name() == name;
if matches {
mark_used(self);
}
matches
}
- pub fn name(&self) -> InternedString { self.meta().name() }
+ pub fn name(&self) -> Name { self.meta().name() }
- pub fn value_str(&self) -> Option<InternedString> {
+ pub fn value_str(&self) -> Option<Symbol> {
self.meta().value_str()
}
}
impl MetaItem {
- pub fn name(&self) -> InternedString {
- match self.node {
- MetaItemKind::Word(ref n) => (*n).clone(),
- MetaItemKind::NameValue(ref n, _) => (*n).clone(),
- MetaItemKind::List(ref n, _) => (*n).clone(),
- }
+ pub fn name(&self) -> Name {
+ self.name
}
- pub fn value_str(&self) -> Option<InternedString> {
+ pub fn value_str(&self) -> Option<Symbol> {
match self.node {
- MetaItemKind::NameValue(_, ref v) => {
+ MetaItemKind::NameValue(ref v) => {
match v.node {
ast::LitKind::Str(ref s, _) => Some((*s).clone()),
_ => None,
pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
match self.node {
- MetaItemKind::List(_, ref l) => Some(&l[..]),
+ MetaItemKind::List(ref l) => Some(&l[..]),
_ => None
}
}
pub fn is_word(&self) -> bool {
match self.node {
- MetaItemKind::Word(_) => true,
+ MetaItemKind::Word => true,
_ => false,
}
}
pub fn span(&self) -> Span { self.span }
pub fn check_name(&self, name: &str) -> bool {
- name == &self.name()[..]
+ self.name() == name
}
pub fn is_value_str(&self) -> bool {
impl Attribute {
/// Extract the MetaItem from inside this Attribute.
pub fn meta(&self) -> &MetaItem {
- &self.node.value
+ &self.value
}
/// Convert self to a normal #[doc="foo"] comment, if it is a
pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
F: FnOnce(&Attribute) -> T,
{
- if self.node.is_sugared_doc {
+ if self.is_sugared_doc {
let comment = self.value_str().unwrap();
let meta = mk_name_value_item_str(
- InternedString::new("doc"),
- token::intern_and_get_ident(&strip_doc_comment_decoration(
- &comment)));
- if self.node.style == ast::AttrStyle::Outer {
- f(&mk_attr_outer(self.node.id, meta))
+ Symbol::intern("doc"),
+ Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())));
+ if self.style == ast::AttrStyle::Outer {
+ f(&mk_attr_outer(self.id, meta))
} else {
- f(&mk_attr_inner(self.node.id, meta))
+ f(&mk_attr_inner(self.id, meta))
}
} else {
f(self)
/* Constructors */
-pub fn mk_name_value_item_str(name: InternedString, value: InternedString)
- -> P<MetaItem> {
+pub fn mk_name_value_item_str(name: Name, value: Symbol) -> MetaItem {
let value_lit = dummy_spanned(ast::LitKind::Str(value, ast::StrStyle::Cooked));
mk_spanned_name_value_item(DUMMY_SP, name, value_lit)
}
-pub fn mk_name_value_item(name: InternedString, value: ast::Lit)
- -> P<MetaItem> {
+pub fn mk_name_value_item(name: Name, value: ast::Lit) -> MetaItem {
mk_spanned_name_value_item(DUMMY_SP, name, value)
}
-pub fn mk_list_item(name: InternedString, items: Vec<NestedMetaItem>) -> P<MetaItem> {
+pub fn mk_list_item(name: Name, items: Vec<NestedMetaItem>) -> MetaItem {
mk_spanned_list_item(DUMMY_SP, name, items)
}
-pub fn mk_list_word_item(name: InternedString) -> ast::NestedMetaItem {
+pub fn mk_list_word_item(name: Name) -> ast::NestedMetaItem {
dummy_spanned(NestedMetaItemKind::MetaItem(mk_spanned_word_item(DUMMY_SP, name)))
}
-pub fn mk_word_item(name: InternedString) -> P<MetaItem> {
+pub fn mk_word_item(name: Name) -> MetaItem {
mk_spanned_word_item(DUMMY_SP, name)
}
-pub fn mk_spanned_name_value_item(sp: Span, name: InternedString, value: ast::Lit)
- -> P<MetaItem> {
- P(respan(sp, MetaItemKind::NameValue(name, value)))
+pub fn mk_spanned_name_value_item(sp: Span, name: Name, value: ast::Lit) -> MetaItem {
+ MetaItem { span: sp, name: name, node: MetaItemKind::NameValue(value) }
}
-pub fn mk_spanned_list_item(sp: Span, name: InternedString, items: Vec<NestedMetaItem>)
- -> P<MetaItem> {
- P(respan(sp, MetaItemKind::List(name, items)))
+pub fn mk_spanned_list_item(sp: Span, name: Name, items: Vec<NestedMetaItem>) -> MetaItem {
+ MetaItem { span: sp, name: name, node: MetaItemKind::List(items) }
}
-pub fn mk_spanned_word_item(sp: Span, name: InternedString) -> P<MetaItem> {
- P(respan(sp, MetaItemKind::Word(name)))
+pub fn mk_spanned_word_item(sp: Span, name: Name) -> MetaItem {
+ MetaItem { span: sp, name: name, node: MetaItemKind::Word }
}
}
/// Returns an inner attribute with the given value.
-pub fn mk_attr_inner(id: AttrId, item: P<MetaItem>) -> Attribute {
+pub fn mk_attr_inner(id: AttrId, item: MetaItem) -> Attribute {
mk_spanned_attr_inner(DUMMY_SP, id, item)
}
/// Returns an innter attribute with the given value and span.
-pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: P<MetaItem>) -> Attribute {
- respan(sp,
- Attribute_ {
- id: id,
- style: ast::AttrStyle::Inner,
- value: item,
- is_sugared_doc: false,
- })
+pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
+ Attribute {
+ id: id,
+ style: ast::AttrStyle::Inner,
+ value: item,
+ is_sugared_doc: false,
+ span: sp,
+ }
}
/// Returns an outer attribute with the given value.
-pub fn mk_attr_outer(id: AttrId, item: P<MetaItem>) -> Attribute {
+pub fn mk_attr_outer(id: AttrId, item: MetaItem) -> Attribute {
mk_spanned_attr_outer(DUMMY_SP, id, item)
}
/// Returns an outer attribute with the given value and span.
-pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: P<MetaItem>) -> Attribute {
- respan(sp,
- Attribute_ {
- id: id,
- style: ast::AttrStyle::Outer,
- value: item,
- is_sugared_doc: false,
- })
+pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
+ Attribute {
+ id: id,
+ style: ast::AttrStyle::Outer,
+ value: item,
+ is_sugared_doc: false,
+ span: sp,
+ }
}
-pub fn mk_doc_attr_outer(id: AttrId, item: P<MetaItem>, is_sugared_doc: bool) -> Attribute {
- dummy_spanned(Attribute_ {
+pub fn mk_doc_attr_outer(id: AttrId, item: MetaItem, is_sugared_doc: bool) -> Attribute {
+ Attribute {
id: id,
style: ast::AttrStyle::Outer,
value: item,
is_sugared_doc: is_sugared_doc,
- })
+ span: DUMMY_SP,
+ }
}
-pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
- hi: BytePos)
+pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, lo: BytePos, hi: BytePos)
-> Attribute {
- let style = doc_comment_style(&text);
+ let style = doc_comment_style(&text.as_str());
let lit = spanned(lo, hi, ast::LitKind::Str(text, ast::StrStyle::Cooked));
- let attr = Attribute_ {
+ Attribute {
id: id,
style: style,
- value: P(spanned(lo, hi, MetaItemKind::NameValue(InternedString::new("doc"), lit))),
- is_sugared_doc: true
- };
- spanned(lo, hi, attr)
-}
-
-/* Searching */
-/// Check if `needle` occurs in `haystack` by a structural
-/// comparison. This is slightly subtle, and relies on ignoring the
-/// span included in the `==` comparison a plain MetaItem.
-pub fn contains(haystack: &[P<MetaItem>], needle: &MetaItem) -> bool {
- debug!("attr::contains (name={})", needle.name());
- haystack.iter().any(|item| {
- debug!(" testing: {}", item.name());
- item.node == needle.node
- })
+ value: MetaItem {
+ span: mk_sp(lo, hi),
+ name: Symbol::intern("doc"),
+ node: MetaItemKind::NameValue(lit),
+ },
+ is_sugared_doc: true,
+ span: mk_sp(lo, hi),
+ }
}
pub fn list_contains_name(items: &[NestedMetaItem], name: &str) -> bool {
})
}
-pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str)
- -> Option<InternedString> {
+pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) -> Option<Symbol> {
attrs.iter()
.find(|at| at.check_name(name))
.and_then(|at| at.value_str())
}
-pub fn last_meta_item_value_str_by_name(items: &[P<MetaItem>], name: &str)
- -> Option<InternedString> {
+pub fn last_meta_item_value_str_by_name(items: &[MetaItem], name: &str) -> Option<Symbol> {
items.iter()
.rev()
.find(|mi| mi.check_name(name))
/* Higher-level applications */
-pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
first_attr_value_str_by_name(attrs, "crate_name")
}
/// Find the value of #[export_name=*] attribute and check its validity.
-pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<InternedString> {
+pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Symbol> {
attrs.iter().fold(None, |ia,attr| {
if attr.check_name("export_name") {
if let s@Some(_) = attr.value_str() {
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub fn find_inline_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> InlineAttr {
- attrs.iter().fold(InlineAttr::None, |ia,attr| {
- match attr.node.value.node {
- MetaItemKind::Word(ref n) if n == "inline" => {
+ attrs.iter().fold(InlineAttr::None, |ia, attr| {
+ match attr.value.node {
+ _ if attr.value.name != "inline" => ia,
+ MetaItemKind::Word => {
mark_used(attr);
InlineAttr::Hint
}
- MetaItemKind::List(ref n, ref items) if n == "inline" => {
+ MetaItemKind::List(ref items) => {
mark_used(attr);
if items.len() != 1 {
diagnostic.map(|d|{ span_err!(d, attr.span, E0534, "expected one argument"); });
/// Tests if a cfg-pattern matches the cfg set
pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
match cfg.node {
- ast::MetaItemKind::List(ref pred, ref mis) => {
+ ast::MetaItemKind::List(ref mis) => {
for mi in mis.iter() {
if !mi.is_meta_item() {
handle_errors(&sess.span_diagnostic, mi.span, AttrError::UnsupportedLiteral);
// The unwraps below may look dangerous, but we've already asserted
// that they won't fail with the loop above.
- match &pred[..] {
+ match &*cfg.name.as_str() {
"any" => mis.iter().any(|mi| {
cfg_matches(mi.meta_item().unwrap(), sess, features)
}),
}
}
},
- ast::MetaItemKind::Word(_) | ast::MetaItemKind::NameValue(..) => {
+ ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
gated_cfg.check_and_emit(sess, feats);
}
- contains(&sess.config, cfg)
+ sess.config.contains(&(cfg.name(), cfg.value_str()))
}
}
}
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Stability {
pub level: StabilityLevel,
- pub feature: InternedString,
+ pub feature: Symbol,
pub rustc_depr: Option<RustcDeprecation>,
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
pub enum StabilityLevel {
// Reason for the current stability level and the relevant rust-lang issue
- Unstable { reason: Option<InternedString>, issue: u32 },
- Stable { since: InternedString },
+ Unstable { reason: Option<Symbol>, issue: u32 },
+ Stable { since: Symbol },
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
pub struct RustcDeprecation {
- pub since: InternedString,
- pub reason: InternedString,
+ pub since: Symbol,
+ pub reason: Symbol,
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
pub struct Deprecation {
- pub since: Option<InternedString>,
- pub note: Option<InternedString>,
+ pub since: Option<Symbol>,
+ pub note: Option<Symbol>,
}
impl StabilityLevel {
'outer: for attr in attrs_iter {
let tag = attr.name();
- let tag = &*tag;
if tag != "rustc_deprecated" && tag != "unstable" && tag != "stable" {
continue // not a stability level
}
mark_used(attr);
if let Some(metas) = attr.meta_item_list() {
- let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
+ let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
return false
}
};
- match tag {
+ match &*tag.as_str() {
"rustc_deprecated" => {
if rustc_depr.is_some() {
span_err!(diagnostic, item_sp, E0540,
let mut reason = None;
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.name() {
+ match &*mi.name().as_str() {
"since" => if !get(mi, &mut since) { continue 'outer },
"reason" => if !get(mi, &mut reason) { continue 'outer },
_ => {
let mut issue = None;
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.name() {
+ match &*mi.name().as_str() {
"feature" => if !get(mi, &mut feature) { continue 'outer },
"reason" => if !get(mi, &mut reason) { continue 'outer },
"issue" => if !get(mi, &mut issue) { continue 'outer },
level: Unstable {
reason: reason,
issue: {
- if let Ok(issue) = issue.parse() {
+ if let Ok(issue) = issue.as_str().parse() {
issue
} else {
span_err!(diagnostic, attr.span(), E0545,
let mut since = None;
for meta in metas {
if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
- match &*mi.name() {
+ match &*mi.name().as_str() {
"feature" => if !get(mi, &mut feature) { continue 'outer },
"since" => if !get(mi, &mut since) { continue 'outer },
_ => {
}
depr = if let Some(metas) = attr.meta_item_list() {
- let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
+ let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
return false
let mut note = None;
for meta in metas {
if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
- match &*mi.name() {
+ match &*mi.name().as_str() {
"since" => if !get(mi, &mut since) { continue 'outer },
"note" => if !get(mi, &mut note) { continue 'outer },
_ => {
find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
}
-pub fn require_unique_names(diagnostic: &Handler, metas: &[P<MetaItem>]) {
+pub fn require_unique_names(diagnostic: &Handler, metas: &[MetaItem]) {
let mut set = HashSet::new();
for meta in metas {
let name = meta.name();
/// structure layout, and `packed` to remove padding.
pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> {
let mut acc = Vec::new();
- match attr.node.value.node {
- ast::MetaItemKind::List(ref s, ref items) if s == "repr" => {
+ match attr.value.node {
+ ast::MetaItemKind::List(ref items) if attr.value.name == "repr" => {
mark_used(attr);
for item in items {
if !item.is_meta_item() {
}
if let Some(mi) = item.word() {
- let word = &*mi.name();
+ let word = &*mi.name().as_str();
let hint = match word {
// Can't use "extern" because it's not a lexical identifier.
"C" => Some(ReprExtern),
#[cfg(test)]
mod tests {
use super::*;
+ use symbol::keywords;
use std::rc::Rc;
#[test]
#[test]
fn t11() {
// Test span_to_expanded_string works with expansion
- use ast::Name;
let cm = init_code_map();
let root = Span { lo: BytePos(0), hi: BytePos(11), expn_id: NO_EXPANSION };
- let format = ExpnFormat::MacroBang(Name(0u32));
+ let format = ExpnFormat::MacroBang(keywords::Invalid.name());
let callee = NameAndSpan { format: format,
allow_internal_unstable: false,
span: None };
fn init_expansion_chain(cm: &CodeMap) -> Span {
// Creates an expansion chain containing two recursive calls
// root -> expA -> expA -> expB -> expB -> end
- use ast::Name;
-
let root = Span { lo: BytePos(0), hi: BytePos(11), expn_id: NO_EXPANSION };
- let format_root = ExpnFormat::MacroBang(Name(0u32));
+ let format_root = ExpnFormat::MacroBang(keywords::Invalid.name());
let callee_root = NameAndSpan { format: format_root,
allow_internal_unstable: false,
span: Some(root) };
let id_a1 = cm.record_expansion(info_a1);
let span_a1 = Span { lo: BytePos(12), hi: BytePos(23), expn_id: id_a1 };
- let format_a = ExpnFormat::MacroBang(Name(1u32));
+ let format_a = ExpnFormat::MacroBang(keywords::As.name());
let callee_a = NameAndSpan { format: format_a,
allow_internal_unstable: false,
span: Some(span_a1) };
let id_b1 = cm.record_expansion(info_b1);
let span_b1 = Span { lo: BytePos(25), hi: BytePos(36), expn_id: id_b1 };
- let format_b = ExpnFormat::MacroBang(Name(2u32));
+ let format_b = ExpnFormat::MacroBang(keywords::Box.name());
let callee_b = NameAndSpan { format: format_b,
allow_internal_unstable: false,
span: None };
use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue};
use {fold, attr};
use ast;
-use codemap::{Spanned, respan};
+use codemap::Spanned;
use parse::ParseSess;
use ptr::P;
match (cfg.meta_item(), mi.meta_item()) {
(Some(cfg), Some(mi)) =>
if cfg_matches(&cfg, self.sess, self.features) {
- self.process_cfg_attr(respan(mi.span, ast::Attribute_ {
+ self.process_cfg_attr(ast::Attribute {
id: attr::mk_attr_id(),
- style: attr.node.style,
+ style: attr.style,
value: mi.clone(),
is_sugared_doc: false,
- }))
+ span: mi.span,
+ })
} else {
None
},
return false;
}
- let mis = match attr.node.value.node {
- ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis,
+ let mis = match attr.value.node {
+ ast::MetaItemKind::List(ref mis) if is_cfg(&attr) => mis,
_ => return true
};
attr.span,
GateIssue::Language,
EXPLAIN_STMT_ATTR_SYNTAX);
- if attr.node.is_sugared_doc {
+ if attr.is_sugared_doc {
err.help("`///` is for documentation comments. For a plain comment, use `//`.");
}
err.emit();
use ext::build::AstBuilder;
use parse::token;
use ptr::P;
+use symbol::Symbol;
use tokenstream::{TokenTree};
use util::small_vector::SmallVector;
));
}
});
- let sym = Ident::with_empty_ctxt(token::gensym(&format!(
+ let sym = Ident::with_empty_ctxt(Symbol::gensym(&format!(
"__register_diagnostic_{}", code
)));
MacEager::items(SmallVector::many(vec![
let (count, expr) =
with_registered_diagnostics(|diagnostics| {
let descriptions: Vec<P<ast::Expr>> =
- diagnostics.iter().filter_map(|(code, info)| {
+ diagnostics.iter().filter_map(|(&code, info)| {
info.description.map(|description| {
ecx.expr_tuple(span, vec![
- ecx.expr_str(span, code.as_str()),
- ecx.expr_str(span, description.as_str())
+ ecx.expr_str(span, code),
+ ecx.expr_str(span, description)
])
})
}).collect();
EntryPointType::Start
} else if attr::contains_name(&item.attrs, "main") {
EntryPointType::MainAttr
- } else if item.ident.name.as_str() == "main" {
+ } else if item.ident.name == "main" {
if depth == 1 {
// This is a top-level function so can be 'main'
EntryPointType::MainNamed
use ext::expand::{self, Expansion};
use ext::hygiene::Mark;
use fold::{self, Folder};
-use parse::{self, parser};
+use parse::{self, parser, DirectoryOwnership};
use parse::token;
-use parse::token::{InternedString, str_to_ident};
use ptr::P;
+use symbol::Symbol;
use util::small_vector::SmallVector;
use std::path::PathBuf;
pub depth: usize,
pub backtrace: ExpnId,
pub module: Rc<ModuleData>,
-
- // True if non-inline modules without a `#[path]` are forbidden at the root of this expansion.
- pub no_noninline_mod: bool,
+ pub directory_ownership: DirectoryOwnership,
}
/// One of these is made during expansion and incrementally updated as we go;
depth: 0,
backtrace: NO_EXPANSION,
module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
- no_noninline_mod: false,
+ directory_ownership: DirectoryOwnership::Owned,
},
}
}
loop {
if self.codemap().with_expn_info(expn_id, |info| {
info.map_or(None, |i| {
- if i.callee.name().as_str() == "include" {
+ if i.callee.name() == "include" {
// Stop going up the backtrace once include! is encountered
return None;
}
self.ecfg.trace_mac = x
}
pub fn ident_of(&self, st: &str) -> ast::Ident {
- str_to_ident(st)
+ ast::Ident::from_str(st)
}
pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
let mut v = Vec::new();
return v
}
pub fn name_of(&self, st: &str) -> ast::Name {
- token::intern(st)
+ Symbol::intern(st)
}
}
/// emitting `err_msg` if `expr` is not a string literal. This does not stop
/// compilation on error, merely emits a non-fatal error and returns None.
pub fn expr_to_spanned_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
- -> Option<Spanned<(InternedString, ast::StrStyle)>> {
+ -> Option<Spanned<(Symbol, ast::StrStyle)>> {
// Update `expr.span`'s expn_id now in case expr is an `include!` macro invocation.
let expr = expr.map(|mut expr| {
expr.span.expn_id = cx.backtrace();
let expr = cx.expander().fold_expr(expr);
match expr.node {
ast::ExprKind::Lit(ref l) => match l.node {
- ast::LitKind::Str(ref s, style) => return Some(respan(expr.span, (s.clone(), style))),
+ ast::LitKind::Str(s, style) => return Some(respan(expr.span, (s, style))),
_ => cx.span_err(l.span, err_msg)
},
_ => cx.span_err(expr.span, err_msg)
}
pub fn expr_to_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
- -> Option<(InternedString, ast::StrStyle)> {
+ -> Option<(Symbol, ast::StrStyle)> {
expr_to_spanned_string(cx, expr, err_msg).map(|s| s.node)
}
use syntax_pos::{Span, DUMMY_SP, Pos};
use codemap::{dummy_spanned, respan, Spanned};
use ext::base::ExtCtxt;
-use parse::token::{self, keywords, InternedString};
use ptr::P;
+use symbol::{Symbol, keywords};
// Transitional reexports so qquote can find the paths it is looking for
mod syntax {
fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr>;
fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
- fn expr_str(&self, sp: Span, s: InternedString) -> P<ast::Expr>;
+ fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr>;
fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
fn expr_none(&self, sp: Span) -> P<ast::Expr>;
fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
- fn expr_fail(&self, span: Span, msg: InternedString) -> P<ast::Expr>;
+ fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr>;
fn expr_unreachable(&self, span: Span) -> P<ast::Expr>;
fn expr_ok(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
generics: Generics) -> P<ast::Item>;
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item>;
- fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute;
+ fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute;
- fn meta_word(&self, sp: Span, w: InternedString) -> P<ast::MetaItem>;
+ fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem;
- fn meta_list_item_word(&self, sp: Span, w: InternedString) -> ast::NestedMetaItem;
+ fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem;
fn meta_list(&self,
sp: Span,
- name: InternedString,
+ name: ast::Name,
mis: Vec<ast::NestedMetaItem> )
- -> P<ast::MetaItem>;
+ -> ast::MetaItem;
fn meta_name_value(&self,
sp: Span,
- name: InternedString,
+ name: ast::Name,
value: ast::LitKind)
- -> P<ast::MetaItem>;
+ -> ast::MetaItem;
fn item_use(&self, sp: Span,
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
self.expr_addr_of(sp, self.expr_vec(sp, exprs))
}
- fn expr_str(&self, sp: Span, s: InternedString) -> P<ast::Expr> {
+ fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
}
fn expr_break(&self, sp: Span) -> P<ast::Expr> {
- self.expr(sp, ast::ExprKind::Break(None))
+ self.expr(sp, ast::ExprKind::Break(None, None))
}
self.expr(sp, ast::ExprKind::Tup(exprs))
}
- fn expr_fail(&self, span: Span, msg: InternedString) -> P<ast::Expr> {
+ fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> {
let loc = self.codemap().lookup_char_pos(span.lo);
- let expr_file = self.expr_str(span,
- token::intern_and_get_ident(&loc.file.name));
+ let expr_file = self.expr_str(span, Symbol::intern(&loc.file.name));
let expr_line = self.expr_u32(span, loc.line as u32);
let expr_file_line_tuple = self.expr_tuple(span, vec![expr_file, expr_line]);
let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple);
}
fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
- self.expr_fail(span,
- InternedString::new(
- "internal error: entered unreachable code"))
+ self.expr_fail(span, Symbol::intern("internal error: entered unreachable code"))
}
fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
self.item_ty_poly(span, name, ty, Generics::default())
}
- fn attribute(&self, sp: Span, mi: P<ast::MetaItem>) -> ast::Attribute {
+ fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute {
attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi)
}
- fn meta_word(&self, sp: Span, w: InternedString) -> P<ast::MetaItem> {
+ fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem {
attr::mk_spanned_word_item(sp, w)
}
- fn meta_list_item_word(&self, sp: Span, w: InternedString) -> ast::NestedMetaItem {
+ fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem {
respan(sp, ast::NestedMetaItemKind::MetaItem(attr::mk_spanned_word_item(sp, w)))
}
- fn meta_list(&self, sp: Span, name: InternedString, mis: Vec<ast::NestedMetaItem>)
- -> P<ast::MetaItem> {
+ fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
+ -> ast::MetaItem {
attr::mk_spanned_list_item(sp, name, mis)
}
- fn meta_name_value(&self, sp: Span, name: InternedString, value: ast::LitKind)
- -> P<ast::MetaItem> {
+ fn meta_name_value(&self, sp: Span, name: ast::Name, value: ast::LitKind)
+ -> ast::MetaItem {
attr::mk_spanned_name_value_item(sp, name, respan(sp, value))
}
use feature_gate::{self, Features};
use fold;
use fold::*;
-use parse::{ParseSess, PResult, lexer};
+use parse::{ParseSess, DirectoryOwnership, PResult, lexer};
use parse::parser::Parser;
-use parse::token::{self, intern, keywords};
+use parse::token;
use print::pprust;
use ptr::P;
use std_inject;
+use symbol::keywords;
use tokenstream::{TokenTree, TokenStream};
use util::small_vector::SmallVector;
use visit::Visitor;
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 {
- mod_path: vec![token::str_to_ident(&self.cx.ecfg.crate_name)],
+ mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
directory: PathBuf::from(self.cx.codemap().span_to_filename(krate.span)),
};
module.directory.pop();
self.cx.resolver.resolve_macro(scope, &mac.node.path, force)
}
InvocationKind::Attr { ref attr, .. } => {
- let ident = ast::Ident::with_empty_ctxt(intern(&*attr.name()));
+ let ident = Ident::with_empty_ctxt(attr.name());
let path = ast::Path::from_ident(attr.span, ident);
self.cx.resolver.resolve_macro(scope, &path, force)
}
};
attr::mark_used(&attr);
- let name = intern(&attr.name());
+ let name = attr.name();
self.cx.bt_push(ExpnInfo {
call_site: attr.span,
callee: NameAndSpan {
match *ext {
MultiModifier(ref mac) => {
- let item = mac.expand(self.cx, attr.span, &attr.node.value, item);
+ let item = mac.expand(self.cx, attr.span, &attr.value, item);
kind.expect_from_annotatables(item)
}
MultiDecorator(ref mac) => {
let mut items = Vec::new();
- mac.expand(self.cx, attr.span, &attr.node.value, &item,
+ mac.expand(self.cx, attr.span, &attr.value, &item,
&mut |item| items.push(item));
items.push(item);
kind.expect_from_annotatables(items)
}
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
- let no_noninline_mod = mem::replace(&mut self.cx.current_expansion.no_noninline_mod, true);
+ let old_directory_ownership = self.cx.current_expansion.directory_ownership;
+ self.cx.current_expansion.directory_ownership = DirectoryOwnership::UnownedViaBlock;
let result = noop_fold_block(block, self);
- self.cx.current_expansion.no_noninline_mod = no_noninline_mod;
+ self.cx.current_expansion.directory_ownership = old_directory_ownership;
result
}
return noop_fold_item(item, self);
}
- let orig_no_noninline_mod = self.cx.current_expansion.no_noninline_mod;
+ let orig_directory_ownership = self.cx.current_expansion.directory_ownership;
let mut module = (*self.cx.current_expansion.module).clone();
module.mod_path.push(item.ident);
if inline_module {
if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
- self.cx.current_expansion.no_noninline_mod = false;
- module.directory.push(&*path);
+ self.cx.current_expansion.directory_ownership = DirectoryOwnership::Owned;
+ module.directory.push(&*path.as_str());
} else {
module.directory.push(&*item.ident.name.as_str());
}
} else {
- self.cx.current_expansion.no_noninline_mod = false;
- module.directory =
+ let mut path =
PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner));
- module.directory.pop();
+ let directory_ownership = match path.file_name().unwrap().to_str() {
+ Some("mod.rs") => DirectoryOwnership::Owned,
+ _ => DirectoryOwnership::UnownedViaMod(false),
+ };
+ path.pop();
+ module.directory = path;
+ self.cx.current_expansion.directory_ownership = directory_ownership;
}
let orig_module =
mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
let result = noop_fold_item(item, self);
self.cx.current_expansion.module = orig_module;
- self.cx.current_expansion.no_noninline_mod = orig_no_noninline_mod;
+ self.cx.current_expansion.directory_ownership = orig_directory_ownership;
return result;
}
// Ensure that test functions are accessible from the test harness.
use ext::base::ExtCtxt;
use ext::expand::{Expansion, ExpansionKind};
use fold::*;
-use parse::token::{intern, keywords};
use ptr::P;
+use symbol::{Symbol, keywords};
use util::move_map::MoveMap;
use util::small_vector::SmallVector;
span: DUMMY_SP,
global: false,
segments: vec![ast::PathSegment {
- identifier: ast::Ident::with_empty_ctxt(intern("macro_rules")),
+ identifier: ast::Ident::with_empty_ctxt(Symbol::intern("macro_rules")),
parameters: ast::PathParameters::none(),
}],
},
pub use ast::Ident;
pub use codemap::{DUMMY_SP, Span};
pub use ext::base::{ExtCtxt, MacResult};
- pub use parse::token::{self, Token, DelimToken, keywords, str_to_ident};
+ pub use parse::token::{self, Token, DelimToken};
+ pub use symbol::keywords;
pub use tokenstream::{TokenTree, TokenStream};
}
use parse::{self, token, classify};
use ptr::P;
use std::rc::Rc;
+ use symbol::Symbol;
use tokenstream::{self, TokenTree};
impl_to_tokens_slice! { P<ast::Item>, [] }
impl_to_tokens_slice! { ast::Arg, [TokenTree::Token(DUMMY_SP, token::Comma)] }
- impl ToTokens for P<ast::MetaItem> {
+ impl ToTokens for ast::MetaItem {
fn to_tokens(&self, _cx: &ExtCtxt) -> Vec<TokenTree> {
let nt = token::NtMeta(self.clone());
vec![TokenTree::Token(DUMMY_SP, token::Interpolated(Rc::new(nt)))]
let mut r = vec![];
// FIXME: The spans could be better
r.push(TokenTree::Token(self.span, token::Pound));
- if self.node.style == ast::AttrStyle::Inner {
+ if self.style == ast::AttrStyle::Inner {
r.push(TokenTree::Token(self.span, token::Not));
}
r.push(TokenTree::Delimited(self.span, Rc::new(tokenstream::Delimited {
delim: token::Bracket,
open_span: self.span,
- tts: self.node.value.to_tokens(cx),
+ tts: self.value.to_tokens(cx),
close_span: self.span,
})));
r
impl ToTokens for str {
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
- let lit = ast::LitKind::Str(
- token::intern_and_get_ident(self), ast::StrStyle::Cooked);
+ let lit = ast::LitKind::Str(Symbol::intern(self), ast::StrStyle::Cooked);
dummy_spanned(lit).to_tokens(cx)
}
}
panictry!(parser.parse_block())
}
-pub fn parse_meta_item_panic(parser: &mut Parser) -> P<ast::MetaItem> {
+pub fn parse_meta_item_panic(parser: &mut Parser) -> ast::MetaItem {
panictry!(parser.parse_meta_item())
}
base::MacEager::expr(expanded)
}
-fn ids_ext(strs: Vec<String> ) -> Vec<ast::Ident> {
- strs.iter().map(|str| str_to_ident(&(*str))).collect()
+fn ids_ext(strs: Vec<String>) -> Vec<ast::Ident> {
+ strs.iter().map(|s| ast::Ident::from_str(s)).collect()
}
-fn id_ext(str: &str) -> ast::Ident {
- str_to_ident(str)
+fn id_ext(s: &str) -> ast::Ident {
+ ast::Ident::from_str(s)
}
// Lift an ident to the expr that evaluates to that ident.
fn mk_ident(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
- let e_str = cx.expr_str(sp, ident.name.as_str());
+ let e_str = cx.expr_str(sp, ident.name);
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("ident_of"),
// Lift a name to the expr that evaluates to that name
fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> P<ast::Expr> {
- let e_str = cx.expr_str(sp, ident.name.as_str());
+ let e_str = cx.expr_str(sp, ident.name);
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("name_of"),
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
-use parse::token;
+use parse::{token, DirectoryOwnership};
use parse;
use print::pprust;
use ptr::P;
+use symbol::Symbol;
use tokenstream;
use util::small_vector::SmallVector;
let topmost = cx.expansion_cause();
let loc = cx.codemap().lookup_char_pos(topmost.lo);
- let filename = token::intern_and_get_ident(&loc.file.name);
- base::MacEager::expr(cx.expr_str(topmost, filename))
+ base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name)))
}
pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
-> Box<base::MacResult+'static> {
let s = pprust::tts_to_string(tts);
- base::MacEager::expr(cx.expr_str(sp,
- token::intern_and_get_ident(&s[..])))
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
}
pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
let mod_path = &cx.current_expansion.module.mod_path;
let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
- base::MacEager::expr(cx.expr_str(
- sp,
- token::intern_and_get_ident(&string[..])))
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
}
/// include! : parse the given file as an expr
};
// The file will be added to the code map by the parser
let path = res_rel_file(cx, sp, Path::new(&file));
- let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, true, None, sp);
+ let directory_ownership = DirectoryOwnership::Owned;
+ let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, directory_ownership, None, sp);
struct ExpandResult<'a> {
p: parse::parser::Parser<'a>,
// Add this input file to the code map to make it available as
// dependency information
let filename = format!("{}", file.display());
- let interned = token::intern_and_get_ident(&src[..]);
cx.codemap().new_filemap_and_lines(&filename, None, &src);
- base::MacEager::expr(cx.expr_str(sp, interned))
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&src)))
}
Err(_) => {
cx.span_err(sp,
use ext::tt::macro_parser::{parse, parse_failure_msg};
use parse::ParseSess;
use parse::lexer::new_tt_reader;
-use parse::parser::{Parser, Restrictions};
-use parse::token::{self, gensym_ident, NtTT, Token};
+use parse::parser::Parser;
+use parse::token::{self, NtTT, Token};
use parse::token::Token::*;
use print;
+use symbol::Symbol;
use tokenstream::{self, TokenTree};
use std::collections::{HashMap};
let trncbr =
new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs);
let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr));
- p.directory = cx.current_expansion.module.directory.clone();
- p.restrictions = match cx.current_expansion.no_noninline_mod {
- true => Restrictions::NO_NONINLINE_MOD,
- false => Restrictions::empty(),
- };
+ let module = &cx.current_expansion.module;
+ p.directory.path = module.directory.clone();
+ p.directory.ownership = cx.current_expansion.directory_ownership;
+ p.root_module_name =
+ module.mod_path.last().map(|id| (*id.name.as_str()).to_owned());
+
p.check_unknown_macro_variable();
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
/// Converts a `macro_rules!` invocation into a syntax extension.
pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
- let lhs_nm = gensym_ident("lhs");
- let rhs_nm = gensym_ident("rhs");
+ let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
+ let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));
// The pattern that macro_rules matches.
// The grammar for macro_rules! is:
// $( $lhs:tt => $rhs:tt );+
// ...quasiquoting this would be nice.
// These spans won't matter, anyways
- let match_lhs_tok = MatchNt(lhs_nm, token::str_to_ident("tt"));
- let match_rhs_tok = MatchNt(rhs_nm, token::str_to_ident("tt"));
+ let match_lhs_tok = MatchNt(lhs_nm, ast::Ident::from_str("tt"));
+ let match_rhs_tok = MatchNt(rhs_nm, ast::Ident::from_str("tt"));
let argument_gram = vec![
TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
tts: vec![
"pat" => {
match *tok {
FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true),
- Ident(i) if (i.name.as_str() == "if" ||
- i.name.as_str() == "in") => Ok(true),
+ Ident(i) if i.name == "if" || i.name == "in" => Ok(true),
_ => Ok(false)
}
},
match *tok {
OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) |
Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true),
- MatchNt(_, ref frag) if frag.name.as_str() == "block" => Ok(true),
- Ident(i) if i.name.as_str() == "as" || i.name.as_str() == "where" => Ok(true),
+ MatchNt(_, ref frag) if frag.name == "block" => Ok(true),
+ Ident(i) if i.name == "as" || i.name == "where" => Ok(true),
_ => Ok(false)
}
},
use errors::{DiagnosticBuilder, Handler};
use visit::{self, FnKind, Visitor};
use parse::ParseSess;
-use parse::token::InternedString;
+use symbol::Symbol;
use std::ascii::AsciiExt;
use std::env;
/// A set of features to be used by later passes.
pub struct Features {
/// #![feature] attrs for stable language features, for error reporting
- pub declared_stable_lang_features: Vec<(InternedString, Span)>,
+ pub declared_stable_lang_features: Vec<(Symbol, Span)>,
/// #![feature] attrs for non-language (library) features
- pub declared_lib_features: Vec<(InternedString, Span)>,
+ pub declared_lib_features: Vec<(Symbol, Span)>,
$(pub $feature: bool),+
}
// instead of just the platforms on which it is the C ABI
(active, abi_sysv64, "1.13.0", Some(36167)),
- // Use the import semantics from RFC 1560.
- (active, item_like_imports, "1.13.0", Some(35120)),
-
// Macros 1.1
(active, proc_macro, "1.13.0", Some(35900)),
(active, link_cfg, "1.14.0", Some(37406)),
(active, use_extern_macros, "1.15.0", Some(35896)),
+
+ // Allows `break {expr}` with a value inside `loop`s.
+ (active, loop_break_value, "1.14.0", Some(37339)),
);
declare_features! (
(accepted, question_mark, "1.13.0", Some(31436)),
// Allows `..` in tuple (struct) patterns
(accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)),
+ (accepted, item_like_imports, "1.14.0", Some(35120)),
);
// (changing above list without updating src/doc/reference.md makes @cmr sad)
impl GatedCfg {
pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
- let name = cfg.name();
+ let name = &*cfg.name().as_str();
GATED_CFGS.iter()
.position(|info| info.0 == name)
.map(|idx| {
impl<'a> Context<'a> {
fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
debug!("check_attribute(attr = {:?})", attr);
- let name = &*attr.name();
+ let name = &*attr.name().as_str();
for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES {
if n == name {
if let &Gated(_, ref name, ref desc, ref has_feature) = gateage {
use ast::NestedMetaItemKind::*;
match item.node {
- Word(..) => false,
- NameValue(_, ref lit) => !lit.node.is_str(),
- List(_, ref list) => list.iter().any(|li| {
+ Word => false,
+ NameValue(ref lit) => !lit.node.is_str(),
+ List(ref list) => list.iter().any(|li| {
match li.node {
- MetaItem(ref mi) => contains_novel_literal(&**mi),
+ MetaItem(ref mi) => contains_novel_literal(&mi),
Literal(_) => true,
}
}),
self.context.check_attribute(attr, false);
}
- if contains_novel_literal(&*(attr.node.value)) {
+ if contains_novel_literal(&attr.value) {
gate_feature_post!(&self, attr_literals, attr.span,
"non-string literals in attributes, or string \
literals in top-level positions, are experimental");
}
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
- let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs,
- "link_name") {
- Some(val) => val.starts_with("llvm."),
+ let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs, "link_name") {
+ Some(val) => val.as_str().starts_with("llvm."),
_ => false
};
if links_to_llvm {
}
}
}
+ ast::ExprKind::Break(_, Some(_)) => {
+ gate_feature_post!(&self, loop_break_value, e.span,
+ "`break` with a value is experimental");
+ }
_ => {}
}
visit::walk_expr(self, e);
use ast;
use syntax_pos::Span;
use codemap::{Spanned, respan};
-use parse::token::{self, keywords};
+use parse::token;
use ptr::P;
+use symbol::keywords;
use tokenstream::*;
use util::small_vector::SmallVector;
use util::move_map::MoveMap;
noop_fold_crate(c, self)
}
- fn fold_meta_items(&mut self, meta_items: Vec<P<MetaItem>>) -> Vec<P<MetaItem>> {
+ fn fold_meta_items(&mut self, meta_items: Vec<MetaItem>) -> Vec<MetaItem> {
noop_fold_meta_items(meta_items, self)
}
noop_fold_meta_list_item(list_item, self)
}
- fn fold_meta_item(&mut self, meta_item: P<MetaItem>) -> P<MetaItem> {
+ fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
noop_fold_meta_item(meta_item, self)
}
}
}
-pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T)
- -> Vec<P<MetaItem>> {
+pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<MetaItem>, fld: &mut T) -> Vec<MetaItem> {
meta_items.move_map(|x| fld.fold_meta_item(x))
}
})
}
-pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> {
- let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at;
- Some(Spanned {
- node: Attribute_ {
- id: id,
- style: style,
- value: fld.fold_meta_item(value),
- is_sugared_doc: is_sugared_doc
- },
- span: fld.new_span(span)
+pub fn noop_fold_attribute<T: Folder>(attr: Attribute, fld: &mut T) -> Option<Attribute> {
+ Some(Attribute {
+ id: attr.id,
+ style: attr.style,
+ value: fld.fold_meta_item(attr.value),
+ is_sugared_doc: attr.is_sugared_doc,
+ span: fld.new_span(attr.span),
})
}
}
}
-pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> {
- mi.map(|Spanned {node, span}| Spanned {
- node: match node {
- MetaItemKind::Word(id) => MetaItemKind::Word(id),
- MetaItemKind::List(id, mis) => {
- MetaItemKind::List(id, mis.move_map(|e| fld.fold_meta_list_item(e)))
- }
- MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s)
+pub fn noop_fold_meta_item<T: Folder>(mi: MetaItem, fld: &mut T) -> MetaItem {
+ MetaItem {
+ name: mi.name,
+ node: match mi.node {
+ MetaItemKind::Word => MetaItemKind::Word,
+ MetaItemKind::List(mis) => {
+ MetaItemKind::List(mis.move_map(|e| fld.fold_meta_list_item(e)))
+ },
+ MetaItemKind::NameValue(s) => MetaItemKind::NameValue(s),
},
- span: fld.new_span(span)
- })
+ span: fld.new_span(mi.span)
+ }
}
pub fn noop_fold_arg<T: Folder>(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg {
});
ExprKind::Path(qself, folder.fold_path(path))
}
- ExprKind::Break(opt_ident) => ExprKind::Break(opt_ident.map(|label|
- respan(folder.new_span(label.span),
- folder.fold_ident(label.node)))
- ),
+ ExprKind::Break(opt_ident, opt_expr) => {
+ ExprKind::Break(opt_ident.map(|label| respan(folder.new_span(label.span),
+ folder.fold_ident(label.node))),
+ opt_expr.map(|e| folder.fold_expr(e)))
+ }
ExprKind::Continue(opt_ident) => ExprKind::Continue(opt_ident.map(|label|
respan(folder.new_span(label.span),
folder.fold_ident(label.node)))
#[cfg(test)]
mod tests {
use std::io;
- use ast;
+ use ast::{self, Ident};
use util::parser_testing::{string_to_crate, matches_codepattern};
- use parse::token;
use print::pprust;
use fold;
use super::*;
impl Folder for ToZzIdentFolder {
fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
- token::str_to_ident("zz")
+ Ident::from_str("zz")
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
#![feature(associated_consts)]
#![feature(const_fn)]
#![feature(libc)]
+#![feature(optin_builtin_traits)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(str_escape)]
pub mod diagnostic_list;
pub mod util {
- pub mod interner;
pub mod lev_distance;
pub mod node_count;
pub mod parser;
pub mod show_span;
pub mod std_inject;
pub mod str;
+pub mod symbol;
pub mod test;
pub mod tokenstream;
pub mod visit;
use attr;
use ast;
use syntax_pos::{mk_sp, Span};
-use codemap::{spanned, Spanned};
+use codemap::spanned;
use parse::common::SeqSep;
use parse::PResult;
use parse::token;
use parse::parser::{Parser, TokenType};
-use ptr::P;
#[derive(PartialEq, Eq, Debug)]
enum InnerAttributeParsePolicy<'a> {
just_parsed_doc_comment = false;
}
token::DocComment(s) => {
- let attr = ::attr::mk_sugared_doc_attr(
- attr::mk_attr_id(),
- self.id_to_interned_str(ast::Ident::with_empty_ctxt(s)),
- self.span.lo,
- self.span.hi
- );
- if attr.node.style != ast::AttrStyle::Outer {
+ let Span { lo, hi, .. } = self.span;
+ let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, lo, hi);
+ if attr.style != ast::AttrStyle::Outer {
let mut err = self.fatal("expected outer doc comment");
err.note("inner doc comments like this (starting with \
`//!` or `/*!`) can only appear before items");
style = ast::AttrStyle::Inner;
}
- Ok(Spanned {
+ Ok(ast::Attribute {
+ id: attr::mk_attr_id(),
+ style: style,
+ value: value,
+ is_sugared_doc: false,
span: span,
- node: ast::Attribute_ {
- id: attr::mk_attr_id(),
- style: style,
- value: value,
- is_sugared_doc: false,
- },
})
}
}
let attr = self.parse_attribute(true)?;
- assert!(attr.node.style == ast::AttrStyle::Inner);
+ assert!(attr.style == ast::AttrStyle::Inner);
attrs.push(attr);
}
token::DocComment(s) => {
// we need to get the position of this token before we bump.
let Span { lo, hi, .. } = self.span;
- let str = self.id_to_interned_str(ast::Ident::with_empty_ctxt(s));
- let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), str, lo, hi);
- if attr.node.style == ast::AttrStyle::Inner {
+ let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, lo, hi);
+ if attr.style == ast::AttrStyle::Inner {
attrs.push(attr);
self.bump();
} else {
///
/// meta_item : IDENT ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
- pub fn parse_meta_item(&mut self) -> PResult<'a, P<ast::MetaItem>> {
+ pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
let nt_meta = match self.token {
token::Interpolated(ref nt) => match **nt {
token::NtMeta(ref e) => Some(e.clone()),
let lo = self.span.lo;
let ident = self.parse_ident()?;
- let name = self.id_to_interned_str(ident);
- match self.token {
- token::Eq => {
- self.bump();
- let lit = self.parse_unsuffixed_lit()?;
- let hi = self.prev_span.hi;
- Ok(P(spanned(lo, hi, ast::MetaItemKind::NameValue(name, lit))))
- }
- token::OpenDelim(token::Paren) => {
- let inner_items = self.parse_meta_seq()?;
- let hi = self.prev_span.hi;
- Ok(P(spanned(lo, hi, ast::MetaItemKind::List(name, inner_items))))
- }
- _ => {
- let hi = self.prev_span.hi;
- Ok(P(spanned(lo, hi, ast::MetaItemKind::Word(name))))
- }
- }
+ let node = if self.eat(&token::Eq) {
+ ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
+ } else if self.token == token::OpenDelim(token::Paren) {
+ ast::MetaItemKind::List(self.parse_meta_seq()?)
+ } else {
+ ast::MetaItemKind::Word
+ };
+ let hi = self.prev_span.hi;
+ Ok(ast::MetaItem { name: ident.name, node: node, span: mk_sp(lo, hi) })
}
/// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast;
+use ast::{self, Ident};
use syntax_pos::{self, BytePos, CharPos, Pos, Span};
use codemap::CodeMap;
use errors::{FatalError, Handler, DiagnosticBuilder};
use ext::tt::transcribe::tt_next_token;
-use parse::token::{self, keywords, str_to_ident};
+use parse::token;
use str::char_at;
+use symbol::{Symbol, keywords};
use rustc_unicode::property::Pattern_White_Space;
use std::borrow::Cow;
/// single-byte delimiter).
pub fn name_from(&self, start: BytePos) -> ast::Name {
debug!("taking an ident from {:?} to {:?}", start, self.pos);
- self.with_str_from(start, token::intern)
+ self.with_str_from(start, Symbol::intern)
}
/// As name_from, with an explicit endpoint.
pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
debug!("taking an ident from {:?} to {:?}", start, end);
- self.with_str_from_to(start, end, token::intern)
+ self.with_str_from_to(start, end, Symbol::intern)
}
/// Calls `f` with a string slice of the source text spanning from `start`
if string == "_" {
None
} else {
- Some(token::intern(string))
+ Some(Symbol::intern(string))
}
})
}
self.with_str_from(start_bpos, |string| {
// comments with only more "/"s are not doc comments
let tok = if is_doc_comment(string) {
- token::DocComment(token::intern(string))
+ token::DocComment(Symbol::intern(string))
} else {
token::Comment
};
} else {
string.into()
};
- token::DocComment(token::intern(&string[..]))
+ token::DocComment(Symbol::intern(&string[..]))
} else {
token::Comment
};
self.err_span_(start_bpos,
self.pos,
"no valid digits found for number");
- return token::Integer(token::intern("0"));
+ return token::Integer(Symbol::intern("0"));
}
// might be a float, but don't be greedy if this is actually an
token::Underscore
} else {
// FIXME: perform NFKC normalization here. (Issue #2253)
- token::Ident(str_to_ident(string))
+ token::Ident(Ident::from_str(string))
}
}));
}
// expansion purposes. See #12512 for the gory details of why
// this is necessary.
let ident = self.with_str_from(start, |lifetime_name| {
- str_to_ident(&format!("'{}", lifetime_name))
+ Ident::from_str(&format!("'{}", lifetime_name))
});
// Conjure up a "keyword checking ident" to make sure that
// the lifetime name is not a keyword.
let keyword_checking_ident = self.with_str_from(start, |lifetime_name| {
- str_to_ident(lifetime_name)
+ Ident::from_str(lifetime_name)
});
let keyword_checking_token = &token::Ident(keyword_checking_ident);
let last_bpos = self.pos;
let id = if valid {
self.name_from(start)
} else {
- token::intern("0")
+ Symbol::intern("0")
};
self.bump(); // advance ch past token
let suffix = self.scan_optional_raw_name();
let id = if valid {
self.name_from(start_bpos + BytePos(1))
} else {
- token::intern("??")
+ Symbol::intern("??")
};
self.bump();
let suffix = self.scan_optional_raw_name();
let id = if valid {
self.name_from_to(content_start_bpos, content_end_bpos)
} else {
- token::intern("??")
+ Symbol::intern("??")
};
let suffix = self.scan_optional_raw_name();
return Ok(token::Literal(token::StrRaw(id, hash_count), suffix));
let id = if valid {
self.name_from(start)
} else {
- token::intern("?")
+ Symbol::intern("?")
};
self.bump(); // advance ch past token
return token::Byte(id);
let id = if valid {
self.name_from(start)
} else {
- token::intern("??")
+ Symbol::intern("??")
};
self.bump();
return token::ByteStr(id);
mod tests {
use super::*;
+ use ast::Ident;
+ use symbol::Symbol;
use syntax_pos::{BytePos, Span, NO_EXPANSION};
use codemap::CodeMap;
use errors;
use parse::token;
- use parse::token::str_to_ident;
use std::io;
use std::rc::Rc;
&sh,
"/* my source file */ fn main() { println!(\"zebra\"); }\n"
.to_string());
- let id = str_to_ident("fn");
+ let id = Ident::from_str("fn");
assert_eq!(string_reader.next_token().tok, token::Comment);
assert_eq!(string_reader.next_token().tok, token::Whitespace);
let tok1 = string_reader.next_token();
// read another token:
let tok3 = string_reader.next_token();
let tok4 = TokenAndSpan {
- tok: token::Ident(str_to_ident("main")),
+ tok: token::Ident(Ident::from_str("main")),
sp: Span {
lo: BytePos(24),
hi: BytePos(28),
// make the identifier by looking up the string in the interner
fn mk_ident(id: &str) -> token::Token {
- token::Ident(str_to_ident(id))
+ token::Ident(Ident::from_str(id))
}
#[test]
let cm = Rc::new(CodeMap::new());
let sh = mk_sh(cm.clone());
assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok,
- token::Literal(token::Char(token::intern("a")), None));
+ token::Literal(token::Char(Symbol::intern("a")), None));
}
#[test]
let cm = Rc::new(CodeMap::new());
let sh = mk_sh(cm.clone());
assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok,
- token::Literal(token::Char(token::intern(" ")), None));
+ token::Literal(token::Char(Symbol::intern(" ")), None));
}
#[test]
let cm = Rc::new(CodeMap::new());
let sh = mk_sh(cm.clone());
assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok,
- token::Literal(token::Char(token::intern("\\n")), None));
+ token::Literal(token::Char(Symbol::intern("\\n")), None));
}
#[test]
let cm = Rc::new(CodeMap::new());
let sh = mk_sh(cm.clone());
assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok,
- token::Lifetime(token::str_to_ident("'abc")));
+ token::Lifetime(Ident::from_str("'abc")));
}
#[test]
assert_eq!(setup(&cm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string())
.next_token()
.tok,
- token::Literal(token::StrRaw(token::intern("\"#a\\b\x00c\""), 3), None));
+ token::Literal(token::StrRaw(Symbol::intern("\"#a\\b\x00c\""), 3), None));
}
#[test]
macro_rules! test {
($input: expr, $tok_type: ident, $tok_contents: expr) => {{
assert_eq!(setup(&cm, &sh, format!("{}suffix", $input)).next_token().tok,
- token::Literal(token::$tok_type(token::intern($tok_contents)),
- Some(token::intern("suffix"))));
+ token::Literal(token::$tok_type(Symbol::intern($tok_contents)),
+ Some(Symbol::intern("suffix"))));
// with a whitespace separator:
assert_eq!(setup(&cm, &sh, format!("{} suffix", $input)).next_token().tok,
- token::Literal(token::$tok_type(token::intern($tok_contents)),
+ token::Literal(token::$tok_type(Symbol::intern($tok_contents)),
None));
}}
}
test!("1.0e10", Float, "1.0e10");
assert_eq!(setup(&cm, &sh, "2us".to_string()).next_token().tok,
- token::Literal(token::Integer(token::intern("2")),
- Some(token::intern("us"))));
+ token::Literal(token::Integer(Symbol::intern("2")),
+ Some(Symbol::intern("us"))));
assert_eq!(setup(&cm, &sh, "r###\"raw\"###suffix".to_string()).next_token().tok,
- token::Literal(token::StrRaw(token::intern("raw"), 3),
- Some(token::intern("suffix"))));
+ token::Literal(token::StrRaw(Symbol::intern("raw"), 3),
+ Some(Symbol::intern("suffix"))));
assert_eq!(setup(&cm, &sh, "br###\"raw\"###suffix".to_string()).next_token().tok,
- token::Literal(token::ByteStrRaw(token::intern("raw"), 3),
- Some(token::intern("suffix"))));
+ token::Literal(token::ByteStrRaw(Symbol::intern("raw"), 3),
+ Some(Symbol::intern("suffix"))));
}
#[test]
_ => panic!("expected a comment!"),
}
assert_eq!(lexer.next_token().tok,
- token::Literal(token::Char(token::intern("a")), None));
+ token::Literal(token::Char(Symbol::intern("a")), None));
}
#[test]
assert_eq!(comment.sp, ::syntax_pos::mk_sp(BytePos(0), BytePos(7)));
assert_eq!(lexer.next_token().tok, token::Whitespace);
assert_eq!(lexer.next_token().tok,
- token::DocComment(token::intern("/// test")));
+ token::DocComment(Symbol::intern("/// test")));
}
}
use errors::{Handler, ColorConfig, DiagnosticBuilder};
use feature_gate::UnstableFeatures;
use parse::parser::Parser;
-use parse::token::InternedString;
use ptr::P;
use str::char_at;
+use symbol::Symbol;
use tokenstream;
use std::cell::RefCell;
+use std::collections::HashSet;
use std::iter;
use std::path::{Path, PathBuf};
use std::rc::Rc;
ParseSess {
span_diagnostic: handler,
unstable_features: UnstableFeatures::from_environment(),
- config: Vec::new(),
+ config: HashSet::new(),
included_mod_stack: RefCell::new(vec![]),
code_map: code_map
}
}
}
+#[derive(Clone)]
+pub struct Directory {
+ pub path: PathBuf,
+ pub ownership: DirectoryOwnership,
+}
+
+#[derive(Copy, Clone)]
+pub enum DirectoryOwnership {
+ Owned,
+ UnownedViaBlock,
+ UnownedViaMod(bool /* legacy warnings? */),
+}
+
// a bunch of utility functions of the form parse_<thing>_from_<source>
// where <thing> includes crate, expr, item, stmt, tts, and one that
// uses a HOF to parse anything, and <source> includes file and
}
pub fn parse_meta_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
- -> PResult<'a, P<ast::MetaItem>> {
+ -> PResult<'a, ast::MetaItem> {
new_parser_from_source_str(sess, name, source).parse_meta_item()
}
/// On an error, use the given span as the source of the problem.
pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
path: &Path,
- owns_directory: bool,
+ directory_ownership: DirectoryOwnership,
module_name: Option<String>,
sp: Span) -> Parser<'a> {
let mut p = filemap_to_parser(sess, file_to_filemap(sess, path, Some(sp)));
- p.owns_directory = owns_directory;
+ p.directory.ownership = directory_ownership;
p.root_module_name = module_name;
p
}
s[1..].chars().all(|c| '0' <= c && c <= '9')
}
-fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
- sd: &Handler, sp: Span) -> ast::LitKind {
+fn filtered_float_lit(data: Symbol, suffix: Option<Symbol>, sd: &Handler, sp: Span)
+ -> ast::LitKind {
debug!("filtered_float_lit: {}, {:?}", data, suffix);
- match suffix.as_ref().map(|s| &**s) {
- Some("f32") => ast::LitKind::Float(data, ast::FloatTy::F32),
- Some("f64") => ast::LitKind::Float(data, ast::FloatTy::F64),
- Some(suf) => {
+ let suffix = match suffix {
+ Some(suffix) => suffix,
+ None => return ast::LitKind::FloatUnsuffixed(data),
+ };
+
+ match &*suffix.as_str() {
+ "f32" => ast::LitKind::Float(data, ast::FloatTy::F32),
+ "f64" => ast::LitKind::Float(data, ast::FloatTy::F64),
+ suf => {
if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
// if it looks like a width, lets try to be helpful.
sd.struct_span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..]))
ast::LitKind::FloatUnsuffixed(data)
}
- None => ast::LitKind::FloatUnsuffixed(data)
}
}
-pub fn float_lit(s: &str, suffix: Option<InternedString>,
- sd: &Handler, sp: Span) -> ast::LitKind {
+pub fn float_lit(s: &str, suffix: Option<Symbol>, sd: &Handler, sp: Span) -> ast::LitKind {
debug!("float_lit: {:?}, {:?}", s, suffix);
// FIXME #2252: bounds checking float literals is deferred until trans
let s = s.chars().filter(|&c| c != '_').collect::<String>();
- let data = token::intern_and_get_ident(&s);
- filtered_float_lit(data, suffix.as_ref().map(|s| &**s), sd, sp)
+ filtered_float_lit(Symbol::intern(&s), suffix, sd, sp)
}
/// Parse a string representing a byte literal into its final form. Similar to `char_lit`
Rc::new(res)
}
-pub fn integer_lit(s: &str,
- suffix: Option<InternedString>,
- sd: &Handler,
- sp: Span)
- -> ast::LitKind {
+pub fn integer_lit(s: &str, suffix: Option<Symbol>, sd: &Handler, sp: Span) -> ast::LitKind {
// s can only be ascii, byte indexing is fine
let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
}
// 1f64 and 2f32 etc. are valid float literals.
- if let Some(ref suf) = suffix {
- if looks_like_width_suffix(&['f'], suf) {
+ if let Some(suf) = suffix {
+ if looks_like_width_suffix(&['f'], &suf.as_str()) {
match base {
16 => sd.span_err(sp, "hexadecimal float literal is not supported"),
8 => sd.span_err(sp, "octal float literal is not supported"),
2 => sd.span_err(sp, "binary float literal is not supported"),
_ => ()
}
- let ident = token::intern_and_get_ident(&s);
- return filtered_float_lit(ident, Some(&suf), sd, sp)
+ return filtered_float_lit(Symbol::intern(&s), Some(suf), sd, sp)
}
}
s = &s[2..];
}
- if let Some(ref suf) = suffix {
- if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
- ty = match &**suf {
+ if let Some(suf) = suffix {
+ if suf.as_str().is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
+ ty = match &*suf.as_str() {
"isize" => ast::LitIntType::Signed(ast::IntTy::Is),
"i8" => ast::LitIntType::Signed(ast::IntTy::I8),
"i16" => ast::LitIntType::Signed(ast::IntTy::I16),
"u16" => ast::LitIntType::Unsigned(ast::UintTy::U16),
"u32" => ast::LitIntType::Unsigned(ast::UintTy::U32),
"u64" => ast::LitIntType::Unsigned(ast::UintTy::U64),
- _ => {
+ suf => {
// i<digits> and u<digits> look like widths, so lets
// give an error message along those lines
if looks_like_width_suffix(&['i', 'u'], suf) {
use std::rc::Rc;
use syntax_pos::{self, Span, BytePos, Pos, NO_EXPANSION};
use codemap::Spanned;
- use ast::{self, PatKind};
+ use ast::{self, Ident, PatKind};
use abi::Abi;
use attr::first_attr_value_str_by_name;
use parse;
use parse::parser::Parser;
- use parse::token::{str_to_ident};
use print::pprust::item_to_string;
use ptr::P;
use tokenstream::{self, TokenTree};
global: false,
segments: vec![
ast::PathSegment {
- identifier: str_to_ident("a"),
+ identifier: Ident::from_str("a"),
parameters: ast::PathParameters::none(),
}
],
global: true,
segments: vec![
ast::PathSegment {
- identifier: str_to_ident("a"),
+ identifier: Ident::from_str("a"),
parameters: ast::PathParameters::none(),
},
ast::PathSegment {
- identifier: str_to_ident("b"),
+ identifier: Ident::from_str("b"),
parameters: ast::PathParameters::none(),
}
]
Some(&TokenTree::Token(_, token::Ident(name_zip))),
Some(&TokenTree::Delimited(_, ref macro_delimed)),
)
- if name_macro_rules.name.as_str() == "macro_rules"
- && name_zip.name.as_str() == "zip" => {
+ if name_macro_rules.name == "macro_rules"
+ && name_zip.name == "zip" => {
let tts = ¯o_delimed.tts[..];
match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
(
Some(&TokenTree::Token(_, token::Dollar)),
Some(&TokenTree::Token(_, token::Ident(ident))),
)
- if first_delimed.delim == token::Paren
- && ident.name.as_str() == "a" => {},
+ if first_delimed.delim == token::Paren && ident.name == "a" => {},
_ => panic!("value 3: {:?}", **first_delimed),
}
let tts = &second_delimed.tts[..];
Some(&TokenTree::Token(_, token::Ident(ident))),
)
if second_delimed.delim == token::Paren
- && ident.name.as_str() == "a" => {},
+ && ident.name == "a" => {},
_ => panic!("value 4: {:?}", **second_delimed),
}
},
let tts = string_to_tts("fn a (b : i32) { b; }".to_string());
let expected = vec![
- TokenTree::Token(sp(0, 2), token::Ident(str_to_ident("fn"))),
- TokenTree::Token(sp(3, 4), token::Ident(str_to_ident("a"))),
+ TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))),
+ TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))),
TokenTree::Delimited(
sp(5, 14),
Rc::new(tokenstream::Delimited {
delim: token::DelimToken::Paren,
open_span: sp(5, 6),
tts: vec![
- TokenTree::Token(sp(6, 7), token::Ident(str_to_ident("b"))),
+ TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))),
TokenTree::Token(sp(8, 9), token::Colon),
- TokenTree::Token(sp(10, 13), token::Ident(str_to_ident("i32"))),
+ TokenTree::Token(sp(10, 13), token::Ident(Ident::from_str("i32"))),
],
close_span: sp(13, 14),
})),
delim: token::DelimToken::Brace,
open_span: sp(15, 16),
tts: vec![
- TokenTree::Token(sp(17, 18), token::Ident(str_to_ident("b"))),
+ TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))),
TokenTree::Token(sp(18, 19), token::Semi),
],
close_span: sp(20, 21),
global: false,
segments: vec![
ast::PathSegment {
- identifier: str_to_ident("d"),
+ identifier: Ident::from_str("d"),
parameters: ast::PathParameters::none(),
}
],
global:false,
segments: vec![
ast::PathSegment {
- identifier: str_to_ident("b"),
+ identifier: Ident::from_str("b"),
parameters: ast::PathParameters::none(),
}
],
id: ast::DUMMY_NODE_ID,
node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
Spanned{ span:sp(0, 1),
- node: str_to_ident("b")
+ node: Ident::from_str("b")
},
None),
span: sp(0,1)}));
// this test depends on the intern order of "fn" and "i32"
assert_eq!(string_to_item("fn a (b : i32) { b; }".to_string()),
Some(
- P(ast::Item{ident:str_to_ident("a"),
+ P(ast::Item{ident:Ident::from_str("a"),
attrs:Vec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::Fn(P(ast::FnDecl {
global:false,
segments: vec![
ast::PathSegment {
- identifier:
- str_to_ident("i32"),
+ identifier: Ident::from_str("i32"),
parameters: ast::PathParameters::none(),
}
],
ast::BindingMode::ByValue(ast::Mutability::Immutable),
Spanned{
span: sp(6,7),
- node: str_to_ident("b")},
+ node: Ident::from_str("b")},
None
),
span: sp(6,7)
global:false,
segments: vec![
ast::PathSegment {
- identifier:
- str_to_ident(
- "b"),
+ identifier: Ident::from_str("b"),
parameters:
ast::PathParameters::none(),
}
let item = parse_item_from_source_str(name.clone(), source, &sess)
.unwrap().unwrap();
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
- assert_eq!(&doc[..], "/// doc comment");
+ assert_eq!(doc, "/// doc comment");
let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
let item = parse_item_from_source_str(name.clone(), source, &sess)
.unwrap().unwrap();
- let docs = item.attrs.iter().filter(|a| &*a.name() == "doc")
+ let docs = item.attrs.iter().filter(|a| a.name() == "doc")
.map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
assert_eq!(&docs[..], b);
let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string();
let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap();
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
- assert_eq!(&doc[..], "/** doc comment\n * with CRLF */");
+ assert_eq!(doc, "/** doc comment\n * with CRLF */");
}
#[test]
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause};
use ast::{BinOpKind, UnOp};
-use ast;
+use {ast, attr};
use codemap::{self, CodeMap, Spanned, spanned, respan};
use syntax_pos::{self, Span, BytePos, mk_sp};
use errors::{self, DiagnosticBuilder};
use parse::common::SeqSep;
use parse::lexer::{Reader, TokenAndSpan};
use parse::obsolete::ObsoleteSyntax;
-use parse::token::{self, intern, keywords, MatchNt, SubstNt, InternedString};
-use parse::{new_sub_parser_from_file, ParseSess};
+use parse::token::{self, MatchNt, SubstNt};
+use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
use util::parser::{AssocOp, Fixity};
use print::pprust;
use ptr::P;
use parse::PResult;
use tokenstream::{self, Delimited, SequenceRepetition, TokenTree};
+use symbol::{Symbol, keywords};
use util::ThinVec;
use std::collections::HashSet;
flags Restrictions: u8 {
const RESTRICTION_STMT_EXPR = 1 << 0,
const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
- const NO_NONINLINE_MOD = 1 << 2,
}
}
/// extra detail when the same error is seen twice
pub obsolete_set: HashSet<ObsoleteSyntax>,
/// Used to determine the path to externally loaded source files
- pub directory: PathBuf,
+ pub directory: Directory,
/// Stack of open delimiters and their spans. Used for error message.
pub open_braces: Vec<(token::DelimToken, Span)>,
- /// Flag if this parser "owns" the directory that it is currently parsing
- /// in. This will affect how nested files are looked up.
- pub owns_directory: bool,
/// Name of the root module this parser originated from. If `None`, then the
/// name is not known. This does not change while the parser is descending
/// into modules, and sub-parsers have new values for this name.
}
pub struct ModulePathSuccess {
- pub path: ::std::path::PathBuf,
- pub owns_directory: bool,
+ pub path: PathBuf,
+ pub directory_ownership: DirectoryOwnership,
+ warn: bool,
}
pub struct ModulePathError {
quote_depth: 0,
parsing_token_tree: false,
obsolete_set: HashSet::new(),
- directory: PathBuf::new(),
+ directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned },
open_braces: Vec::new(),
- owns_directory: true,
root_module_name: None,
expected_tokens: Vec::new(),
tts: Vec::new(),
parser.token = tok.tok;
parser.span = tok.sp;
if parser.span != syntax_pos::DUMMY_SP {
- parser.directory = PathBuf::from(sess.codemap().span_to_filename(parser.span));
- parser.directory.pop();
+ parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span));
+ parser.directory.path.pop();
}
parser
}
&self.sess.span_diagnostic
}
- pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
- id.name.as_str()
- }
-
/// Is the current token one of the keywords that signals a bare function
/// type?
pub fn token_is_bare_fn_keyword(&mut self) -> bool {
// float literals, so all the handling is done
// internally.
token::Integer(s) => {
- (false, parse::integer_lit(&s.as_str(),
- suf.as_ref().map(|s| s.as_str()),
- &self.sess.span_diagnostic,
- self.span))
+ let diag = &self.sess.span_diagnostic;
+ (false, parse::integer_lit(&s.as_str(), suf, diag, self.span))
}
token::Float(s) => {
- (false, parse::float_lit(&s.as_str(),
- suf.as_ref().map(|s| s.as_str()),
- &self.sess.span_diagnostic,
- self.span))
+ let diag = &self.sess.span_diagnostic;
+ (false, parse::float_lit(&s.as_str(), suf, diag, self.span))
}
token::Str_(s) => {
- (true,
- LitKind::Str(token::intern_and_get_ident(&parse::str_lit(&s.as_str())),
- ast::StrStyle::Cooked))
+ let s = Symbol::intern(&parse::str_lit(&s.as_str()));
+ (true, LitKind::Str(s, ast::StrStyle::Cooked))
}
token::StrRaw(s, n) => {
- (true,
- LitKind::Str(
- token::intern_and_get_ident(&parse::raw_str_lit(&s.as_str())),
- ast::StrStyle::Raw(n)))
+ let s = Symbol::intern(&parse::raw_str_lit(&s.as_str()));
+ (true, LitKind::Str(s, ast::StrStyle::Raw(n)))
+ }
+ token::ByteStr(i) => {
+ (true, LitKind::ByteStr(parse::byte_str_lit(&i.as_str())))
+ }
+ token::ByteStrRaw(i, _) => {
+ (true, LitKind::ByteStr(Rc::new(i.to_string().into_bytes())))
}
- token::ByteStr(i) =>
- (true, LitKind::ByteStr(parse::byte_str_lit(&i.as_str()))),
- token::ByteStrRaw(i, _) =>
- (true,
- LitKind::ByteStr(Rc::new(i.to_string().into_bytes()))),
};
if suffix_illegal {
ex = ExprKind::Ret(None);
}
} else if self.eat_keyword(keywords::Break) {
- if self.token.is_lifetime() {
- ex = ExprKind::Break(Some(Spanned {
+ let lt = if self.token.is_lifetime() {
+ let spanned_lt = Spanned {
node: self.get_lifetime(),
span: self.span
- }));
+ };
self.bump();
+ Some(spanned_lt)
} else {
- ex = ExprKind::Break(None);
- }
+ None
+ };
+ let e = if self.token.can_begin_expr()
+ && !(self.token == token::OpenDelim(token::Brace)
+ && self.restrictions.contains(
+ Restrictions::RESTRICTION_NO_STRUCT_LITERAL)) {
+ Some(self.parse_expr()?)
+ } else {
+ None
+ };
+ ex = ExprKind::Break(lt, e);
hi = self.prev_span.hi;
} else if self.token.is_keyword(keywords::Let) {
// Catch this syntax error here, instead of in `check_strict_keywords`, so
let prev_span = self.prev_span;
let fstr = n.as_str();
let mut err = self.diagnostic().struct_span_err(prev_span,
- &format!("unexpected token: `{}`", n.as_str()));
+ &format!("unexpected token: `{}`", n));
if fstr.chars().all(|x| "0123456789.".contains(x)) {
let float = match fstr.parse::<f64>().ok() {
Some(f) => f,
})));
} else if self.token.is_keyword(keywords::Crate) {
let ident = match self.token {
- token::Ident(id) => ast::Ident { name: token::intern("$crate"), ..id },
+ token::Ident(id) => ast::Ident { name: Symbol::intern("$crate"), ..id },
_ => unreachable!(),
};
self.bump();
/// Emit an expected item after attributes error.
fn expected_item_err(&self, attrs: &[Attribute]) {
let message = match attrs.last() {
- Some(&Attribute { node: ast::Attribute_ { is_sugared_doc: true, .. }, .. }) => {
- "expected item after doc comment"
- }
+ Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
_ => "expected item after attributes",
};
}
} else {
// FIXME: Bad copy of attrs
- let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD;
- match self.with_res(restrictions,
- |this| this.parse_item_(attrs.clone(), false, true))? {
+ let old_directory_ownership =
+ mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
+ let item = self.parse_item_(attrs.clone(), false, true)?;
+ self.directory.ownership = old_directory_ownership;
+ match item {
Some(i) => Stmt {
id: ast::DUMMY_NODE_ID,
span: mk_sp(lo, i.span.hi),
Visibility::Inherited => (),
_ => {
let is_macro_rules: bool = match self.token {
- token::Ident(sid) => sid.name == intern("macro_rules"),
+ token::Ident(sid) => sid.name == Symbol::intern("macro_rules"),
_ => false,
};
if is_macro_rules {
self.bump();
if in_cfg {
// This mod is in an external file. Let's go get it!
- let (m, attrs) = self.eval_src_mod(id, &outer_attrs, id_span)?;
- Ok((id, m, Some(attrs)))
+ let ModulePathSuccess { path, directory_ownership, warn } =
+ self.submod_path(id, &outer_attrs, id_span)?;
+ let (module, mut attrs) =
+ self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
+ if warn {
+ let attr = ast::Attribute {
+ id: attr::mk_attr_id(),
+ style: ast::AttrStyle::Outer,
+ value: ast::MetaItem {
+ name: Symbol::intern("warn_directory_ownership"),
+ node: ast::MetaItemKind::Word,
+ span: syntax_pos::DUMMY_SP,
+ },
+ is_sugared_doc: false,
+ span: syntax_pos::DUMMY_SP,
+ };
+ attr::mark_known(&attr);
+ attrs.push(attr);
+ }
+ Ok((id, module, Some(attrs)))
} else {
let placeholder = ast::Mod { inner: syntax_pos::DUMMY_SP, items: Vec::new() };
Ok((id, ItemKind::Mod(placeholder), None))
}
} else {
- let directory = self.directory.clone();
- let restrictions = self.push_directory(id, &outer_attrs);
+ let old_directory = self.directory.clone();
+ self.push_directory(id, &outer_attrs);
self.expect(&token::OpenDelim(token::Brace))?;
let mod_inner_lo = self.span.lo;
let attrs = self.parse_inner_attributes()?;
- let m = self.with_res(restrictions, |this| {
- this.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)
- })?;
- self.directory = directory;
- Ok((id, ItemKind::Mod(m), Some(attrs)))
+ let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
+ self.directory = old_directory;
+ Ok((id, ItemKind::Mod(module), Some(attrs)))
}
}
- fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) -> Restrictions {
- if let Some(path) = ::attr::first_attr_value_str_by_name(attrs, "path") {
- self.directory.push(&*path);
- self.restrictions - Restrictions::NO_NONINLINE_MOD
+ fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
+ if let Some(path) = attr::first_attr_value_str_by_name(attrs, "path") {
+ self.directory.path.push(&*path.as_str());
+ self.directory.ownership = DirectoryOwnership::Owned;
} else {
- let default_path = self.id_to_interned_str(id);
- self.directory.push(&*default_path);
- self.restrictions
+ self.directory.path.push(&*id.name.as_str());
}
}
pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
- ::attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d))
+ attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d.as_str()))
}
/// Returns either a path to a module, or .
let secondary_exists = codemap.file_exists(&secondary_path);
let result = match (default_exists, secondary_exists) {
- (true, false) => Ok(ModulePathSuccess { path: default_path, owns_directory: false }),
- (false, true) => Ok(ModulePathSuccess { path: secondary_path, owns_directory: true }),
+ (true, false) => Ok(ModulePathSuccess {
+ path: default_path,
+ directory_ownership: DirectoryOwnership::UnownedViaMod(false),
+ warn: false,
+ }),
+ (false, true) => Ok(ModulePathSuccess {
+ path: secondary_path,
+ directory_ownership: DirectoryOwnership::Owned,
+ warn: false,
+ }),
(false, false) => Err(ModulePathError {
err_msg: format!("file not found for module `{}`", mod_name),
help_msg: format!("name the file either {} or {} inside the directory {:?}",
id: ast::Ident,
outer_attrs: &[ast::Attribute],
id_sp: Span) -> PResult<'a, ModulePathSuccess> {
- if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &self.directory) {
- return Ok(ModulePathSuccess { path: p, owns_directory: true });
+ if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
+ return Ok(ModulePathSuccess {
+ directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
+ Some("mod.rs") => DirectoryOwnership::Owned,
+ _ => DirectoryOwnership::UnownedViaMod(true),
+ },
+ path: path,
+ warn: false,
+ });
}
- let paths = Parser::default_submod_path(id, &self.directory, self.sess.codemap());
+ let paths = Parser::default_submod_path(id, &self.directory.path, self.sess.codemap());
- if self.restrictions.contains(Restrictions::NO_NONINLINE_MOD) {
+ if let DirectoryOwnership::UnownedViaBlock = self.directory.ownership {
let msg =
"Cannot declare a non-inline module inside a block unless it has a path attribute";
let mut err = self.diagnostic().struct_span_err(id_sp, msg);
err.span_note(id_sp, &msg);
}
return Err(err);
- } else if !self.owns_directory {
+ } else if let DirectoryOwnership::UnownedViaMod(warn) = self.directory.ownership {
+ if warn {
+ if let Ok(result) = paths.result {
+ return Ok(ModulePathSuccess { warn: true, ..result });
+ }
+ }
let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location");
- let this_module = match self.directory.file_name() {
+ let this_module = match self.directory.path.file_name() {
Some(file_name) => file_name.to_str().unwrap().to_owned(),
None => self.root_module_name.as_ref().unwrap().clone(),
};
&format!("... or maybe `use` the module `{}` instead \
of possibly redeclaring it",
paths.name));
- }
- return Err(err);
+ return Err(err);
+ } else {
+ return Err(err);
+ };
}
match paths.result {
/// Read a module from a source file.
fn eval_src_mod(&mut self,
- id: ast::Ident,
- outer_attrs: &[ast::Attribute],
+ path: PathBuf,
+ directory_ownership: DirectoryOwnership,
+ name: String,
id_sp: Span)
-> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> {
- let ModulePathSuccess { path, owns_directory } = self.submod_path(id,
- outer_attrs,
- id_sp)?;
-
- self.eval_src_mod_from_path(path,
- owns_directory,
- id.to_string(),
- id_sp)
- }
-
- fn eval_src_mod_from_path(&mut self,
- path: PathBuf,
- owns_directory: bool,
- name: String,
- id_sp: Span) -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> {
let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
let mut err = String::from("circular modules: ");
included_mod_stack.push(path.clone());
drop(included_mod_stack);
- let mut p0 = new_sub_parser_from_file(self.sess, &path, owns_directory, Some(name), id_sp);
+ let mut p0 =
+ new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
let mod_inner_lo = p0.span.lo;
let mod_attrs = p0.parse_inner_attributes()?;
let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
})
}
- pub fn parse_optional_str(&mut self)
- -> Option<(InternedString,
- ast::StrStyle,
- Option<ast::Name>)> {
+ pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
let ret = match self.token {
- token::Literal(token::Str_(s), suf) => {
- let s = self.id_to_interned_str(ast::Ident::with_empty_ctxt(s));
- (s, ast::StrStyle::Cooked, suf)
- }
- token::Literal(token::StrRaw(s, n), suf) => {
- let s = self.id_to_interned_str(ast::Ident::with_empty_ctxt(s));
- (s, ast::StrStyle::Raw(n), suf)
- }
+ token::Literal(token::Str_(s), suf) => (s, ast::StrStyle::Cooked, suf),
+ token::Literal(token::StrRaw(s, n), suf) => (s, ast::StrStyle::Raw(n), suf),
_ => return None
};
self.bump();
Some(ret)
}
- pub fn parse_str(&mut self) -> PResult<'a, (InternedString, StrStyle)> {
+ pub fn parse_str(&mut self) -> PResult<'a, (Symbol, StrStyle)> {
match self.parse_optional_str() {
Some((s, style, suf)) => {
let sp = self.prev_span;
use ast::{self};
use ptr::P;
-use util::interner::Interner;
+use symbol::keywords;
use tokenstream;
-use serialize::{Decodable, Decoder, Encodable, Encoder};
-use std::cell::RefCell;
use std::fmt;
-use std::ops::Deref;
use std::rc::Rc;
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
NtTy(P<ast::Ty>),
NtIdent(ast::SpannedIdent),
/// Stuff inside brackets for attributes
- NtMeta(P<ast::MetaItem>),
+ NtMeta(ast::MetaItem),
NtPath(ast::Path),
NtTT(tokenstream::TokenTree),
// These are not exposed to macros, but are used by quasiquote.
}
}
}
-
-// In this macro, there is the requirement that the name (the number) must be monotonically
-// increasing by one in the special identifiers, starting at 0; the same holds for the keywords,
-// except starting from the next number instead of zero.
-macro_rules! declare_keywords {(
- $( ($index: expr, $konst: ident, $string: expr) )*
-) => {
- pub mod keywords {
- use ast;
- #[derive(Clone, Copy, PartialEq, Eq)]
- pub struct Keyword {
- ident: ast::Ident,
- }
- impl Keyword {
- #[inline] pub fn ident(self) -> ast::Ident { self.ident }
- #[inline] pub fn name(self) -> ast::Name { self.ident.name }
- }
- $(
- #[allow(non_upper_case_globals)]
- pub const $konst: Keyword = Keyword {
- ident: ast::Ident::with_empty_ctxt(ast::Name($index))
- };
- )*
- }
-
- fn mk_fresh_ident_interner() -> IdentInterner {
- Interner::prefill(&[$($string,)*])
- }
-}}
-
-// NB: leaving holes in the ident table is bad! a different ident will get
-// interned with the id from the hole, but it will be between the min and max
-// of the reserved words, and thus tagged as "reserved".
-// After modifying this list adjust `is_strict_keyword`/`is_reserved_keyword`,
-// this should be rarely necessary though if the keywords are kept in alphabetic order.
-declare_keywords! {
- // Invalid identifier
- (0, Invalid, "")
-
- // Strict keywords used in the language.
- (1, As, "as")
- (2, Box, "box")
- (3, Break, "break")
- (4, Const, "const")
- (5, Continue, "continue")
- (6, Crate, "crate")
- (7, Else, "else")
- (8, Enum, "enum")
- (9, Extern, "extern")
- (10, False, "false")
- (11, Fn, "fn")
- (12, For, "for")
- (13, If, "if")
- (14, Impl, "impl")
- (15, In, "in")
- (16, Let, "let")
- (17, Loop, "loop")
- (18, Match, "match")
- (19, Mod, "mod")
- (20, Move, "move")
- (21, Mut, "mut")
- (22, Pub, "pub")
- (23, Ref, "ref")
- (24, Return, "return")
- (25, SelfValue, "self")
- (26, SelfType, "Self")
- (27, Static, "static")
- (28, Struct, "struct")
- (29, Super, "super")
- (30, Trait, "trait")
- (31, True, "true")
- (32, Type, "type")
- (33, Unsafe, "unsafe")
- (34, Use, "use")
- (35, Where, "where")
- (36, While, "while")
-
- // Keywords reserved for future use.
- (37, Abstract, "abstract")
- (38, Alignof, "alignof")
- (39, Become, "become")
- (40, Do, "do")
- (41, Final, "final")
- (42, Macro, "macro")
- (43, Offsetof, "offsetof")
- (44, Override, "override")
- (45, Priv, "priv")
- (46, Proc, "proc")
- (47, Pure, "pure")
- (48, Sizeof, "sizeof")
- (49, Typeof, "typeof")
- (50, Unsized, "unsized")
- (51, Virtual, "virtual")
- (52, Yield, "yield")
-
- // Weak keywords, have special meaning only in specific contexts.
- (53, Default, "default")
- (54, StaticLifetime, "'static")
- (55, Union, "union")
-}
-
-// looks like we can get rid of this completely...
-pub type IdentInterner = Interner;
-
-// if an interner exists in TLS, return it. Otherwise, prepare a
-// fresh one.
-// FIXME(eddyb) #8726 This should probably use a thread-local reference.
-pub fn with_ident_interner<T, F: FnOnce(&mut IdentInterner) -> T>(f: F) -> T {
- thread_local!(static KEY: RefCell<IdentInterner> = {
- RefCell::new(mk_fresh_ident_interner())
- });
- KEY.with(|interner| f(&mut *interner.borrow_mut()))
-}
-
-/// Reset the ident interner to its initial state.
-pub fn reset_ident_interner() {
- with_ident_interner(|interner| *interner = mk_fresh_ident_interner());
-}
-
-pub fn clear_ident_interner() {
- with_ident_interner(|interner| *interner = IdentInterner::new());
-}
-
-/// Represents a string stored in the thread-local interner. Because the
-/// interner lives for the life of the thread, this can be safely treated as an
-/// immortal string, as long as it never crosses between threads.
-///
-/// FIXME(pcwalton): You must be careful about what you do in the destructors
-/// of objects stored in TLS, because they may run after the interner is
-/// destroyed. In particular, they must not access string contents. This can
-/// be fixed in the future by just leaking all strings until thread death
-/// somehow.
-#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
-pub struct InternedString {
- string: Rc<str>,
-}
-
-impl InternedString {
- #[inline]
- pub fn new(string: &'static str) -> InternedString {
- InternedString {
- string: Rc::__from_str(string),
- }
- }
-
- #[inline]
- pub fn new_from_name(name: ast::Name) -> InternedString {
- with_ident_interner(|interner| InternedString { string: interner.get(name) })
- }
-}
-
-impl Deref for InternedString {
- type Target = str;
-
- fn deref(&self) -> &str { &self.string }
-}
-
-impl fmt::Debug for InternedString {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(&self.string, f)
- }
-}
-
-impl fmt::Display for InternedString {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.string, f)
- }
-}
-
-impl<'a> PartialEq<&'a str> for InternedString {
- #[inline(always)]
- fn eq(&self, other: & &'a str) -> bool {
- PartialEq::eq(&self.string[..], *other)
- }
- #[inline(always)]
- fn ne(&self, other: & &'a str) -> bool {
- PartialEq::ne(&self.string[..], *other)
- }
-}
-
-impl<'a> PartialEq<InternedString> for &'a str {
- #[inline(always)]
- fn eq(&self, other: &InternedString) -> bool {
- PartialEq::eq(*self, &other.string[..])
- }
- #[inline(always)]
- fn ne(&self, other: &InternedString) -> bool {
- PartialEq::ne(*self, &other.string[..])
- }
-}
-
-impl PartialEq<str> for InternedString {
- #[inline(always)]
- fn eq(&self, other: &str) -> bool {
- PartialEq::eq(&self.string[..], other)
- }
- #[inline(always)]
- fn ne(&self, other: &str) -> bool {
- PartialEq::ne(&self.string[..], other)
- }
-}
-
-impl PartialEq<InternedString> for str {
- #[inline(always)]
- fn eq(&self, other: &InternedString) -> bool {
- PartialEq::eq(self, &other.string[..])
- }
- #[inline(always)]
- fn ne(&self, other: &InternedString) -> bool {
- PartialEq::ne(self, &other.string[..])
- }
-}
-
-impl Decodable for InternedString {
- fn decode<D: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
- Ok(intern(&d.read_str()?).as_str())
- }
-}
-
-impl Encodable for InternedString {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- s.emit_str(&self.string)
- }
-}
-
-/// Interns and returns the string contents of an identifier, using the
-/// thread-local interner.
-#[inline]
-pub fn intern_and_get_ident(s: &str) -> InternedString {
- intern(s).as_str()
-}
-
-/// Maps a string to its interned representation.
-#[inline]
-pub fn intern(s: &str) -> ast::Name {
- with_ident_interner(|interner| interner.intern(s))
-}
-
-/// gensym's a new usize, using the current interner.
-#[inline]
-pub fn gensym(s: &str) -> ast::Name {
- with_ident_interner(|interner| interner.gensym(s))
-}
-
-/// Maps a string to an identifier with an empty syntax context.
-#[inline]
-pub fn str_to_ident(s: &str) -> ast::Ident {
- ast::Ident::with_empty_ctxt(intern(s))
-}
-
-/// Maps a string to a gensym'ed identifier.
-#[inline]
-pub fn gensym_ident(s: &str) -> ast::Ident {
- ast::Ident::with_empty_ctxt(gensym(s))
-}
-
-// create a fresh name that maps to the same string as the old one.
-// note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
-// that is, that the new name and the old one are connected to ptr_eq strings.
-pub fn fresh_name(src: ast::Ident) -> ast::Name {
- with_ident_interner(|interner| interner.gensym_copy(src.name))
- // following: debug version. Could work in final except that it's incompatible with
- // good error messages and uses of struct names in ambiguous could-be-binding
- // locations. Also definitely destroys the guarantee given above about ptr_eq.
- /*let num = rand::thread_rng().gen_uint_range(0,0xffff);
- gensym(format!("{}_{}",ident_to_string(src),num))*/
-}
use codemap::{self, CodeMap};
use syntax_pos::{self, BytePos};
use errors;
-use parse::token::{self, keywords, BinOpToken, Token, InternedString};
+use parse::token::{self, BinOpToken, Token};
use parse::lexer::comments;
use parse;
use print::pp::{self, break_offset, word, space, zerobreak, hardbreak};
use print::pp::Breaks::{Consistent, Inconsistent};
use ptr::P;
use std_inject;
+use symbol::{Symbol, keywords};
use tokenstream::{self, TokenTree};
use std::ascii;
// of the feature gate, so we fake them up here.
// #![feature(prelude_import)]
- let prelude_import_meta = attr::mk_list_word_item(InternedString::new("prelude_import"));
- let list = attr::mk_list_item(InternedString::new("feature"),
- vec![prelude_import_meta]);
+ let prelude_import_meta = attr::mk_list_word_item(Symbol::intern("prelude_import"));
+ let list = attr::mk_list_item(Symbol::intern("feature"), vec![prelude_import_meta]);
let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), list);
try!(s.print_attribute(&fake_attr));
// #![no_std]
- let no_std_meta = attr::mk_word_item(InternedString::new("no_std"));
+ let no_std_meta = attr::mk_word_item(Symbol::intern("no_std"));
let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), no_std_meta);
try!(s.print_attribute(&fake_attr));
}
_ => ()
}
match lit.node {
- ast::LitKind::Str(ref st, style) => self.print_string(&st, style),
+ ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
ast::LitKind::Byte(byte) => {
let mut res = String::from("b'");
res.extend(ascii::escape_default(byte).map(|c| c as char));
&f,
t.ty_to_string()))
}
- ast::LitKind::FloatUnsuffixed(ref f) => word(self.writer(), &f[..]),
+ ast::LitKind::FloatUnsuffixed(ref f) => word(self.writer(), &f.as_str()),
ast::LitKind::Bool(val) => {
if val { word(self.writer(), "true") } else { word(self.writer(), "false") }
}
trailing_hardbreak: bool) -> io::Result<()> {
let mut count = 0;
for attr in attrs {
- if attr.node.style == kind {
+ if attr.style == kind {
try!(self.print_attribute_inline(attr, is_inline));
if is_inline {
try!(self.nbsp());
try!(self.hardbreak_if_not_bol());
}
try!(self.maybe_print_comment(attr.span.lo));
- if attr.node.is_sugared_doc {
- try!(word(self.writer(), &attr.value_str().unwrap()));
+ if attr.is_sugared_doc {
+ try!(word(self.writer(), &attr.value_str().unwrap().as_str()));
hardbreak(self.writer())
} else {
- match attr.node.style {
+ match attr.style {
ast::AttrStyle::Inner => try!(word(self.writer(), "#![")),
ast::AttrStyle::Outer => try!(word(self.writer(), "#[")),
}
fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
try!(self.ibox(INDENT_UNIT));
match item.node {
- ast::MetaItemKind::Word(ref name) => {
- try!(word(self.writer(), &name));
+ ast::MetaItemKind::Word => {
+ try!(word(self.writer(), &item.name.as_str()));
}
- ast::MetaItemKind::NameValue(ref name, ref value) => {
- try!(self.word_space(&name[..]));
+ ast::MetaItemKind::NameValue(ref value) => {
+ try!(self.word_space(&item.name.as_str()));
try!(self.word_space("="));
try!(self.print_literal(value));
}
- ast::MetaItemKind::List(ref name, ref items) => {
- try!(word(self.writer(), &name));
+ ast::MetaItemKind::List(ref items) => {
+ try!(word(self.writer(), &item.name.as_str()));
try!(self.popen());
try!(self.commasep(Consistent,
&items[..],
ast::ExprKind::Path(Some(ref qself), ref path) => {
try!(self.print_qpath(path, qself, true))
}
- ast::ExprKind::Break(opt_ident) => {
+ ast::ExprKind::Break(opt_ident, ref opt_expr) => {
try!(word(&mut self.s, "break"));
try!(space(&mut self.s));
if let Some(ident) = opt_ident {
try!(self.print_ident(ident.node));
try!(space(&mut self.s));
}
+ if let Some(ref expr) = *opt_expr {
+ try!(self.print_expr(expr));
+ try!(space(&mut self.s));
+ }
}
ast::ExprKind::Continue(opt_ident) => {
try!(word(&mut self.s, "continue"));
ast::ExprKind::InlineAsm(ref a) => {
try!(word(&mut self.s, "asm!"));
try!(self.popen());
- try!(self.print_string(&a.asm, a.asm_str_style));
+ try!(self.print_string(&a.asm.as_str(), a.asm_str_style));
try!(self.word_space(":"));
- try!(self.commasep(Inconsistent, &a.outputs,
- |s, out| {
- let mut ch = out.constraint.chars();
+ try!(self.commasep(Inconsistent, &a.outputs, |s, out| {
+ let constraint = out.constraint.as_str();
+ let mut ch = constraint.chars();
match ch.next() {
Some('=') if out.is_rw => {
try!(s.print_string(&format!("+{}", ch.as_str()),
ast::StrStyle::Cooked))
}
- _ => try!(s.print_string(&out.constraint,
- ast::StrStyle::Cooked))
+ _ => try!(s.print_string(&constraint, ast::StrStyle::Cooked))
}
try!(s.popen());
try!(s.print_expr(&out.expr));
try!(space(&mut self.s));
try!(self.word_space(":"));
- try!(self.commasep(Inconsistent, &a.inputs,
- |s, &(ref co, ref o)| {
- try!(s.print_string(&co, ast::StrStyle::Cooked));
+ try!(self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| {
+ try!(s.print_string(&co.as_str(), ast::StrStyle::Cooked));
try!(s.popen());
try!(s.print_expr(&o));
try!(s.pclose());
try!(self.commasep(Inconsistent, &a.clobbers,
|s, co| {
- try!(s.print_string(&co, ast::StrStyle::Cooked));
+ try!(s.print_string(&co.as_str(), ast::StrStyle::Cooked));
Ok(())
}));
use ast;
use codemap;
- use parse::token;
use syntax_pos;
#[test]
fn test_fun_to_string() {
- let abba_ident = token::str_to_ident("abba");
+ let abba_ident = ast::Ident::from_str("abba");
let decl = ast::FnDecl {
inputs: Vec::new(),
#[test]
fn test_variant_to_string() {
- let ident = token::str_to_ident("principal_skinner");
+ let ident = ast::Ident::from_str("principal_skinner");
let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
name: ident,
use ast;
use attr;
+use symbol::{Symbol, keywords};
use syntax_pos::{DUMMY_SP, Span};
use codemap::{self, ExpnInfo, NameAndSpan, MacroAttribute};
-use parse::token::{intern, InternedString, keywords};
-use parse::{token, ParseSess};
+use parse::ParseSess;
use ptr::P;
/// Craft a span that will be ignored by the stability lint's
let info = ExpnInfo {
call_site: DUMMY_SP,
callee: NameAndSpan {
- format: MacroAttribute(intern("std_inject")),
+ format: MacroAttribute(Symbol::intern("std_inject")),
span: None,
allow_internal_unstable: true,
}
None => return krate,
};
- let crate_name = token::intern(&alt_std_name.unwrap_or(name.to_string()));
+ let crate_name = Symbol::intern(&alt_std_name.unwrap_or(name.to_string()));
krate.module.items.insert(0, P(ast::Item {
attrs: vec![attr::mk_attr_outer(attr::mk_attr_id(),
- attr::mk_word_item(InternedString::new("macro_use")))],
+ attr::mk_word_item(Symbol::intern("macro_use")))],
vis: ast::Visibility::Inherited,
node: ast::ItemKind::ExternCrate(Some(crate_name)),
- ident: token::str_to_ident(name),
+ ident: ast::Ident::from_str(name),
id: ast::DUMMY_NODE_ID,
span: DUMMY_SP,
}));
let span = ignored_span(sess, DUMMY_SP);
krate.module.items.insert(0, P(ast::Item {
attrs: vec![ast::Attribute {
- node: ast::Attribute_ {
- style: ast::AttrStyle::Outer,
- value: P(ast::MetaItem {
- node: ast::MetaItemKind::Word(token::intern_and_get_ident("prelude_import")),
- span: span,
- }),
- id: attr::mk_attr_id(),
- is_sugared_doc: false,
+ style: ast::AttrStyle::Outer,
+ value: ast::MetaItem {
+ name: Symbol::intern("prelude_import"),
+ node: ast::MetaItemKind::Word,
+ span: span,
},
+ id: attr::mk_attr_id(),
+ is_sugared_doc: false,
span: span,
}],
vis: ast::Visibility::Inherited,
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
global: false,
segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment {
- identifier: token::str_to_ident(name),
+ identifier: ast::Ident::from_str(name),
parameters: ast::PathParameters::none(),
}).collect(),
span: span,
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! An "interner" is a data structure that associates values with usize tags and
+//! allows bidirectional lookup; i.e. given a value, one can easily find the
+//! type, and vice versa.
+
+use serialize::{Decodable, Decoder, Encodable, Encoder};
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::fmt;
+
+/// A symbol is an interned or gensymed string.
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Symbol(u32);
+
+// The interner in thread-local, so `Symbol` shouldn't move between threads.
+impl !Send for Symbol { }
+
+impl Symbol {
+ /// Maps a string to its interned representation.
+ pub fn intern(string: &str) -> Self {
+ with_interner(|interner| interner.intern(string))
+ }
+
+ /// gensym's a new usize, using the current interner.
+ pub fn gensym(string: &str) -> Self {
+ with_interner(|interner| interner.gensym(string))
+ }
+
+ pub fn as_str(self) -> InternedString {
+ with_interner(|interner| unsafe {
+ InternedString {
+ string: ::std::mem::transmute::<&str, &str>(interner.get(self))
+ }
+ })
+ }
+
+ pub fn as_u32(self) -> u32 {
+ self.0
+ }
+}
+
+impl fmt::Debug for Symbol {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}({})", self, self.0)
+ }
+}
+
+impl fmt::Display for Symbol {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.as_str(), f)
+ }
+}
+
+impl Encodable for Symbol {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ s.emit_str(&self.as_str())
+ }
+}
+
+impl Decodable for Symbol {
+ fn decode<D: Decoder>(d: &mut D) -> Result<Symbol, D::Error> {
+ Ok(Symbol::intern(&d.read_str()?))
+ }
+}
+
+impl<'a> PartialEq<&'a str> for Symbol {
+ fn eq(&self, other: &&str) -> bool {
+ *self.as_str() == **other
+ }
+}
+
+#[derive(Default)]
+pub struct Interner {
+ names: HashMap<Box<str>, Symbol>,
+ strings: Vec<Box<str>>,
+}
+
+impl Interner {
+ pub fn new() -> Self {
+ Interner::default()
+ }
+
+ fn prefill(init: &[&str]) -> Self {
+ let mut this = Interner::new();
+ for &string in init {
+ this.intern(string);
+ }
+ this
+ }
+
+ pub fn intern(&mut self, string: &str) -> Symbol {
+ if let Some(&name) = self.names.get(string) {
+ return name;
+ }
+
+ let name = Symbol(self.strings.len() as u32);
+ let string = string.to_string().into_boxed_str();
+ self.strings.push(string.clone());
+ self.names.insert(string, name);
+ name
+ }
+
+ fn gensym(&mut self, string: &str) -> Symbol {
+ let gensym = Symbol(self.strings.len() as u32);
+ // leave out of `names` to avoid colliding
+ self.strings.push(string.to_string().into_boxed_str());
+ gensym
+ }
+
+ pub fn get(&self, name: Symbol) -> &str {
+ &self.strings[name.0 as usize]
+ }
+}
+
+// In this macro, there is the requirement that the name (the number) must be monotonically
+// increasing by one in the special identifiers, starting at 0; the same holds for the keywords,
+// except starting from the next number instead of zero.
+macro_rules! declare_keywords {(
+ $( ($index: expr, $konst: ident, $string: expr) )*
+) => {
+ pub mod keywords {
+ use ast;
+ #[derive(Clone, Copy, PartialEq, Eq)]
+ pub struct Keyword {
+ ident: ast::Ident,
+ }
+ impl Keyword {
+ #[inline] pub fn ident(self) -> ast::Ident { self.ident }
+ #[inline] pub fn name(self) -> ast::Name { self.ident.name }
+ }
+ $(
+ #[allow(non_upper_case_globals)]
+ pub const $konst: Keyword = Keyword {
+ ident: ast::Ident::with_empty_ctxt(ast::Name($index))
+ };
+ )*
+ }
+
+ impl Interner {
+ fn fresh() -> Self {
+ Interner::prefill(&[$($string,)*])
+ }
+ }
+}}
+
+// NB: leaving holes in the ident table is bad! a different ident will get
+// interned with the id from the hole, but it will be between the min and max
+// of the reserved words, and thus tagged as "reserved".
+// After modifying this list adjust `is_strict_keyword`/`is_reserved_keyword`,
+// this should be rarely necessary though if the keywords are kept in alphabetic order.
+declare_keywords! {
+ // Invalid identifier
+ (0, Invalid, "")
+
+ // Strict keywords used in the language.
+ (1, As, "as")
+ (2, Box, "box")
+ (3, Break, "break")
+ (4, Const, "const")
+ (5, Continue, "continue")
+ (6, Crate, "crate")
+ (7, Else, "else")
+ (8, Enum, "enum")
+ (9, Extern, "extern")
+ (10, False, "false")
+ (11, Fn, "fn")
+ (12, For, "for")
+ (13, If, "if")
+ (14, Impl, "impl")
+ (15, In, "in")
+ (16, Let, "let")
+ (17, Loop, "loop")
+ (18, Match, "match")
+ (19, Mod, "mod")
+ (20, Move, "move")
+ (21, Mut, "mut")
+ (22, Pub, "pub")
+ (23, Ref, "ref")
+ (24, Return, "return")
+ (25, SelfValue, "self")
+ (26, SelfType, "Self")
+ (27, Static, "static")
+ (28, Struct, "struct")
+ (29, Super, "super")
+ (30, Trait, "trait")
+ (31, True, "true")
+ (32, Type, "type")
+ (33, Unsafe, "unsafe")
+ (34, Use, "use")
+ (35, Where, "where")
+ (36, While, "while")
+
+ // Keywords reserved for future use.
+ (37, Abstract, "abstract")
+ (38, Alignof, "alignof")
+ (39, Become, "become")
+ (40, Do, "do")
+ (41, Final, "final")
+ (42, Macro, "macro")
+ (43, Offsetof, "offsetof")
+ (44, Override, "override")
+ (45, Priv, "priv")
+ (46, Proc, "proc")
+ (47, Pure, "pure")
+ (48, Sizeof, "sizeof")
+ (49, Typeof, "typeof")
+ (50, Unsized, "unsized")
+ (51, Virtual, "virtual")
+ (52, Yield, "yield")
+
+ // Weak keywords, have special meaning only in specific contexts.
+ (53, Default, "default")
+ (54, StaticLifetime, "'static")
+ (55, Union, "union")
+}
+
+// If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
+fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
+ thread_local!(static INTERNER: RefCell<Interner> = {
+ RefCell::new(Interner::fresh())
+ });
+ INTERNER.with(|interner| f(&mut *interner.borrow_mut()))
+}
+
+/// Represents a string stored in the thread-local interner. Because the
+/// interner lives for the life of the thread, this can be safely treated as an
+/// immortal string, as long as it never crosses between threads.
+///
+/// FIXME(pcwalton): You must be careful about what you do in the destructors
+/// of objects stored in TLS, because they may run after the interner is
+/// destroyed. In particular, they must not access string contents. This can
+/// be fixed in the future by just leaking all strings until thread death
+/// somehow.
+#[derive(Clone, PartialEq, Hash, PartialOrd, Eq, Ord)]
+pub struct InternedString {
+ string: &'static str,
+}
+
+impl !Send for InternedString { }
+
+impl ::std::ops::Deref for InternedString {
+ type Target = str;
+ fn deref(&self) -> &str { self.string }
+}
+
+impl fmt::Debug for InternedString {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Debug::fmt(self.string, f)
+ }
+}
+
+impl fmt::Display for InternedString {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self.string, f)
+ }
+}
+
+impl Decodable for InternedString {
+ fn decode<D: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
+ Ok(Symbol::intern(&d.read_str()?).as_str())
+ }
+}
+
+impl Encodable for InternedString {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ s.emit_str(self.string)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use ast::Name;
+
+ #[test]
+ fn interner_tests() {
+ let mut i: Interner = Interner::new();
+ // first one is zero:
+ assert_eq!(i.intern("dog"), Name(0));
+ // re-use gets the same entry:
+ assert_eq!(i.intern ("dog"), Name(0));
+ // different string gets a different #:
+ assert_eq!(i.intern("cat"), Name(1));
+ assert_eq!(i.intern("cat"), Name(1));
+ // dog is still at zero
+ assert_eq!(i.intern("dog"), Name(0));
+ // gensym gets 3
+ assert_eq!(i.gensym("zebra"), Name(2));
+ // gensym of same string gets new number :
+ assert_eq!(i.gensym("zebra"), Name(3));
+ // gensym of *existing* string gets new number:
+ assert_eq!(i.gensym("dog"), Name(4));
+ }
+}
use fold::Folder;
use util::move_map::MoveMap;
use fold;
-use parse::token::{intern, keywords, InternedString};
use parse::{token, ParseSess};
use print::pprust;
-use ast;
+use ast::{self, Ident};
use ptr::P;
+use symbol::{self, Symbol, keywords};
use util::small_vector::SmallVector;
enum ShouldPanic {
No,
- Yes(Option<InternedString>),
+ Yes(Option<Symbol>),
}
struct Test {
span: Span,
- path: Vec<ast::Ident> ,
+ path: Vec<Ident> ,
bench: bool,
ignore: bool,
should_panic: ShouldPanic
struct TestCtxt<'a> {
sess: &'a ParseSess,
span_diagnostic: &'a errors::Handler,
- path: Vec<ast::Ident>,
+ path: Vec<Ident>,
ext_cx: ExtCtxt<'a>,
testfns: Vec<Test>,
- reexport_test_harness_main: Option<InternedString>,
+ reexport_test_harness_main: Option<Symbol>,
is_test_crate: bool,
// top-level re-export submodule, filled out after folding is finished
- toplevel_reexport: Option<ast::Ident>,
+ toplevel_reexport: Option<Ident>,
}
// Traverse the crate, collecting all the test functions, eliding any
struct TestHarnessGenerator<'a> {
cx: TestCtxt<'a>,
- tests: Vec<ast::Ident>,
+ tests: Vec<Ident>,
// submodule name, gensym'd identifier for re-exports
- tested_submods: Vec<(ast::Ident, ast::Ident)>,
+ tested_submods: Vec<(Ident, Ident)>,
}
impl<'a> fold::Folder for TestHarnessGenerator<'a> {
EntryPointType::MainAttr |
EntryPointType::Start =>
folded.map(|ast::Item {id, ident, attrs, node, vis, span}| {
- let allow_str = InternedString::new("allow");
- let dead_code_str = InternedString::new("dead_code");
+ let allow_str = Symbol::intern("allow");
+ let dead_code_str = Symbol::intern("dead_code");
let word_vec = vec![attr::mk_list_word_item(dead_code_str)];
let allow_dead_code_item = attr::mk_list_item(allow_str, word_vec);
let allow_dead_code = attr::mk_attr_outer(attr::mk_attr_id(),
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { mac }
}
-fn mk_reexport_mod(cx: &mut TestCtxt, parent: ast::NodeId, tests: Vec<ast::Ident>,
- tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
- let super_ = token::str_to_ident("super");
+fn mk_reexport_mod(cx: &mut TestCtxt,
+ parent: ast::NodeId,
+ tests: Vec<Ident>,
+ tested_submods: Vec<(Ident, Ident)>)
+ -> (P<ast::Item>, Ident) {
+ let super_ = Ident::from_str("super");
// Generate imports with `#[allow(private_in_public)]` to work around issue #36768.
let allow_private_in_public = cx.ext_cx.attribute(DUMMY_SP, cx.ext_cx.meta_list(
DUMMY_SP,
- InternedString::new("allow"),
- vec![cx.ext_cx.meta_list_item_word(DUMMY_SP, InternedString::new("private_in_public"))],
+ Symbol::intern("allow"),
+ vec![cx.ext_cx.meta_list_item_word(DUMMY_SP, Symbol::intern("private_in_public"))],
));
let items = tests.into_iter().map(|r| {
cx.ext_cx.item_use_simple(DUMMY_SP, ast::Visibility::Public,
items: items,
};
- let sym = token::gensym_ident("__test_reexports");
+ let sym = Ident::with_empty_ctxt(Symbol::gensym("__test_reexports"));
let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent };
cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent);
let it = cx.ext_cx.monotonic_expander().fold_item(P(ast::Item {
fn generate_test_harness(sess: &ParseSess,
resolver: &mut Resolver,
- reexport_test_harness_main: Option<InternedString>,
+ reexport_test_harness_main: Option<Symbol>,
krate: ast::Crate,
sd: &errors::Handler) -> ast::Crate {
// Remove the entry points
cx.ext_cx.bt_push(ExpnInfo {
call_site: DUMMY_SP,
callee: NameAndSpan {
- format: MacroAttribute(intern("test")),
+ format: MacroAttribute(Symbol::intern("test")),
span: None,
allow_internal_unstable: false,
}
let info = ExpnInfo {
call_site: DUMMY_SP,
callee: NameAndSpan {
- format: MacroAttribute(intern("test")),
+ format: MacroAttribute(Symbol::intern("test")),
span: None,
allow_internal_unstable: true,
}
*/
fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
- let id_test = token::str_to_ident("test");
+ let id_test = Ident::from_str("test");
let (vi, vis, ident) = if cx.is_test_crate {
(ast::ItemKind::Use(
P(nospan(ast::ViewPathSimple(id_test,
let ecx = &cx.ext_cx;
// test::test_main_static
- let test_main_path = ecx.path(sp, vec![token::str_to_ident("test"),
- token::str_to_ident("test_main_static")]);
+ let test_main_path =
+ ecx.path(sp, vec![Ident::from_str("test"), Ident::from_str("test_main_static")]);
+
// test::test_main_static(...)
let test_main_path_expr = ecx.expr_path(test_main_path);
- let tests_ident_expr = ecx.expr_ident(sp, token::str_to_ident("TESTS"));
+ let tests_ident_expr = ecx.expr_ident(sp, Ident::from_str("TESTS"));
let call_test_main = ecx.expr_call(sp, test_main_path_expr,
vec![tests_ident_expr]);
let call_test_main = ecx.stmt_expr(call_test_main);
// #![main]
- let main_meta = ecx.meta_word(sp, token::intern_and_get_ident("main"));
+ let main_meta = ecx.meta_word(sp, Symbol::intern("main"));
let main_attr = ecx.attribute(sp, main_meta);
// pub fn main() { ... }
let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
dummy_spanned(ast::Constness::NotConst),
::abi::Abi::Rust, ast::Generics::default(), main_body);
let main = P(ast::Item {
- ident: token::str_to_ident("main"),
+ ident: Ident::from_str("main"),
attrs: vec![main_attr],
id: ast::DUMMY_NODE_ID,
node: main,
items: vec![import, mainfn, tests],
};
let item_ = ast::ItemKind::Mod(testmod);
- let mod_ident = token::gensym_ident("__test");
+ let mod_ident = Ident::with_empty_ctxt(Symbol::gensym("__test"));
let mut expander = cx.ext_cx.monotonic_expander();
let item = expander.fold_item(P(ast::Item {
vis: ast::Visibility::Public,
span: DUMMY_SP,
})).pop().unwrap();
- let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
+ let reexport = cx.reexport_test_harness_main.map(|s| {
// building `use <ident> = __test::main`
- let reexport_ident = token::str_to_ident(&s);
+ let reexport_ident = Ident::with_empty_ctxt(s);
let use_path =
nospan(ast::ViewPathSimple(reexport_ident,
- path_node(vec![mod_ident, token::str_to_ident("main")])));
+ path_node(vec![mod_ident, Ident::from_str("main")])));
expander.fold_item(P(ast::Item {
id: ast::DUMMY_NODE_ID,
codemap::Spanned { node: t, span: DUMMY_SP }
}
-fn path_node(ids: Vec<ast::Ident> ) -> ast::Path {
+fn path_node(ids: Vec<Ident>) -> ast::Path {
ast::Path {
span: DUMMY_SP,
global: false,
}
}
-fn path_name_i(idents: &[ast::Ident]) -> String {
+fn path_name_i(idents: &[Ident]) -> String {
// FIXME: Bad copies (#2543 -- same for everything else that says "bad")
idents.iter().map(|i| i.to_string()).collect::<Vec<String>>().join("::")
}
fn is_test_crate(krate: &ast::Crate) -> bool {
match attr::find_crate_name(&krate.attrs) {
- Some(ref s) if "test" == &s[..] => true,
+ Some(s) if "test" == &*s.as_str() => true,
_ => false
}
}
// path to the #[test] function: "foo::bar::baz"
let path_string = path_name_i(&path[..]);
- let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..]));
+ let name_expr = ecx.expr_str(span, Symbol::intern(&path_string));
// self::test::StaticTestName($name_expr)
let name_expr = ecx.expr_call(span,
};
let fail_expr = match test.should_panic {
ShouldPanic::No => ecx.expr_path(should_panic_path("No")),
- ShouldPanic::Yes(ref msg) => {
- match *msg {
- Some(ref msg) => {
- let msg = ecx.expr_str(span, msg.clone());
+ ShouldPanic::Yes(msg) => {
+ match msg {
+ Some(msg) => {
+ let msg = ecx.expr_str(span, msg);
let path = should_panic_path("YesWithMessage");
ecx.expr_call(span, ecx.expr_path(path), vec![msg])
}
use parse;
use parse::token::{self, Token, Lit, Nonterminal};
use print::pprust;
+use symbol::Symbol;
use std::fmt;
use std::iter::*;
TokenTree::Delimited(sp, Rc::new(Delimited {
delim: token::Bracket,
open_span: sp,
- tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"))),
+ tts: vec![TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"))),
TokenTree::Token(sp, token::Eq),
TokenTree::Token(sp, token::Literal(
- token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
+ token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))],
close_span: sp,
}))
}
pub fn maybe_str(&self) -> Option<ast::Lit> {
match *self {
TokenTree::Token(sp, Token::Literal(Lit::Str_(s), _)) => {
- let l = LitKind::Str(token::intern_and_get_ident(&parse::str_lit(&s.as_str())),
+ let l = LitKind::Str(Symbol::intern(&parse::str_lit(&s.as_str())),
ast::StrStyle::Cooked);
Some(Spanned {
node: l,
})
}
TokenTree::Token(sp, Token::Literal(Lit::StrRaw(s, n), _)) => {
- let l = LitKind::Str(token::intern_and_get_ident(&parse::raw_str_lit(&s.as_str())),
+ let l = LitKind::Str(Symbol::intern(&parse::raw_str_lit(&s.as_str())),
ast::StrStyle::Raw(n));
Some(Spanned {
node: l,
#[cfg(test)]
mod tests {
use super::*;
+ use syntax::ast::Ident;
use syntax_pos::{Span, BytePos, NO_EXPANSION, DUMMY_SP};
- use parse::token::{self, str_to_ident, Token};
+ use parse::token::{self, Token};
use util::parser_testing::string_to_tts;
use std::rc::Rc;
let test_res = TokenStream::from_tts(string_to_tts("foo::bar::baz".to_string()))
.slice(2..3);
let test_eqs = TokenStream::from_tts(vec![TokenTree::Token(sp(5,8),
- token::Ident(str_to_ident("bar")))]);
+ token::Ident(Ident::from_str("bar")))]);
assert_eq!(test_res, test_eqs)
}
#[test]
fn test_is_empty() {
let test0 = TokenStream::from_tts(Vec::new());
- let test1 = TokenStream::from_tts(vec![TokenTree::Token(sp(0, 1),
- Token::Ident(str_to_ident("a")))]);
+ let test1 = TokenStream::from_tts(
+ vec![TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a")))]
+ );
+
let test2 = TokenStream::from_tts(string_to_tts("foo(bar::baz)".to_string()));
assert_eq!(test0.is_empty(), true);
assert_eq!(test0, None);
let test1_expected = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
- token::Ident(str_to_ident("bar"))),
+ token::Ident(Ident::from_str("bar"))),
TokenTree::Token(sp(4, 6), token::ModSep),
TokenTree::Token(sp(6, 9),
- token::Ident(str_to_ident("baz")))]);
+ token::Ident(Ident::from_str("baz")))]);
assert_eq!(test1, Some(test1_expected));
let test2_expected = TokenStream::from_tts(vec![TokenTree::Token(sp(1, 4),
- token::Ident(str_to_ident("foo"))),
+ token::Ident(Ident::from_str("foo"))),
TokenTree::Token(sp(4, 5), token::Comma),
TokenTree::Token(sp(5, 8),
- token::Ident(str_to_ident("bar"))),
+ token::Ident(Ident::from_str("bar"))),
TokenTree::Token(sp(8, 9), token::Comma),
TokenTree::Token(sp(9, 12),
- token::Ident(str_to_ident("baz")))]);
+ token::Ident(Ident::from_str("baz")))]);
assert_eq!(test2, Some(test2_expected));
assert_eq!(test3, None);
assert_eq!(test0, None);
assert_eq!(test1, None);
- assert_eq!(test2, Some(str_to_ident("foo")));
+ assert_eq!(test2, Some(Ident::from_str("foo")));
assert_eq!(test3, None);
assert_eq!(test4, None);
}
let test0 = as_paren_delimited_stream(string_to_tts("foo,bar,".to_string()));
let test1 = as_paren_delimited_stream(string_to_tts("baz(foo,bar)".to_string()));
- let test0_tts = vec![TokenTree::Token(sp(0, 3), token::Ident(str_to_ident("foo"))),
+ let test0_tts = vec![TokenTree::Token(sp(0, 3), token::Ident(Ident::from_str("foo"))),
TokenTree::Token(sp(3, 4), token::Comma),
- TokenTree::Token(sp(4, 7), token::Ident(str_to_ident("bar"))),
+ TokenTree::Token(sp(4, 7), token::Ident(Ident::from_str("bar"))),
TokenTree::Token(sp(7, 8), token::Comma)];
let test0_stream = TokenStream::from_tts(vec![TokenTree::Delimited(sp(0, 8),
Rc::new(Delimited {
assert_eq!(test0, test0_stream);
- let test1_tts = vec![TokenTree::Token(sp(4, 7), token::Ident(str_to_ident("foo"))),
+ let test1_tts = vec![TokenTree::Token(sp(4, 7), token::Ident(Ident::from_str("foo"))),
TokenTree::Token(sp(7, 8), token::Comma),
- TokenTree::Token(sp(8, 11), token::Ident(str_to_ident("bar")))];
+ TokenTree::Token(sp(8, 11), token::Ident(Ident::from_str("bar")))];
- let test1_parse = vec![TokenTree::Token(sp(0, 3), token::Ident(str_to_ident("baz"))),
+ let test1_parse = vec![TokenTree::Token(sp(0, 3), token::Ident(Ident::from_str("baz"))),
TokenTree::Delimited(sp(3, 12),
Rc::new(Delimited {
delim: token::DelimToken::Paren,
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! An "interner" is a data structure that associates values with usize tags and
-//! allows bidirectional lookup; i.e. given a value, one can easily find the
-//! type, and vice versa.
-
-use ast::Name;
-
-use std::collections::HashMap;
-use std::rc::Rc;
-
-#[derive(Default)]
-pub struct Interner {
- names: HashMap<Rc<str>, Name>,
- strings: Vec<Rc<str>>,
-}
-
-/// When traits can extend traits, we should extend index<Name,T> to get []
-impl Interner {
- pub fn new() -> Self {
- Interner::default()
- }
-
- pub fn prefill(init: &[&str]) -> Self {
- let mut this = Interner::new();
- for &string in init {
- this.intern(string);
- }
- this
- }
-
- pub fn intern(&mut self, string: &str) -> Name {
- if let Some(&name) = self.names.get(string) {
- return name;
- }
-
- let name = Name(self.strings.len() as u32);
- let string = Rc::__from_str(string);
- self.strings.push(string.clone());
- self.names.insert(string, name);
- name
- }
-
- pub fn gensym(&mut self, string: &str) -> Name {
- let gensym = Name(self.strings.len() as u32);
- // leave out of `names` to avoid colliding
- self.strings.push(Rc::__from_str(string));
- gensym
- }
-
- /// Create a gensym with the same name as an existing entry.
- pub fn gensym_copy(&mut self, name: Name) -> Name {
- let gensym = Name(self.strings.len() as u32);
- // leave out of `names` to avoid colliding
- let string = self.strings[name.0 as usize].clone();
- self.strings.push(string);
- gensym
- }
-
- pub fn get(&self, name: Name) -> Rc<str> {
- self.strings[name.0 as usize].clone()
- }
-
- pub fn find(&self, string: &str) -> Option<Name> {
- self.names.get(string).cloned()
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use ast::Name;
-
- #[test]
- fn interner_tests() {
- let mut i: Interner = Interner::new();
- // first one is zero:
- assert_eq!(i.intern("dog"), Name(0));
- // re-use gets the same entry:
- assert_eq!(i.intern ("dog"), Name(0));
- // different string gets a different #:
- assert_eq!(i.intern("cat"), Name(1));
- assert_eq!(i.intern("cat"), Name(1));
- // dog is still at zero
- assert_eq!(i.intern("dog"), Name(0));
- // gensym gets 3
- assert_eq!(i.gensym("zebra"), Name(2));
- // gensym of same string gets new number :
- assert_eq!(i.gensym("zebra"), Name(3));
- // gensym of *existing* string gets new number:
- assert_eq!(i.gensym("dog"), Name(4));
- // gensym tests again with gensym_copy:
- assert_eq!(i.gensym_copy(Name(2)), Name(5));
- assert_eq!(&*i.get(Name(5)), "zebra");
- assert_eq!(i.gensym_copy(Name(2)), Name(6));
- assert_eq!(&*i.get(Name(6)), "zebra");
- assert_eq!(&*i.get(Name(0)), "dog");
- assert_eq!(&*i.get(Name(1)), "cat");
- assert_eq!(&*i.get(Name(2)), "zebra");
- assert_eq!(&*i.get(Name(3)), "zebra");
- assert_eq!(&*i.get(Name(4)), "dog");
- }
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast::Name;
use std::cmp;
-use parse::token::InternedString;
+use symbol::Symbol;
/// To find the Levenshtein distance between two strings
pub fn lev_distance(a: &str, b: &str) -> usize {
/// to one-third of the given word
pub fn find_best_match_for_name<'a, T>(iter_names: T,
lookup: &str,
- dist: Option<usize>) -> Option<InternedString>
- where T: Iterator<Item = &'a Name> {
+ dist: Option<usize>) -> Option<Symbol>
+ where T: Iterator<Item = &'a Symbol> {
let max_dist = dist.map_or_else(|| cmp::max(lookup.len(), 3) / 3, |d| d);
iter_names
- .filter_map(|name| {
+ .filter_map(|&name| {
let dist = lev_distance(lookup, &name.as_str());
match dist <= max_dist { // filter the unwanted cases
- true => Some((name.as_str(), dist)),
+ true => Some((name, dist)),
false => None,
}
})
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use parse::token::{Token, BinOpToken, keywords};
+use parse::token::{Token, BinOpToken};
+use symbol::keywords;
use ast::BinOpKind;
/// Associative operator with precedence.
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast;
+use ast::{self, Ident};
use parse::{ParseSess,PResult,filemap_to_tts};
use parse::{lexer, new_parser_from_source_str};
use parse::parser::Parser;
-use parse::token;
use ptr::P;
use tokenstream;
use std::iter::Peekable;
})
}
-/// Convert a vector of strings to a vector of ast::Ident's
-pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<ast::Ident> {
- ids.iter().map(|u| token::str_to_ident(*u)).collect()
+/// Convert a vector of strings to a vector of Ident's
+pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<Ident> {
+ ids.iter().map(|u| Ident::from_str(*u)).collect()
}
/// Does the given string match the pattern? whitespace in the first string
}
visitor.visit_path(path, expression.id)
}
- ExprKind::Break(ref opt_sp_ident) | ExprKind::Continue(ref opt_sp_ident) => {
+ ExprKind::Break(ref opt_sp_ident, ref opt_expr) => {
+ walk_opt_sp_ident(visitor, opt_sp_ident);
+ walk_list!(visitor, visit_expr, opt_expr);
+ }
+ ExprKind::Continue(ref opt_sp_ident) => {
walk_opt_sp_ident(visitor, opt_sp_ident);
}
ExprKind::Ret(ref optional_expression) => {
use syntax::ext::base;
use syntax::ext::base::*;
use syntax::feature_gate;
-use syntax::parse::token::intern;
use syntax::parse::{self, token};
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax::ast::AsmDialect;
use syntax_pos::Span;
use syntax::tokenstream;
})
.unwrap_or(tts.len());
let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
- let mut asm = token::InternedString::new("");
+ let mut asm = Symbol::intern("");
let mut asm_str_style = None;
let mut outputs = Vec::new();
let mut inputs = Vec::new();
// It's the opposite of '=&' which means that the memory
// cannot be shared with any other operand (usually when
// a register is clobbered early.)
- let mut ch = constraint.chars();
+ let constraint_str = constraint.as_str();
+ let mut ch = constraint_str.chars();
let output = match ch.next() {
Some('=') => None,
Some('+') => {
- Some(token::intern_and_get_ident(&format!("={}", ch.as_str())))
+ Some(Symbol::intern(&format!("={}", ch.as_str())))
}
_ => {
cx.span_err(span, "output operand constraint lacks '=' or '+'");
};
let is_rw = output.is_some();
- let is_indirect = constraint.contains("*");
+ let is_indirect = constraint_str.contains("*");
outputs.push(ast::InlineAsmOutput {
- constraint: output.unwrap_or(constraint.clone()),
+ constraint: output.unwrap_or(constraint),
expr: out,
is_rw: is_rw,
is_indirect: is_indirect,
let (constraint, _str_style) = panictry!(p.parse_str());
- if constraint.starts_with("=") {
+ if constraint.as_str().starts_with("=") {
cx.span_err(p.prev_span, "input operand constraint contains '='");
- } else if constraint.starts_with("+") {
+ } else if constraint.as_str().starts_with("+") {
cx.span_err(p.prev_span, "input operand constraint contains '+'");
}
if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.prev_span, "expected a clobber, found an option");
- } else if s.starts_with("{") || s.ends_with("}") {
+ } else if s.as_str().starts_with("{") || s.as_str().ends_with("}") {
cx.span_err(p.prev_span, "clobber should not be surrounded by braces");
}
let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: sp,
callee: codemap::NameAndSpan {
- format: codemap::MacroBang(intern("asm")),
+ format: codemap::MacroBang(Symbol::intern("asm")),
span: None,
allow_internal_unstable: false,
},
MacEager::expr(P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::InlineAsm(P(ast::InlineAsm {
- asm: token::intern_and_get_ident(&asm),
+ asm: asm,
asm_str_style: asm_str_style.unwrap(),
outputs: outputs,
inputs: inputs,
use syntax::ast;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax_pos;
use syntax::tokenstream;
ast::LitKind::Str(ref s, _) |
ast::LitKind::Float(ref s, _) |
ast::LitKind::FloatUnsuffixed(ref s) => {
- accumulator.push_str(&s);
+ accumulator.push_str(&s.as_str());
}
ast::LitKind::Char(c) => {
accumulator.push(c);
}
}
}
- base::MacEager::expr(cx.expr_str(sp, token::intern_and_get_ident(&accumulator[..])))
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
}
use syntax::ext::base;
use syntax::feature_gate;
use syntax::parse::token;
-use syntax::parse::token::str_to_ident;
use syntax::ptr::P;
use syntax_pos::Span;
use syntax::tokenstream::TokenTree;
}
}
}
- let res = str_to_ident(&res_str);
+ let res = ast::Ident::from_str(&res_str);
struct Result {
ident: ast::Ident,
use syntax::attr;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::{keywords, InternedString};
use syntax::ptr::P;
+use syntax::symbol::{Symbol, keywords};
use syntax_pos::Span;
pub fn expand_deriving_clone(cx: &mut ExtCtxt,
_ => cx.span_bug(span, "#[derive(Clone)] on trait item or impl item"),
}
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
use syntax::ast::{self, Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_eq(cx: &mut ExtCtxt,
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable)) {
- let inline = cx.meta_word(span, InternedString::new("inline"));
- let hidden = cx.meta_list_item_word(span, InternedString::new("hidden"));
- let doc = cx.meta_list(span, InternedString::new("doc"), vec![hidden]);
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
+ let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
+ let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)];
let trait_def = TraitDef {
span: span,
use syntax::ast::{self, Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_ord(cx: &mut ExtCtxt,
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable)) {
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
use syntax::ast::{BinOpKind, Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
macro_rules! md {
($name:expr, $f:ident) => { {
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
MethodDef {
name: $name,
use syntax::ast::{self, BinOpKind, Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
push: &mut FnMut(Annotatable)) {
macro_rules! md {
($name:expr, $op:expr, $equal:expr) => { {
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
MethodDef {
name: $name,
vec![Box::new(ordering_ty)],
true));
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
let partial_cmp_def = MethodDef {
use syntax::codemap::Span;
use syntax::ext::base::*;
use syntax::fold::Folder;
-use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
-struct MarkAttrs<'a>(&'a [InternedString]);
+struct MarkAttrs<'a>(&'a [ast::Name]);
impl<'a> Visitor for MarkAttrs<'a> {
fn visit_attribute(&mut self, attr: &Attribute) {
pub struct CustomDerive {
inner: fn(TokenStream) -> TokenStream,
- attrs: Vec<InternedString>,
+ attrs: Vec<ast::Name>,
}
impl CustomDerive {
- pub fn new(inner: fn(TokenStream) -> TokenStream,
- attrs: Vec<InternedString>)
- -> CustomDerive {
+ pub fn new(inner: fn(TokenStream) -> TokenStream, attrs: Vec<ast::Name>) -> CustomDerive {
CustomDerive { inner: inner, attrs: attrs }
}
}
use deriving::generic::*;
use deriving::generic::ty::*;
-use syntax::ast;
+use syntax::ast::{self, Ident};
use syntax::ast::{Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
use syntax::ptr::P;
use syntax_pos::{DUMMY_SP, Span};
// We want to make sure we have the expn_id set so that we can use unstable methods
let span = Span { expn_id: cx.backtrace(), ..span };
- let name = cx.expr_lit(span,
- ast::LitKind::Str(ident.name.as_str(), ast::StrStyle::Cooked));
- let builder = token::str_to_ident("builder");
+ let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
+ let builder = Ident::from_str("builder");
let builder_expr = cx.expr_ident(span, builder.clone());
let fmt = substr.nonself_args[0].clone();
if !is_struct {
// tuple struct/"normal" variant
let expr =
- cx.expr_method_call(span, fmt, token::str_to_ident("debug_tuple"), vec![name]);
+ cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields {
let expr = cx.expr_method_call(span,
builder_expr.clone(),
- token::str_to_ident("field"),
+ Ident::from_str("field"),
vec![field]);
// Use `let _ = expr;` to avoid triggering the
} else {
// normal struct/struct variant
let expr =
- cx.expr_method_call(span, fmt, token::str_to_ident("debug_struct"), vec![name]);
+ cx.expr_method_call(span, fmt, Ident::from_str("debug_struct"), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields {
let name = cx.expr_lit(field.span,
- ast::LitKind::Str(field.name.unwrap().name.as_str(),
+ ast::LitKind::Str(field.name.unwrap().name,
ast::StrStyle::Cooked));
// Use double indirection to make sure this works for unsized types
let field = cx.expr_addr_of(field.span, field);
let expr = cx.expr_method_call(span,
builder_expr.clone(),
- token::str_to_ident("field"),
+ Ident::from_str("field"),
vec![name, field]);
stmts.push(stmt_let_undescore(cx, span, expr));
}
_ => unreachable!(),
};
- let expr = cx.expr_method_call(span, builder_expr, token::str_to_ident("finish"), vec![]);
+ let expr = cx.expr_method_call(span, builder_expr, Ident::from_str("finish"), vec![]);
stmts.push(cx.stmt_expr(expr));
let block = cx.block(span, stmts);
use syntax::ast::{Expr, MetaItem, Mutability};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
-use syntax::parse::token;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt,
cx.expr_method_call(trait_span,
decoder,
cx.ident_of("read_struct"),
- vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ vec![cx.expr_str(trait_span, substr.type_ident.name),
cx.expr_usize(trait_span, nfields),
cx.lambda1(trait_span, result, blkarg)])
}
let rvariant_arg = cx.ident_of("read_enum_variant_arg");
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
- variants.push(cx.expr_str(v_span, ident.name.as_str()));
+ variants.push(cx.expr_str(v_span, ident.name));
let path = cx.path(trait_span, vec![substr.type_ident, ident]);
let decoded = decode_static_fields(cx, v_span, path, parts, |cx, span, _, field| {
cx.expr_method_call(trait_span,
decoder,
cx.ident_of("read_enum"),
- vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ vec![cx.expr_str(trait_span, substr.type_ident.name),
cx.lambda1(trait_span, result, blkarg)])
}
_ => cx.bug("expected StaticEnum or StaticStruct in derive(Decodable)"),
fields: &StaticFields,
mut getarg: F)
-> P<Expr>
- where F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P<Expr>
+ where F: FnMut(&mut ExtCtxt, Span, Symbol, usize) -> P<Expr>
{
match *fields {
Unnamed(ref fields, is_tuple) => {
let fields = fields.iter()
.enumerate()
.map(|(i, &span)| {
- getarg(cx,
- span,
- token::intern_and_get_ident(&format!("_field{}", i)),
- i)
+ getarg(cx, span, Symbol::intern(&format!("_field{}", i)), i)
})
.collect();
let fields = fields.iter()
.enumerate()
.map(|(i, &(ident, span))| {
- let arg = getarg(cx, span, ident.name.as_str(), i);
+ let arg = getarg(cx, span, ident.name, i);
cx.field_imm(span, ident, arg)
})
.collect();
use syntax::ast::{Expr, MetaItem};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::InternedString;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_default(cx: &mut ExtCtxt,
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable)) {
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
let trait_def = TraitDef {
span: span,
use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt,
let mut stmts = Vec::new();
for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
let name = match name {
- Some(id) => id.name.as_str(),
- None => token::intern_and_get_ident(&format!("_field{}", i)),
+ Some(id) => id.name,
+ None => Symbol::intern(&format!("_field{}", i)),
};
let self_ref = cx.expr_addr_of(span, self_.clone());
let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
cx.expr_method_call(trait_span,
encoder,
cx.ident_of("emit_struct"),
- vec![cx.expr_str(trait_span, substr.type_ident.name.as_str()),
+ vec![cx.expr_str(trait_span, substr.type_ident.name),
cx.expr_usize(trait_span, fields.len()),
blk])
}
}
let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
- let name = cx.expr_str(trait_span, variant.node.name.name.as_str());
+ let name = cx.expr_str(trait_span, variant.node.name.name);
let call = cx.expr_method_call(trait_span,
blkencoder,
cx.ident_of("emit_enum_variant"),
let ret = cx.expr_method_call(trait_span,
encoder,
cx.ident_of("emit_enum"),
- vec![cx.expr_str(trait_span,
- substr.type_ident.name.as_str()),
+ vec![cx.expr_str(trait_span ,substr.type_ident.name),
blk]);
cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
}
use syntax::ext::build::AstBuilder;
use syntax::codemap::{self, dummy_spanned, respan};
use syntax::util::move_map::MoveMap;
-use syntax::parse::token::{InternedString, keywords};
use syntax::ptr::P;
+use syntax::symbol::{Symbol, keywords};
use syntax_pos::{DUMMY_SP, Span};
use errors::Handler;
attrs.extend(item.attrs
.iter()
.filter(|a| {
- match &a.name()[..] {
+ match &*a.name().as_str() {
"allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
_ => false,
}
let attr = cx.attribute(self.span,
cx.meta_word(self.span,
- InternedString::new("automatically_derived")));
+ Symbol::intern("automatically_derived")));
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
let opt_trait_ref = Some(trait_ref);
- let unused_qual = cx.attribute(self.span,
- cx.meta_list(self.span,
- InternedString::new("allow"),
- vec![cx.meta_list_item_word(self.span,
- InternedString::new("unused_qualifications"))]));
+ let unused_qual = {
+ let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications"));
+ cx.attribute(self.span, cx.meta_list(self.span, Symbol::intern("allow"), vec![word]))
+ };
+
let mut a = vec![attr, unused_qual];
a.extend(self.attributes.iter().cloned());
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate::{self, emit_feature_err};
-use syntax::parse::token::{intern, intern_and_get_ident};
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
macro_rules! pathvec {
expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: span,
callee: codemap::NameAndSpan {
- format: codemap::MacroAttribute(intern(attr_name)),
+ format: codemap::MacroAttribute(Symbol::intern(attr_name)),
span: Some(span),
allow_internal_unstable: true,
},
}
};
+ let derive = Symbol::intern("derive");
let mut derive_attrs = Vec::new();
item = item.map_attrs(|attrs| {
- let partition = attrs.into_iter().partition(|attr| &attr.name() == "derive");
+ let partition = attrs.into_iter().partition(|attr| attr.name() == derive);
derive_attrs = partition.0;
partition.1
});
// Expand `#[derive]`s after other attribute macro invocations.
if cx.resolver.find_attr_invoc(&mut item.attrs.clone()).is_some() {
return vec![Annotatable::Item(item.map_attrs(|mut attrs| {
- attrs.push(cx.attribute(span, P(mitem.clone())));
+ attrs.push(cx.attribute(span, mitem.clone()));
attrs.extend(derive_attrs);
attrs
}))];
let mut traits = get_traits(mitem, cx);
for derive_attr in derive_attrs {
- traits.extend(get_traits(&derive_attr.node.value, cx));
+ traits.extend(get_traits(&derive_attr.value, cx));
}
// First, weed out malformed #[derive]
let tword = titem.word().unwrap();
let tname = tword.name();
- if is_builtin_trait(&tname) || {
- let derive_mode =
- ast::Path::from_ident(titem.span, ast::Ident::with_empty_ctxt(intern(&tname)));
+ if is_builtin_trait(tname) || {
+ let derive_mode = ast::Path::from_ident(titem.span, ast::Ident::with_empty_ctxt(tname));
cx.resolver.resolve_macro(cx.current_expansion.mark, &derive_mode, false).map(|ext| {
if let SyntaxExtension::CustomDerive(_) = *ext { true } else { false }
}).unwrap_or(false)
feature_gate::EXPLAIN_CUSTOM_DERIVE);
} else {
cx.span_warn(titem.span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE);
- let name = intern_and_get_ident(&format!("derive_{}", tname));
+ let name = Symbol::intern(&format!("derive_{}", tname));
let mitem = cx.meta_word(titem.span, name);
new_attributes.push(cx.attribute(mitem.span, mitem));
}
item = item.map(|mut i| {
i.attrs.extend(new_attributes);
if traits.len() > 0 {
- let list = cx.meta_list(mitem.span,
- intern_and_get_ident("derive"),
- traits);
+ let list = cx.meta_list(mitem.span, derive, traits);
i.attrs.push(cx.attribute(mitem.span, list));
}
i
let macros_11_derive = traits.iter()
.cloned()
.enumerate()
- .filter(|&(_, ref name)| !is_builtin_trait(&name.name().unwrap()))
+ .filter(|&(_, ref name)| !is_builtin_trait(name.name().unwrap()))
.next();
if let Some((i, titem)) = macros_11_derive {
if !cx.ecfg.features.unwrap().proc_macro {
emit_feature_err(cx.parse_sess, "proc_macro", titem.span, issue, msg);
}
- let tname = ast::Ident::with_empty_ctxt(intern(&titem.name().unwrap()));
+ let tname = ast::Ident::with_empty_ctxt(titem.name().unwrap());
let path = ast::Path::from_ident(titem.span, tname);
let ext = cx.resolver.resolve_macro(cx.current_expansion.mark, &path, false).unwrap();
traits.remove(i);
if traits.len() > 0 {
item = item.map(|mut i| {
- let list = cx.meta_list(mitem.span,
- intern_and_get_ident("derive"),
- traits);
+ let list = cx.meta_list(mitem.span, derive, traits);
i.attrs.push(cx.attribute(mitem.span, list));
i
});
}
let titem = cx.meta_list_item_word(titem.span, titem.name().unwrap());
- let mitem = cx.meta_list(titem.span,
- intern_and_get_ident("derive"),
- vec![titem]);
+ let mitem = cx.meta_list(titem.span, derive, vec![titem]);
let item = Annotatable::Item(item);
if let SyntaxExtension::CustomDerive(ref ext) = *ext {
return ext.expand(cx, mitem.span, &mitem, item);
// RFC #1445. `#[derive(PartialEq, Eq)]` adds a (trusted)
// `#[structural_match]` attribute.
- if traits.iter().filter_map(|t| t.name()).any(|t| t == "PartialEq") &&
- traits.iter().filter_map(|t| t.name()).any(|t| t == "Eq") {
- let structural_match = intern_and_get_ident("structural_match");
+ let (partial_eq, eq) = (Symbol::intern("PartialEq"), Symbol::intern("Eq"));
+ if traits.iter().any(|t| t.name() == Some(partial_eq)) &&
+ traits.iter().any(|t| t.name() == Some(eq)) {
+ let structural_match = Symbol::intern("structural_match");
let span = allow_unstable(cx, span, "derive(PartialEq, Eq)");
let meta = cx.meta_word(span, structural_match);
item = item.map(|mut i| {
// the same as the copy implementation.
//
// Add a marker attribute here picked up during #[derive(Clone)]
- if traits.iter().filter_map(|t| t.name()).any(|t| t == "Clone") &&
- traits.iter().filter_map(|t| t.name()).any(|t| t == "Copy") {
- let marker = intern_and_get_ident("rustc_copy_clone_marker");
+ let (copy, clone) = (Symbol::intern("Copy"), Symbol::intern("Clone"));
+ if traits.iter().any(|t| t.name() == Some(clone)) &&
+ traits.iter().any(|t| t.name() == Some(copy)) {
+ let marker = Symbol::intern("rustc_copy_clone_marker");
let span = allow_unstable(cx, span, "derive(Copy, Clone)");
let meta = cx.meta_word(span, marker);
item = item.map(|mut i| {
let mut items = Vec::new();
for titem in traits.iter() {
let tname = titem.word().unwrap().name();
- let name = intern_and_get_ident(&format!("derive({})", tname));
+ let name = Symbol::intern(&format!("derive({})", tname));
let mitem = cx.meta_word(titem.span, name);
let span = Span {
expn_id: cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: titem.span,
callee: codemap::NameAndSpan {
- format: codemap::MacroAttribute(intern(&format!("derive({})", tname))),
+ format: codemap::MacroAttribute(Symbol::intern(&format!("derive({})", tname))),
span: Some(titem.span),
allow_internal_unstable: true,
},
};
let my_item = Annotatable::Item(item);
- expand_builtin(&tname, cx, span, &mitem, &my_item, &mut |a| {
+ expand_builtin(&tname.as_str(), cx, span, &mitem, &my_item, &mut |a| {
items.push(a);
});
item = my_item.expect_item();
macro_rules! derive_traits {
($( $name:expr => $func:path, )+) => {
- pub fn is_builtin_trait(name: &str) -> bool {
- match name {
+ pub fn is_builtin_trait(name: ast::Name) -> bool {
+ match &*name.as_str() {
$( $name )|+ => true,
_ => false,
}
span.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo {
call_site: span,
callee: codemap::NameAndSpan {
- format: codemap::MacroAttribute(intern("derive")),
+ format: codemap::MacroAttribute(Symbol::intern("derive")),
span: Some(span),
allow_internal_unstable: true,
},
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use syntax::tokenstream;
Some(v) => v,
};
- let e = match env::var(&var[..]) {
+ let e = match env::var(&*var.as_str()) {
Err(..) => {
cx.expr_path(cx.path_all(sp,
true,
Ok(s) => {
cx.expr_call_global(sp,
cx.std_path(&["option", "Option", "Some"]),
- vec![cx.expr_str(sp, token::intern_and_get_ident(&s[..]))])
+ vec![cx.expr_str(sp, Symbol::intern(&s))])
}
};
MacEager::expr(e)
Some((v, _style)) => v,
};
let msg = match exprs.next() {
- None => token::intern_and_get_ident(&format!("environment variable `{}` not defined", var)),
+ 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),
return DummyResult::expr(sp);
}
- let e = match env::var(&var[..]) {
+ let e = match env::var(&*var.as_str()) {
Err(_) => {
- cx.span_err(sp, &msg);
+ cx.span_err(sp, &msg.as_str());
cx.expr_usize(sp, 0)
}
- Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s)),
+ Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
};
MacEager::expr(e)
}
use syntax::ext::base::*;
use syntax::ext::base;
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::{self, keywords};
+use syntax::parse::token;
use syntax::ptr::P;
+use syntax::symbol::{Symbol, keywords};
use syntax_pos::{Span, DUMMY_SP};
use syntax::tokenstream;
/// Translate the accumulated string literals to a literal expression
fn trans_literal_string(&mut self) -> P<ast::Expr> {
let sp = self.fmtsp;
- let s = token::intern_and_get_ident(&self.literal);
+ let s = Symbol::intern(&self.literal);
self.literal.clear();
self.ecx.expr_str(sp, s)
}
fmtsp: fmt.span,
};
- let mut parser = parse::Parser::new(&fmt.node.0);
+ let fmt_str = &*fmt.node.0.as_str();
+ let mut parser = parse::Parser::new(fmt_str);
let mut pieces = vec![];
loop {
// Decide if we want to look for foreign formatting directives.
if args_used < args_unused {
use super::format_foreign as foreign;
- let fmt_str = &fmt.node.0[..];
// The set of foreign substitutions we've explained. This prevents spamming the user
// with `%d should be written as {}` over and over again.
use syntax::ast;
use syntax::ext::base::{MacroExpanderFn, NormalTT, IdentTT, MultiModifier, NamedSyntaxExtension};
use syntax::ext::tt::macro_rules::MacroRulesExpander;
-use syntax::parse::token::intern;
+use syntax::symbol::Symbol;
pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver,
user_exts: Vec<NamedSyntaxExtension>,
resolver.add_ext(ast::Ident::with_empty_ctxt(name), Rc::new(ext));
};
- register(intern("macro_rules"), IdentTT(Box::new(MacroRulesExpander), None, false));
+ register(Symbol::intern("macro_rules"), IdentTT(Box::new(MacroRulesExpander), None, false));
macro_rules! register {
($( $name:ident: $f:expr, )*) => { $(
- register(intern(stringify!($name)),
+ register(Symbol::intern(stringify!($name)),
NormalTT(Box::new($f as MacroExpanderFn), None, false));
)* }
}
}
// format_args uses `unstable` things internally.
- register(intern("format_args"), NormalTT(Box::new(format::expand_format_args), None, true));
+ register(Symbol::intern("format_args"),
+ NormalTT(Box::new(format::expand_format_args), None, true));
- register(intern("derive"), MultiModifier(Box::new(deriving::expand_derive)));
+ register(Symbol::intern("derive"), MultiModifier(Box::new(deriving::expand_derive)));
for (name, ext) in user_exts {
register(name, ext);
use syntax::ext::build::AstBuilder;
use syntax::ext::expand::ExpansionConfig;
use syntax::parse::ParseSess;
-use syntax::parse::token::{self, InternedString};
use syntax::feature_gate::Features;
use syntax::fold::Folder;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::{Span, DUMMY_SP};
use syntax::visit::{self, Visitor};
use deriving;
struct CustomDerive {
- trait_name: InternedString,
+ trait_name: ast::Name,
function_name: Ident,
span: Span,
- attrs: Vec<InternedString>,
+ attrs: Vec<ast::Name>,
}
struct CollectCustomDerives<'a> {
self.handler.span_err(trait_attr.span(), "must only be one word");
}
- if deriving::is_builtin_trait(&trait_name) {
+ if deriving::is_builtin_trait(trait_name) {
self.handler.span_err(trait_attr.span(),
"cannot override a built-in #[derive] mode");
}
let eid = cx.codemap().record_expansion(ExpnInfo {
call_site: DUMMY_SP,
callee: NameAndSpan {
- format: MacroAttribute(token::intern("proc_macro")),
+ format: MacroAttribute(Symbol::intern("proc_macro")),
span: None,
allow_internal_unstable: true,
}
});
let span = Span { expn_id: eid, ..DUMMY_SP };
- let proc_macro = token::str_to_ident("proc_macro");
+ let proc_macro = Ident::from_str("proc_macro");
let krate = cx.item(span,
proc_macro,
Vec::new(),
ast::ItemKind::ExternCrate(None));
- let __internal = token::str_to_ident("__internal");
- let registry = token::str_to_ident("Registry");
- let registrar = token::str_to_ident("registrar");
- let register_custom_derive = token::str_to_ident("register_custom_derive");
+ let __internal = Ident::from_str("__internal");
+ let registry = Ident::from_str("Registry");
+ let registrar = Ident::from_str("registrar");
+ let register_custom_derive = Ident::from_str("register_custom_derive");
let stmts = custom_derives.iter().map(|cd| {
let path = cx.path_global(cd.span, vec![cd.function_name]);
- let trait_name = cx.expr_str(cd.span, cd.trait_name.clone());
+ let trait_name = cx.expr_str(cd.span, cd.trait_name);
let attrs = cx.expr_vec_slice(
span,
- cd.attrs.iter().map(|s| cx.expr_str(cd.span, s.clone())).collect::<Vec<_>>()
+ cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
);
(path, trait_name, attrs)
}).map(|(path, trait_name, attrs)| {
cx.ty(span, ast::TyKind::Tup(Vec::new())),
cx.block(span, stmts));
- let derive_registrar = token::intern_and_get_ident("rustc_derive_registrar");
- let derive_registrar = cx.meta_word(span, derive_registrar);
+ let derive_registrar = cx.meta_word(span, Symbol::intern("rustc_derive_registrar"));
let derive_registrar = cx.attribute(span, derive_registrar);
let func = func.map(|mut i| {
i.attrs.push(derive_registrar);
i.vis = ast::Visibility::Public;
i
});
- let ident = ast::Ident::with_empty_ctxt(token::gensym("registrar"));
+ let ident = ast::Ident::with_empty_ctxt(Symbol::gensym("registrar"));
let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| {
i.vis = ast::Visibility::Public;
i
use syntax::ext::base::ExtCtxt;
use syntax::ext::base;
use syntax::feature_gate;
-use syntax::parse::token::keywords;
+use syntax::symbol::keywords;
use syntax_pos::Span;
use syntax::tokenstream::TokenTree;
}
}
-extern "C" LLVMAttributeRef LLVMRustCreateAttribute(LLVMContextRef C, LLVMRustAttribute Kind, uint64_t Val) {
- return wrap(Attribute::get(*unwrap(C), from_rust(Kind), Val));
-}
-
-extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, LLVMAttributeRef attr) {
+extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, LLVMRustAttribute attr) {
CallSite Call = CallSite(unwrap<Instruction>(Instr));
- AttrBuilder B(unwrap(attr));
+ Attribute Attr = Attribute::get(Call->getContext(), from_rust(attr));
+ AttrBuilder B(Attr);
Call.setAttributes(
Call.getAttributes().addAttributes(Call->getContext(), index,
AttributeSet::get(Call->getContext(),
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
unsigned index,
- LLVMAttributeRef attr)
+ LLVMRustAttribute attr)
{
Function *A = unwrap<Function>(Fn);
- AttrBuilder B(unwrap(attr));
+ Attribute Attr = Attribute::get(A->getContext(), from_rust(attr));
+ AttrBuilder B(Attr);
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
}
extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
unsigned index,
- LLVMAttributeRef attr)
+ LLVMRustAttribute attr)
{
Function *F = unwrap<Function>(Fn);
const AttributeSet PAL = F->getAttributes();
- AttrBuilder B(unwrap(attr));
+ Attribute Attr = Attribute::get(F->getContext(), from_rust(attr));
+ AttrBuilder B(Attr);
const AttributeSet PALnew =
PAL.removeAttributes(F->getContext(), index,
AttributeSet::get(F->getContext(), index, B));
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
- if it.ident.name.as_str() == "lintme" {
+ if it.ident.name == "lintme" {
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
}
}
use syntax::ast::{self, Item, MetaItem, ItemKind};
use syntax::ext::base::*;
-use syntax::parse::{self, token};
+use syntax::parse;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax::tokenstream::TokenTree;
use syntax_pos::Span;
use rustc_plugin::Registry;
reg.register_macro("make_a_1", expand_make_a_1);
reg.register_macro("identity", expand_identity);
reg.register_syntax_extension(
- token::intern("into_multi_foo"),
+ Symbol::intern("into_multi_foo"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
MultiModifier(Box::new(expand_into_foo_multi)));
reg.register_syntax_extension(
- token::intern("duplicate"),
+ Symbol::intern("duplicate"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
MultiDecorator(Box::new(expand_duplicate)));
}
push: &mut FnMut(Annotatable))
{
let copy_name = match mi.node {
- ast::MetaItemKind::List(_, ref xs) => {
+ ast::MetaItemKind::List(ref xs) => {
if let Some(word) = xs[0].word() {
- token::str_to_ident(&word.name())
+ ast::Ident::with_empty_ctxt(word.name())
} else {
cx.span_err(mi.span, "Expected word");
return;
extern crate syntax_pos;
use syntax::ast;
-use syntax::parse;
use syntax::print::pprust;
+use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;
fn main() {
cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan {
- format: syntax::codemap::MacroBang(parse::token::intern("")),
+ format: syntax::codemap::MacroBang(Symbol::intern("")),
allow_internal_unstable: false,
span: None,
}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod bar {
- pub fn foo() {}
-}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(item_like_imports)]
-
-pub mod c {
- pub struct S {}
- pub struct TS();
- pub struct US;
- pub enum E {
- V {},
- TV(),
- UV,
- }
-
- pub struct Item;
-}
-
-pub mod xm1 {
- pub use ::c::*;
- pub type S = ::c::Item;
-}
-pub mod xm2 {
- pub use ::c::*;
- pub const S: ::c::Item = ::c::Item;
-}
-
-pub mod xm3 {
- pub use ::c::*;
- pub type TS = ::c::Item;
-}
-pub mod xm4 {
- pub use ::c::*;
- pub const TS: ::c::Item = ::c::Item;
-}
-
-pub mod xm5 {
- pub use ::c::*;
- pub type US = ::c::Item;
-}
-pub mod xm6 {
- pub use ::c::*;
- pub const US: ::c::Item = ::c::Item;
-}
-
-pub mod xm7 {
- pub use ::c::E::*;
- pub type V = ::c::Item;
-}
-pub mod xm8 {
- pub use ::c::E::*;
- pub const V: ::c::Item = ::c::Item;
-}
-
-pub mod xm9 {
- pub use ::c::E::*;
- pub type TV = ::c::Item;
-}
-pub mod xmA {
- pub use ::c::E::*;
- pub const TV: ::c::Item = ::c::Item;
-}
-
-pub mod xmB {
- pub use ::c::E::*;
- pub type UV = ::c::Item;
-}
-pub mod xmC {
- pub use ::c::E::*;
- pub const UV: ::c::Item = ::c::Item;
-}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// FIXME: Remove when `item_like_imports` is stabilized.
-
-pub mod c {
- pub struct S {}
- pub struct TS();
- pub struct US;
- pub enum E {
- V {},
- TV(),
- UV,
- }
-
- pub struct Item;
-}
-
-pub mod proxy {
- pub use c::*;
- pub use c::E::*;
-}
-
-pub mod xm1 {
- pub use ::proxy::*;
- pub type S = ::c::Item;
-}
-pub mod xm2 {
- pub use ::proxy::*;
- pub const S: ::c::Item = ::c::Item;
-}
-
-pub mod xm3 {
- pub use ::proxy::*;
- pub type TS = ::c::Item;
-}
-pub mod xm4 {
- pub use ::proxy::*;
- pub const TS: ::c::Item = ::c::Item;
-}
-
-pub mod xm5 {
- pub use ::proxy::*;
- pub type US = ::c::Item;
-}
-pub mod xm6 {
- pub use ::proxy::*;
- pub const US: ::c::Item = ::c::Item;
-}
-
-pub mod xm7 {
- pub use ::proxy::*;
- pub type V = ::c::Item;
-}
-pub mod xm8 {
- pub use ::proxy::*;
- pub const V: ::c::Item = ::c::Item;
-}
-
-pub mod xm9 {
- pub use ::proxy::*;
- pub type TV = ::c::Item;
-}
-pub mod xmA {
- pub use ::proxy::*;
- pub const TV: ::c::Item = ::c::Item;
-}
-
-pub mod xmB {
- pub use ::proxy::*;
- pub type UV = ::c::Item;
-}
-pub mod xmC {
- pub use ::proxy::*;
- pub const UV: ::c::Item = ::c::Item;
-}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod c {
+ pub struct S {}
+ pub struct TS();
+ pub struct US;
+ pub enum E {
+ V {},
+ TV(),
+ UV,
+ }
+
+ pub struct Item;
+}
+
+pub mod xm1 {
+ pub use ::c::*;
+ pub type S = ::c::Item;
+}
+pub mod xm2 {
+ pub use ::c::*;
+ pub const S: ::c::Item = ::c::Item;
+}
+
+pub mod xm3 {
+ pub use ::c::*;
+ pub type TS = ::c::Item;
+}
+pub mod xm4 {
+ pub use ::c::*;
+ pub const TS: ::c::Item = ::c::Item;
+}
+
+pub mod xm5 {
+ pub use ::c::*;
+ pub type US = ::c::Item;
+}
+pub mod xm6 {
+ pub use ::c::*;
+ pub const US: ::c::Item = ::c::Item;
+}
+
+pub mod xm7 {
+ pub use ::c::E::*;
+ pub type V = ::c::Item;
+}
+pub mod xm8 {
+ pub use ::c::E::*;
+ pub const V: ::c::Item = ::c::Item;
+}
+
+pub mod xm9 {
+ pub use ::c::E::*;
+ pub type TV = ::c::Item;
+}
+pub mod xmA {
+ pub use ::c::E::*;
+ pub const TV: ::c::Item = ::c::Item;
+}
+
+pub mod xmB {
+ pub use ::c::E::*;
+ pub type UV = ::c::Item;
+}
+pub mod xmC {
+ pub use ::c::E::*;
+ pub const UV: ::c::Item = ::c::Item;
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type="metadata"]
+
+pub struct Foo {
+ pub field: i32,
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type="rlib"]
+
+pub struct Foo {
+ pub field: i32,
+}
let _ = cf as *const Bar;
//~^ ERROR casting
//~^^ NOTE vtable kinds
+
+ vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
+ //~^ ERROR casting `&{float}` as `f32` is invalid
+ //~| NOTE cannot cast `&{float}` as `f32`
+ //~| NOTE did you mean `*s`?
}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: cannot declare a new module at this location
+// error-pattern: will become a hard error
+// error-pattern: compilation successful
+
+#![feature(rustc_attrs)]
+
+#[path="mod_file_not_owning_aux3.rs"]
+mod foo;
+
+#[rustc_error]
+fn main() {}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that macro-expanded non-inline modules behave correctly
+
+macro_rules! mod_decl {
+ ($i:ident) => { mod $i; }
+}
+
+mod macro_expanded_mod_helper {
+ mod_decl!(foo); // This should search in the folder `macro_expanded_mod_helper`
+}
+
+fn main() {
+ mod_decl!(foo); //~ ERROR Cannot declare a non-inline module inside a block
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test
+
+mod_decl!(bar);
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: cannot declare a new module at this location
+
+mod mod_file_not_owning_aux1;
+
+fn main() {}
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test this is not a test
+
+macro_rules! m {
+ () => { mod mod_file_not_owning_aux2; }
+}
+m!();
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test this is not a test
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-test this is not a test
+
+mod mod_file_not_owning_aux2;
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that non-inline modules are not allowed inside blocks.
+
+fn main() {
+ mod foo; //~ ERROR Cannot declare a non-inline module inside a block
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// error-pattern: cannot declare a new module at this location
+
+// This is not a directory owner since the file name is not "mod.rs".
+#[path = "mod_file_not_owning_aux1.rs"]
+mod foo;
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ loop {
+ break 123; //~ ERROR `break` with a value is experimental
+ }
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(rustc_attrs)]
+
mod foo {
pub use bar::*;
- pub use main as f; //~ ERROR has already been imported
+ pub use main as f;
}
mod bar {
}
pub use foo::*;
-pub use baz::*; //~ ERROR has already been imported
+pub use baz::*;
mod baz {
pub use super::*;
}
-pub fn main() {}
+#[rustc_error]
+pub fn main() {} //~ ERROR compilation successful
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::*;
-use bar::*; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::*;
-use foo::*; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::Baz;
-use bar::*; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::*;
-use bar::Baz; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::Baz;
-use bar::Baz; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use qux::*;
-use foo::*; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that import shadowing using globs causes errors
-
-#![no_implicit_prelude]
-
-use foo::*;
-use qux::*; //~ERROR a type named `Baz` has already been imported in this module
-
-mod foo {
- pub type Baz = isize;
-}
-
-mod bar {
- pub type Baz = isize;
-}
-
-mod qux {
- pub use bar::Baz;
-}
-
-fn main() {}
}
fn main() {
- zed::foo(); //~ ERROR unresolved name
+ zed::foo(); //~ ERROR `foo` is private
bar();
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(item_like_imports)]
-
mod a {
pub fn foo() {}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(item_like_imports)]
-
mod a {
fn foo() {}
mod foo {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(pub_restricted, item_like_imports)]
+#![feature(pub_restricted)]
#![deny(unused)]
mod foo {
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue_12612_1.rs
-
-extern crate issue_12612_1 as foo;
-
-use foo::bar;
-
-mod test {
- use bar::foo; //~ ERROR unresolved import `bar::foo` [E0432]
- //~^ Maybe a missing `extern crate bar;`?
-}
-
-fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(rustc_attrs)]
+
pub use bar::*;
mod bar {
pub use super::*;
}
-pub use baz::*; //~ ERROR already been imported
+pub use baz::*;
mod baz {
pub use main as f;
}
-pub fn main() {}
+#[rustc_error]
+pub fn main() {} //~ ERROR compilation successful
use bar::Foo; //~ ERROR unresolved import `bar::Foo` [E0432]
//~^ no `Foo` in `bar`
mod bar {
- use Foo; //~ ERROR unresolved import `Foo` [E0432]
- //~^ no `Foo` in the root
+ use Foo;
}
fn main() {}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(loop_break_value)]
+#![feature(never_type)]
+
+fn main() {
+ let val: ! = loop { break break; };
+ //~^ ERROR mismatched types
+
+ loop {
+ if true {
+ break "asdf";
+ } else {
+ break 123; //~ ERROR mismatched types
+ }
+ };
+
+ let _: i32 = loop {
+ break "asdf"; //~ ERROR mismatched types
+ };
+
+ let _: i32 = 'outer_loop: loop {
+ loop {
+ break 'outer_loop "nope"; //~ ERROR mismatched types
+ break "ok";
+ };
+ };
+
+ 'while_loop: while true {
+ break;
+ break (); //~ ERROR `break` with value from a `while` loop
+ loop {
+ break 'while_loop 123;
+ //~^ ERROR `break` with value from a `while` loop
+ //~| ERROR mismatched types
+ break 456;
+ break 789;
+ };
+ }
+
+ 'while_let_loop: while let Some(_) = Some(()) {
+ if break () { //~ ERROR `break` with value from a `while let` loop
+ break;
+ break None;
+ //~^ ERROR `break` with value from a `while let` loop
+ //~| ERROR mismatched types
+ }
+ loop {
+ break 'while_let_loop "nope";
+ //~^ ERROR `break` with value from a `while let` loop
+ //~| ERROR mismatched types
+ break 33;
+ };
+ }
+
+ 'for_loop: for _ in &[1,2,3] {
+ break (); //~ ERROR `break` with value from a `for` loop
+ break [()];
+ //~^ ERROR `break` with value from a `for` loop
+ //~| ERROR mismatched types
+ loop {
+ break Some(3);
+ break 'for_loop Some(17);
+ //~^ ERROR `break` with value from a `for` loop
+ //~| ERROR mismatched types
+ };
+ }
+
+ let _: i32 = 'a: loop {
+ let _: () = 'b: loop {
+ break ('c: loop {
+ break;
+ break 'c 123; //~ ERROR mismatched types
+ });
+ break 'a 123;
+ };
+ };
+
+ loop {
+ break (break, break); //~ ERROR mismatched types
+ };
+
+ loop {
+ break;
+ break 2; //~ ERROR mismatched types
+ };
+
+ loop {
+ break 2;
+ break; //~ ERROR mismatched types
+ break 4;
+ };
+}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that macro-expanded non-inline modules behave correctly
-
-macro_rules! mod_decl {
- ($i:ident) => { mod $i; }
-}
-
-mod macro_expanded_mod_helper {
- mod_decl!(foo); // This should search in the folder `macro_expanded_mod_helper`
-}
-
-fn main() {
- mod_decl!(foo); //~ ERROR Cannot declare a non-inline module inside a block
-}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test
-
-mod_decl!(bar);
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-// error-pattern: cannot declare a new module at this location
-
-mod mod_file_not_owning_aux1;
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test this is not a test
-
-mod mod_file_not_owning_aux2;
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-test this is not a test
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:namespace-mix-new.rs
-
-#![feature(item_like_imports)]
-
-extern crate namespace_mix_new;
-use namespace_mix_new::*;
-
-mod c {
- pub struct S {}
- pub struct TS();
- pub struct US;
- pub enum E {
- V {},
- TV(),
- UV,
- }
-
- pub struct Item;
-}
-
-// Use something emitting the type argument name, e.g. unsatisfied bound.
-trait Impossible {}
-fn check<T: Impossible>(_: T) {}
-
-mod m1 {
- pub use ::c::*;
- pub type S = ::c::Item;
-}
-mod m2 {
- pub use ::c::*;
- pub const S: ::c::Item = ::c::Item;
-}
-
-fn f12() {
- check(m1::S{}); //~ ERROR c::Item
- check(m1::S); //~ ERROR unresolved name
- check(m2::S{}); //~ ERROR c::S
- check(m2::S); //~ ERROR c::Item
-}
-fn xf12() {
- check(xm1::S{}); //~ ERROR c::Item
- check(xm1::S); //~ ERROR unresolved name
- check(xm2::S{}); //~ ERROR c::S
- check(xm2::S); //~ ERROR c::Item
-}
-
-mod m3 {
- pub use ::c::*;
- pub type TS = ::c::Item;
-}
-mod m4 {
- pub use ::c::*;
- pub const TS: ::c::Item = ::c::Item;
-}
-
-fn f34() {
- check(m3::TS{}); //~ ERROR c::Item
- check(m3::TS); //~ ERROR c::TS
- check(m4::TS{}); //~ ERROR c::TS
- check(m4::TS); //~ ERROR c::Item
-}
-fn xf34() {
- check(xm3::TS{}); //~ ERROR c::Item
- check(xm3::TS); //~ ERROR c::TS
- check(xm4::TS{}); //~ ERROR c::TS
- check(xm4::TS); //~ ERROR c::Item
-}
-
-mod m5 {
- pub use ::c::*;
- pub type US = ::c::Item;
-}
-mod m6 {
- pub use ::c::*;
- pub const US: ::c::Item = ::c::Item;
-}
-
-fn f56() {
- check(m5::US{}); //~ ERROR c::Item
- check(m5::US); //~ ERROR c::US
- check(m6::US{}); //~ ERROR c::US
- check(m6::US); //~ ERROR c::Item
-}
-fn xf56() {
- check(xm5::US{}); //~ ERROR c::Item
- check(xm5::US); //~ ERROR c::US
- check(xm6::US{}); //~ ERROR c::US
- check(xm6::US); //~ ERROR c::Item
-}
-
-mod m7 {
- pub use ::c::E::*;
- pub type V = ::c::Item;
-}
-mod m8 {
- pub use ::c::E::*;
- pub const V: ::c::Item = ::c::Item;
-}
-
-fn f78() {
- check(m7::V{}); //~ ERROR c::Item
- check(m7::V); //~ ERROR name of a struct or struct variant
- check(m8::V{}); //~ ERROR c::E
- check(m8::V); //~ ERROR c::Item
-}
-fn xf78() {
- check(xm7::V{}); //~ ERROR c::Item
- check(xm7::V); //~ ERROR name of a struct or struct variant
- check(xm8::V{}); //~ ERROR c::E
- check(xm8::V); //~ ERROR c::Item
-}
-
-mod m9 {
- pub use ::c::E::*;
- pub type TV = ::c::Item;
-}
-mod mA {
- pub use ::c::E::*;
- pub const TV: ::c::Item = ::c::Item;
-}
-
-fn f9A() {
- check(m9::TV{}); //~ ERROR c::Item
- check(m9::TV); //~ ERROR c::E
- check(mA::TV{}); //~ ERROR c::E
- check(mA::TV); //~ ERROR c::Item
-}
-fn xf9A() {
- check(xm9::TV{}); //~ ERROR c::Item
- check(xm9::TV); //~ ERROR c::E
- check(xmA::TV{}); //~ ERROR c::E
- check(xmA::TV); //~ ERROR c::Item
-}
-
-mod mB {
- pub use ::c::E::*;
- pub type UV = ::c::Item;
-}
-mod mC {
- pub use ::c::E::*;
- pub const UV: ::c::Item = ::c::Item;
-}
-
-fn fBC() {
- check(mB::UV{}); //~ ERROR c::Item
- check(mB::UV); //~ ERROR c::E
- check(mC::UV{}); //~ ERROR c::E
- check(mC::UV); //~ ERROR c::Item
-}
-fn xfBC() {
- check(xmB::UV{}); //~ ERROR c::Item
- check(xmB::UV); //~ ERROR c::E
- check(xmC::UV{}); //~ ERROR c::E
- check(xmC::UV); //~ ERROR c::Item
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// FIXME: Remove when `item_like_imports` is stabilized.
-
-// aux-build:namespace-mix-old.rs
-
-extern crate namespace_mix_old;
-use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC};
-
-mod c {
- pub struct S {}
- pub struct TS();
- pub struct US;
- pub enum E {
- V {},
- TV(),
- UV,
- }
-
- pub struct Item;
-}
-
-mod proxy {
- pub use c::*;
- pub use c::E::*;
-}
-
-// Use something emitting the type argument name, e.g. unsatisfied bound.
-trait Impossible {}
-fn check<T: Impossible>(_: T) {}
-
-mod m1 {
- pub use ::proxy::*;
- pub type S = ::c::Item;
-}
-mod m2 {
- pub use ::proxy::*;
- pub const S: ::c::Item = ::c::Item;
-}
-
-fn f12() {
- check(m1::S{}); //~ ERROR c::Item
- check(m1::S); //~ ERROR unresolved name
- check(m2::S{}); //~ ERROR c::S
- check(m2::S); //~ ERROR c::Item
-}
-fn xf12() {
- check(xm1::S{}); //~ ERROR c::Item
- check(xm1::S); //~ ERROR unresolved name
- check(xm2::S{}); //~ ERROR c::S
- check(xm2::S); //~ ERROR c::Item
-}
-
-mod m3 {
- pub use ::proxy::*;
- pub type TS = ::c::Item;
-}
-mod m4 {
- pub use ::proxy::*;
- pub const TS: ::c::Item = ::c::Item;
-}
-
-fn f34() {
- check(m3::TS{}); //~ ERROR c::Item
- check(m3::TS); //~ ERROR c::TS
- check(m4::TS{}); //~ ERROR c::TS
- check(m4::TS); //~ ERROR c::Item
-}
-fn xf34() {
- check(xm3::TS{}); //~ ERROR c::Item
- check(xm3::TS); //~ ERROR c::TS
- check(xm4::TS{}); //~ ERROR c::TS
- check(xm4::TS); //~ ERROR c::Item
-}
-
-mod m5 {
- pub use ::proxy::*;
- pub type US = ::c::Item;
-}
-mod m6 {
- pub use ::proxy::*;
- pub const US: ::c::Item = ::c::Item;
-}
-
-fn f56() {
- check(m5::US{}); //~ ERROR c::Item
- check(m5::US); //~ ERROR c::US
- check(m6::US{}); //~ ERROR c::US
- check(m6::US); //~ ERROR c::Item
-}
-fn xf56() {
- check(xm5::US{}); //~ ERROR c::Item
- check(xm5::US); //~ ERROR c::US
- check(xm6::US{}); //~ ERROR c::US
- check(xm6::US); //~ ERROR c::Item
-}
-
-mod m7 {
- pub use ::proxy::*;
- pub type V = ::c::Item;
-}
-mod m8 {
- pub use ::proxy::*;
- pub const V: ::c::Item = ::c::Item;
-}
-
-fn f78() {
- check(m7::V{}); //~ ERROR c::Item
- check(m7::V); //~ ERROR name of a struct or struct variant
- check(m8::V{}); //~ ERROR c::E
- check(m8::V); //~ ERROR c::Item
-}
-fn xf78() {
- check(xm7::V{}); //~ ERROR c::Item
- check(xm7::V); //~ ERROR name of a struct or struct variant
- check(xm8::V{}); //~ ERROR c::E
- check(xm8::V); //~ ERROR c::Item
-}
-
-mod m9 {
- pub use ::proxy::*;
- pub type TV = ::c::Item;
-}
-mod mA {
- pub use ::proxy::*;
- pub const TV: ::c::Item = ::c::Item;
-}
-
-fn f9A() {
- check(m9::TV{}); //~ ERROR c::Item
- check(m9::TV); //~ ERROR c::E
- check(mA::TV{}); //~ ERROR c::E
- check(mA::TV); //~ ERROR c::Item
-}
-fn xf9A() {
- check(xm9::TV{}); //~ ERROR c::Item
- check(xm9::TV); //~ ERROR c::E
- check(xmA::TV{}); //~ ERROR c::E
- check(xmA::TV); //~ ERROR c::Item
-}
-
-mod mB {
- pub use ::proxy::*;
- pub type UV = ::c::Item;
-}
-mod mC {
- pub use ::proxy::*;
- pub const UV: ::c::Item = ::c::Item;
-}
-
-fn fBC() {
- check(mB::UV{}); //~ ERROR c::Item
- check(mB::UV); //~ ERROR c::E
- check(mC::UV{}); //~ ERROR c::E
- check(mC::UV); //~ ERROR c::Item
-}
-fn xfBC() {
- check(xmB::UV{}); //~ ERROR c::Item
- check(xmB::UV); //~ ERROR c::E
- check(xmC::UV{}); //~ ERROR c::E
- check(xmC::UV); //~ ERROR c::Item
-}
-
-fn main() {}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:namespace-mix.rs
+
+extern crate namespace_mix;
+use namespace_mix::*;
+
+mod c {
+ pub struct S {}
+ pub struct TS();
+ pub struct US;
+ pub enum E {
+ V {},
+ TV(),
+ UV,
+ }
+
+ pub struct Item;
+}
+
+// Use something emitting the type argument name, e.g. unsatisfied bound.
+trait Impossible {}
+fn check<T: Impossible>(_: T) {}
+
+mod m1 {
+ pub use ::c::*;
+ pub type S = ::c::Item;
+}
+mod m2 {
+ pub use ::c::*;
+ pub const S: ::c::Item = ::c::Item;
+}
+
+fn f12() {
+ check(m1::S{}); //~ ERROR c::Item
+ check(m1::S); //~ ERROR unresolved name
+ check(m2::S{}); //~ ERROR c::S
+ check(m2::S); //~ ERROR c::Item
+}
+fn xf12() {
+ check(xm1::S{}); //~ ERROR c::Item
+ check(xm1::S); //~ ERROR unresolved name
+ check(xm2::S{}); //~ ERROR c::S
+ check(xm2::S); //~ ERROR c::Item
+}
+
+mod m3 {
+ pub use ::c::*;
+ pub type TS = ::c::Item;
+}
+mod m4 {
+ pub use ::c::*;
+ pub const TS: ::c::Item = ::c::Item;
+}
+
+fn f34() {
+ check(m3::TS{}); //~ ERROR c::Item
+ check(m3::TS); //~ ERROR c::TS
+ check(m4::TS{}); //~ ERROR c::TS
+ check(m4::TS); //~ ERROR c::Item
+}
+fn xf34() {
+ check(xm3::TS{}); //~ ERROR c::Item
+ check(xm3::TS); //~ ERROR c::TS
+ check(xm4::TS{}); //~ ERROR c::TS
+ check(xm4::TS); //~ ERROR c::Item
+}
+
+mod m5 {
+ pub use ::c::*;
+ pub type US = ::c::Item;
+}
+mod m6 {
+ pub use ::c::*;
+ pub const US: ::c::Item = ::c::Item;
+}
+
+fn f56() {
+ check(m5::US{}); //~ ERROR c::Item
+ check(m5::US); //~ ERROR c::US
+ check(m6::US{}); //~ ERROR c::US
+ check(m6::US); //~ ERROR c::Item
+}
+fn xf56() {
+ check(xm5::US{}); //~ ERROR c::Item
+ check(xm5::US); //~ ERROR c::US
+ check(xm6::US{}); //~ ERROR c::US
+ check(xm6::US); //~ ERROR c::Item
+}
+
+mod m7 {
+ pub use ::c::E::*;
+ pub type V = ::c::Item;
+}
+mod m8 {
+ pub use ::c::E::*;
+ pub const V: ::c::Item = ::c::Item;
+}
+
+fn f78() {
+ check(m7::V{}); //~ ERROR c::Item
+ check(m7::V); //~ ERROR name of a struct or struct variant
+ check(m8::V{}); //~ ERROR c::E
+ check(m8::V); //~ ERROR c::Item
+}
+fn xf78() {
+ check(xm7::V{}); //~ ERROR c::Item
+ check(xm7::V); //~ ERROR name of a struct or struct variant
+ check(xm8::V{}); //~ ERROR c::E
+ check(xm8::V); //~ ERROR c::Item
+}
+
+mod m9 {
+ pub use ::c::E::*;
+ pub type TV = ::c::Item;
+}
+mod mA {
+ pub use ::c::E::*;
+ pub const TV: ::c::Item = ::c::Item;
+}
+
+fn f9A() {
+ check(m9::TV{}); //~ ERROR c::Item
+ check(m9::TV); //~ ERROR c::E
+ check(mA::TV{}); //~ ERROR c::E
+ check(mA::TV); //~ ERROR c::Item
+}
+fn xf9A() {
+ check(xm9::TV{}); //~ ERROR c::Item
+ check(xm9::TV); //~ ERROR c::E
+ check(xmA::TV{}); //~ ERROR c::E
+ check(xmA::TV); //~ ERROR c::Item
+}
+
+mod mB {
+ pub use ::c::E::*;
+ pub type UV = ::c::Item;
+}
+mod mC {
+ pub use ::c::E::*;
+ pub const UV: ::c::Item = ::c::Item;
+}
+
+fn fBC() {
+ check(mB::UV{}); //~ ERROR c::Item
+ check(mB::UV); //~ ERROR c::E
+ check(mC::UV{}); //~ ERROR c::E
+ check(mC::UV); //~ ERROR c::Item
+}
+fn xfBC() {
+ check(xmB::UV{}); //~ ERROR c::Item
+ check(xmB::UV); //~ ERROR c::E
+ check(xmC::UV{}); //~ ERROR c::E
+ check(xmC::UV); //~ ERROR c::Item
+}
+
+fn main() {}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that non-inline modules are not allowed inside blocks.
-
-fn main() {
- mod foo; //~ ERROR Cannot declare a non-inline module inside a block
-}
fn test2() {
use bar::glob::foo;
- //~^ ERROR unresolved import `bar::glob::foo` [E0432]
- //~| no `foo` in `bar::glob`
+ //~^ ERROR `foo` is private
}
#[start] fn main(_: isize, _: *const *const u8) -> isize { 3 }
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rmeta_rlib.rs
+// no-prefer-dynamic
+// must-compile-successfully
+
+// Check that building a metadata crate works with a dependent, rlib crate.
+// This is a cfail test since there is no executable to run.
+
+#![crate_type="metadata"]
+
+extern crate rmeta_rlib;
+use rmeta_rlib::Foo;
+
+pub fn main() {
+ let _ = Foo { field: 42 };
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rmeta_meta.rs
+// no-prefer-dynamic
+// must-compile-successfully
+
+// Check that building a metadata crate works with a dependent, metadata-only
+// crate.
+// This is a cfail test since there is no executable to run.
+
+#![crate_type="metadata"]
+
+extern crate rmeta_meta;
+use rmeta_meta::Foo;
+
+pub fn main() {
+ let _ = Foo { field: 42 };
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+// Check that building a metadata crate finds an error.
+
+#![crate_type="metadata"]
+
+fn main() {
+ let _ = Foo; //~ ERROR unresolved name `Foo`
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rmeta_meta.rs
+// no-prefer-dynamic
+// error-pattern: crate `rmeta_meta` required to be available in rlib, but it was not available
+
+// Check that building a non-metadata crate fails if a dependent crate is
+// metadata-only.
+
+extern crate rmeta_meta;
+use rmeta_meta::Foo;
+
+fn main() {
+ let _ = Foo { field: 42 };
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rmeta_meta.rs
+// no-prefer-dynamic
+
+// Check that building a metadata crate finds an error with a dependent,
+// metadata-only crate.
+
+#![crate_type="metadata"]
+
+extern crate rmeta_meta;
+use rmeta_meta::Foo;
+
+fn main() {
+ let _ = Foo { field2: 42 }; //~ ERROR struct `rmeta_meta::Foo` has no field named `field2`
+}
}
mod bar {
- use foo::bar::f as g; //~ ERROR unresolved import
+ use foo::bar::f as g; //~ ERROR module `bar` is private
use foo as f;
pub use foo::*;
}
-use bar::f::f; //~ ERROR unresolved import
+use bar::f::f; //~ ERROR module `f` is private
fn main() {}
const XUnit: u8 = 0;
extern crate variant_namespacing;
-pub use variant_namespacing::XE::*;
+pub use variant_namespacing::XE::{XStruct, XTuple, XUnit};
//~^ ERROR `XStruct` has already been defined
//~| ERROR `XTuple` has already been defined
//~| ERROR `XUnit` has already been defined
-pub use E::*;
+pub use E::{Struct, Tuple, Unit};
//~^ ERROR `Struct` has already been defined
//~| ERROR `Tuple` has already been defined
//~| ERROR `Unit` has already been defined
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// This test case tests the incremental compilation hash (ICH) implementation
+// for struct constructor expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// must-compile-successfully
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+struct RegularStruct {
+ x: i32,
+ y: i64,
+ z: i16,
+}
+
+// Change field value (regular struct) -----------------------------------------
+#[cfg(cfail1)]
+fn change_field_value_regular_struct() -> RegularStruct {
+ RegularStruct {
+ x: 0,
+ y: 1,
+ z: 2,
+ }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_field_value_regular_struct() -> RegularStruct {
+ RegularStruct {
+ x: 0,
+ y: 2,
+ z: 2,
+ }
+}
+
+
+
+// Change field order (regular struct) -----------------------------------------
+#[cfg(cfail1)]
+fn change_field_order_regular_struct() -> RegularStruct {
+ RegularStruct {
+ x: 3,
+ y: 4,
+ z: 5,
+ }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_field_order_regular_struct() -> RegularStruct {
+ RegularStruct {
+ y: 4,
+ x: 3,
+ z: 5,
+ }
+}
+
+
+
+// Add field (regular struct) --------------------------------------------------
+#[cfg(cfail1)]
+fn add_field_regular_struct() -> RegularStruct {
+ let struct1 = RegularStruct {
+ x: 3,
+ y: 4,
+ z: 5,
+ };
+
+ RegularStruct {
+ x: 7,
+ .. struct1
+ }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn add_field_regular_struct() -> RegularStruct {
+ let struct1 = RegularStruct {
+ x: 3,
+ y: 4,
+ z: 5,
+ };
+
+ RegularStruct {
+ x: 7,
+ y: 8,
+ .. struct1
+ }
+}
+
+
+
+// Change field label (regular struct) -----------------------------------------
+#[cfg(cfail1)]
+fn change_field_label_regular_struct() -> RegularStruct {
+ let struct1 = RegularStruct {
+ x: 3,
+ y: 4,
+ z: 5,
+ };
+
+ RegularStruct {
+ x: 7,
+ y: 9,
+ .. struct1
+ }
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_field_label_regular_struct() -> RegularStruct {
+ let struct1 = RegularStruct {
+ x: 3,
+ y: 4,
+ z: 5,
+ };
+
+ RegularStruct {
+ x: 7,
+ z: 9,
+ .. struct1
+ }
+}
+
+
+
+struct RegularStruct2 {
+ x: i8,
+ y: i8,
+ z: i8,
+}
+
+// Change constructor path (regular struct) ------------------------------------
+#[cfg(cfail1)]
+fn change_constructor_path_regular_struct() {
+ let _ = RegularStruct {
+ x: 0,
+ y: 1,
+ z: 2,
+ };
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_constructor_path_regular_struct() {
+ let _ = RegularStruct2 {
+ x: 0,
+ y: 1,
+ z: 2,
+ };
+}
+
+
+
+// Change constructor path indirectly (regular struct) -------------------------
+mod change_constructor_path_indirectly_regular_struct {
+ #[cfg(cfail1)]
+ use super::RegularStruct as Struct;
+ #[cfg(not(cfail1))]
+ use super::RegularStruct2 as Struct;
+
+ fn function() -> Struct {
+ Struct {
+ x: 0,
+ y: 1,
+ z: 2,
+ }
+ }
+}
+
+
+
+struct TupleStruct(i32, i64, i16);
+
+// Change field value (tuple struct) -------------------------------------------
+#[cfg(cfail1)]
+fn change_field_value_tuple_struct() -> TupleStruct {
+ TupleStruct(0, 1, 2)
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_field_value_tuple_struct() -> TupleStruct {
+ TupleStruct(0, 1, 3)
+}
+
+
+
+struct TupleStruct2(u16, u16, u16);
+
+// Change constructor path (tuple struct) --------------------------------------
+#[cfg(cfail1)]
+fn change_constructor_path_tuple_struct() {
+ let _ = TupleStruct(0, 1, 2);
+}
+
+#[cfg(not(cfail1))]
+#[rustc_dirty(label="Hir", cfg="cfail2")]
+#[rustc_clean(label="Hir", cfg="cfail3")]
+#[rustc_metadata_dirty(cfg="cfail2")]
+#[rustc_metadata_clean(cfg="cfail3")]
+fn change_constructor_path_tuple_struct() {
+ let _ = TupleStruct2(0, 1, 2);
+}
+
+
+
+// Change constructor path indirectly (tuple struct) ---------------------------
+mod change_constructor_path_indirectly_tuple_struct {
+ #[cfg(cfail1)]
+ use super::TupleStruct as Struct;
+ #[cfg(not(cfail1))]
+ use super::TupleStruct2 as Struct;
+
+ fn function() -> Struct {
+ Struct(0, 1, 2)
+ }
+}
// compile-flags: -Z parse-only
-// error-pattern:expected `]`
+// error-pattern:expected one of `=` or `]`
// asterisk is bogus
#[attr*]
// ignore-test: this is an auxiliary file for circular-modules-main.rs
+#[path = "circular_modules_main.rs"]
mod circular_modules_main;
pub fn say_hello() {
use syntax::ast;
use syntax::codemap;
-use syntax::parse;
use syntax::print::pprust;
+use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;
fn main() {
cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan {
- format: syntax::codemap::MacroBang(parse::token::intern("")),
+ format: syntax::codemap::MacroBang(Symbol::intern("")),
allow_internal_unstable: false,
span: None,
}
use rustc_metadata::cstore::CStore;
use rustc_errors::registry::Registry;
+use std::collections::HashSet;
use std::path::PathBuf;
use std::rc::Rc;
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
let (sess, cstore) = basic_sess(sysroot);
- let cfg = build_configuration(&sess, vec![]);
+ let cfg = build_configuration(&sess, HashSet::new());
let control = CompileController::basic();
let input = Input::Str { name: anon_src(), input: code };
compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control);
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) a.rs && $(RUSTC) b.rs && $(RUSTC) c.rs
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(proc_macro)]
+#![allow(unused)]
+#![crate_type = "proc-macro"]
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+#[macro_use] extern crate a;
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "staticlib"]
+extern crate b;
+extern crate a;
use proc_macro_tokens::build::ident_eq;
+use syntax::ast::Ident;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::ext::proc_macro_shim::build_block_emitter;
use syntax::tokenstream::{TokenTree, TokenStream};
-use syntax::parse::token::str_to_ident;
use syntax::codemap::Span;
use rustc_plugin::Registry;
let test: TokenStream = clause.slice(0..1);
let rhs: TokenStream = clause.slice_from(1..);
- if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() {
+ if ident_eq(&test[0], Ident::from_str("else")) || rest.is_empty() {
qquote!({unquote(rhs)})
} else {
qquote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ext::proc_macro_shim::build_block_emitter;
use syntax::ext::base::{ExtCtxt, MacResult};
-use syntax::parse::token::{self, Token, DelimToken, keywords, str_to_ident};
+use syntax::parse::token::{self, Token, DelimToken};
use syntax::tokenstream::{TokenTree, TokenStream};
#[plugin_registrar]
let test: TokenStream = clause.slice(0..1);
let rhs: TokenStream = clause.slice_from(1..);
- if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() {
+ if ident_eq(&test[0], Ident::from_str("else")) || rest.is_empty() {
qquote!({unquote(rhs)})
} else {
qquote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
let test: TokenStream = clause.slice(0..1);
let rhs: TokenStream = clause.slice_from(1..);
- if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() {
+ if ident_eq(&test[0], Ident::from_str("else")) || rest.is_empty() {
qquote!({unquote(rhs)})
} else {
qquote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } })
// force-host
-#![feature(plugin_registrar, rustc_private, item_like_imports)]
+#![feature(plugin_registrar, rustc_private)]
extern crate syntax;
extern crate syntax_ext;
use syntax::codemap::Span;
use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
-use syntax::parse::token::{intern, InternedString};
+use syntax::symbol::Symbol;
use syntax::ptr::P;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_syntax_extension(intern("derive_CustomPartialEq"),
+ reg.register_syntax_extension(Symbol::intern("derive_CustomPartialEq"),
MultiDecorator(Box::new(expand_deriving_partial_eq)));
}
substr)
}
- let inline = cx.meta_word(span, InternedString::new("inline"));
+ let inline = cx.meta_word(span, Symbol::intern("inline"));
let attrs = vec![cx.attribute(span, inline)];
let methods = vec![MethodDef {
name: "eq",
use syntax::ast;
use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax_ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure};
use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self};
use syntax_pos::Span;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_syntax_extension(
- token::intern("derive_TotalSum"),
+ Symbol::intern("derive_TotalSum"),
MultiDecorator(box expand));
}
|cx, span, subexpr, field, _| {
cx.expr_binary(span, ast::BinOpKind::Add, subexpr,
cx.expr_method_call(span, field,
- token::str_to_ident("total_sum"), vec![]))
+ ast::Ident::from_str("total_sum"), vec![]))
},
zero,
box |cx, span, _, _| { cx.span_bug(span, "wtf??"); },
use syntax::ast;
use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
-use syntax::parse::token;
+use syntax::symbol::Symbol;
use syntax::ptr::P;
use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure};
use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching};
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_syntax_extension(
- token::intern("derive_TotalSum"),
+ Symbol::intern("derive_TotalSum"),
MultiDecorator(box expand));
}
impl EarlyLintPass for Pass {
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
- if it.ident.name.as_str() == "lintme" {
+ if it.ident.name == "lintme" {
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
}
}
use syntax::ext::quote::rt::ToTokens;
use syntax::parse::{self, token};
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax::tokenstream::TokenTree;
use syntax_pos::Span;
use rustc_plugin::Registry;
reg.register_macro("make_a_1", expand_make_a_1);
reg.register_macro("identity", expand_identity);
reg.register_syntax_extension(
- token::intern("into_multi_foo"),
+ Symbol::intern("into_multi_foo"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
MultiModifier(Box::new(expand_into_foo_multi)));
reg.register_syntax_extension(
- token::intern("duplicate"),
+ Symbol::intern("duplicate"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
MultiDecorator(Box::new(expand_duplicate)));
reg.register_syntax_extension(
- token::intern("caller"),
+ Symbol::intern("caller"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
MultiDecorator(Box::new(expand_caller)));
}
it: &Annotatable,
push: &mut FnMut(Annotatable)) {
let copy_name = match mi.node {
- ast::MetaItemKind::List(_, ref xs) => {
+ ast::MetaItemKind::List(ref xs) => {
if let Some(word) = xs[0].word() {
- token::str_to_ident(&word.name())
+ ast::Ident::with_empty_ctxt(word.name())
} else {
cx.span_err(mi.span, "Expected word");
return;
}
let fn_name = match list[0].name() {
- Some(name) => token::str_to_ident(&name),
+ Some(name) => ast::Ident::with_empty_ctxt(name),
None => cx.span_fatal(list[0].span(), "First parameter must be an ident.")
};
use syntax::ast;
use syntax::ext::build::AstBuilder;
use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT};
-use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
+use syntax::symbol::Symbol;
use syntax_pos::Span;
use syntax::tokenstream;
use rustc_plugin::Registry;
_: &[tokenstream::TokenTree]) -> Box<MacResult+'cx> {
let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
.collect::<Vec<_>>().join(", ");
- let interned = token::intern_and_get_ident(&args[..]);
- MacEager::expr(ecx.expr_str(sp, interned))
+ MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))
}
}
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
let args = reg.args().to_owned();
- reg.register_syntax_extension(token::intern("plugin_args"),
+ reg.register_syntax_extension(Symbol::intern("plugin_args"),
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
NormalTT(Box::new(Expander { args: args, }), None, false));
}
use rustc_plugin::Registry;
use syntax::ext::base::SyntaxExtension;
use syntax::ext::proc_macro_shim::prelude::*;
+use syntax::symbol::Symbol;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_syntax_extension(token::intern("attr_tru"),
+ reg.register_syntax_extension(Symbol::intern("attr_tru"),
SyntaxExtension::AttrProcMacro(Box::new(attr_tru)));
- reg.register_syntax_extension(token::intern("attr_identity"),
+ reg.register_syntax_extension(Symbol::intern("attr_identity"),
SyntaxExtension::AttrProcMacro(Box::new(attr_identity)));
- reg.register_syntax_extension(token::intern("tru"),
+ reg.register_syntax_extension(Symbol::intern("tru"),
SyntaxExtension::ProcMacro(Box::new(tru)));
- reg.register_syntax_extension(token::intern("ret_tru"),
+ reg.register_syntax_extension(Symbol::intern("ret_tru"),
SyntaxExtension::ProcMacro(Box::new(ret_tru)));
- reg.register_syntax_extension(token::intern("identity"),
+ reg.register_syntax_extension(Symbol::intern("identity"),
SyntaxExtension::ProcMacro(Box::new(identity)));
}
extern crate rustc;
extern crate rustc_plugin;
-use syntax::parse::token::{str_to_ident, NtExpr, NtPat};
-use syntax::ast::{Pat};
+use syntax::parse::token::{NtExpr, NtPat};
+use syntax::ast::{Ident, Pat};
use syntax::tokenstream::{TokenTree};
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::ext::build::AstBuilder;
}
};
- let matched_nt = match *map[&str_to_ident("matched")] {
+ let matched_nt = match *map[&Ident::from_str("matched")] {
MatchedNonterminal(ref nt) => nt.clone(),
_ => unreachable!(),
};
- let mac_expr = match (&*matched_nt, &*map[&str_to_ident("pat")]) {
+ let mac_expr = match (&*matched_nt, &*map[&Ident::from_str("pat")]) {
(&NtExpr(ref matched_expr), &MatchedSeq(ref pats, seq_sp)) => {
let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt| {
match **pat_nt {
use proc_macro_tokens::prelude::*;
extern crate syntax;
-use syntax::ast::Ident;
-use syntax::codemap::DUMMY_SP;
-use syntax::parse::token::{self, Token, keywords, str_to_ident};
fn main() {
let lex_true = lex("true");
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This test case tests whether we can handle code bases that contain a high
+// number of closures, something that needs special handling in the MingGW
+// toolchain.
+// See https://github.com/rust-lang/rust/issues/34793 for more information.
+
+// Make sure we don't optimize anything away:
+// compile-flags: -C no-prepopulate-passes
+
+// Expand something exponentially
+macro_rules! go_bacterial {
+ ($mac:ident) => ($mac!());
+ ($mac:ident 1 $($t:tt)*) => (
+ go_bacterial!($mac $($t)*);
+ go_bacterial!($mac $($t)*);
+ )
+}
+
+macro_rules! mk_closure {
+ () => ((move || {})())
+}
+
+macro_rules! mk_fn {
+ () => {
+ {
+ fn function() {
+ // Make 16 closures
+ go_bacterial!(mk_closure 1 1 1 1);
+ }
+ let _ = function();
+ }
+ }
+}
+
+fn main() {
+ // Make 2^12 functions, each containing 16 closures,
+ // resulting in 2^16 closures overall.
+ go_bacterial!(mk_fn 1 1 1 1 1 1 1 1 1 1 1 1);
+}
extern crate syntax_pos;
use syntax::print::pprust::*;
-use syntax::parse::token::intern;
+use syntax::symbol::Symbol;
use syntax_pos::DUMMY_SP;
fn main() {
cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan {
- format: syntax::codemap::MacroBang(intern("")),
+ format: syntax::codemap::MacroBang(Symbol::intern("")),
allow_internal_unstable: false,
span: None,
}
// quote_meta_item!
let meta = quote_meta_item!(cx, cfg(foo = "bar"));
- check!(meta_item_to_string, meta, *quote_meta_item!(cx, $meta); r#"cfg(foo = "bar")"#);
+ check!(meta_item_to_string, meta, quote_meta_item!(cx, $meta); r#"cfg(foo = "bar")"#);
let attr = quote_attr!(cx, #![$meta]);
check!(attribute_to_string, attr; r#"#![cfg(foo = "bar")]"#);
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type="rlib"]
+#![crate_name="rmeta_aux"]
+
+pub struct Foo {
+ pub field: i32,
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type="metadata"]
+#![crate_name="rmeta_aux"]
+
+pub struct Foo {
+ pub field2: i32,
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(item_like_imports)]
#![allow(unused)]
// Like other items, private imports can be imported and used non-lexically in paths.
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn gimme_a_raw_pointer<T>(_: *const T) { }
+
+fn test<T>(t: T) { }
+
+fn main() {
+ // Clearly `pointer` must be of type `*const ()`.
+ let pointer = &() as *const _;
+ gimme_a_raw_pointer(pointer);
+
+ let t = test as fn (i32);
+ t(0i32);
+}
+
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(loop_break_value)]
+#![feature(never_type)]
+
+#[allow(unused)]
+fn never_returns() {
+ loop {
+ break loop {};
+ }
+}
+
+pub fn main() {
+ let value = 'outer: loop {
+ if 1 == 1 {
+ break 13;
+ } else {
+ let _never: ! = loop {
+ break loop {
+ break 'outer panic!();
+ }
+ };
+ }
+ };
+ assert_eq!(value, 13);
+
+ let x = [1, 3u32, 5];
+ let y = [17];
+ let z = [];
+ let coerced: &[_] = loop {
+ match 2 {
+ 1 => break &x,
+ 2 => break &y,
+ 3 => break &z,
+ _ => (),
+ }
+ };
+ assert_eq!(coerced, &[17u32]);
+
+ let trait_unified = loop {
+ break if true {
+ break Default::default()
+ } else {
+ break [13, 14]
+ };
+ };
+ assert_eq!(trait_unified, [0, 0]);
+
+ let trait_unified_2 = loop {
+ if false {
+ break [String::from("Hello")]
+ } else {
+ break Default::default()
+ };
+ };
+ assert_eq!(trait_unified_2, [""]);
+
+ let trait_unified_3 = loop {
+ break if false {
+ break [String::from("Hello")]
+ } else {
+ ["Yes".into()]
+ };
+ };
+ assert_eq!(trait_unified_3, ["Yes"]);
+
+ let regular_break = loop {
+ if true {
+ break;
+ } else {
+ break break Default::default();
+ }
+ };
+ assert_eq!(regular_break, ());
+
+ let regular_break_2 = loop {
+ if true {
+ break Default::default();
+ } else {
+ break;
+ }
+ };
+ assert_eq!(regular_break_2, ());
+
+ let regular_break_3 = loop {
+ break if true {
+ Default::default()
+ } else {
+ break;
+ }
+ };
+ assert_eq!(regular_break_3, ());
+
+ let regular_break_4 = loop {
+ break ();
+ break;
+ };
+ assert_eq!(regular_break_4, ());
+
+ let regular_break_5 = loop {
+ break;
+ break ();
+ };
+ assert_eq!(regular_break_5, ());
+
+ let nested_break_value = 'outer2: loop {
+ let _a: u32 = 'inner: loop {
+ if true {
+ break 'outer2 "hello";
+ } else {
+ break 'inner 17;
+ }
+ };
+ panic!();
+ };
+ assert_eq!(nested_break_value, "hello");
+
+ let break_from_while_cond = loop {
+ while break {
+ panic!();
+ }
+ break 123;
+ };
+ assert_eq!(break_from_while_cond, 123);
+}
+++ /dev/null
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This test case tests whether we can handle code bases that contain a high
-// number of closures, something that needs special handling in the MingGW
-// toolchain.
-// See https://github.com/rust-lang/rust/issues/34793 for more information.
-
-// Expand something exponentially
-macro_rules! go_bacterial {
- ($mac:ident) => ($mac!());
- ($mac:ident 1 $($t:tt)*) => (
- go_bacterial!($mac $($t)*);
- go_bacterial!($mac $($t)*);
- )
-}
-
-macro_rules! mk_closure {
- () => ({
- let c = |a: u32| a + 4;
- let _ = c(2);
- })
-}
-
-macro_rules! mk_fn {
- () => {
- {
- fn function() {
- // Make 16 closures
- go_bacterial!(mk_closure 1 1 1 1);
- }
- let _ = function();
- }
- }
-}
-
-fn main() {
- // Make 2^12 functions, each containing 16 closures,
- // resulting in 2^16 closures overall.
- go_bacterial!(mk_fn 1 1 1 1 1 1 1 1 1 1 1 1);
-}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that using rlibs and rmeta dep crates work together. Specifically, that
+// there can be both an rmeta and an rlib file and rustc will prefer the rlib.
+
+// aux-build:rmeta_rmeta.rs
+// aux-build:rmeta_rlib.rs
+
+extern crate rmeta_aux;
+use rmeta_aux::Foo;
+
+pub fn main() {
+ let _ = Foo { field: 42 };
+}