From 9a857b4472142b6d0bf65e9185c4c2619e722fb0 Mon Sep 17 00:00:00 2001 From: Adolfo Ochagavía Date: Sat, 22 Nov 2014 16:02:49 +0100 Subject: libsyntax: Forbid type parameters in tuple indices This breaks code like ``` let t = (42i, 42i); ... t.0:: ...; ``` Change this code to not contain an unused type parameter. For example: ``` let t = (42i, 42i); ... t.0 ...; ``` Closes https://github.com/rust-lang/rust/issues/19096 [breaking-change] --- src/libsyntax/parse/parser.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ab0543d64b7..e4fa6508820 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -49,8 +49,7 @@ use ast::{PolyTraitRef}; use ast::{QPath, RequiredMethod}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; -use ast::{StructVariantKind, BiSub}; -use ast::StrStyle; +use ast::{StructVariantKind, BiSub, StrStyle}; use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; @@ -65,10 +64,8 @@ use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause, WherePredicate}; use ast; -use ast_util::{as_prec, ident_to_path, operator_prec}; -use ast_util; -use codemap::{Span, BytePos, Spanned, spanned, mk_sp}; -use codemap; +use ast_util::{mod, as_prec, ident_to_path, operator_prec}; +use codemap::{mod, Span, BytePos, Spanned, spanned, mk_sp}; use diagnostic; use ext::tt::macro_parser; use parse; @@ -2472,24 +2469,19 @@ impl<'a> Parser<'a> { } token::Literal(token::Integer(n), suf) => { let sp = self.span; + + // A tuple index may not have a suffix self.expect_no_suffix(sp, "tuple index", suf); - let index = n.as_str(); let dot = self.last_span.hi; hi = self.span.hi; self.bump(); - let (_, tys) = if self.eat(&token::ModSep) { - self.expect_lt(); - self.parse_generic_values_after_lt() - } else { - (Vec::new(), Vec::new()) - }; - let num = from_str::(index); - match num { + let index = from_str::(n.as_str()); + match index { Some(n) => { let id = spanned(dot, hi, n); - let field = self.mk_tup_field(e, id, tys); + let field = self.mk_tup_field(e, id, Vec::new()); e = self.mk_expr(lo, hi, field); } None => { -- cgit 1.4.1-3-g733a5 From 35316972ff2e7ea02a4583141d3ac69b79610067 Mon Sep 17 00:00:00 2001 From: Adolfo Ochagavía Date: Sun, 23 Nov 2014 12:14:35 +0100 Subject: Remove type parameters from ExprField and ExprTupField --- src/librustc/lint/builtin.rs | 18 +++----- src/librustc/middle/cfg/construct.rs | 4 +- src/librustc/middle/const_eval.rs | 15 +++--- src/librustc/middle/dead.rs | 14 ++---- src/librustc/middle/expr_use_visitor.rs | 8 ++-- src/librustc/middle/liveness.rs | 23 ++++------ src/librustc/middle/mem_categorization.rs | 4 +- src/librustc/middle/privacy.rs | 27 ++++------- src/librustc/middle/region.rs | 9 ++-- src/librustc/middle/resolve.rs | 12 ++--- src/librustc/middle/typeck/check/method/confirm.rs | 13 ++---- src/librustc/middle/typeck/check/mod.rs | 53 +++++++--------------- src/librustc_back/svh.rs | 4 +- src/librustc_trans/save/mod.rs | 26 ++++------- src/librustc_trans/trans/consts.rs | 20 +++----- src/librustc_trans/trans/debuginfo.rs | 12 ++--- src/librustc_trans/trans/expr.rs | 43 +++++------------- src/libsyntax/ast.rs | 4 +- src/libsyntax/ext/build.rs | 4 +- src/libsyntax/fold.rs | 10 ++-- src/libsyntax/parse/parser.rs | 28 +++++------- src/libsyntax/print/pprust.rs | 18 +------- src/libsyntax/visit.rs | 10 +--- 23 files changed, 125 insertions(+), 254 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 00c68f42c32..9fe7a21243f 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -37,22 +37,18 @@ use util::ppaux::{ty_to_string}; use util::nodemap::{FnvHashMap, NodeSet}; use lint::{Context, LintPass, LintArray}; -use std::cmp; +use std::{cmp, slice}; use std::collections::hash_map::{Occupied, Vacant}; use std::num::SignedInt; -use std::slice; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; -use syntax::abi; -use syntax::ast_map; -use syntax::ast_util::is_shift_binop; -use syntax::attr::AttrMetaMethods; -use syntax::attr; +use syntax::{abi, ast, ast_map}; +use syntax::ast_util::{mod, is_shift_binop}; +use syntax::attr::{mod, AttrMetaMethods}; use syntax::codemap::{Span, DUMMY_SP}; use syntax::parse::token; -use syntax::{ast, ast_util, visit}; use syntax::ast::{TyI, TyU, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64}; use syntax::ptr::P; -use syntax::visit::Visitor; +use syntax::visit::{mod, Visitor}; declare_lint!(WHILE_TRUE, Warn, "suggest using `loop { }` instead of `while true { }`") @@ -1112,8 +1108,8 @@ impl UnusedParens { } ast::ExprUnary(_, ref x) | ast::ExprCast(ref x, _) | - ast::ExprField(ref x, _, _) | - ast::ExprTupField(ref x, _, _) | + ast::ExprField(ref x, _) | + ast::ExprTupField(ref x, _) | ast::ExprIndex(ref x, _) => { // &X { y: 1 }, X { y: 1 }.y contains_exterior_struct_lit(&**x) diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 42e1ede147e..61c56cf9ecc 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -475,8 +475,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { ast::ExprCast(ref e, _) | ast::ExprUnary(_, ref e) | ast::ExprParen(ref e) | - ast::ExprField(ref e, _, _) | - ast::ExprTupField(ref e, _, _) => { + ast::ExprField(ref e, _) | + ast::ExprTupField(ref e, _) => { self.straightline(expr, pred, Some(&**e).into_iter()) } diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index c7c67e8a67b..98ac7e413ca 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -15,19 +15,16 @@ pub use self::const_val::*; pub use self::constness::*; use metadata::csearch; -use middle::astencode; -use middle::def; +use middle::{astencode, def}; use middle::pat_util::def_to_path; use middle::ty::{mod, Ty}; -use middle::typeck::astconv; -use middle::typeck::check; -use util::nodemap::{DefIdMap}; +use middle::typeck::{astconv, check}; +use util::nodemap::DefIdMap; use syntax::ast::{mod, Expr}; use syntax::parse::token::InternedString; use syntax::ptr::P; -use syntax::visit::Visitor; -use syntax::visit; +use syntax::visit::{mod, Visitor}; use syntax::{ast_map, ast_util, codemap}; use std::rc::Rc; @@ -234,9 +231,9 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> { } } - ast::ExprField(ref base, _, _) => self.classify(&**base), + ast::ExprField(ref base, _) => self.classify(&**base), - ast::ExprTupField(ref base, _, _) => self.classify(&**base), + ast::ExprTupField(ref base, _) => self.classify(&**base), ast::ExprIndex(ref base, ref idx) => join(self.classify(&**base), self.classify(&**idx)), diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 62a5d23e333..cf2e9a65859 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -12,20 +12,14 @@ // closely. The idea is that all reachable symbols are live, codes called // from live codes are live, and everything else is dead. -use middle::def; -use middle::pat_util; -use middle::privacy; -use middle::ty; -use middle::typeck; +use middle::{def, pat_util, privacy, ty, typeck}; use lint; use util::nodemap::NodeSet; use std::collections::HashSet; -use syntax::ast; -use syntax::ast_map; +use syntax::{ast, ast_map, codemap}; use syntax::ast_util::{local_def, is_local, PostExpansionMethod}; use syntax::attr::{mod, AttrMetaMethods}; -use syntax::codemap; use syntax::visit::{mod, Visitor}; // Any local node that may call something in its body block should be @@ -277,10 +271,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { ast::ExprMethodCall(..) => { self.lookup_and_handle_method(expr.id, expr.span); } - ast::ExprField(ref lhs, ref ident, _) => { + ast::ExprField(ref lhs, ref ident) => { self.handle_field_access(&**lhs, &ident.node); } - ast::ExprTupField(ref lhs, idx, _) => { + ast::ExprTupField(ref lhs, idx) => { self.handle_tup_field_access(&**lhs, idx.node); } _ => () diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 645a1aef3dc..fa0f59f6860 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -20,11 +20,9 @@ pub use self::ConsumeMode::*; pub use self::MoveReason::*; use self::OverloadedCallType::*; +use middle::{def, region, pat_util}; use middle::mem_categorization as mc; -use middle::def; use middle::mem_categorization::Typer; -use middle::region; -use middle::pat_util; use middle::ty::{mod, Ty}; use middle::typeck::{MethodCall, MethodObject, MethodTraitObject}; use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam}; @@ -331,11 +329,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { } } - ast::ExprField(ref base, _, _) => { // base.f + ast::ExprField(ref base, _) => { // base.f self.select_from_expr(&**base); } - ast::ExprTupField(ref base, _, _) => { // base. + ast::ExprTupField(ref base, _) => { // base. self.select_from_expr(&**base); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7d13d2e5f94..15d9e87a9d5 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -113,24 +113,19 @@ use self::VarKind::*; use middle::def::*; use middle::mem_categorization::Typer; -use middle::pat_util; -use middle::typeck; -use middle::ty; +use middle::{pat_util, typeck, ty}; use lint; use util::nodemap::NodeMap; -use std::fmt; -use std::io; +use std::{fmt, io, uint}; use std::rc::Rc; -use std::uint; use syntax::ast::{mod, NodeId, Expr}; use syntax::codemap::{BytePos, original_sp, Span}; -use syntax::parse::token::special_idents; -use syntax::parse::token; +use syntax::parse::token::{mod, special_idents}; use syntax::print::pprust::{expr_to_string, block_to_string}; use syntax::ptr::P; -use syntax::{visit, ast_util}; -use syntax::visit::{Visitor, FnKind}; +use syntax::ast_util; +use syntax::visit::{mod, Visitor, FnKind}; /// For use with `propagate_through_loop`. enum LoopKind<'a> { @@ -967,11 +962,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.access_path(expr, succ, ACC_READ | ACC_USE) } - ast::ExprField(ref e, _, _) => { + ast::ExprField(ref e, _) => { self.propagate_through_expr(&**e, succ) } - ast::ExprTupField(ref e, _, _) => { + ast::ExprTupField(ref e, _) => { self.propagate_through_expr(&**e, succ) } @@ -1295,8 +1290,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match expr.node { ast::ExprPath(_) => succ, - ast::ExprField(ref e, _, _) => self.propagate_through_expr(&**e, succ), - ast::ExprTupField(ref e, _, _) => self.propagate_through_expr(&**e, succ), + ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ), + ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ), _ => self.propagate_through_expr(expr, succ) } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 78b6c19874a..e9986e47e4a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -477,7 +477,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Ok(self.cat_deref(expr, base_cmt, 0, false)) } - ast::ExprField(ref base, f_name, _) => { + ast::ExprField(ref base, f_name) => { let base_cmt = if_ok!(self.cat_expr(&**base)); debug!("cat_expr(cat_field): id={} expr={} base={}", expr.id, @@ -486,7 +486,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Ok(self.cat_field(expr, base_cmt, f_name.node.name, expr_ty)) } - ast::ExprTupField(ref base, idx, _) => { + ast::ExprTupField(ref base, idx) => { let base_cmt = if_ok!(self.cat_expr(&**base)); Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty)) } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index c2835ba5647..66c782877f9 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -17,20 +17,17 @@ use self::FieldName::*; use std::mem::replace; use metadata::csearch; -use middle::def; -use middle::resolve; +use middle::{def, resolve}; use middle::ty::{mod, Ty}; use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam}; use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject}; use util::nodemap::{NodeMap, NodeSet}; -use syntax::ast; -use syntax::ast_map; +use syntax::{ast, ast_map}; use syntax::ast_util::{is_local, local_def, PostExpansionMethod}; use syntax::codemap::Span; use syntax::parse::token; -use syntax::visit; -use syntax::visit::Visitor; +use syntax::visit::{mod, Visitor}; type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a resolve::ExportMap2); @@ -836,20 +833,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &ast::Expr) { match expr.node { - ast::ExprField(ref base, ident, _) => { - match ty::expr_ty_adjusted(self.tcx, &**base).sty { - ty::ty_struct(id, _) => { - self.check_field(expr.span, id, NamedField(ident.node)); - } - _ => {} + ast::ExprField(ref base, ident) => { + if let ty::ty_struct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty { + self.check_field(expr.span, id, NamedField(ident.node)); } } - ast::ExprTupField(ref base, idx, _) => { - match ty::expr_ty_adjusted(self.tcx, &**base).sty { - ty::ty_struct(id, _) => { - self.check_field(expr.span, id, UnnamedField(idx.node)); - } - _ => {} + ast::ExprTupField(ref base, idx) => { + if let ty::ty_struct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty { + self.check_field(expr.span, id, UnnamedField(idx.node)); } } ast::ExprMethodCall(ident, _, _) => { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 8a50cb4ed4e..c5511f995bc 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -22,8 +22,7 @@ Most of the documentation on regions can be found in use session::Session; -use middle::ty::{FreeRegion}; -use middle::ty::{mod, Ty}; +use middle::ty::{mod, Ty, FreeRegion}; use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap}; use util::common::can_reach; @@ -33,7 +32,6 @@ use syntax::codemap::Span; use syntax::{ast, visit}; use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local}; use syntax::ast_util::{stmt_id}; -use syntax::ptr::P; use syntax::visit::{Visitor, FnKind}; /// CodeExtent represents a statically-describable extent that can be @@ -824,11 +822,10 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) { match expr.node { ast::ExprAddrOf(_, ref subexpr) | ast::ExprUnary(ast::UnDeref, ref subexpr) | - ast::ExprField(ref subexpr, _, _) | - ast::ExprTupField(ref subexpr, _, _) | + ast::ExprField(ref subexpr, _) | + ast::ExprTupField(ref subexpr, _) | ast::ExprIndex(ref subexpr, _) | ast::ExprParen(ref subexpr) => { - let subexpr: &'a P = subexpr; // FIXME(#11586) expr = &**subexpr; } _ => { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6ad3d67af0a..68a31c83ea4 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -71,17 +71,13 @@ use syntax::ast::{Variant, ViewItem, ViewItemExternCrate}; use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::ast::{Visibility}; use syntax::ast; -use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat}; -use syntax::ast_util; +use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat}; use syntax::attr::AttrMetaMethods; use syntax::ext::mtwt; -use syntax::parse::token::special_names; -use syntax::parse::token::special_idents; -use syntax::parse::token; +use syntax::parse::token::{mod, special_names, special_idents}; use syntax::codemap::{Span, DUMMY_SP, Pos}; use syntax::owned_slice::OwnedSlice; -use syntax::visit; -use syntax::visit::Visitor; +use syntax::visit::{mod, Visitor}; use std::collections::{HashMap, HashSet}; use std::collections::hash_map::{Occupied, Vacant}; @@ -5959,7 +5955,7 @@ impl<'a> Resolver<'a> { fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) { match expr.node { - ExprField(_, ident, _) => { + ExprField(_, ident) => { // FIXME(#6890): Even though you can't treat a method like a // field, we need to add any trait methods we find that match // the field name so that we can do some nice error reporting diff --git a/src/librustc/middle/typeck/check/method/confirm.rs b/src/librustc/middle/typeck/check/method/confirm.rs index c53befcc10d..5bcd96e66ef 100644 --- a/src/librustc/middle/typeck/check/method/confirm.rs +++ b/src/librustc/middle/typeck/check/method/confirm.rs @@ -10,16 +10,13 @@ use super::probe; -use middle::subst; -use middle::subst::Subst; +use middle::subst::{mod, Subst}; use middle::traits; use middle::ty::{mod, Ty}; -use middle::typeck::check; -use middle::typeck::check::{FnCtxt, NoPreference, PreferMutLvalue}; +use middle::typeck::check::{mod, FnCtxt, NoPreference, PreferMutLvalue}; use middle::typeck::{MethodCall, MethodCallee, MethodObject, MethodOrigin, MethodParam, MethodStatic, MethodTraitObject, MethodTypeParam}; -use middle::typeck::infer; -use middle::typeck::infer::InferCtxt; +use middle::typeck::infer::{mod, InferCtxt}; use middle::ty_fold::HigherRankedFoldable; use syntax::ast; use syntax::codemap::Span; @@ -510,8 +507,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { let last = exprs[exprs.len() - 1]; match last.node { ast::ExprParen(ref expr) | - ast::ExprField(ref expr, _, _) | - ast::ExprTupField(ref expr, _, _) | + ast::ExprField(ref expr, _) | + ast::ExprTupField(ref expr, _) | ast::ExprSlice(ref expr, _, _, _) | ast::ExprIndex(ref expr, _) | ast::ExprUnary(ast::UnDeref, ref expr) => exprs.push(&**expr), diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 85d2f573615..d38c5bc0ca9 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -83,62 +83,41 @@ use self::IsBinopAssignment::*; use self::TupleArgumentsFlag::*; use session::Session; -use middle::const_eval; -use middle::def; +use middle::{const_eval, def, traits}; use middle::lang_items::IteratorItem; -use middle::mem_categorization::McResult; -use middle::mem_categorization; -use middle::pat_util::pat_id_map; -use middle::pat_util; +use middle::mem_categorization::{mod, McResult}; +use middle::pat_util::{mod, pat_id_map}; use middle::region::CodeExtent; -use middle::subst; -use middle::subst::{Subst, Substs, VecPerParamSpace, ParamSpace}; -use middle::traits; -use middle::ty::{FnSig, VariantInfo}; -use middle::ty::{Polytype}; +use middle::subst::{mod, Subst, Substs, VecPerParamSpace, ParamSpace}; +use middle::ty::{FnSig, VariantInfo, Polytype}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{mod, Ty}; use middle::ty::liberate_late_bound_regions; use middle::ty_fold::TypeFolder; -use middle::typeck::astconv::AstConv; -use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; -use middle::typeck::astconv; +use middle::typeck::astconv::{mod, ast_region_to_region, ast_ty_to_ty, AstConv}; use middle::typeck::check::_match::pat_ctxt; -use middle::typeck::CrateCtxt; -use middle::typeck::infer; use middle::typeck::rscope::RegionScope; -use middle::typeck::{lookup_def_ccx}; -use middle::typeck::no_params; -use middle::typeck::{require_same_types}; -use middle::typeck::{MethodCall, MethodCallee, MethodMap, ObjectCastMap}; -use middle::typeck::{TypeAndSubsts}; -use middle::typeck; +use middle::typeck::{mod, CrateCtxt, infer, lookup_def_ccx, no_params, require_same_types}; +use middle::typeck::{MethodCall, MethodCallee, MethodMap, ObjectCastMap, TypeAndSubsts}; use middle::lang_items::TypeIdLangItem; use lint; use util::common::{block_query, indenter, loop_query}; -use util::ppaux; -use util::ppaux::{UserString, Repr}; +use util::ppaux::{mod, UserString, Repr}; use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; use std::cell::{Cell, Ref, RefCell}; use std::collections::hash_map::{Occupied, Vacant}; use std::mem::replace; use std::rc::Rc; -use syntax::abi; -use syntax::ast::{ProvidedMethod, RequiredMethod, TypeTraitItem}; -use syntax::ast; -use syntax::ast_util::{local_def, PostExpansionMethod}; -use syntax::ast_util; -use syntax::attr; -use syntax::codemap::Span; -use syntax::codemap; +use syntax::{mod, abi, attr}; +use syntax::ast::{mod, ProvidedMethod, RequiredMethod, TypeTraitItem}; +use syntax::ast_util::{mod, local_def, PostExpansionMethod}; +use syntax::codemap::{mod, Span}; use syntax::owned_slice::OwnedSlice; use syntax::parse::token; use syntax::print::pprust; use syntax::ptr::P; -use syntax::visit; -use syntax::visit::Visitor; -use syntax; +use syntax::visit::{mod, Visitor}; pub mod _match; pub mod vtable; @@ -4405,10 +4384,10 @@ fn check_expr_with_unifier<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.require_expr_have_sized_type(expr, traits::StructInitializerSized); } - ast::ExprField(ref base, ref field, _) => { + ast::ExprField(ref base, ref field) => { check_field(fcx, expr, lvalue_pref, &**base, field); } - ast::ExprTupField(ref base, idx, _) => { + ast::ExprTupField(ref base, idx) => { check_tup_field(fcx, expr, lvalue_pref, &**base, idx); } ast::ExprIndex(ref base, ref idx) => { diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index cda8a1b1b5f..549d636e8cb 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -278,8 +278,8 @@ mod svh_visitor { ExprBlock(..) => SawExprBlock, ExprAssign(..) => SawExprAssign, ExprAssignOp(op, _, _) => SawExprAssignOp(op), - ExprField(_, id, _) => SawExprField(content(id.node)), - ExprTupField(_, id, _) => SawExprTupField(id.node), + ExprField(_, id) => SawExprField(content(id.node)), + ExprTupField(_, id) => SawExprTupField(id.node), ExprIndex(..) => SawExprIndex, ExprSlice(..) => SawExprSlice, ExprPath(..) => SawExprPath, diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 67ed95f83fd..ec228c8aa15 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -30,34 +30,26 @@ use driver::driver::CrateAnalysis; use session::Session; -use middle::def; +use middle::{def, typeck}; use middle::ty::{mod, Ty}; -use middle::typeck; use std::cell::Cell; -use std::io; -use std::io::File; -use std::io::fs; +use std::io::{mod, File, fs}; use std::os; -use syntax::ast; -use syntax::ast_util; -use syntax::ast_util::PostExpansionMethod; -use syntax::ast::{NodeId,DefId}; +use syntax::ast_util::{mod, PostExpansionMethod}; +use syntax::ast::{mod, NodeId, DefId}; use syntax::ast_map::NodeItem; use syntax::attr; use syntax::codemap::*; -use syntax::parse::token; -use syntax::parse::token::{get_ident,keywords}; +use syntax::parse::token::{mod, get_ident, keywords}; use syntax::owned_slice::OwnedSlice; -use syntax::visit; -use syntax::visit::Visitor; +use syntax::visit::{mod, Visitor}; use syntax::print::pprust::{path_to_string,ty_to_string}; use syntax::ptr::P; use self::span_utils::SpanUtils; -use self::recorder::Recorder; -use self::recorder::FmtStrs; +use self::recorder::{Recorder, FmtStrs}; use util::ppaux; @@ -1293,7 +1285,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { ast::ExprStruct(ref path, ref fields, ref base) => self.process_struct_lit(ex, path, fields, base), ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args), - ast::ExprField(ref sub_ex, ident, _) => { + ast::ExprField(ref sub_ex, ident) => { if generated_code(sub_ex.span) { return } @@ -1319,7 +1311,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { "Expected struct type, but not ty_struct"), } }, - ast::ExprTupField(ref sub_ex, idx, _) => { + ast::ExprTupField(ref sub_ex, idx) => { if generated_code(sub_ex.span) { return } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 4213e941727..c7cdf937049 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -13,22 +13,14 @@ use back::abi; use llvm; use llvm::{ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True, False}; use llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, - RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; + RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; use metadata::csearch; -use middle::const_eval; -use middle::def; -use trans::adt; -use trans::base; -use trans::base::push_ctxt; -use trans::closure; +use middle::{const_eval, def}; +use trans::{adt, closure, consts, debuginfo, expr, inline, machine}; +use trans::base::{mod, push_ctxt}; use trans::common::*; -use trans::consts; -use trans::expr; -use trans::inline; -use trans::machine; use trans::type_::Type; use trans::type_of; -use trans::debuginfo; use middle::ty::{mod, Ty}; use util::ppaux::{Repr, ty_to_string}; @@ -418,7 +410,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { } } } - ast::ExprField(ref base, field, _) => { + ast::ExprField(ref base, field) => { let (bv, bt) = const_expr(cx, &**base); let brepr = adt::represent_type(cx, bt); expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { @@ -426,7 +418,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { adt::const_get_field(cx, &*brepr, bv, discr, ix) }) } - ast::ExprTupField(ref base, idx, _) => { + ast::ExprTupField(ref base, idx) => { let (bv, bt) = const_expr(cx, &**base); let brepr = adt::represent_type(cx, bt); expr::with_field_tys(cx.tcx(), bt, None, |discr, _| { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 075b6b0dd6e..a3472e194cf 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -197,13 +197,10 @@ use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::debuginfo::*; use metadata::csearch; use middle::subst::{mod, Subst, Substs}; -use trans::adt; +use trans::{mod, adt, machine, type_of}; use trans::common::*; -use trans::machine; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; -use trans::type_of; use trans::type_::Type; -use trans; use middle::ty::{mod, Ty}; use middle::pat_util; use session::config::{mod, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; @@ -219,8 +216,7 @@ use syntax::util::interner::Interner; use syntax::codemap::{Span, Pos}; use syntax::{ast, codemap, ast_util, ast_map}; use syntax::ast_util::PostExpansionMethod; -use syntax::parse::token; -use syntax::parse::token::special_idents; +use syntax::parse::token::{mod, special_idents}; static DW_LANG_RUST: c_uint = 0x9000; @@ -3456,8 +3452,8 @@ fn populate_scope_map(cx: &CrateContext, ast::ExprCast(ref sub_exp, _) | ast::ExprAddrOf(_, ref sub_exp) | - ast::ExprField(ref sub_exp, _, _) | - ast::ExprTupField(ref sub_exp, _, _) | + ast::ExprField(ref sub_exp, _) | + ast::ExprTupField(ref sub_exp, _) | ast::ExprParen(ref sub_exp) => walk_expr(cx, &**sub_exp, scope_stack, scope_map), diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 670e893cc0e..9e004b137bb 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -38,47 +38,26 @@ pub use self::Dest::*; use self::lazy_binop_ty::*; use back::abi; -use llvm; -use llvm::{ValueRef}; +use llvm::{mod, ValueRef}; use middle::def; use middle::mem_categorization::Typer; -use middle::subst; -use middle::subst::Subst; -use trans::_match; -use trans::adt; -use trans::asm; +use middle::subst::{mod, Subst}; +use trans::{_match, adt, asm, base, callee, closure, consts, controlflow}; +use trans::{debuginfo, glue, machine, meth, inline, tvec, type_of}; use trans::base::*; -use trans::base; use trans::build::*; -use trans::callee; -use trans::cleanup; -use trans::cleanup::CleanupMethods; -use trans::closure; +use trans::cleanup::{mod, CleanupMethods}; use trans::common::*; -use trans::consts; -use trans::controlflow; use trans::datum::*; -use trans::debuginfo; -use trans::glue; -use trans::machine; -use trans::meth; -use trans::inline; -use trans::tvec; -use trans::type_of; -use middle::ty::{struct_fields, tup_fields}; -use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe}; -use middle::ty::{AutoPtr}; -use middle::ty::{mod, Ty}; -use middle::typeck; -use middle::typeck::MethodCall; +use middle::ty::{mod, struct_fields, tup_fields}; +use middle::ty::{AdjustDerefRef, AdjustAddEnv, AutoUnsafe, AutoPtr, Ty}; +use middle::typeck::{mod, MethodCall}; use util::common::indenter; use util::ppaux::Repr; use trans::machine::{llsize_of, llsize_of_alloc}; use trans::type_::Type; -use syntax::ast; -use syntax::ast_util; -use syntax::codemap; +use syntax::{ast, ast_util, codemap}; use syntax::print::pprust::{expr_to_string}; use syntax::ptr::P; use std::rc::Rc; @@ -599,10 +578,10 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprPath(_) => { trans_def(bcx, expr, bcx.def(expr.id)) } - ast::ExprField(ref base, ident, _) => { + ast::ExprField(ref base, ident) => { trans_rec_field(bcx, &**base, ident.node) } - ast::ExprTupField(ref base, idx, _) => { + ast::ExprTupField(ref base, idx) => { trans_rec_tup_field(bcx, &**base, idx.node) } ast::ExprIndex(ref base, ref idx) => { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5d4fd2704a2..3d33774aa55 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -673,8 +673,8 @@ pub enum Expr_ { ExprAssign(P, P), ExprAssignOp(BinOp, P, P), - ExprField(P, SpannedIdent, Vec>), - ExprTupField(P, Spanned, Vec>), + ExprField(P, SpannedIdent), + ExprTupField(P, Spanned), ExprIndex(P, P), ExprSlice(P, Option>, Option>, Mutability), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b18a0c8411c..2c7f9e889f8 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -577,7 +577,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }; let id = Spanned { node: ident, span: field_span }; - self.expr(sp, ast::ExprField(expr, id, Vec::new())) + self.expr(sp, ast::ExprField(expr, id)) } fn expr_tup_field_access(&self, sp: Span, expr: P, idx: uint) -> P { let field_span = Span { @@ -587,7 +587,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }; let id = Spanned { node: idx, span: field_span }; - self.expr(sp, ast::ExprTupField(expr, id, Vec::new())) + self.expr(sp, ast::ExprTupField(expr, id)) } fn expr_addr_of(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1bdf9ea73df..6941c0e9c18 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1345,15 +1345,13 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> folder.fold_expr(el), folder.fold_expr(er)) } - ExprField(el, ident, tys) => { + ExprField(el, ident) => { ExprField(folder.fold_expr(el), - respan(ident.span, folder.fold_ident(ident.node)), - tys.move_map(|x| folder.fold_ty(x))) + respan(ident.span, folder.fold_ident(ident.node))) } - ExprTupField(el, ident, tys) => { + ExprTupField(el, ident) => { ExprTupField(folder.fold_expr(el), - respan(ident.span, folder.fold_uint(ident.node)), - tys.move_map(|x| folder.fold_ty(x))) + respan(ident.span, folder.fold_uint(ident.node))) } ExprIndex(el, er) => { ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e4fa6508820..a9306c71240 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -71,14 +71,11 @@ use ext::tt::macro_parser; use parse; use parse::attr::ParserAttr; use parse::classify; -use parse::common::{SeqSep, seq_sep_none}; -use parse::common::{seq_sep_trailing_allowed}; -use parse::lexer::Reader; -use parse::lexer::TokenAndSpan; +use parse::common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed}; +use parse::lexer::{Reader, TokenAndSpan}; use parse::obsolete::*; -use parse::token::{MatchNt, SubstNt, InternedString}; +use parse::token::{mod, MatchNt, SubstNt, InternedString}; use parse::token::{keywords, special_idents}; -use parse::token; use parse::{new_sub_parser_from_file, ParseSess}; use print::pprust; use ptr::P; @@ -86,7 +83,6 @@ use owned_slice::OwnedSlice; use std::collections::HashSet; use std::io::fs::PathExtensions; -use std::mem::replace; use std::mem; use std::num::Float; use std::rc::Rc; @@ -912,7 +908,7 @@ impl<'a> Parser<'a> { tok: token::Underscore, sp: self.span, }; - replace(&mut self.buffer[buffer_start], placeholder) + mem::replace(&mut self.buffer[buffer_start], placeholder) }; self.span = next.sp; self.token = next.tok; @@ -921,7 +917,7 @@ impl<'a> Parser<'a> { /// Advance the parser by one token and return the bumped token. pub fn bump_and_get(&mut self) -> token::Token { - let old_token = replace(&mut self.token, token::Underscore); + let old_token = mem::replace(&mut self.token, token::Underscore); self.bump(); old_token } @@ -2100,14 +2096,12 @@ impl<'a> Parser<'a> { ExprSlice(expr, start, end, mutbl) } - pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent, - tys: Vec>) -> ast::Expr_ { - ExprField(expr, ident, tys) + pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent) -> ast::Expr_ { + ExprField(expr, ident) } - pub fn mk_tup_field(&mut self, expr: P, idx: codemap::Spanned, - tys: Vec>) -> ast::Expr_ { - ExprTupField(expr, idx, tys) + pub fn mk_tup_field(&mut self, expr: P, idx: codemap::Spanned) -> ast::Expr_ { + ExprTupField(expr, idx) } pub fn mk_assign_op(&mut self, binop: ast::BinOp, @@ -2462,7 +2456,7 @@ impl<'a> Parser<'a> { } let id = spanned(dot, hi, i); - let field = self.mk_field(e, id, tys); + let field = self.mk_field(e, id); e = self.mk_expr(lo, hi, field); } } @@ -2481,7 +2475,7 @@ impl<'a> Parser<'a> { match index { Some(n) => { let id = spanned(dot, hi, n); - let field = self.mk_tup_field(e, id, Vec::new()); + let field = self.mk_tup_field(e, id); e = self.mk_expr(lo, hi, field); } None => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 4ce0d74bd37..2b80be0bf2a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1734,29 +1734,15 @@ impl<'a> State<'a> { try!(self.word_space("=")); try!(self.print_expr(&**rhs)); } - ast::ExprField(ref expr, id, ref tys) => { + ast::ExprField(ref expr, id) => { try!(self.print_expr(&**expr)); try!(word(&mut self.s, ".")); try!(self.print_ident(id.node)); - if tys.len() > 0u { - try!(word(&mut self.s, "::<")); - try!(self.commasep( - Inconsistent, tys.as_slice(), - |s, ty| s.print_type(&**ty))); - try!(word(&mut self.s, ">")); - } } - ast::ExprTupField(ref expr, id, ref tys) => { + ast::ExprTupField(ref expr, id) => { try!(self.print_expr(&**expr)); try!(word(&mut self.s, ".")); try!(self.print_uint(id.node)); - if tys.len() > 0u { - try!(word(&mut self.s, "::<")); - try!(self.commasep( - Inconsistent, tys.as_slice(), - |s, ty| s.print_type(&**ty))); - try!(word(&mut self.s, ">")); - } } ast::ExprIndex(ref expr, ref index) => { try!(self.print_expr(&**expr)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index a0bdd739113..3f87dbc0740 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -838,17 +838,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(&**right_expression); visitor.visit_expr(&**left_expression) } - ExprField(ref subexpression, _, ref types) => { + ExprField(ref subexpression, _) => { visitor.visit_expr(&**subexpression); - for typ in types.iter() { - visitor.visit_ty(&**typ) - } } - ExprTupField(ref subexpression, _, ref types) => { + ExprTupField(ref subexpression, _) => { visitor.visit_expr(&**subexpression); - for typ in types.iter() { - visitor.visit_ty(&**typ) - } } ExprIndex(ref main_expression, ref index_expression) => { visitor.visit_expr(&**main_expression); -- cgit 1.4.1-3-g733a5 From a9c1152c4bf72132806cb76045b3464d59db07da Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 14 Nov 2014 14:20:57 -0800 Subject: std: Add a new top-level thread_local module This commit removes the `std::local_data` module in favor of a new `std::thread_local` module providing thread local storage. The module provides two variants of TLS: one which owns its contents and one which is based on scoped references. Each implementation has pros and cons listed in the documentation. Both flavors have accessors through a function called `with` which yield a reference to a closure provided. Both flavors also panic if a reference cannot be yielded and provide a function to test whether an access would panic or not. This is an implementation of [RFC 461][rfc] and full details can be found in that RFC. This is a breaking change due to the removal of the `std::local_data` module. All users can migrate to the new thread local system like so: thread_local!(static FOO: Rc>> = Rc::new(RefCell::new(None))) The old `local_data` module inherently contained the `Rc>>` as an implementation detail which must now be explicitly stated by users. [rfc]: https://github.com/rust-lang/rfcs/pull/461 [breaking-change] --- src/liblog/lib.rs | 19 +- src/librustc/util/common.rs | 13 +- src/librustc_trans/trans/base.rs | 35 +- src/librustdoc/html/format.rs | 26 +- src/librustdoc/html/markdown.rs | 55 +- src/librustdoc/html/render.rs | 45 +- src/librustdoc/lib.rs | 17 +- src/librustdoc/markdown.rs | 2 +- src/librustdoc/passes.rs | 4 +- src/librustdoc/stability_summary.rs | 4 +- src/librustrt/lib.rs | 1 - src/librustrt/local_data.rs | 696 --------------------- src/librustrt/task.rs | 64 +- src/libstd/collections/hash/map.rs | 133 ++-- src/libstd/failure.rs | 15 +- src/libstd/io/stdio.rs | 31 +- src/libstd/lib.rs | 31 +- src/libstd/macros.rs | 22 - src/libstd/rand/mod.rs | 31 +- src/libstd/sync/future.rs | 24 - src/libstd/sys/common/mod.rs | 1 + src/libstd/sys/common/thread_local.rs | 306 +++++++++ src/libstd/sys/unix/mod.rs | 7 +- src/libstd/sys/unix/thread_local.rs | 52 ++ src/libstd/sys/windows/mod.rs | 7 +- src/libstd/sys/windows/thread_local.rs | 238 +++++++ src/libstd/thread_local/mod.rs | 634 +++++++++++++++++++ src/libstd/thread_local/scoped.rs | 261 ++++++++ src/libsyntax/attr.rs | 20 +- src/libsyntax/diagnostics/plugin.rs | 32 +- src/libsyntax/ext/mtwt.rs | 28 +- src/libsyntax/parse/token.rs | 13 +- .../plugin_crate_outlive_expansion_phase.rs | 5 +- src/test/compile-fail/core-tls-store-pointer.rs | 16 - src/test/compile-fail/macro-local-data-key-priv.rs | 4 +- src/test/run-pass/macro-local-data-key.rs | 26 - src/test/run-pass/panic-during-tld-destroy.rs | 33 - src/test/run-pass/running-with-no-runtime.rs | 8 - 38 files changed, 1809 insertions(+), 1150 deletions(-) delete mode 100644 src/librustrt/local_data.rs create mode 100644 src/libstd/sys/common/thread_local.rs create mode 100644 src/libstd/sys/unix/thread_local.rs create mode 100644 src/libstd/sys/windows/thread_local.rs create mode 100644 src/libstd/thread_local/mod.rs create mode 100644 src/libstd/thread_local/scoped.rs delete mode 100644 src/test/compile-fail/core-tls-store-pointer.rs delete mode 100644 src/test/run-pass/macro-local-data-key.rs delete mode 100644 src/test/run-pass/panic-during-tld-destroy.rs (limited to 'src/libsyntax/parse') diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index fd2d97d4deb..dab033e0972 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -171,7 +171,7 @@ extern crate regex; -use regex::Regex; +use std::cell::RefCell; use std::fmt; use std::io::LineBufferedWriter; use std::io; @@ -181,6 +181,8 @@ use std::rt; use std::slice; use std::sync::{Once, ONCE_INIT}; +use regex::Regex; + use directive::LOG_LEVEL_NAMES; pub mod macros; @@ -213,7 +215,9 @@ pub const WARN: u32 = 2; /// Error log level pub const ERROR: u32 = 1; -local_data_key!(local_logger: Box) +thread_local!(static LOCAL_LOGGER: RefCell>> = { + RefCell::new(None) +}) /// A trait used to represent an interface to a task-local logger. Each task /// can have its own custom logger which can respond to logging messages @@ -283,7 +287,9 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) { // Completely remove the local logger from TLS in case anyone attempts to // frob the slot while we're doing the logging. This will destroy any logger // set during logging. - let mut logger = local_logger.replace(None).unwrap_or_else(|| { + let mut logger = LOCAL_LOGGER.with(|s| { + s.borrow_mut().take() + }).unwrap_or_else(|| { box DefaultLogger { handle: io::stderr() } as Box }); logger.log(&LogRecord { @@ -293,7 +299,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) { module_path: loc.module_path, line: loc.line, }); - local_logger.replace(Some(logger)); + set_logger(logger); } /// Getter for the global log level. This is a function so that it can be called @@ -305,7 +311,10 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } } /// Replaces the task-local logger with the specified logger, returning the old /// logger. pub fn set_logger(logger: Box) -> Option> { - local_logger.replace(Some(logger)) + let mut l = Some(logger); + LOCAL_LOGGER.with(|slot| { + mem::replace(&mut *slot.borrow_mut(), l.take()) + }) } /// A LogRecord is created by the logging macros, and passed as the only diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index e2fa02584f4..7973004d515 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -10,7 +10,7 @@ #![allow(non_camel_case_types)] -use std::cell::RefCell; +use std::cell::{RefCell, Cell}; use std::collections::HashMap; use std::fmt::Show; use std::hash::{Hash, Hasher}; @@ -26,11 +26,14 @@ use syntax::visit::Visitor; pub struct ErrorReported; pub fn time(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { - local_data_key!(depth: uint); + thread_local!(static DEPTH: Cell = Cell::new(0)); if !do_it { return f(u); } - let old = depth.get().map(|d| *d).unwrap_or(0); - depth.replace(Some(old + 1)); + let old = DEPTH.with(|slot| { + let r = slot.get(); + slot.set(r + 1); + r + }); let mut u = Some(u); let mut rv = None; @@ -41,7 +44,7 @@ pub fn time(do_it: bool, what: &str, u: U, f: |U| -> T) -> T { println!("{}time: {}.{:03} \t{}", " ".repeat(old), dur.num_seconds(), dur.num_milliseconds() % 1000, what); - depth.replace(Some(old)); + DEPTH.with(|slot| slot.set(old)); rv } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 85085f46731..bdf2eca21d6 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -100,17 +100,20 @@ use syntax::visit::Visitor; use syntax::visit; use syntax::{ast, ast_util, ast_map}; -local_data_key!(task_local_insn_key: RefCell>) +thread_local!(static TASK_LOCAL_INSN_KEY: RefCell>> = { + RefCell::new(None) +}) pub fn with_insn_ctxt(blk: |&[&'static str]|) { - match task_local_insn_key.get() { - Some(ctx) => blk(ctx.borrow().as_slice()), - None => () - } + TASK_LOCAL_INSN_KEY.with(|slot| { + slot.borrow().as_ref().map(|s| blk(s.as_slice())); + }) } pub fn init_insn_ctxt() { - task_local_insn_key.replace(Some(RefCell::new(Vec::new()))); + TASK_LOCAL_INSN_KEY.with(|slot| { + *slot.borrow_mut() = Some(Vec::new()); + }); } pub struct _InsnCtxt { @@ -120,19 +123,23 @@ pub struct _InsnCtxt { #[unsafe_destructor] impl Drop for _InsnCtxt { fn drop(&mut self) { - match task_local_insn_key.get() { - Some(ctx) => { ctx.borrow_mut().pop(); } - None => {} - } + TASK_LOCAL_INSN_KEY.with(|slot| { + match slot.borrow_mut().as_mut() { + Some(ctx) => { ctx.pop(); } + None => {} + } + }) } } pub fn push_ctxt(s: &'static str) -> _InsnCtxt { debug!("new InsnCtxt: {}", s); - match task_local_insn_key.get() { - Some(ctx) => ctx.borrow_mut().push(s), - None => {} - } + TASK_LOCAL_INSN_KEY.with(|slot| { + match slot.borrow_mut().as_mut() { + Some(ctx) => ctx.push(s), + None => {} + } + }); _InsnCtxt { _cannot_construct_outside_of_this_module: () } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a7f33151547..2b521d1da06 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -26,7 +26,7 @@ use stability_summary::ModuleSummary; use html::item_type; use html::item_type::ItemType; use html::render; -use html::render::{cache_key, current_location_key}; +use html::render::{cache, CURRENT_LOCATION_KEY}; /// Helper to render an optional visibility with a space after it (if the /// visibility is preset) @@ -236,9 +236,9 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, generics.push_str(">"); } - let loc = current_location_key.get().unwrap(); - let cache = cache_key.get().unwrap(); - let abs_root = root(&**cache, loc.as_slice()); + let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone()); + let cache = cache(); + let abs_root = root(&*cache, loc.as_slice()); let rel_root = match path.segments[0].name.as_slice() { "self" => Some("./".to_string()), _ => None, @@ -271,7 +271,7 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, } } - match info(&**cache) { + match info(&*cache) { // This is a documented path, link to it! Some((ref fqp, shortty)) if abs_root.is_some() => { let mut url = String::from_str(abs_root.unwrap().as_slice()); @@ -308,12 +308,12 @@ fn path(w: &mut fmt::Formatter, path: &clean::Path, print_all: bool, fn primitive_link(f: &mut fmt::Formatter, prim: clean::PrimitiveType, name: &str) -> fmt::Result { - let m = cache_key.get().unwrap(); + let m = cache(); let mut needs_termination = false; match m.primitive_locations.get(&prim) { Some(&ast::LOCAL_CRATE) => { - let loc = current_location_key.get().unwrap(); - let len = if loc.len() == 0 {0} else {loc.len() - 1}; + let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); + let len = if len == 0 {0} else {len - 1}; try!(write!(f, "", "../".repeat(len), prim.to_url_str())); @@ -327,8 +327,8 @@ fn primitive_link(f: &mut fmt::Formatter, let loc = match m.extern_locations[cnum] { render::Remote(ref s) => Some(s.to_string()), render::Local => { - let loc = current_location_key.get().unwrap(); - Some("../".repeat(loc.len())) + let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); + Some("../".repeat(len)) } render::Unknown => None, }; @@ -371,12 +371,10 @@ impl fmt::Show for clean::Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::TyParamBinder(id) => { - let m = cache_key.get().unwrap(); - f.write(m.typarams[ast_util::local_def(id)].as_bytes()) + f.write(cache().typarams[ast_util::local_def(id)].as_bytes()) } clean::Generic(did) => { - let m = cache_key.get().unwrap(); - f.write(m.typarams[did].as_bytes()) + f.write(cache().typarams[did].as_bytes()) } clean::ResolvedPath{ did, ref typarams, ref path } => { try!(resolved_path(f, did, path, false)); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 07b58e1b66c..11dc8f4f660 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -147,10 +147,14 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { } } -local_data_key!(used_header_map: RefCell>) -local_data_key!(test_idx: Cell) -// None == render an example, but there's no crate name -local_data_key!(pub playground_krate: Option) +thread_local!(static USED_HEADER_MAP: RefCell> = { + RefCell::new(HashMap::new()) +}) +thread_local!(static TEST_IDX: Cell = Cell::new(0)) + +thread_local!(pub static PLAYGROUND_KRATE: RefCell>> = { + RefCell::new(None) +}) pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { extern fn block(ob: *mut hoedown_buffer, orig_text: *const hoedown_buffer, @@ -183,12 +187,15 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { stripped_filtered_line(*l).is_none() }); let text = lines.collect::>().connect("\n"); - if !rendered { + if rendered { return } + PLAYGROUND_KRATE.with(|krate| { let mut s = String::new(); - let id = playground_krate.get().map(|krate| { - let idx = test_idx.get().unwrap(); - let i = idx.get(); - idx.set(i + 1); + let id = krate.borrow().as_ref().map(|krate| { + let idx = TEST_IDX.with(|slot| { + let i = slot.get(); + slot.set(i + 1); + i + }); let test = origtext.lines().map(|l| { stripped_filtered_line(l).unwrap_or(l) @@ -197,15 +204,15 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { let test = test::maketest(test.as_slice(), krate, false, false); s.push_str(format!("{}", - i, Escape(test.as_slice())).as_slice()); - format!("rust-example-rendered-{}", i) + idx, Escape(test.as_slice())).as_slice()); + format!("rust-example-rendered-{}", idx) }); let id = id.as_ref().map(|a| a.as_slice()); s.push_str(highlight::highlight(text.as_slice(), None, id) .as_slice()); let output = s.to_c_str(); hoedown_buffer_puts(ob, output.as_ptr()); - } + }) } } @@ -229,18 +236,20 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { // This is a terrible hack working around how hoedown gives us rendered // html for text rather than the raw text. - let id = id.replace("", "").replace("", "").to_string(); let opaque = opaque as *mut hoedown_html_renderer_state; let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) }; // Make sure our hyphenated ID is unique for this page - let map = used_header_map.get().unwrap(); - let id = match map.borrow_mut().get_mut(&id) { - None => id, - Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) } - }; - map.borrow_mut().insert(id.clone(), 1); + let id = USED_HEADER_MAP.with(|map| { + let id = id.replace("", "").replace("", "").to_string(); + let id = match map.borrow_mut().get_mut(&id) { + None => id, + Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) } + }; + map.borrow_mut().insert(id.clone(), 1); + id + }); let sec = match opaque.toc_builder { Some(ref mut builder) => { @@ -262,9 +271,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { text.with_c_str(|p| unsafe { hoedown_buffer_puts(ob, p) }); } - if used_header_map.get().is_none() { - reset_headers(); - } + reset_headers(); unsafe { let ob = hoedown_buffer_new(DEF_OUNIT); @@ -418,8 +425,8 @@ impl LangString { /// used at the beginning of rendering an entire HTML page to reset from the /// previous state (if any). pub fn reset_headers() { - used_header_map.replace(Some(RefCell::new(HashMap::new()))); - test_idx.replace(Some(Cell::new(0))); + USED_HEADER_MAP.with(|s| s.borrow_mut().clear()); + TEST_IDX.with(|s| s.set(0)); } impl<'a> fmt::Show for Markdown<'a> { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9e3c336a7a0..466af36898e 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -34,8 +34,10 @@ //! both occur before the crate is rendered. pub use self::ExternalLocation::*; -use std::collections::{HashMap, HashSet}; +use std::cell::RefCell; use std::collections::hash_map::{Occupied, Vacant}; +use std::collections::{HashMap, HashSet}; +use std::default::Default; use std::fmt; use std::io::fs::PathExtensions; use std::io::{fs, File, BufferedWriter, BufferedReader}; @@ -141,6 +143,7 @@ pub struct Impl { /// to be a fairly large and expensive structure to clone. Instead this adheres /// to `Send` so it may be stored in a `Arc` instance and shared among the various /// rendering tasks. +#[deriving(Default)] pub struct Cache { /// Mapping of typaram ids to the name of the type parameter. This is used /// when pretty-printing a type (so pretty printing doesn't have to @@ -235,8 +238,9 @@ struct IndexItem { // TLS keys used to carry information around during rendering. -local_data_key!(pub cache_key: Arc) -local_data_key!(pub current_location_key: Vec ) +thread_local!(static CACHE_KEY: RefCell> = Default::default()) +thread_local!(pub static CURRENT_LOCATION_KEY: RefCell> = + RefCell::new(Vec::new())) /// Generates the documentation for `crate` into the directory `dst` pub fn run(mut krate: clean::Crate, @@ -280,10 +284,12 @@ pub fn run(mut krate: clean::Crate, clean::NameValue(ref x, ref s) if "html_playground_url" == x.as_slice() => { cx.layout.playground_url = s.to_string(); - let name = krate.name.clone(); - if markdown::playground_krate.get().is_none() { - markdown::playground_krate.replace(Some(Some(name))); - } + markdown::PLAYGROUND_KRATE.with(|slot| { + if slot.borrow().is_none() { + let name = krate.name.clone(); + *slot.borrow_mut() = Some(Some(name)); + } + }); } clean::Word(ref x) if "html_no_source" == x.as_slice() => { @@ -297,7 +303,8 @@ pub fn run(mut krate: clean::Crate, } // Crawl the crate to build various caches used for the output - let analysis = ::analysiskey.get(); + let analysis = ::ANALYSISKEY.with(|a| a.clone()); + let analysis = analysis.borrow(); let public_items = analysis.as_ref().map(|a| a.public_items.clone()); let public_items = public_items.unwrap_or(NodeSet::new()); let paths: HashMap, ItemType)> = @@ -370,8 +377,8 @@ pub fn run(mut krate: clean::Crate, // Freeze the cache now that the index has been built. Put an Arc into TLS // for future parallelization opportunities let cache = Arc::new(cache); - cache_key.replace(Some(cache.clone())); - current_location_key.replace(Some(Vec::new())); + CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone()); + CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear()); try!(write_shared(&cx, &krate, &*cache, index)); let krate = try!(render_sources(&mut cx, krate)); @@ -1134,7 +1141,9 @@ impl Context { info!("Rendering an item to {}", w.path().display()); // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. - current_location_key.replace(Some(cx.current.clone())); + CURRENT_LOCATION_KEY.with(|slot| { + *slot.borrow_mut() = cx.current.clone(); + }); let mut title = cx.current.connect("::"); if pushname { @@ -1177,7 +1186,7 @@ impl Context { &Item{ cx: cx, item: it })); } else { let mut url = "../".repeat(cx.current.len()); - match cache_key.get().unwrap().paths.get(&it.def_id) { + match cache().paths.get(&it.def_id) { Some(&(ref names, _)) => { for name in names[..names.len() - 1].iter() { url.push_str(name.as_slice()); @@ -1324,7 +1333,7 @@ impl<'a> Item<'a> { // If we don't know where the external documentation for this crate is // located, then we return `None`. } else { - let cache = cache_key.get().unwrap(); + let cache = cache(); let path = &cache.external_paths[self.item.def_id]; let root = match cache.extern_locations[self.item.def_id.krate] { Remote(ref s) => s.to_string(), @@ -1751,7 +1760,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, "")); } - let cache = cache_key.get().unwrap(); + let cache = cache(); try!(write!(w, "

Implementors