From df572fcf4eea79baddc0136573cbbeed88db001e Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 23:52:50 +0000 Subject: [PATCH 01/42] Remove unused function `lower_opt_bounds` --- src/librustc/hir/lowering.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0026412013c8e..e4b87ab8bf344 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -593,12 +593,6 @@ pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { } } -pub fn lower_opt_bounds(lctx: &LoweringContext, - b: &Option) - -> Option { - b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds)) -} - fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } From 417fe6d16e981c01bf258cd8b47a812bfb33723d Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 22:20:53 +0000 Subject: [PATCH 02/42] Refactor away method `LoweringContext::diagnostic` --- src/librustc/hir/lowering.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e4b87ab8bf344..4bfe514c39d10 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -50,7 +50,6 @@ use std::collections::BTreeMap; use std::iter; use syntax::ast::*; use syntax::attr::{ThinAttributes, ThinAttributesExt}; -use syntax::errors::Handler; use syntax::ext::mtwt; use syntax::ptr::P; use syntax::codemap::{respan, Spanned, Span}; @@ -94,7 +93,7 @@ impl Resolver for DummyResolver { } } -impl<'a, 'hir> LoweringContext<'a> { +impl<'a> LoweringContext<'a> { pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>, resolver: &'a mut Resolver) @@ -125,11 +124,6 @@ impl<'a, 'hir> LoweringContext<'a> { hir::Ident::from_name(token::gensym(s)) } - // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics. - fn diagnostic(&self) -> &Handler { - self.id_assigner.diagnostic() - } - fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { let old_def = self.parent_def.get(); self.parent_def.set(match self.resolver.borrow_mut().definitions() { @@ -1245,8 +1239,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], &[("start", e1), ("end", e2)]), - _ => panic!(lctx.diagnostic().span_fatal(e.span, - "inclusive range with no end")) + _ => panic!(lctx.id_assigner.diagnostic() + .span_fatal(e.span, "inclusive range with no end")), }; } ExprKind::Path(ref qself, ref path) => { From eed8d70ac5177e6f378d08318f77499231e24e32 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 07:59:19 +0000 Subject: [PATCH 03/42] Give lowering functions mutable access to the lowering context --- src/librustc/hir/lowering.rs | 281 ++++++++++++++--------------- src/librustc_driver/driver.rs | 4 +- src/librustc_metadata/astencode.rs | 16 +- src/librustdoc/test.rs | 4 +- 4 files changed, 152 insertions(+), 153 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4bfe514c39d10..dc4ed655c9b88 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -57,8 +57,6 @@ use syntax::parse::token; use syntax::std_inject; use syntax::visit::{self, Visitor}; -use std::cell::{Cell, RefCell}; - pub struct LoweringContext<'a> { crate_root: Option<&'static str>, // Use to assign ids to hir nodes that do not directly correspond to an ast node @@ -66,8 +64,8 @@ pub struct LoweringContext<'a> { // As we walk the AST we must keep track of the current 'parent' def id (in // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. - parent_def: Cell>, - resolver: RefCell<&'a mut Resolver>, + parent_def: Option, + resolver: &'a mut Resolver, } pub trait Resolver { @@ -111,8 +109,8 @@ impl<'a> LoweringContext<'a> { LoweringContext { crate_root: crate_root, id_assigner: id_assigner, - parent_def: Cell::new(None), - resolver: RefCell::new(resolver), + parent_def: None, + resolver: resolver, } } @@ -124,32 +122,34 @@ impl<'a> LoweringContext<'a> { hir::Ident::from_name(token::gensym(s)) } - fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { - let old_def = self.parent_def.get(); - self.parent_def.set(match self.resolver.borrow_mut().definitions() { + fn with_parent_def(&mut self, parent_id: NodeId, f: F) -> T + where F: FnOnce(&mut LoweringContext) -> T + { + let old_def = self.parent_def; + self.parent_def = match self.resolver.definitions() { Some(defs) => Some(defs.opt_def_index(parent_id).unwrap()), None => old_def, - }); + }; - let result = f(); + let result = f(self); - self.parent_def.set(old_def); + self.parent_def = old_def; result } } -pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident { +pub fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { hir::Ident { name: mtwt::resolve(ident), unhygienic_name: ident.name, } } -pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec) -> hir::HirVec { +pub fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { attrs.clone().into() } -pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { +pub fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { ViewPathSimple(ident, ref path) => { @@ -186,7 +186,7 @@ fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { } } -pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { +pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { hir::Arm { attrs: lower_attrs(lctx, &arm.attrs), pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), @@ -195,7 +195,7 @@ pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { } } -pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { +pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { match d.node { DeclKind::Local(ref l) => P(Spanned { node: hir::DeclLocal(lower_local(lctx, l)), @@ -208,7 +208,7 @@ pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { } } -pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBinding { +pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { hir::TypeBinding { id: b.id, name: b.ident.name, @@ -217,7 +217,7 @@ pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBin } } -pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { +pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { use syntax::ast::TyKind::*; P(hir::Ty { id: t.id, @@ -267,14 +267,14 @@ pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { }) } -pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { +pub fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), } } -pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { +pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { Spanned { node: hir::Variant_ { name: v.node.name.name, @@ -289,7 +289,7 @@ pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { // Path segments are usually unhygienic, hygienic path segments can occur only in // identifier-like paths originating from `ExprPath`. // Make life simpler for rustc_resolve by renaming only such segments. -pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { +pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; hir::Path { global: p.global, @@ -310,11 +310,11 @@ pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) - } } -pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { +pub fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { lower_path_full(lctx, p, false) } -pub fn lower_path_parameters(lctx: &LoweringContext, +pub fn lower_path_parameters(lctx: &mut LoweringContext, path_parameters: &PathParameters) -> hir::PathParameters { match *path_parameters { @@ -325,7 +325,7 @@ pub fn lower_path_parameters(lctx: &LoweringContext, } } -pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, +pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, data: &AngleBracketedParameterData) -> hir::AngleBracketedParameterData { let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; @@ -336,7 +336,7 @@ pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, } } -pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, +pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, data: &ParenthesizedParameterData) -> hir::ParenthesizedParameterData { let &ParenthesizedParameterData { ref inputs, ref output, span } = data; @@ -347,7 +347,7 @@ pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, } } -pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { +pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { P(hir::Local { id: l.id, ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), @@ -358,7 +358,7 @@ pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { }) } -pub fn lower_explicit_self_underscore(lctx: &LoweringContext, +pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, es: &SelfKind) -> hir::ExplicitSelf_ { match *es { @@ -375,21 +375,21 @@ pub fn lower_explicit_self_underscore(lctx: &LoweringContext, } } -pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability { +pub fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { match m { Mutability::Mutable => hir::MutMutable, Mutability::Immutable => hir::MutImmutable, } } -pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { +pub fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { Spanned { node: lower_explicit_self_underscore(lctx, &s.node), span: s.span, } } -pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { +pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { hir::Arg { id: arg.id, pat: lower_pat(lctx, &arg.pat), @@ -397,7 +397,7 @@ pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { } } -pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { +pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { P(hir::FnDecl { inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), output: match decl.output { @@ -409,7 +409,7 @@ pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { }) } -pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { +pub fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { match *tpb { TraitTyParamBound(ref ty, modifier) => { hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), @@ -421,7 +421,7 @@ pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir:: } } -pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { +pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { hir::TyParam { id: tp.id, name: tp.ident.name, @@ -431,13 +431,13 @@ pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { } } -pub fn lower_ty_params(lctx: &LoweringContext, +pub fn lower_ty_params(lctx: &mut LoweringContext, tps: &P<[TyParam]>) -> hir::HirVec { tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } -pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { +pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { hir::Lifetime { id: l.id, name: l.name, @@ -445,30 +445,31 @@ pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { } } -pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { +pub fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { hir::LifetimeDef { lifetime: lower_lifetime(lctx, &l.lifetime), bounds: lower_lifetimes(lctx, &l.bounds), } } -pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec) -> hir::HirVec { +pub fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) + -> hir::HirVec { lts.iter().map(|l| lower_lifetime(lctx, l)).collect() } -pub fn lower_lifetime_defs(lctx: &LoweringContext, +pub fn lower_lifetime_defs(lctx: &mut LoweringContext, lts: &Vec) -> hir::HirVec { lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() } -pub fn lower_opt_lifetime(lctx: &LoweringContext, +pub fn lower_opt_lifetime(lctx: &mut LoweringContext, o_lt: &Option) -> Option { o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) } -pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { +pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { hir::Generics { ty_params: lower_ty_params(lctx, &g.ty_params), lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), @@ -476,7 +477,7 @@ pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { } } -pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { +pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { hir::WhereClause { id: wc.id, predicates: wc.predicates @@ -486,7 +487,7 @@ pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::Wher } } -pub fn lower_where_predicate(lctx: &LoweringContext, +pub fn lower_where_predicate(lctx: &mut LoweringContext, pred: &WherePredicate) -> hir::WherePredicate { match *pred { @@ -524,7 +525,7 @@ pub fn lower_where_predicate(lctx: &LoweringContext, } } -pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { +pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { match *vdata { VariantData::Struct(ref fields, id) => { hir::VariantData::Struct(fields.iter() @@ -544,14 +545,14 @@ pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::V } } -pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { +pub fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { path: lower_path(lctx, &p.path), ref_id: p.ref_id, } } -pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { +pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { hir::PolyTraitRef { bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), trait_ref: lower_trait_ref(lctx, &p.trait_ref), @@ -559,7 +560,7 @@ pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::Po } } -pub fn lower_struct_field(lctx: &LoweringContext, +pub fn lower_struct_field(lctx: &mut LoweringContext, (index, f): (usize, &StructField)) -> hir::StructField { hir::StructField { @@ -572,7 +573,7 @@ pub fn lower_struct_field(lctx: &LoweringContext, } } -pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { +pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { hir::Field { name: respan(f.ident.span, f.ident.node.name), expr: lower_expr(lctx, &f.expr), @@ -580,18 +581,18 @@ pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { } } -pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { +pub fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { hir::MutTy { ty: lower_ty(lctx, &mt.ty), mutbl: lower_mutability(lctx, mt.mutbl), } } -fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { +fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } -pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { +pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { P(hir::Block { id: b.id, stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), @@ -601,7 +602,7 @@ pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { }) } -pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { +pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { match *i { ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), ItemKind::Use(ref view_path) => { @@ -669,8 +670,8 @@ pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { } } -pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { - lctx.with_parent_def(i.id, || { +pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { + lctx.with_parent_def(i.id, |lctx| { hir::TraitItem { id: i.id, name: i.ident.name, @@ -694,8 +695,8 @@ pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem }) } -pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { - lctx.with_parent_def(i.id, || { +pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { + lctx.with_parent_def(i.id, |lctx| { hir::ImplItem { id: i.id, name: i.ident.name, @@ -717,7 +718,7 @@ pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { }) } -pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { +pub fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), @@ -726,7 +727,7 @@ pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { struct ItemLowerer<'lcx, 'interner: 'lcx> { items: BTreeMap, - lctx: &'lcx LoweringContext<'interner>, + lctx: &'lcx mut LoweringContext<'interner>, } impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { @@ -736,7 +737,7 @@ impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { } } -pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { +pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { let items = { let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; visit::walk_crate(&mut item_lowerer, c); @@ -753,7 +754,7 @@ pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { } } -pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { +pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { hir::MacroDef { name: m.ident.name, attrs: lower_attrs(lctx, &m.attrs), @@ -767,12 +768,12 @@ pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { } } -pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { +pub fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { hir::ItemId { id: i.id } } -pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lctx.with_parent_def(i.id, || { +pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { + let node = lctx.with_parent_def(i.id, |lctx| { lower_item_kind(lctx, &i.node) }); @@ -786,8 +787,8 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { } } -pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - lctx.with_parent_def(i.id, || { +pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { + lctx.with_parent_def(i.id, |lctx| { hir::ForeignItem { id: i.id, name: i.ident.name, @@ -806,7 +807,7 @@ pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::Forei }) } -pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { +pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { hir::MethodSig { generics: lower_generics(lctx, &sig.generics), abi: sig.abi, @@ -817,21 +818,21 @@ pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodS } } -pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety { +pub fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { match u { Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Normal => hir::Unsafety::Normal, } } -pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness { +pub fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { match c { Constness::Const => hir::Constness::Const, Constness::NotConst => hir::Constness::NotConst, } } -pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { +pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { match u { UnOp::Deref => hir::UnDeref, UnOp::Not => hir::UnNot, @@ -839,7 +840,7 @@ pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { } } -pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { +pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { Spanned { node: match b.node { BinOpKind::Add => hir::BiAdd, @@ -865,13 +866,13 @@ pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { } } -pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { +pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { P(hir::Pat { id: p.id, node: match p.node { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { - lctx.with_parent_def(p.id, || { + lctx.with_parent_def(p.id, |lctx| { hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), respan(pth1.span, lower_ident(lctx, pth1.node)), sub.as_ref().map(|x| lower_pat(lctx, x))) @@ -930,7 +931,7 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { }) } -pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { +pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { P(hir::Expr { id: e.id, node: match e.node { @@ -977,17 +978,17 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let move_val_init = ["intrinsics", "move_val_init"]; let inplace_finalize = ["ops", "InPlace", "finalize"]; - let make_call = |lctx: &LoweringContext, p, args| { + let make_call = |lctx: &mut LoweringContext, p, args| { let path = core_path(lctx, e.span, p); let path = expr_path(lctx, path, None); expr_call(lctx, e.span, path, args, None) }; - let mk_stmt_let = |lctx: &LoweringContext, bind, expr| { + let mk_stmt_let = |lctx: &mut LoweringContext, bind, expr| { stmt_let(lctx, e.span, false, bind, expr, None) }; - let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| { + let mk_stmt_let_mut = |lctx: &mut LoweringContext, bind, expr| { stmt_let(lctx, e.span, true, bind, expr, None) }; @@ -1145,7 +1146,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::MatchSource::Normal) } ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { - lctx.with_parent_def(e.id, || { + lctx.with_parent_def(e.id, |lctx| { hir::ExprClosure(lower_capture_clause(lctx, capture_clause), lower_fn_decl(lctx, decl), lower_block(lctx, body), @@ -1171,7 +1172,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) } ExprKind::Range(ref e1, ref e2, lims) => { - fn make_struct(lctx: &LoweringContext, + fn make_struct(lctx: &mut LoweringContext, ast_expr: &Expr, path: &[&str], fields: &[(&str, &P)]) -> P { @@ -1187,21 +1188,19 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { structpath, ast_expr.attrs.clone()) } else { - expr_struct(lctx, - ast_expr.span, - structpath, - fields.into_iter().map(|&(s, e)| { - field(token::intern(s), - signal_block_expr(lctx, - hir_vec![], - lower_expr(lctx, &**e), - e.span, - hir::PopUnstableBlock, - None), - ast_expr.span) - }).collect(), - None, - ast_expr.attrs.clone()) + let fields = fields.into_iter().map(|&(s, e)| { + let expr = lower_expr(lctx, &e); + let signal_block = signal_block_expr(lctx, + hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + field(token::intern(s), signal_block, ast_expr.span) + }).collect(); + let attrs = ast_expr.attrs.clone(); + + expr_struct(lctx, ast_expr.span, structpath, fields, None, attrs) }; signal_block_expr(lctx, @@ -1613,7 +1612,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { }) } -pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { +pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { match s.node { StmtKind::Decl(ref d, id) => { Spanned { @@ -1637,14 +1636,14 @@ pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { } } -pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::CaptureClause { +pub fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { match c { CaptureBy::Value => hir::CaptureByValue, CaptureBy::Ref => hir::CaptureByRef, } } -pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility { +pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { match *v { Visibility::Public => hir::Public, Visibility::Crate(_) => hir::Visibility::Crate, @@ -1654,42 +1653,42 @@ pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibili } } -pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness { +pub fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { match d { Defaultness::Default => hir::Defaultness::Default, Defaultness::Final => hir::Defaultness::Final, } } -pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { +pub fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { match *b { BlockCheckMode::Default => hir::DefaultBlock, BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), } } -pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { +pub fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { match *b { BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), } } -pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { +pub fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { match u { CompilerGenerated => hir::CompilerGenerated, UserProvided => hir::UserProvided, } } -pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { +pub fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { match i { ImplPolarity::Positive => hir::ImplPolarity::Positive, ImplPolarity::Negative => hir::ImplPolarity::Negative, } } -pub fn lower_trait_bound_modifier(_lctx: &LoweringContext, +pub fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, f: TraitBoundModifier) -> hir::TraitBoundModifier { match f { @@ -1720,12 +1719,12 @@ fn field(name: Name, expr: P, span: Span) -> hir::Field { } } -fn expr_break(lctx: &LoweringContext, span: Span, +fn expr_break(lctx: &mut LoweringContext, span: Span, attrs: ThinAttributes) -> P { expr(lctx, span, hir::ExprBreak(None), attrs) } -fn expr_call(lctx: &LoweringContext, +fn expr_call(lctx: &mut LoweringContext, span: Span, e: P, args: hir::HirVec>, @@ -1734,32 +1733,32 @@ fn expr_call(lctx: &LoweringContext, expr(lctx, span, hir::ExprCall(e, args), attrs) } -fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident, +fn expr_ident(lctx: &mut LoweringContext, span: Span, id: hir::Ident, attrs: ThinAttributes, binding: NodeId) -> P { let expr = expr(lctx, span, hir::ExprPath(None, path_ident(span, id)), attrs); - let mut resolver = lctx.resolver.borrow_mut(); - let def = resolver.definitions().map(|defs| Def::Local(defs.local_def_id(binding), binding)) - .unwrap_or(Def::Err); - resolver.record_resolution(expr.id, def); + let def = lctx.resolver.definitions().map(|defs| { + Def::Local(defs.local_def_id(binding), binding) + }).unwrap_or(Def::Err); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P, +fn expr_mut_addr_of(lctx: &mut LoweringContext, span: Span, e: P, attrs: ThinAttributes) -> P { expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) } -fn expr_path(lctx: &LoweringContext, path: hir::Path, +fn expr_path(lctx: &mut LoweringContext, path: hir::Path, attrs: ThinAttributes) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, true); + let def = lctx.resolver.resolve_generated_global_path(&path, true); let expr = expr(lctx, path.span, hir::ExprPath(None, path), attrs); - lctx.resolver.borrow_mut().record_resolution(expr.id, def); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr_match(lctx: &LoweringContext, +fn expr_match(lctx: &mut LoweringContext, span: Span, arg: P, arms: hir::HirVec, @@ -1769,30 +1768,30 @@ fn expr_match(lctx: &LoweringContext, expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) } -fn expr_block(lctx: &LoweringContext, b: P, +fn expr_block(lctx: &mut LoweringContext, b: P, attrs: ThinAttributes) -> P { expr(lctx, b.span, hir::ExprBlock(b), attrs) } -fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec>, +fn expr_tuple(lctx: &mut LoweringContext, sp: Span, exprs: hir::HirVec>, attrs: ThinAttributes) -> P { expr(lctx, sp, hir::ExprTup(exprs), attrs) } -fn expr_struct(lctx: &LoweringContext, +fn expr_struct(lctx: &mut LoweringContext, sp: Span, path: hir::Path, fields: hir::HirVec, e: Option>, attrs: ThinAttributes) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, false); + let def = lctx.resolver.resolve_generated_global_path(&path, false); let expr = expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs); - lctx.resolver.borrow_mut().record_resolution(expr.id, def); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, +fn expr(lctx: &mut LoweringContext, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P { P(hir::Expr { id: lctx.next_id(), @@ -1802,7 +1801,7 @@ fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, }) } -fn stmt_let(lctx: &LoweringContext, +fn stmt_let(lctx: &mut LoweringContext, sp: Span, mutbl: bool, ident: hir::Ident, @@ -1827,11 +1826,11 @@ fn stmt_let(lctx: &LoweringContext, (respan(sp, hir::StmtDecl(P(decl), lctx.next_id())), pat_id) } -fn block_expr(lctx: &LoweringContext, expr: P) -> P { +fn block_expr(lctx: &mut LoweringContext, expr: P) -> P { block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) } -fn block_all(lctx: &LoweringContext, +fn block_all(lctx: &mut LoweringContext, span: Span, stmts: hir::HirVec, expr: Option>) @@ -1845,51 +1844,51 @@ fn block_all(lctx: &LoweringContext, }) } -fn pat_ok(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_ok(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let ok = std_path(lctx, &["result", "Result", "Ok"]); let path = path_global(span, ok); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_err(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_err(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let err = std_path(lctx, &["result", "Result", "Err"]); let path = path_global(span, err); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_some(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_some(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let some = std_path(lctx, &["option", "Option", "Some"]); let path = path_global(span, some); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_none(lctx: &LoweringContext, span: Span) -> P { +fn pat_none(lctx: &mut LoweringContext, span: Span) -> P { let none = std_path(lctx, &["option", "Option", "None"]); let path = path_global(span, none); pat_enum(lctx, span, path, hir_vec![]) } -fn pat_enum(lctx: &LoweringContext, +fn pat_enum(lctx: &mut LoweringContext, span: Span, path: hir::Path, subpats: hir::HirVec>) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, true); + let def = lctx.resolver.resolve_generated_global_path(&path, true); let pt = if subpats.is_empty() { hir::PatKind::Path(path) } else { hir::PatKind::TupleStruct(path, Some(subpats)) }; let pat = pat(lctx, span, pt); - lctx.resolver.borrow_mut().record_resolution(pat.id, def); + lctx.resolver.record_resolution(pat.id, def); pat } -fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P { +fn pat_ident(lctx: &mut LoweringContext, span: Span, ident: hir::Ident) -> P { pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) } -fn pat_ident_binding_mode(lctx: &LoweringContext, +fn pat_ident_binding_mode(lctx: &mut LoweringContext, span: Span, ident: hir::Ident, bm: hir::BindingMode) @@ -1903,22 +1902,22 @@ fn pat_ident_binding_mode(lctx: &LoweringContext, let pat = pat(lctx, span, pat_ident); - let mut resolver = lctx.resolver.borrow_mut(); - let def = resolver.definitions().map(|defs| { + let parent_def = lctx.parent_def; + let def = lctx.resolver.definitions().map(|defs| { let def_path_data = DefPathData::Binding(ident.name); - let def_index = defs.create_def_with_parent(lctx.parent_def.get(), pat.id, def_path_data); + let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); Def::Local(DefId::local(def_index), pat.id) }).unwrap_or(Def::Err); - resolver.record_resolution(pat.id, def); + lctx.resolver.record_resolution(pat.id, def); pat } -fn pat_wild(lctx: &LoweringContext, span: Span) -> P { +fn pat_wild(lctx: &mut LoweringContext, span: Span) -> P { pat(lctx, span, hir::PatKind::Wild) } -fn pat(lctx: &LoweringContext, span: Span, pat: hir::PatKind) -> P { +fn pat(lctx: &mut LoweringContext, span: Span, pat: hir::PatKind) -> P { P(hir::Pat { id: lctx.next_id(), node: pat, @@ -1969,7 +1968,7 @@ fn path_all(sp: Span, } } -fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { +fn std_path(lctx: &mut LoweringContext, components: &[&str]) -> Vec { let mut v = Vec::new(); if let Some(s) = lctx.crate_root { v.push(hir::Ident::from_name(token::intern(s))); @@ -1980,12 +1979,12 @@ fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { // Given suffix ["b","c","d"], returns path `::std::b::c::d` when // `fld.cx.use_std`, and `::core::b::c::d` otherwise. -fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path { +fn core_path(lctx: &mut LoweringContext, span: Span, components: &[&str]) -> hir::Path { let idents = std_path(lctx, components); path_global(span, idents) } -fn signal_block_expr(lctx: &LoweringContext, +fn signal_block_expr(lctx: &mut LoweringContext, stmts: hir::HirVec, expr: P, span: Span, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e72204e5e22de..66b1b28a0e505 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -787,8 +787,8 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let lcx = LoweringContext::new(sess, Some(krate), &mut resolver); - hir_map::Forest::new(lower_crate(&lcx, krate), dep_graph) + let mut lcx = LoweringContext::new(sess, Some(krate), &mut resolver); + hir_map::Forest::new(lower_crate(&mut lcx, krate), dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 56f6a3f7b14cb..ce525b716ff2c 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1326,11 +1326,11 @@ fn mk_ctxt() -> parse::ParseSess { } #[cfg(test)] -fn with_testing_context T>(f: F) -> T { +fn with_testing_context T>(f: F) -> T { let assigner = FakeNodeIdAssigner; let mut resolver = DummyResolver; - let lcx = LoweringContext::new(&assigner, None, &mut resolver); - f(lcx) + let mut lcx = LoweringContext::new(&assigner, None, &mut resolver); + f(&mut lcx) } #[cfg(test)] @@ -1347,7 +1347,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo() {} ).unwrap())); }); @@ -1357,7 +1357,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); }); @@ -1367,7 +1367,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; return z; @@ -1387,10 +1387,10 @@ fn test_simplification() { ).unwrap(); let cx = mk_ctxt(); with_testing_context(|lcx| { - let hir_item = lower_item(&lcx, &item); + let hir_item = lower_item(lcx, &item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); - let item_exp = InlinedItem::Item(P(lower_item(&lcx, "e_item!(&cx, + let item_exp = InlinedItem::Item(P(lower_item(lcx, "e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index fc548924e2964..0f518900ea787 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -98,8 +98,8 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); - let krate = lower_crate(&lcx, &krate); + let mut lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); + let krate = lower_crate(&mut lcx, &krate); let opts = scrape_test_config(&krate); From 8d5c5785d58f435d2d6e6e408e20c5c0b02a8e41 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 00:05:50 +0000 Subject: [PATCH 04/42] Remove needless `pub`s --- src/librustc/hir/lowering.rs | 162 +++++++++++++++++------------------ 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dc4ed655c9b88..40f6fddf10970 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -138,18 +138,18 @@ impl<'a> LoweringContext<'a> { } } -pub fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { +fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { hir::Ident { name: mtwt::resolve(ident), unhygienic_name: ident.name, } } -pub fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { +fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { attrs.clone().into() } -pub fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { +fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { ViewPathSimple(ident, ref path) => { @@ -186,7 +186,7 @@ fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { } } -pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { +fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { hir::Arm { attrs: lower_attrs(lctx, &arm.attrs), pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), @@ -195,7 +195,7 @@ pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { } } -pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { +fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { match d.node { DeclKind::Local(ref l) => P(Spanned { node: hir::DeclLocal(lower_local(lctx, l)), @@ -208,7 +208,7 @@ pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { } } -pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { +fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { hir::TypeBinding { id: b.id, name: b.ident.name, @@ -217,7 +217,7 @@ pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::Typ } } -pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { +fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { use syntax::ast::TyKind::*; P(hir::Ty { id: t.id, @@ -267,14 +267,14 @@ pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { }) } -pub fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { +fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), } } -pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { +fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { Spanned { node: hir::Variant_ { name: v.node.name.name, @@ -289,7 +289,7 @@ pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { // Path segments are usually unhygienic, hygienic path segments can occur only in // identifier-like paths originating from `ExprPath`. // Make life simpler for rustc_resolve by renaming only such segments. -pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { +fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; hir::Path { global: p.global, @@ -310,13 +310,13 @@ pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: boo } } -pub fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { +fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { lower_path_full(lctx, p, false) } -pub fn lower_path_parameters(lctx: &mut LoweringContext, - path_parameters: &PathParameters) - -> hir::PathParameters { +fn lower_path_parameters(lctx: &mut LoweringContext, + path_parameters: &PathParameters) + -> hir::PathParameters { match *path_parameters { PathParameters::AngleBracketed(ref data) => hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), @@ -325,9 +325,9 @@ pub fn lower_path_parameters(lctx: &mut LoweringContext, } } -pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, - data: &AngleBracketedParameterData) - -> hir::AngleBracketedParameterData { +fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, + data: &AngleBracketedParameterData) + -> hir::AngleBracketedParameterData { let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; hir::AngleBracketedParameterData { lifetimes: lower_lifetimes(lctx, lifetimes), @@ -336,9 +336,9 @@ pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, } } -pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, - data: &ParenthesizedParameterData) - -> hir::ParenthesizedParameterData { +fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, + data: &ParenthesizedParameterData) + -> hir::ParenthesizedParameterData { let &ParenthesizedParameterData { ref inputs, ref output, span } = data; hir::ParenthesizedParameterData { inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), @@ -347,7 +347,7 @@ pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, } } -pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { +fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { P(hir::Local { id: l.id, ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), @@ -358,9 +358,9 @@ pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { }) } -pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, - es: &SelfKind) - -> hir::ExplicitSelf_ { +fn lower_explicit_self_underscore(lctx: &mut LoweringContext, + es: &SelfKind) + -> hir::ExplicitSelf_ { match *es { SelfKind::Static => hir::SelfStatic, SelfKind::Value(v) => hir::SelfValue(v.name), @@ -375,21 +375,21 @@ pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, } } -pub fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { +fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { match m { Mutability::Mutable => hir::MutMutable, Mutability::Immutable => hir::MutImmutable, } } -pub fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { +fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { Spanned { node: lower_explicit_self_underscore(lctx, &s.node), span: s.span, } } -pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { +fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { hir::Arg { id: arg.id, pat: lower_pat(lctx, &arg.pat), @@ -397,7 +397,7 @@ pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { } } -pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { +fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { P(hir::FnDecl { inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), output: match decl.output { @@ -409,7 +409,7 @@ pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P hir::TyParamBound { +fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { match *tpb { TraitTyParamBound(ref ty, modifier) => { hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), @@ -421,7 +421,7 @@ pub fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> h } } -pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { +fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { hir::TyParam { id: tp.id, name: tp.ident.name, @@ -431,13 +431,13 @@ pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam } } -pub fn lower_ty_params(lctx: &mut LoweringContext, - tps: &P<[TyParam]>) - -> hir::HirVec { +fn lower_ty_params(lctx: &mut LoweringContext, + tps: &P<[TyParam]>) + -> hir::HirVec { tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } -pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { +fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { hir::Lifetime { id: l.id, name: l.name, @@ -445,31 +445,31 @@ pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetim } } -pub fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { +fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { hir::LifetimeDef { lifetime: lower_lifetime(lctx, &l.lifetime), bounds: lower_lifetimes(lctx, &l.bounds), } } -pub fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) +fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) -> hir::HirVec { lts.iter().map(|l| lower_lifetime(lctx, l)).collect() } -pub fn lower_lifetime_defs(lctx: &mut LoweringContext, - lts: &Vec) - -> hir::HirVec { +fn lower_lifetime_defs(lctx: &mut LoweringContext, + lts: &Vec) + -> hir::HirVec { lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() } -pub fn lower_opt_lifetime(lctx: &mut LoweringContext, - o_lt: &Option) - -> Option { +fn lower_opt_lifetime(lctx: &mut LoweringContext, + o_lt: &Option) + -> Option { o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) } -pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { +fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { hir::Generics { ty_params: lower_ty_params(lctx, &g.ty_params), lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), @@ -477,7 +477,7 @@ pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics } } -pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { +fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { hir::WhereClause { id: wc.id, predicates: wc.predicates @@ -487,9 +487,9 @@ pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir:: } } -pub fn lower_where_predicate(lctx: &mut LoweringContext, - pred: &WherePredicate) - -> hir::WherePredicate { +fn lower_where_predicate(lctx: &mut LoweringContext, + pred: &WherePredicate) + -> hir::WherePredicate { match *pred { WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, ref bounded_ty, @@ -525,7 +525,7 @@ pub fn lower_where_predicate(lctx: &mut LoweringContext, } } -pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { +fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { match *vdata { VariantData::Struct(ref fields, id) => { hir::VariantData::Struct(fields.iter() @@ -545,14 +545,14 @@ pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hi } } -pub fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { +fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { path: lower_path(lctx, &p.path), ref_id: p.ref_id, } } -pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { +fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { hir::PolyTraitRef { bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), trait_ref: lower_trait_ref(lctx, &p.trait_ref), @@ -560,9 +560,9 @@ pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir } } -pub fn lower_struct_field(lctx: &mut LoweringContext, - (index, f): (usize, &StructField)) - -> hir::StructField { +fn lower_struct_field(lctx: &mut LoweringContext, + (index, f): (usize, &StructField)) + -> hir::StructField { hir::StructField { span: f.span, id: f.id, @@ -573,7 +573,7 @@ pub fn lower_struct_field(lctx: &mut LoweringContext, } } -pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { +fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { hir::Field { name: respan(f.ident.span, f.ident.node.name), expr: lower_expr(lctx, &f.expr), @@ -581,7 +581,7 @@ pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { } } -pub fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { +fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { hir::MutTy { ty: lower_ty(lctx, &mt.ty), mutbl: lower_mutability(lctx, mt.mutbl), @@ -592,7 +592,7 @@ fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyPa bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } -pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { +fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { P(hir::Block { id: b.id, stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), @@ -602,7 +602,7 @@ pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { }) } -pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { +fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { match *i { ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), ItemKind::Use(ref view_path) => { @@ -670,7 +670,7 @@ pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { } } -pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { +fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { lctx.with_parent_def(i.id, |lctx| { hir::TraitItem { id: i.id, @@ -695,7 +695,7 @@ pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::Trait }) } -pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { +fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { lctx.with_parent_def(i.id, |lctx| { hir::ImplItem { id: i.id, @@ -718,7 +718,7 @@ pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplIte }) } -pub fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { +fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), @@ -754,7 +754,7 @@ pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { } } -pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { +fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { hir::MacroDef { name: m.ident.name, attrs: lower_attrs(lctx, &m.attrs), @@ -768,7 +768,7 @@ pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDe } } -pub fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { +fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { hir::ItemId { id: i.id } } @@ -787,7 +787,7 @@ pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { } } -pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { +fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { lctx.with_parent_def(i.id, |lctx| { hir::ForeignItem { id: i.id, @@ -807,7 +807,7 @@ pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::F }) } -pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { +fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { hir::MethodSig { generics: lower_generics(lctx, &sig.generics), abi: sig.abi, @@ -818,21 +818,21 @@ pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::Met } } -pub fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { +fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { match u { Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Normal => hir::Unsafety::Normal, } } -pub fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { +fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { match c { Constness::Const => hir::Constness::Const, Constness::NotConst => hir::Constness::NotConst, } } -pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { +fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { match u { UnOp::Deref => hir::UnDeref, UnOp::Not => hir::UnNot, @@ -840,7 +840,7 @@ pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { } } -pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { +fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { Spanned { node: match b.node { BinOpKind::Add => hir::BiAdd, @@ -866,7 +866,7 @@ pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { } } -pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { +fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { P(hir::Pat { id: p.id, node: match p.node { @@ -931,7 +931,7 @@ pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { }) } -pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { +fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { P(hir::Expr { id: e.id, node: match e.node { @@ -1612,7 +1612,7 @@ pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { }) } -pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { +fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { match s.node { StmtKind::Decl(ref d, id) => { Spanned { @@ -1636,14 +1636,14 @@ pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { } } -pub fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { +fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { match c { CaptureBy::Value => hir::CaptureByValue, CaptureBy::Ref => hir::CaptureByRef, } } -pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { +fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { match *v { Visibility::Public => hir::Public, Visibility::Crate(_) => hir::Visibility::Crate, @@ -1653,44 +1653,44 @@ pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visi } } -pub fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { +fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { match d { Defaultness::Default => hir::Defaultness::Default, Defaultness::Final => hir::Defaultness::Final, } } -pub fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { +fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { match *b { BlockCheckMode::Default => hir::DefaultBlock, BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), } } -pub fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { +fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { match *b { BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), } } -pub fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { +fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { match u { CompilerGenerated => hir::CompilerGenerated, UserProvided => hir::UserProvided, } } -pub fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { +fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { match i { ImplPolarity::Positive => hir::ImplPolarity::Positive, ImplPolarity::Negative => hir::ImplPolarity::Negative, } } -pub fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, - f: TraitBoundModifier) - -> hir::TraitBoundModifier { +fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, + f: TraitBoundModifier) + -> hir::TraitBoundModifier { match f { TraitBoundModifier::None => hir::TraitBoundModifier::None, TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, From 0a380897a8273d6310604297cf97d8cf28eec798 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 10 May 2016 14:53:48 +1000 Subject: [PATCH 05/42] Copy more libraries from local Rust to stage0 When bootstrapping Rust using a previously built toolchain, I noticed a number of libraries were not copied in. As a result the copied in rustc fails to execute because it can't find all its dependences. Add them into the local_stage0.sh script. --- src/etc/local_stage0.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/etc/local_stage0.sh b/src/etc/local_stage0.sh index aee69a5c8bc58..fb455441910b8 100755 --- a/src/etc/local_stage0.sh +++ b/src/etc/local_stage0.sh @@ -55,6 +55,14 @@ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}extra*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_D cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}rust*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}std*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}syntax*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}flate*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}fmt_macros*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}getopts*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}graphviz*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}log*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}rbml*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}serialize*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}term*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ # do not fail if one of the above fails, as all we need is a working rustc! exit 0 From 946efcd4cae78640222d855c6c8aafafc0f844ef Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 01:11:59 +0000 Subject: [PATCH 06/42] Refactor the `hir::lowering::lower_*` functions into methods of `LoweringContext` --- src/librustc/hir/lowering.rs | 2759 ++++++++++++++-------------- src/librustc_driver/driver.rs | 6 +- src/librustc_metadata/astencode.rs | 12 +- src/librustdoc/test.rs | 5 +- 4 files changed, 1383 insertions(+), 1399 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 40f6fddf10970..0f65c5c64e491 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -114,6 +114,35 @@ impl<'a> LoweringContext<'a> { } } + pub fn lower_crate(&mut self, c: &Crate) -> hir::Crate { + struct ItemLowerer<'lcx, 'interner: 'lcx> { + items: BTreeMap, + lctx: &'lcx mut LoweringContext<'interner>, + } + + impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { + fn visit_item(&mut self, item: &'lcx Item) { + self.items.insert(item.id, self.lctx.lower_item(item)); + visit::walk_item(self, item); + } + } + + let items = { + let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self }; + visit::walk_crate(&mut item_lowerer, c); + item_lowerer.items + }; + + hir::Crate { + module: self.lower_mod(&c.module), + attrs: self.lower_attrs(&c.attrs), + config: c.config.clone().into(), + span: c.span, + exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), + items: items, + } + } + fn next_id(&self) -> NodeId { self.id_assigner.next_node_id() } @@ -136,1564 +165,1520 @@ impl<'a> LoweringContext<'a> { self.parent_def = old_def; result } -} -fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { - hir::Ident { - name: mtwt::resolve(ident), - unhygienic_name: ident.name, + fn lower_ident(&mut self, ident: Ident) -> hir::Ident { + hir::Ident { + name: mtwt::resolve(ident), + unhygienic_name: ident.name, + } } -} -fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { - attrs.clone().into() -} - -fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { - P(Spanned { - node: match view_path.node { - ViewPathSimple(ident, ref path) => { - hir::ViewPathSimple(ident.name, lower_path(lctx, path)) - } - ViewPathGlob(ref path) => { - hir::ViewPathGlob(lower_path(lctx, path)) - } - ViewPathList(ref path, ref path_list_idents) => { - hir::ViewPathList(lower_path(lctx, path), - path_list_idents.iter() - .map(lower_path_list_item) - .collect()) - } - }, - span: view_path.span, - }) -} + fn lower_attrs(&mut self, attrs: &Vec) -> hir::HirVec { + attrs.clone().into() + } -fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { - Spanned { - node: match path_list_ident.node { - PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { - id: id, - name: name.name, - rename: rename.map(|x| x.name), - }, - PathListItemKind::Mod { id, rename } => hir::PathListMod { - id: id, - rename: rename.map(|x| x.name), + fn lower_view_path(&mut self, view_path: &ViewPath) -> P { + P(Spanned { + node: match view_path.node { + ViewPathSimple(ident, ref path) => { + hir::ViewPathSimple(ident.name, self.lower_path(path)) + } + ViewPathGlob(ref path) => { + hir::ViewPathGlob(self.lower_path(path)) + } + ViewPathList(ref path, ref path_list_idents) => { + hir::ViewPathList(self.lower_path(path), + path_list_idents.iter() + .map(|item| self.lower_path_list_item(item)) + .collect()) + } }, - }, - span: path_list_ident.span, + span: view_path.span, + }) } -} -fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { - hir::Arm { - attrs: lower_attrs(lctx, &arm.attrs), - pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), - guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)), - body: lower_expr(lctx, &arm.body), + fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem { + Spanned { + node: match path_list_ident.node { + PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { + id: id, + name: name.name, + rename: rename.map(|x| x.name), + }, + PathListItemKind::Mod { id, rename } => hir::PathListMod { + id: id, + rename: rename.map(|x| x.name), + }, + }, + span: path_list_ident.span, + } } -} -fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { - match d.node { - DeclKind::Local(ref l) => P(Spanned { - node: hir::DeclLocal(lower_local(lctx, l)), - span: d.span, - }), - DeclKind::Item(ref it) => P(Spanned { - node: hir::DeclItem(lower_item_id(lctx, it)), - span: d.span, - }), + fn lower_arm(&mut self, arm: &Arm) -> hir::Arm { + 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), + } } -} -fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { - hir::TypeBinding { - id: b.id, - name: b.ident.name, - ty: lower_ty(lctx, &b.ty), - span: b.span, + fn lower_decl(&mut self, d: &Decl) -> P { + match d.node { + DeclKind::Local(ref l) => P(Spanned { + node: hir::DeclLocal(self.lower_local(l)), + span: d.span, + }), + DeclKind::Item(ref it) => P(Spanned { + node: hir::DeclItem(self.lower_item_id(it)), + span: d.span, + }), + } } -} - -fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { - use syntax::ast::TyKind::*; - P(hir::Ty { - id: t.id, - node: match t.node { - Infer => hir::TyInfer, - Vec(ref ty) => hir::TyVec(lower_ty(lctx, ty)), - Ptr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)), - Rptr(ref region, ref mt) => { - hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt)) - } - BareFn(ref f) => { - hir::TyBareFn(P(hir::BareFnTy { - lifetimes: lower_lifetime_defs(lctx, &f.lifetimes), - unsafety: lower_unsafety(lctx, f.unsafety), - abi: f.abi, - decl: lower_fn_decl(lctx, &f.decl), - })) - } - Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()), - Paren(ref ty) => { - return lower_ty(lctx, ty); - } - Path(ref qself, ref path) => { - let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, - } - }); - hir::TyPath(qself, lower_path(lctx, path)) - } - ObjectSum(ref ty, ref bounds) => { - hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds)) - } - FixedLengthVec(ref ty, ref e) => { - hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e)) - } - Typeof(ref expr) => { - hir::TyTypeof(lower_expr(lctx, expr)) - } - PolyTraitRef(ref bounds) => { - hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect()) - } - Mac(_) => panic!("TyMac should have been expanded by now."), - }, - span: t.span, - }) -} -fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { - hir::ForeignMod { - abi: fm.abi, - items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), + fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding { + hir::TypeBinding { + id: b.id, + name: b.ident.name, + ty: self.lower_ty(&b.ty), + span: b.span, + } } -} -fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { - Spanned { - node: hir::Variant_ { - name: v.node.name.name, - attrs: lower_attrs(lctx, &v.node.attrs), - data: lower_variant_data(lctx, &v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)), - }, - span: v.span, + fn lower_ty(&mut self, t: &Ty) -> P { + use syntax::ast::TyKind::*; + P(hir::Ty { + id: t.id, + node: match t.node { + Infer => hir::TyInfer, + Vec(ref ty) => hir::TyVec(self.lower_ty(ty)), + Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)), + Rptr(ref region, ref mt) => { + hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt)) + } + BareFn(ref f) => { + hir::TyBareFn(P(hir::BareFnTy { + lifetimes: self.lower_lifetime_defs(&f.lifetimes), + unsafety: self.lower_unsafety(f.unsafety), + abi: f.abi, + decl: self.lower_fn_decl(&f.decl), + })) + } + Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()), + Paren(ref ty) => { + return self.lower_ty(ty); + } + Path(ref qself, ref path) => { + let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: self.lower_ty(ty), + position: position, + } + }); + hir::TyPath(qself, self.lower_path(path)) + } + ObjectSum(ref ty, ref bounds) => { + hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds)) + } + FixedLengthVec(ref ty, ref e) => { + hir::TyFixedLengthVec(self.lower_ty(ty), self.lower_expr(e)) + } + Typeof(ref expr) => { + hir::TyTypeof(self.lower_expr(expr)) + } + PolyTraitRef(ref bounds) => { + let bounds = bounds.iter().map(|b| self.lower_ty_param_bound(b)).collect(); + hir::TyPolyTraitRef(bounds) + } + Mac(_) => panic!("TyMac should have been expanded by now."), + }, + span: t.span, + }) } -} -// Path segments are usually unhygienic, hygienic path segments can occur only in -// identifier-like paths originating from `ExprPath`. -// Make life simpler for rustc_resolve by renaming only such segments. -fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { - let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; - hir::Path { - global: p.global, - segments: p.segments - .iter() - .map(|&PathSegment { identifier, ref parameters }| { - hir::PathSegment { - identifier: if maybe_hygienic { - lower_ident(lctx, identifier) - } else { - hir::Ident::from_name(identifier.name) - }, - parameters: lower_path_parameters(lctx, parameters), - } - }) - .collect(), - span: p.span, + fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod { + hir::ForeignMod { + abi: fm.abi, + items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(), + } } -} -fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { - lower_path_full(lctx, p, false) -} - -fn lower_path_parameters(lctx: &mut LoweringContext, - path_parameters: &PathParameters) - -> hir::PathParameters { - match *path_parameters { - PathParameters::AngleBracketed(ref data) => - hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), - PathParameters::Parenthesized(ref data) => - hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)), + fn lower_variant(&mut self, v: &Variant) -> hir::Variant { + Spanned { + node: hir::Variant_ { + 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)), + }, + span: v.span, + } } -} -fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, - data: &AngleBracketedParameterData) - -> hir::AngleBracketedParameterData { - let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; - hir::AngleBracketedParameterData { - lifetimes: lower_lifetimes(lctx, lifetimes), - types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(), - bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(), + // Path segments are usually unhygienic, hygienic path segments can occur only in + // identifier-like paths originating from `ExprPath`. + // Make life simpler for rustc_resolve by renaming only such segments. + fn lower_path_full(&mut self, p: &Path, maybe_hygienic: bool) -> hir::Path { + let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; + hir::Path { + global: p.global, + segments: p.segments + .iter() + .map(|&PathSegment { identifier, ref parameters }| { + hir::PathSegment { + identifier: if maybe_hygienic { + self.lower_ident(identifier) + } else { + hir::Ident::from_name(identifier.name) + }, + parameters: self.lower_path_parameters(parameters), + } + }) + .collect(), + span: p.span, + } } -} -fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, - data: &ParenthesizedParameterData) - -> hir::ParenthesizedParameterData { - let &ParenthesizedParameterData { ref inputs, ref output, span } = data; - hir::ParenthesizedParameterData { - inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), - output: output.as_ref().map(|ty| lower_ty(lctx, ty)), - span: span, + fn lower_path(&mut self, p: &Path) -> hir::Path { + self.lower_path_full(p, false) } -} -fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { - P(hir::Local { - id: l.id, - ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), - pat: lower_pat(lctx, &l.pat), - init: l.init.as_ref().map(|e| lower_expr(lctx, e)), - span: l.span, - attrs: l.attrs.clone(), - }) -} - -fn lower_explicit_self_underscore(lctx: &mut LoweringContext, - es: &SelfKind) - -> hir::ExplicitSelf_ { - match *es { - SelfKind::Static => hir::SelfStatic, - SelfKind::Value(v) => hir::SelfValue(v.name), - SelfKind::Region(ref lifetime, m, ident) => { - hir::SelfRegion(lower_opt_lifetime(lctx, lifetime), - lower_mutability(lctx, m), - ident.name) - } - SelfKind::Explicit(ref typ, ident) => { - hir::SelfExplicit(lower_ty(lctx, typ), ident.name) + fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters { + match *path_parameters { + PathParameters::AngleBracketed(ref data) => + hir::AngleBracketedParameters(self.lower_angle_bracketed_parameter_data(data)), + PathParameters::Parenthesized(ref data) => + hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)), } } -} -fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { - match m { - Mutability::Mutable => hir::MutMutable, - Mutability::Immutable => hir::MutImmutable, + fn lower_angle_bracketed_parameter_data(&mut self, + data: &AngleBracketedParameterData) + -> hir::AngleBracketedParameterData { + let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; + hir::AngleBracketedParameterData { + lifetimes: self.lower_lifetimes(lifetimes), + types: types.iter().map(|ty| self.lower_ty(ty)).collect(), + bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(), + } } -} -fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { - Spanned { - node: lower_explicit_self_underscore(lctx, &s.node), - span: s.span, + fn lower_parenthesized_parameter_data(&mut self, + data: &ParenthesizedParameterData) + -> hir::ParenthesizedParameterData { + let &ParenthesizedParameterData { ref inputs, ref output, span } = data; + hir::ParenthesizedParameterData { + inputs: inputs.iter().map(|ty| self.lower_ty(ty)).collect(), + output: output.as_ref().map(|ty| self.lower_ty(ty)), + span: span, + } } -} -fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { - hir::Arg { - id: arg.id, - pat: lower_pat(lctx, &arg.pat), - ty: lower_ty(lctx, &arg.ty), + fn lower_local(&mut self, l: &Local) -> P { + P(hir::Local { + 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)), + span: l.span, + attrs: l.attrs.clone(), + }) } -} - -fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { - P(hir::FnDecl { - inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), - output: match decl.output { - FunctionRetTy::Ty(ref ty) => hir::Return(lower_ty(lctx, ty)), - FunctionRetTy::Default(span) => hir::DefaultReturn(span), - FunctionRetTy::None(span) => hir::NoReturn(span), - }, - variadic: decl.variadic, - }) -} -fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { - match *tpb { - TraitTyParamBound(ref ty, modifier) => { - hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), - lower_trait_bound_modifier(lctx, modifier)) - } - RegionTyParamBound(ref lifetime) => { - hir::RegionTyParamBound(lower_lifetime(lctx, lifetime)) + fn lower_explicit_self_underscore(&mut self, es: &SelfKind) -> hir::ExplicitSelf_ { + match *es { + SelfKind::Static => hir::SelfStatic, + SelfKind::Value(v) => hir::SelfValue(v.name), + SelfKind::Region(ref lifetime, m, ident) => { + hir::SelfRegion(self.lower_opt_lifetime(lifetime), + self.lower_mutability(m), + ident.name) + } + SelfKind::Explicit(ref typ, ident) => { + hir::SelfExplicit(self.lower_ty(typ), ident.name) + } } } -} -fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { - hir::TyParam { - id: tp.id, - name: tp.ident.name, - bounds: lower_bounds(lctx, &tp.bounds), - default: tp.default.as_ref().map(|x| lower_ty(lctx, x)), - span: tp.span, + fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability { + match m { + Mutability::Mutable => hir::MutMutable, + Mutability::Immutable => hir::MutImmutable, + } } -} - -fn lower_ty_params(lctx: &mut LoweringContext, - tps: &P<[TyParam]>) - -> hir::HirVec { - tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() -} -fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { - hir::Lifetime { - id: l.id, - name: l.name, - span: l.span, + fn lower_explicit_self(&mut self, s: &ExplicitSelf) -> hir::ExplicitSelf { + Spanned { + node: self.lower_explicit_self_underscore(&s.node), + span: s.span, + } } -} -fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { - hir::LifetimeDef { - lifetime: lower_lifetime(lctx, &l.lifetime), - bounds: lower_lifetimes(lctx, &l.bounds), + fn lower_arg(&mut self, arg: &Arg) -> hir::Arg { + hir::Arg { + id: arg.id, + pat: self.lower_pat(&arg.pat), + ty: self.lower_ty(&arg.ty), + } } -} - -fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) - -> hir::HirVec { - lts.iter().map(|l| lower_lifetime(lctx, l)).collect() -} -fn lower_lifetime_defs(lctx: &mut LoweringContext, - lts: &Vec) - -> hir::HirVec { - lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() -} + fn lower_fn_decl(&mut self, decl: &FnDecl) -> P { + P(hir::FnDecl { + inputs: decl.inputs.iter().map(|x| self.lower_arg(x)).collect(), + output: match decl.output { + FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)), + FunctionRetTy::Default(span) => hir::DefaultReturn(span), + FunctionRetTy::None(span) => hir::NoReturn(span), + }, + variadic: decl.variadic, + }) + } -fn lower_opt_lifetime(lctx: &mut LoweringContext, - o_lt: &Option) - -> Option { - o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) -} + fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound { + match *tpb { + TraitTyParamBound(ref ty, modifier) => { + hir::TraitTyParamBound(self.lower_poly_trait_ref(ty), + self.lower_trait_bound_modifier(modifier)) + } + RegionTyParamBound(ref lifetime) => { + hir::RegionTyParamBound(self.lower_lifetime(lifetime)) + } + } + } -fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { - hir::Generics { - ty_params: lower_ty_params(lctx, &g.ty_params), - lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), - where_clause: lower_where_clause(lctx, &g.where_clause), + fn lower_ty_param(&mut self, tp: &TyParam) -> hir::TyParam { + hir::TyParam { + id: tp.id, + name: tp.ident.name, + bounds: self.lower_bounds(&tp.bounds), + default: tp.default.as_ref().map(|x| self.lower_ty(x)), + span: tp.span, + } } -} -fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { - hir::WhereClause { - id: wc.id, - predicates: wc.predicates - .iter() - .map(|predicate| lower_where_predicate(lctx, predicate)) - .collect(), + fn lower_ty_params(&mut self, tps: &P<[TyParam]>) -> hir::HirVec { + tps.iter().map(|tp| self.lower_ty_param(tp)).collect() } -} -fn lower_where_predicate(lctx: &mut LoweringContext, - pred: &WherePredicate) - -> hir::WherePredicate { - match *pred { - WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, - ref bounded_ty, - ref bounds, - span}) => { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes), - bounded_ty: lower_ty(lctx, bounded_ty), - bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(), - span: span, - }) - } - WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, - ref bounds, - span}) => { - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: span, - lifetime: lower_lifetime(lctx, lifetime), - bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(), - }) - } - WherePredicate::EqPredicate(WhereEqPredicate{ id, - ref path, - ref ty, - span}) => { - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - id: id, - path: lower_path(lctx, path), - ty: lower_ty(lctx, ty), - span: span, - }) + fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { + hir::Lifetime { + id: l.id, + name: l.name, + span: l.span, } } -} -fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { - match *vdata { - VariantData::Struct(ref fields, id) => { - hir::VariantData::Struct(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) + fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef { + hir::LifetimeDef { + lifetime: self.lower_lifetime(&l.lifetime), + bounds: self.lower_lifetimes(&l.bounds), } - VariantData::Tuple(ref fields, id) => { - hir::VariantData::Tuple(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) - } - VariantData::Unit(id) => hir::VariantData::Unit(id), } -} -fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { - hir::TraitRef { - path: lower_path(lctx, &p.path), - ref_id: p.ref_id, + fn lower_lifetimes(&mut self, lts: &Vec) -> hir::HirVec { + lts.iter().map(|l| self.lower_lifetime(l)).collect() } -} -fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { - hir::PolyTraitRef { - bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), - trait_ref: lower_trait_ref(lctx, &p.trait_ref), - span: p.span, + fn lower_lifetime_defs(&mut self, lts: &Vec) -> hir::HirVec { + lts.iter().map(|l| self.lower_lifetime_def(l)).collect() } -} -fn lower_struct_field(lctx: &mut LoweringContext, - (index, f): (usize, &StructField)) - -> hir::StructField { - hir::StructField { - span: f.span, - id: f.id, - name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), - vis: lower_visibility(lctx, &f.vis), - ty: lower_ty(lctx, &f.ty), - attrs: lower_attrs(lctx, &f.attrs), + fn lower_opt_lifetime(&mut self, o_lt: &Option) -> Option { + o_lt.as_ref().map(|lt| self.lower_lifetime(lt)) } -} -fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { - hir::Field { - name: respan(f.ident.span, f.ident.node.name), - expr: lower_expr(lctx, &f.expr), - span: f.span, + fn lower_generics(&mut self, g: &Generics) -> hir::Generics { + hir::Generics { + ty_params: self.lower_ty_params(&g.ty_params), + lifetimes: self.lower_lifetime_defs(&g.lifetimes), + where_clause: self.lower_where_clause(&g.where_clause), + } } -} -fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { - hir::MutTy { - ty: lower_ty(lctx, &mt.ty), - mutbl: lower_mutability(lctx, mt.mutbl), + fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause { + hir::WhereClause { + id: wc.id, + predicates: wc.predicates + .iter() + .map(|predicate| self.lower_where_predicate(predicate)) + .collect(), + } } -} - -fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { - bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() -} - -fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { - P(hir::Block { - id: b.id, - stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), - expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)), - rules: lower_block_check_mode(lctx, &b.rules), - span: b.span, - }) -} -fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { - match *i { - ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), - ItemKind::Use(ref view_path) => { - hir::ItemUse(lower_view_path(lctx, view_path)) - } - ItemKind::Static(ref t, m, ref e) => { - hir::ItemStatic(lower_ty(lctx, t), - lower_mutability(lctx, m), - lower_expr(lctx, e)) - } - ItemKind::Const(ref t, ref e) => { - hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e)) - } - ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { - hir::ItemFn(lower_fn_decl(lctx, decl), - lower_unsafety(lctx, unsafety), - lower_constness(lctx, constness), - abi, - lower_generics(lctx, generics), - lower_block(lctx, body)) - } - ItemKind::Mod(ref m) => hir::ItemMod(lower_mod(lctx, m)), - ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)), - ItemKind::Ty(ref t, ref generics) => { - hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics)) - } - ItemKind::Enum(ref enum_definition, ref generics) => { - hir::ItemEnum(hir::EnumDef { - variants: enum_definition.variants - .iter() - .map(|x| lower_variant(lctx, x)) - .collect(), - }, - lower_generics(lctx, generics)) - } - ItemKind::Struct(ref struct_def, ref generics) => { - let struct_def = lower_variant_data(lctx, struct_def); - hir::ItemStruct(struct_def, lower_generics(lctx, generics)) + fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate { + match *pred { + WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, + ref bounded_ty, + ref bounds, + span}) => { + hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes), + bounded_ty: self.lower_ty(bounded_ty), + bounds: bounds.iter().map(|x| self.lower_ty_param_bound(x)).collect(), + span: span, + }) + } + WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, + ref bounds, + span}) => { + hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + span: span, + lifetime: self.lower_lifetime(lifetime), + bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(), + }) + } + WherePredicate::EqPredicate(WhereEqPredicate{ id, + ref path, + ref ty, + span}) => { + hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + id: id, + path: self.lower_path(path), + ty: self.lower_ty(ty), + span: span, + }) + } } - ItemKind::DefaultImpl(unsafety, ref trait_ref) => { - hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety), - lower_trait_ref(lctx, trait_ref)) + } + + fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData { + match *vdata { + VariantData::Struct(ref fields, id) => { + hir::VariantData::Struct(fields.iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + id) + } + VariantData::Tuple(ref fields, id) => { + hir::VariantData::Tuple(fields.iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + id) + } + VariantData::Unit(id) => hir::VariantData::Unit(id), } - ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { - let new_impl_items = impl_items.iter() - .map(|item| lower_impl_item(lctx, item)) - .collect(); - let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref)); - hir::ItemImpl(lower_unsafety(lctx, unsafety), - lower_impl_polarity(lctx, polarity), - lower_generics(lctx, generics), - ifce, - lower_ty(lctx, ty), - new_impl_items) + } + + fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef { + hir::TraitRef { + path: self.lower_path(&p.path), + ref_id: p.ref_id, } - ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { - let bounds = lower_bounds(lctx, bounds); - let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect(); - hir::ItemTrait(lower_unsafety(lctx, unsafety), - lower_generics(lctx, generics), - bounds, - items) + } + + fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef { + hir::PolyTraitRef { + bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes), + trait_ref: self.lower_trait_ref(&p.trait_ref), + span: p.span, } - ItemKind::Mac(_) => panic!("Shouldn't still be around"), } -} -fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { - lctx.with_parent_def(i.id, |lctx| { - hir::TraitItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(lctx, ty), - default.as_ref().map(|x| lower_expr(lctx, x))) - } - TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(lctx, sig), - body.as_ref().map(|x| lower_block(lctx, x))) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(lctx, bounds), - default.as_ref().map(|x| lower_ty(lctx, x))) - } - }, - span: i.span, + fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField { + hir::StructField { + span: f.span, + id: f.id, + name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), + vis: self.lower_visibility(&f.vis), + ty: self.lower_ty(&f.ty), + attrs: self.lower_attrs(&f.attrs), } - }) -} + } -fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { - lctx.with_parent_def(i.id, |lctx| { - hir::ImplItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - vis: lower_visibility(lctx, &i.vis), - defaultness: lower_defaultness(lctx, i.defaultness), - node: match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) - } - ImplItemKind::Method(ref sig, ref body) => { - hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) - } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, - span: i.span, + 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), + span: f.span, } - }) -} + } -fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { - hir::Mod { - inner: m.inner, - item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), + fn lower_mt(&mut self, mt: &MutTy) -> hir::MutTy { + hir::MutTy { + ty: self.lower_ty(&mt.ty), + mutbl: self.lower_mutability(mt.mutbl), + } } -} -struct ItemLowerer<'lcx, 'interner: 'lcx> { - items: BTreeMap, - lctx: &'lcx mut LoweringContext<'interner>, -} + fn lower_bounds(&mut self, bounds: &TyParamBounds) -> hir::TyParamBounds { + bounds.iter().map(|bound| self.lower_ty_param_bound(bound)).collect() + } -impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { - fn visit_item(&mut self, item: &'lcx Item) { - self.items.insert(item.id, lower_item(self.lctx, item)); - visit::walk_item(self, item); + fn lower_block(&mut self, b: &Block) -> P { + P(hir::Block { + id: b.id, + stmts: b.stmts.iter().map(|s| self.lower_stmt(s)).collect(), + expr: b.expr.as_ref().map(|ref x| self.lower_expr(x)), + rules: self.lower_block_check_mode(&b.rules), + span: b.span, + }) } -} -pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { - let items = { - let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; - visit::walk_crate(&mut item_lowerer, c); - item_lowerer.items - }; + fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ { + match *i { + ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), + ItemKind::Use(ref view_path) => { + hir::ItemUse(self.lower_view_path(view_path)) + } + ItemKind::Static(ref t, m, ref e) => { + hir::ItemStatic(self.lower_ty(t), + self.lower_mutability(m), + self.lower_expr(e)) + } + ItemKind::Const(ref t, ref e) => { + hir::ItemConst(self.lower_ty(t), self.lower_expr(e)) + } + ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { + hir::ItemFn(self.lower_fn_decl(decl), + self.lower_unsafety(unsafety), + self.lower_constness(constness), + abi, + self.lower_generics(generics), + self.lower_block(body)) + } + ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)), + ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)), + ItemKind::Ty(ref t, ref generics) => { + hir::ItemTy(self.lower_ty(t), self.lower_generics(generics)) + } + ItemKind::Enum(ref enum_definition, ref generics) => { + hir::ItemEnum(hir::EnumDef { + variants: enum_definition.variants + .iter() + .map(|x| self.lower_variant(x)) + .collect(), + }, + self.lower_generics(generics)) + } + ItemKind::Struct(ref struct_def, ref generics) => { + let struct_def = self.lower_variant_data(struct_def); + hir::ItemStruct(struct_def, self.lower_generics(generics)) + } + ItemKind::DefaultImpl(unsafety, ref trait_ref) => { + hir::ItemDefaultImpl(self.lower_unsafety(unsafety), + self.lower_trait_ref(trait_ref)) + } + ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { + let new_impl_items = impl_items.iter() + .map(|item| self.lower_impl_item(item)) + .collect(); + let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref)); + hir::ItemImpl(self.lower_unsafety(unsafety), + self.lower_impl_polarity(polarity), + self.lower_generics(generics), + ifce, + self.lower_ty(ty), + new_impl_items) + } + ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { + let bounds = self.lower_bounds(bounds); + let items = items.iter().map(|item| self.lower_trait_item(item)).collect(); + hir::ItemTrait(self.lower_unsafety(unsafety), + self.lower_generics(generics), + bounds, + items) + } + ItemKind::Mac(_) => panic!("Shouldn't still be around"), + } + } - hir::Crate { - module: lower_mod(lctx, &c.module), - attrs: lower_attrs(lctx, &c.attrs), - config: c.config.clone().into(), - span: c.span, - exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(), - items: items, + fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { + self.with_parent_def(i.id, |this| { + hir::TraitItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + 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))) + } + TraitItemKind::Method(ref sig, ref body) => { + hir::MethodTraitItem(this.lower_method_sig(sig), + body.as_ref().map(|x| this.lower_block(x))) + } + TraitItemKind::Type(ref bounds, ref default) => { + hir::TypeTraitItem(this.lower_bounds(bounds), + default.as_ref().map(|x| this.lower_ty(x))) + } + }, + span: i.span, + } + }) } -} -fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { - hir::MacroDef { - name: m.ident.name, - attrs: lower_attrs(lctx, &m.attrs), - id: m.id, - span: m.span, - imported_from: m.imported_from.map(|x| x.name), - export: m.export, - use_locally: m.use_locally, - allow_internal_unstable: m.allow_internal_unstable, - body: m.body.clone().into(), + fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem { + self.with_parent_def(i.id, |this| { + hir::ImplItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + vis: this.lower_visibility(&i.vis), + defaultness: this.lower_defaultness(i.defaultness), + node: match i.node { + ImplItemKind::Const(ref ty, ref expr) => { + hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr)) + } + ImplItemKind::Method(ref sig, ref body) => { + hir::ImplItemKind::Method(this.lower_method_sig(sig), + this.lower_block(body)) + } + ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)), + ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }, + span: i.span, + } + }) } -} -fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { - hir::ItemId { id: i.id } -} + fn lower_mod(&mut self, m: &Mod) -> hir::Mod { + hir::Mod { + inner: m.inner, + item_ids: m.items.iter().map(|x| self.lower_item_id(x)).collect(), + } + } -pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { - let node = lctx.with_parent_def(i.id, |lctx| { - lower_item_kind(lctx, &i.node) - }); + fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef { + hir::MacroDef { + name: m.ident.name, + attrs: self.lower_attrs(&m.attrs), + id: m.id, + span: m.span, + imported_from: m.imported_from.map(|x| x.name), + export: m.export, + use_locally: m.use_locally, + allow_internal_unstable: m.allow_internal_unstable, + body: m.body.clone().into(), + } + } - hir::Item { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: node, - vis: lower_visibility(lctx, &i.vis), - span: i.span, + fn lower_item_id(&mut self, i: &Item) -> hir::ItemId { + hir::ItemId { id: i.id } } -} -fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - lctx.with_parent_def(i.id, |lctx| { - hir::ForeignItem { + pub fn lower_item(&mut self, i: &Item) -> hir::Item { + let node = self.with_parent_def(i.id, |this| { + this.lower_item_kind(&i.node) + }); + + hir::Item { id: i.id, name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - ForeignItemKind::Fn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) - } - ForeignItemKind::Static(ref t, m) => { - hir::ForeignItemStatic(lower_ty(lctx, t), m) - } - }, - vis: lower_visibility(lctx, &i.vis), + attrs: self.lower_attrs(&i.attrs), + node: node, + vis: self.lower_visibility(&i.vis), span: i.span, } - }) -} + } -fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { - hir::MethodSig { - generics: lower_generics(lctx, &sig.generics), - abi: sig.abi, - explicit_self: lower_explicit_self(lctx, &sig.explicit_self), - unsafety: lower_unsafety(lctx, sig.unsafety), - constness: lower_constness(lctx, sig.constness), - decl: lower_fn_decl(lctx, &sig.decl), + fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem { + self.with_parent_def(i.id, |this| { + hir::ForeignItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + node: match i.node { + ForeignItemKind::Fn(ref fdec, ref generics) => { + hir::ForeignItemFn(this.lower_fn_decl(fdec), this.lower_generics(generics)) + } + ForeignItemKind::Static(ref t, m) => { + hir::ForeignItemStatic(this.lower_ty(t), m) + } + }, + vis: this.lower_visibility(&i.vis), + span: i.span, + } + }) } -} -fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { - match u { - Unsafety::Unsafe => hir::Unsafety::Unsafe, - Unsafety::Normal => hir::Unsafety::Normal, + fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig { + hir::MethodSig { + generics: self.lower_generics(&sig.generics), + abi: sig.abi, + explicit_self: self.lower_explicit_self(&sig.explicit_self), + unsafety: self.lower_unsafety(sig.unsafety), + constness: self.lower_constness(sig.constness), + decl: self.lower_fn_decl(&sig.decl), + } } -} -fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { - match c { - Constness::Const => hir::Constness::Const, - Constness::NotConst => hir::Constness::NotConst, + fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety { + match u { + Unsafety::Unsafe => hir::Unsafety::Unsafe, + Unsafety::Normal => hir::Unsafety::Normal, + } } -} -fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { - match u { - UnOp::Deref => hir::UnDeref, - UnOp::Not => hir::UnNot, - UnOp::Neg => hir::UnNeg, + fn lower_constness(&mut self, c: Constness) -> hir::Constness { + match c { + Constness::Const => hir::Constness::Const, + Constness::NotConst => hir::Constness::NotConst, + } } -} -fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { - Spanned { - node: match b.node { - BinOpKind::Add => hir::BiAdd, - BinOpKind::Sub => hir::BiSub, - BinOpKind::Mul => hir::BiMul, - BinOpKind::Div => hir::BiDiv, - BinOpKind::Rem => hir::BiRem, - BinOpKind::And => hir::BiAnd, - BinOpKind::Or => hir::BiOr, - BinOpKind::BitXor => hir::BiBitXor, - BinOpKind::BitAnd => hir::BiBitAnd, - BinOpKind::BitOr => hir::BiBitOr, - BinOpKind::Shl => hir::BiShl, - BinOpKind::Shr => hir::BiShr, - BinOpKind::Eq => hir::BiEq, - BinOpKind::Lt => hir::BiLt, - BinOpKind::Le => hir::BiLe, - BinOpKind::Ne => hir::BiNe, - BinOpKind::Ge => hir::BiGe, - BinOpKind::Gt => hir::BiGt, - }, - span: b.span, + fn lower_unop(&mut self, u: UnOp) -> hir::UnOp { + match u { + UnOp::Deref => hir::UnDeref, + UnOp::Not => hir::UnNot, + UnOp::Neg => hir::UnNeg, + } } -} -fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { - P(hir::Pat { - id: p.id, - node: match p.node { - PatKind::Wild => hir::PatKind::Wild, - PatKind::Ident(ref binding_mode, pth1, ref sub) => { - lctx.with_parent_def(p.id, |lctx| { - hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), - respan(pth1.span, lower_ident(lctx, pth1.node)), - sub.as_ref().map(|x| lower_pat(lctx, x))) - }) - } - PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), - PatKind::TupleStruct(ref pth, ref pats) => { - hir::PatKind::TupleStruct(lower_path(lctx, pth), - pats.as_ref() - .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) - } - PatKind::Path(ref pth) => { - hir::PatKind::Path(lower_path(lctx, pth)) - } - PatKind::QPath(ref qself, ref pth) => { - let qself = hir::QSelf { - ty: lower_ty(lctx, &qself.ty), - position: qself.position, - }; - hir::PatKind::QPath(qself, lower_path(lctx, pth)) - } - PatKind::Struct(ref pth, ref fields, etc) => { - let pth = lower_path(lctx, pth); - let fs = fields.iter() - .map(|f| { - Spanned { - span: f.span, - node: hir::FieldPat { - name: f.node.ident.name, - pat: lower_pat(lctx, &f.node.pat), - is_shorthand: f.node.is_shorthand, - }, - } - }) - .collect(); - hir::PatKind::Struct(pth, fs, etc) - } - PatKind::Tup(ref elts) => { - hir::PatKind::Tup(elts.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Box(ref inner) => hir::PatKind::Box(lower_pat(lctx, inner)), - PatKind::Ref(ref inner, mutbl) => { - hir::PatKind::Ref(lower_pat(lctx, inner), lower_mutability(lctx, mutbl)) - } - PatKind::Range(ref e1, ref e2) => { - hir::PatKind::Range(lower_expr(lctx, e1), lower_expr(lctx, e2)) - } - PatKind::Vec(ref before, ref slice, ref after) => { - hir::PatKind::Vec(before.iter().map(|x| lower_pat(lctx, x)).collect(), - slice.as_ref().map(|x| lower_pat(lctx, x)), - after.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: p.span, - }) -} + fn lower_binop(&mut self, b: BinOp) -> hir::BinOp { + Spanned { + node: match b.node { + BinOpKind::Add => hir::BiAdd, + BinOpKind::Sub => hir::BiSub, + BinOpKind::Mul => hir::BiMul, + BinOpKind::Div => hir::BiDiv, + BinOpKind::Rem => hir::BiRem, + BinOpKind::And => hir::BiAnd, + BinOpKind::Or => hir::BiOr, + BinOpKind::BitXor => hir::BiBitXor, + BinOpKind::BitAnd => hir::BiBitAnd, + BinOpKind::BitOr => hir::BiBitOr, + BinOpKind::Shl => hir::BiShl, + BinOpKind::Shr => hir::BiShr, + BinOpKind::Eq => hir::BiEq, + BinOpKind::Lt => hir::BiLt, + BinOpKind::Le => hir::BiLe, + BinOpKind::Ne => hir::BiNe, + BinOpKind::Ge => hir::BiGe, + BinOpKind::Gt => hir::BiGt, + }, + span: b.span, + } + } -fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { - P(hir::Expr { - id: e.id, - node: match e.node { - // Issue #22181: - // Eventually a desugaring for `box EXPR` - // (similar to the desugaring above for `in PLACE BLOCK`) - // should go here, desugaring - // - // to: - // - // let mut place = BoxPlace::make_place(); - // let raw_place = Place::pointer(&mut place); - // let value = $value; - // unsafe { - // ::std::ptr::write(raw_place, value); - // Boxed::finalize(place) - // } - // - // But for now there are type-inference issues doing that. - ExprKind::Box(ref e) => { - hir::ExprBox(lower_expr(lctx, e)) - } + fn lower_pat(&mut self, p: &Pat) -> P { + P(hir::Pat { + id: p.id, + node: match p.node { + PatKind::Wild => hir::PatKind::Wild, + PatKind::Ident(ref binding_mode, pth1, ref sub) => { + self.with_parent_def(p.id, |this| { + hir::PatKind::Ident(this.lower_binding_mode(binding_mode), + respan(pth1.span, this.lower_ident(pth1.node)), + sub.as_ref().map(|x| this.lower_pat(x))) + }) + } + PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)), + PatKind::TupleStruct(ref pth, ref pats) => { + hir::PatKind::TupleStruct(self.lower_path(pth), + pats.as_ref() + .map(|pats| pats.iter().map(|x| self.lower_pat(x)).collect())) + } + PatKind::Path(ref pth) => { + hir::PatKind::Path(self.lower_path(pth)) + } + PatKind::QPath(ref qself, ref pth) => { + let qself = hir::QSelf { + ty: self.lower_ty(&qself.ty), + position: qself.position, + }; + hir::PatKind::QPath(qself, self.lower_path(pth)) + } + PatKind::Struct(ref pth, ref fields, etc) => { + let pth = self.lower_path(pth); + let fs = fields.iter() + .map(|f| { + Spanned { + span: f.span, + node: hir::FieldPat { + name: f.node.ident.name, + pat: self.lower_pat(&f.node.pat), + is_shorthand: f.node.is_shorthand, + }, + } + }) + .collect(); + hir::PatKind::Struct(pth, fs, etc) + } + PatKind::Tup(ref elts) => { + hir::PatKind::Tup(elts.iter().map(|x| self.lower_pat(x)).collect()) + } + PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), + PatKind::Ref(ref inner, mutbl) => { + 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)) + } + PatKind::Vec(ref before, ref slice, ref after) => { + hir::PatKind::Vec(before.iter().map(|x| self.lower_pat(x)).collect(), + slice.as_ref().map(|x| self.lower_pat(x)), + after.iter().map(|x| self.lower_pat(x)).collect()) + } + PatKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: p.span, + }) + } - // Desugar ExprBox: `in (PLACE) EXPR` - ExprKind::InPlace(ref placer, ref value_expr) => { + fn lower_expr(&mut self, e: &Expr) -> P { + P(hir::Expr { + id: e.id, + node: match e.node { + // Issue #22181: + // Eventually a desugaring for `box EXPR` + // (similar to the desugaring above for `in PLACE BLOCK`) + // should go here, desugaring + // // to: // - // let p = PLACE; - // let mut place = Placer::make_place(p); + // let mut place = BoxPlace::make_place(); // let raw_place = Place::pointer(&mut place); - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let placer_expr = lower_expr(lctx, placer); - let value_expr = lower_expr(lctx, value_expr); - - let placer_ident = lctx.str_to_ident("placer"); - let place_ident = lctx.str_to_ident("place"); - let p_ptr_ident = lctx.str_to_ident("p_ptr"); - - let make_place = ["ops", "Placer", "make_place"]; - let place_pointer = ["ops", "Place", "pointer"]; - let move_val_init = ["intrinsics", "move_val_init"]; - let inplace_finalize = ["ops", "InPlace", "finalize"]; - - let make_call = |lctx: &mut LoweringContext, p, args| { - let path = core_path(lctx, e.span, p); - let path = expr_path(lctx, path, None); - expr_call(lctx, e.span, path, args, None) - }; - - let mk_stmt_let = |lctx: &mut LoweringContext, bind, expr| { - stmt_let(lctx, e.span, false, bind, expr, None) - }; - - let mk_stmt_let_mut = |lctx: &mut LoweringContext, bind, expr| { - stmt_let(lctx, e.span, true, bind, expr, None) - }; - - // let placer = ; - let (s1, placer_binding) = { - let placer_expr = signal_block_expr(lctx, - hir_vec![], - placer_expr, - e.span, - hir::PopUnstableBlock, - None); - mk_stmt_let(lctx, placer_ident, placer_expr) - }; - - // let mut place = Placer::make_place(placer); - let (s2, place_binding) = { - let placer = expr_ident(lctx, e.span, placer_ident, None, placer_binding); - let call = make_call(lctx, &make_place, hir_vec![placer]); - mk_stmt_let_mut(lctx, place_ident, call) - }; - - // let p_ptr = Place::pointer(&mut place); - let (s3, p_ptr_binding) = { - let agent = expr_ident(lctx, e.span, place_ident, None, place_binding); - let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)]; - let call = make_call(lctx, &place_pointer, args); - mk_stmt_let(lctx, p_ptr_ident, call) - }; - - // pop_unsafe!(EXPR)); - let pop_unsafe_expr = { - let value_expr = signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnstableBlock, - None); - signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated), None) - }; - - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let expr = { - let ptr = expr_ident(lctx, e.span, p_ptr_ident, None, p_ptr_binding); - let call_move_val_init = - hir::StmtSemi( - make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), - lctx.next_id()); - let call_move_val_init = respan(e.span, call_move_val_init); - - let place = expr_ident(lctx, e.span, place_ident, None, place_binding); - let call = make_call(lctx, &inplace_finalize, hir_vec![place]); - signal_block_expr(lctx, - hir_vec![call_move_val_init], - call, - e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated), None) - }; - - return signal_block_expr(lctx, - hir_vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock, - e.attrs.clone()); - } + // let value = $value; + // unsafe { + // ::std::ptr::write(raw_place, value); + // Boxed::finalize(place) + // } + // + // But for now there are type-inference issues doing that. + ExprKind::Box(ref e) => { + hir::ExprBox(self.lower_expr(e)) + } - ExprKind::Vec(ref exprs) => { - hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Repeat(ref expr, ref count) => { - let expr = lower_expr(lctx, expr); - let count = lower_expr(lctx, count); - hir::ExprRepeat(expr, count) - } - ExprKind::Tup(ref elts) => { - hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Call(ref f, ref args) => { - let f = lower_expr(lctx, f); - hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::MethodCall(i, ref tps, ref args) => { - let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect(); - let args = args.iter().map(|x| lower_expr(lctx, x)).collect(); - hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) - } - ExprKind::Binary(binop, ref lhs, ref rhs) => { - let binop = lower_binop(lctx, binop); - let lhs = lower_expr(lctx, lhs); - let rhs = lower_expr(lctx, rhs); - hir::ExprBinary(binop, lhs, rhs) - } - ExprKind::Unary(op, ref ohs) => { - let op = lower_unop(lctx, op); - let ohs = lower_expr(lctx, ohs); - hir::ExprUnary(op, ohs) - } - ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())), - ExprKind::Cast(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprCast(expr, lower_ty(lctx, ty)) - } - ExprKind::Type(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprType(expr, lower_ty(lctx, ty)) - } - ExprKind::AddrOf(m, ref ohs) => { - let m = lower_mutability(lctx, m); - let ohs = lower_expr(lctx, ohs); - hir::ExprAddrOf(m, ohs) - } - // More complicated than you might expect because the else branch - // might be `if let`. - ExprKind::If(ref cond, ref blk, ref else_opt) => { - let else_opt = else_opt.as_ref().map(|els| { - match els.node { - ExprKind::IfLet(..) => { - // wrap the if-let expr in a block - let span = els.span; - let els = lower_expr(lctx, els); - let id = lctx.next_id(); - let blk = P(hir::Block { - stmts: hir_vec![], - expr: Some(els), - id: id, - rules: hir::DefaultBlock, - span: span, - }); - expr_block(lctx, blk, None) - } - _ => lower_expr(lctx, els), - } - }); + // Desugar ExprBox: `in (PLACE) EXPR` + ExprKind::InPlace(ref placer, ref value_expr) => { + // to: + // + // let p = PLACE; + // let mut place = Placer::make_place(p); + // let raw_place = Place::pointer(&mut place); + // push_unsafe!({ + // 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_ident = self.str_to_ident("placer"); + let place_ident = self.str_to_ident("place"); + let p_ptr_ident = self.str_to_ident("p_ptr"); + + let make_place = ["ops", "Placer", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let move_val_init = ["intrinsics", "move_val_init"]; + let inplace_finalize = ["ops", "InPlace", "finalize"]; + + let make_call = |this: &mut LoweringContext, p, args| { + let path = core_path(this, e.span, p); + let path = expr_path(this, path, None); + expr_call(this, e.span, path, args, None) + }; - hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt) - } - ExprKind::While(ref cond, ref body, opt_ident) => { - hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Loop(ref body, opt_ident) => { - hir::ExprLoop(lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Match(ref expr, ref arms) => { - hir::ExprMatch(lower_expr(lctx, expr), - arms.iter().map(|x| lower_arm(lctx, x)).collect(), - hir::MatchSource::Normal) - } - ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { - lctx.with_parent_def(e.id, |lctx| { - hir::ExprClosure(lower_capture_clause(lctx, capture_clause), - lower_fn_decl(lctx, decl), - lower_block(lctx, body), - fn_decl_span) - }) - } - ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), - ExprKind::Assign(ref el, ref er) => { - hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::AssignOp(op, ref el, ref er) => { - hir::ExprAssignOp(lower_binop(lctx, op), - lower_expr(lctx, el), - lower_expr(lctx, er)) - } - ExprKind::Field(ref el, ident) => { - hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name)) - } - ExprKind::TupField(ref el, ident) => { - hir::ExprTupField(lower_expr(lctx, el), ident) - } - ExprKind::Index(ref el, ref er) => { - hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::Range(ref e1, ref e2, lims) => { - fn make_struct(lctx: &mut LoweringContext, - ast_expr: &Expr, - path: &[&str], - fields: &[(&str, &P)]) -> P { - let strs = std_path(lctx, &iter::once(&"ops") - .chain(path) - .map(|s| *s) - .collect::>()); - - let structpath = path_global(ast_expr.span, strs); - - let hir_expr = if fields.len() == 0 { - expr_path(lctx, - structpath, - ast_expr.attrs.clone()) - } else { - let fields = fields.into_iter().map(|&(s, e)| { - let expr = lower_expr(lctx, &e); - let signal_block = signal_block_expr(lctx, - hir_vec![], - expr, - e.span, - hir::PopUnstableBlock, - None); - field(token::intern(s), signal_block, ast_expr.span) - }).collect(); - let attrs = ast_expr.attrs.clone(); - - expr_struct(lctx, ast_expr.span, structpath, fields, None, attrs) + let mk_stmt_let = |this: &mut LoweringContext, bind, expr| { + stmt_let(this, e.span, false, bind, expr, None) }; - signal_block_expr(lctx, - hir_vec![], - hir_expr, - ast_expr.span, - hir::PushUnstableBlock, - None) - } + let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| { + stmt_let(this, e.span, true, bind, expr, None) + }; - use syntax::ast::RangeLimits::*; + // let placer = ; + let (s1, placer_binding) = { + let placer_expr = signal_block_expr(self, + hir_vec![], + placer_expr, + e.span, + hir::PopUnstableBlock, + None); + mk_stmt_let(self, placer_ident, placer_expr) + }; - return match (e1, e2, lims) { - (&None, &None, HalfOpen) => - make_struct(lctx, e, &["RangeFull"], - &[]), + // let mut place = Placer::make_place(placer); + let (s2, place_binding) = { + let placer = expr_ident(self, e.span, placer_ident, None, placer_binding); + let call = make_call(self, &make_place, hir_vec![placer]); + mk_stmt_let_mut(self, place_ident, call) + }; - (&Some(ref e1), &None, HalfOpen) => - make_struct(lctx, e, &["RangeFrom"], - &[("start", e1)]), + // let p_ptr = Place::pointer(&mut place); + let (s3, p_ptr_binding) = { + let agent = expr_ident(self, e.span, place_ident, None, place_binding); + let args = hir_vec![expr_mut_addr_of(self, e.span, agent, None)]; + let call = make_call(self, &place_pointer, args); + mk_stmt_let(self, p_ptr_ident, call) + }; - (&None, &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["RangeTo"], - &[("end", e2)]), + // pop_unsafe!(EXPR)); + let pop_unsafe_expr = { + let value_expr = signal_block_expr(self, + hir_vec![], + value_expr, + e.span, + hir::PopUnstableBlock, + None); + signal_block_expr(self, + hir_vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated), None) + }; - (&Some(ref e1), &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["Range"], - &[("start", e1), ("end", e2)]), + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + let expr = { + let ptr = expr_ident(self, e.span, p_ptr_ident, None, p_ptr_binding); + let call_move_val_init = + hir::StmtSemi( + make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), + self.next_id()); + let call_move_val_init = respan(e.span, call_move_val_init); + + let place = expr_ident(self, e.span, place_ident, None, place_binding); + let call = make_call(self, &inplace_finalize, hir_vec![place]); + signal_block_expr(self, + hir_vec![call_move_val_init], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated), None) + }; - (&None, &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeToInclusive"], - &[("end", e2)]), + return signal_block_expr(self, + hir_vec![s1, s2, s3], + expr, + e.span, + hir::PushUnstableBlock, + e.attrs.clone()); + } - (&Some(ref e1), &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], - &[("start", e1), ("end", e2)]), + ExprKind::Vec(ref exprs) => { + hir::ExprVec(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); + 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); + hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect()) + } + ExprKind::MethodCall(i, ref tps, ref args) => { + let tps = tps.iter().map(|x| self.lower_ty(x)).collect(); + let args = args.iter().map(|x| self.lower_expr(x)).collect(); + hir::ExprMethodCall(respan(i.span, i.node.name), tps, 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); + hir::ExprBinary(binop, lhs, rhs) + } + ExprKind::Unary(op, ref ohs) => { + let op = self.lower_unop(op); + let ohs = 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); + hir::ExprCast(expr, self.lower_ty(ty)) + } + ExprKind::Type(ref expr, ref ty) => { + let expr = 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); + hir::ExprAddrOf(m, ohs) + } + // More complicated than you might expect because the else branch + // might be `if let`. + ExprKind::If(ref cond, ref blk, ref else_opt) => { + let else_opt = else_opt.as_ref().map(|els| { + match els.node { + ExprKind::IfLet(..) => { + // wrap the if-let expr in a block + let span = els.span; + let els = self.lower_expr(els); + let id = self.next_id(); + let blk = P(hir::Block { + stmts: hir_vec![], + expr: Some(els), + id: id, + rules: hir::DefaultBlock, + span: span, + }); + expr_block(self, blk, None) + } + _ => self.lower_expr(els), + } + }); - _ => panic!(lctx.id_assigner.diagnostic() - .span_fatal(e.span, "inclusive range with no end")), - }; - } - ExprKind::Path(ref qself, ref path) => { - let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, + hir::ExprIf(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), + opt_ident.map(|ident| self.lower_ident(ident))) + } + ExprKind::Loop(ref body, opt_ident) => { + hir::ExprLoop(self.lower_block(body), + opt_ident.map(|ident| self.lower_ident(ident))) + } + ExprKind::Match(ref expr, ref arms) => { + hir::ExprMatch(self.lower_expr(expr), + arms.iter().map(|x| self.lower_arm(x)).collect(), + hir::MatchSource::Normal) + } + ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { + self.with_parent_def(e.id, |this| { + hir::ExprClosure(this.lower_capture_clause(capture_clause), + this.lower_fn_decl(decl), + this.lower_block(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)) + } + ExprKind::AssignOp(op, ref el, ref er) => { + hir::ExprAssignOp(self.lower_binop(op), + self.lower_expr(el), + self.lower_expr(er)) + } + ExprKind::Field(ref el, ident) => { + hir::ExprField(self.lower_expr(el), respan(ident.span, ident.node.name)) + } + ExprKind::TupField(ref el, ident) => { + hir::ExprTupField(self.lower_expr(el), ident) + } + ExprKind::Index(ref el, ref er) => { + hir::ExprIndex(self.lower_expr(el), 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)]) -> P { + let strs = std_path(this, &iter::once(&"ops") + .chain(path) + .map(|s| *s) + .collect::>()); + + let structpath = path_global(ast_expr.span, strs); + + let hir_expr = if fields.len() == 0 { + expr_path(this, + structpath, + ast_expr.attrs.clone()) + } else { + let fields = fields.into_iter().map(|&(s, e)| { + let expr = this.lower_expr(&e); + let signal_block = signal_block_expr(this, + hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + field(token::intern(s), signal_block, ast_expr.span) + }).collect(); + let attrs = ast_expr.attrs.clone(); + + expr_struct(this, ast_expr.span, structpath, fields, None, attrs) + }; + + signal_block_expr(this, + hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) } - }); - hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none())) - } - ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))), - ExprKind::InlineAsm(InlineAsm { - ref inputs, - ref outputs, - ref asm, - asm_str_style, - ref clobbers, - volatile, - alignstack, - dialect, - expn_id, - }) => hir::ExprInlineAsm(hir::InlineAsm { - inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), - outputs: outputs.iter() - .map(|out| { - hir::InlineAsmOutput { - constraint: out.constraint.clone(), - is_rw: out.is_rw, - is_indirect: out.is_indirect, - } - }) - .collect(), - asm: asm.clone(), - asm_str_style: asm_str_style, - clobbers: clobbers.clone().into(), - volatile: volatile, - alignstack: alignstack, - dialect: dialect, - expn_id: expn_id, - }, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(), - inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()), - ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { - hir::ExprStruct(lower_path(lctx, path), - fields.iter().map(|x| lower_field(lctx, x)).collect(), - maybe_expr.as_ref().map(|x| lower_expr(lctx, x))) - } - ExprKind::Paren(ref ex) => { - // merge attributes into the inner expression. - return lower_expr(lctx, ex).map(|mut ex| { - ex.attrs.update(|attrs| { - attrs.prepend(e.attrs.clone()) + + use syntax::ast::RangeLimits::*; + + return match (e1, e2, lims) { + (&None, &None, HalfOpen) => + make_struct(self, e, &["RangeFull"], + &[]), + + (&Some(ref e1), &None, HalfOpen) => + make_struct(self, e, &["RangeFrom"], + &[("start", e1)]), + + (&None, &Some(ref e2), HalfOpen) => + make_struct(self, e, &["RangeTo"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), HalfOpen) => + make_struct(self, e, &["Range"], + &[("start", e1), ("end", e2)]), + + (&None, &Some(ref e2), Closed) => + make_struct(self, e, &["RangeToInclusive"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), Closed) => + make_struct(self, e, &["RangeInclusive", "NonEmpty"], + &[("start", e1), ("end", e2)]), + + _ => panic!(self.id_assigner.diagnostic() + .span_fatal(e.span, "inclusive range with no end")), + }; + } + ExprKind::Path(ref qself, ref path) => { + let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: self.lower_ty(ty), + position: position, + } }); - ex - }); - } + hir::ExprPath(hir_qself, self.lower_path_full(path, qself.is_none())) + } + ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { + respan(sp_ident.span, self.lower_ident(sp_ident.node)) + })), + ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { + respan(sp_ident.span, self.lower_ident(sp_ident.node)) + })), + ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))), + ExprKind::InlineAsm(InlineAsm { + ref inputs, + ref outputs, + ref asm, + asm_str_style, + ref clobbers, + volatile, + alignstack, + dialect, + expn_id, + }) => hir::ExprInlineAsm(hir::InlineAsm { + inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), + outputs: outputs.iter() + .map(|out| { + hir::InlineAsmOutput { + constraint: out.constraint.clone(), + is_rw: out.is_rw, + is_indirect: out.is_indirect, + } + }) + .collect(), + asm: asm.clone(), + asm_str_style: asm_str_style, + clobbers: clobbers.clone().into(), + volatile: volatile, + alignstack: alignstack, + dialect: dialect, + expn_id: expn_id, + }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(), + inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()), + ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { + hir::ExprStruct(self.lower_path(path), + fields.iter().map(|x| self.lower_field(x)).collect(), + maybe_expr.as_ref().map(|x| self.lower_expr(x))) + } + ExprKind::Paren(ref ex) => { + // merge attributes into the inner expression. + return self.lower_expr(ex).map(|mut ex| { + ex.attrs.update(|attrs| { + attrs.prepend(e.attrs.clone()) + }); + ex + }); + } - // Desugar ExprIfLet - // From: `if let = []` - ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { - // to: - // - // match { - // => , - // [_ if => ,] - // _ => [ | ()] - // } - - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `[_ if => ,]` - let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); - let else_if_arms = { - let mut arms = vec![]; - loop { - let else_opt_continue = else_opt.and_then(|els| { - els.and_then(|els| { - match els.node { - // else if - hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(lctx, e.span); - arms.push(hir::Arm { - attrs: hir_vec![], - pats: hir_vec![pat_under], - guard: Some(cond), - body: expr_block(lctx, then, None), - }); - else_opt.map(|else_opt| (else_opt, true)) + // Desugar ExprIfLet + // From: `if let = []` + ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { + // to: + // + // match { + // => , + // [_ if => ,] + // _ => [ | ()] + // } + + // ` => ` + let pat_arm = { + let body = self.lower_block(body); + let body_expr = expr_block(self, body, None); + arm(hir_vec![self.lower_pat(pat)], body_expr) + }; + + // `[_ if => ,]` + let mut else_opt = else_opt.as_ref().map(|e| self.lower_expr(e)); + let else_if_arms = { + let mut arms = vec![]; + loop { + let else_opt_continue = else_opt.and_then(|els| { + els.and_then(|els| { + match els.node { + // else if + hir::ExprIf(cond, then, else_opt) => { + let pat_under = pat_wild(self, e.span); + arms.push(hir::Arm { + attrs: hir_vec![], + pats: hir_vec![pat_under], + guard: Some(cond), + body: expr_block(self, then, None), + }); + else_opt.map(|else_opt| (else_opt, true)) + } + _ => Some((P(els), false)), } - _ => Some((P(els), false)), + }) + }); + match else_opt_continue { + Some((e, true)) => { + else_opt = Some(e); + } + Some((e, false)) => { + else_opt = Some(e); + break; + } + None => { + else_opt = None; + break; } - }) - }); - match else_opt_continue { - Some((e, true)) => { - else_opt = Some(e); - } - Some((e, false)) => { - else_opt = Some(e); - break; - } - None => { - else_opt = None; - break; } } - } - arms - }; - - let contains_else_clause = else_opt.is_some(); - - // `_ => [ | ()]` - let else_arm = { - let pat_under = pat_wild(lctx, e.span); - let else_expr = - else_opt.unwrap_or_else( - || expr_tuple(lctx, e.span, hir_vec![], None)); - arm(hir_vec![pat_under], else_expr) - }; - - let mut arms = Vec::with_capacity(else_if_arms.len() + 2); - arms.push(pat_arm); - arms.extend(else_if_arms); - arms.push(else_arm); - - let sub_expr = lower_expr(lctx, sub_expr); - // add attributes to the outer returned expr node - return expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms.into(), - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - }), - e.attrs.clone()); - } + arms + }; - // Desugar ExprWhileLet - // From: `[opt_ident]: while let = ` - ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { - // to: - // - // [opt_ident]: loop { - // match { - // => , - // _ => break - // } - // } - - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `_ => break` - let break_arm = { - let pat_under = pat_wild(lctx, e.span); - let break_expr = expr_break(lctx, e.span, None); - arm(hir_vec![pat_under], break_expr) - }; - - // `match { ... }` - let arms = hir_vec![pat_arm, break_arm]; - let sub_expr = lower_expr(lctx, sub_expr); - let match_expr = expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms, - hir::MatchSource::WhileLetDesugar), - None); - - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - // 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 }); - } + let contains_else_clause = else_opt.is_some(); - // Desugar ExprForLoop - // From: `[opt_ident]: for in ` - ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { - // to: - // - // { - // let result = match ::std::iter::IntoIterator::into_iter() { - // mut iter => { - // [opt_ident]: loop { - // match ::std::iter::Iterator::next(&mut iter) { - // ::std::option::Option::Some() => , - // ::std::option::Option::None => break - // } - // } - // } - // }; - // result - // } - - // expand - let head = lower_expr(lctx, head); - - let iter = lctx.str_to_ident("iter"); - - // `::std::option::Option::Some() => ` - let pat_arm = { - let body_block = lower_block(lctx, body); - let body_span = body_block.span; - let body_expr = P(hir::Expr { - id: lctx.next_id(), - node: hir::ExprBlock(body_block), - span: body_span, - attrs: None, - }); - let pat = lower_pat(lctx, pat); - let some_pat = pat_some(lctx, e.span, pat); + // `_ => [ | ()]` + let else_arm = { + let pat_under = pat_wild(self, e.span); + let else_expr = + else_opt.unwrap_or_else( + || expr_tuple(self, e.span, hir_vec![], None)); + arm(hir_vec![pat_under], else_expr) + }; - arm(hir_vec![some_pat], body_expr) - }; + let mut arms = Vec::with_capacity(else_if_arms.len() + 2); + arms.push(pat_arm); + arms.extend(else_if_arms); + arms.push(else_arm); + + let sub_expr = self.lower_expr(sub_expr); + // add attributes to the outer returned expr node + return expr(self, + e.span, + hir::ExprMatch(sub_expr, + arms.into(), + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + }), + e.attrs.clone()); + } - // `::std::option::Option::None => break` - let break_arm = { - let break_expr = expr_break(lctx, e.span, None); + // Desugar ExprWhileLet + // From: `[opt_ident]: while let = ` + ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { + // to: + // + // [opt_ident]: loop { + // match { + // => , + // _ => break + // } + // } + + // ` => ` + let pat_arm = { + let body = self.lower_block(body); + let body_expr = expr_block(self, body, None); + arm(hir_vec![self.lower_pat(pat)], body_expr) + }; - arm(hir_vec![pat_none(lctx, e.span)], break_expr) - }; + // `_ => break` + let break_arm = { + let pat_under = pat_wild(self, e.span); + let break_expr = expr_break(self, e.span, None); + arm(hir_vec![pat_under], break_expr) + }; - // `mut iter` - let iter_pat = - pat_ident_binding_mode(lctx, e.span, iter, hir::BindByValue(hir::MutMutable)); + // `match { ... }` + let arms = hir_vec![pat_arm, break_arm]; + let sub_expr = self.lower_expr(sub_expr); + let match_expr = expr(self, + e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar), + None); + + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(self, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| self.lower_ident(ident))); + // 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 }); + } - // `match ::std::iter::Iterator::next(&mut iter) { ... }` - let match_expr = { - let next_path = { - let strs = std_path(lctx, &["iter", "Iterator", "next"]); + // Desugar ExprForLoop + // From: `[opt_ident]: for in ` + ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { + // to: + // + // { + // let result = match ::std::iter::IntoIterator::into_iter() { + // mut iter => { + // [opt_ident]: loop { + // match ::std::iter::Iterator::next(&mut iter) { + // ::std::option::Option::Some() => , + // ::std::option::Option::None => break + // } + // } + // } + // }; + // result + // } + + // expand + let head = self.lower_expr(head); + + let iter = self.str_to_ident("iter"); + + // `::std::option::Option::Some() => ` + let pat_arm = { + let body_block = self.lower_block(body); + let body_span = body_block.span; + let body_expr = P(hir::Expr { + id: self.next_id(), + node: hir::ExprBlock(body_block), + span: body_span, + attrs: None, + }); + let pat = self.lower_pat(pat); + let some_pat = pat_some(self, e.span, pat); - path_global(e.span, strs) + arm(hir_vec![some_pat], body_expr) }; - let iter = expr_ident(lctx, e.span, iter, None, iter_pat.id); - let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None); - let next_path = expr_path(lctx, next_path, None); - let next_expr = expr_call(lctx, - e.span, - next_path, - hir_vec![ref_mut_iter], - None); - let arms = hir_vec![pat_arm, break_arm]; - expr(lctx, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), - None) - }; + // `::std::option::Option::None => break` + let break_arm = { + let break_expr = expr_break(self, e.span, None); - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - let loop_expr = - P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); + arm(hir_vec![pat_none(self, e.span)], break_expr) + }; - // `mut iter => { ... }` - let iter_arm = arm(hir_vec![iter_pat], loop_expr); + // `mut iter` + let iter_pat = pat_ident_binding_mode(self, e.span, iter, + hir::BindByValue(hir::MutMutable)); + + // `match ::std::iter::Iterator::next(&mut iter) { ... }` + let match_expr = { + let next_path = { + let strs = std_path(self, &["iter", "Iterator", "next"]); + + path_global(e.span, strs) + }; + let iter = expr_ident(self, e.span, iter, None, iter_pat.id); + let ref_mut_iter = expr_mut_addr_of(self, e.span, iter, None); + let next_path = expr_path(self, next_path, None); + let next_expr = expr_call(self, + e.span, + next_path, + hir_vec![ref_mut_iter], + None); + let arms = hir_vec![pat_arm, break_arm]; + + expr(self, + e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), + None) + }; - // `match ::std::iter::IntoIterator::into_iter() { ... }` - let into_iter_expr = { - let into_iter_path = { - let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(self, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| self.lower_ident(ident))); + let loop_expr = + P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); - path_global(e.span, strs) - }; + // `mut iter => { ... }` + let iter_arm = arm(hir_vec![iter_pat], loop_expr); - let into_iter = expr_path(lctx, into_iter_path, None); - expr_call(lctx, e.span, into_iter, hir_vec![head], None) - }; - - let match_expr = expr_match(lctx, - e.span, - into_iter_expr, - hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - None); - - // `{ let _result = ...; _result }` - // underscore prevents an unused_variables lint if the head diverges - let result_ident = lctx.str_to_ident("_result"); - let (let_stmt, let_stmt_binding) = - stmt_let(lctx, e.span, false, result_ident, match_expr, None); - - let result = expr_ident(lctx, e.span, result_ident, None, let_stmt_binding); - let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); - // add the attributes to the outer returned expr node - return expr_block(lctx, block, e.attrs.clone()); - } + // `match ::std::iter::IntoIterator::into_iter() { ... }` + let into_iter_expr = { + let into_iter_path = { + let strs = std_path(self, &["iter", "IntoIterator", "into_iter"]); - // Desugar ExprKind::Try - // From: `?` - ExprKind::Try(ref sub_expr) => { - // to: - // - // { - // match { - // Ok(val) => val, - // Err(err) => { - // return Err(From::from(err)) - // } - // } - // } + path_global(e.span, strs) + }; - // expand - let sub_expr = lower_expr(lctx, sub_expr); - - // Ok(val) => val - let ok_arm = { - let val_ident = lctx.str_to_ident("val"); - let val_pat = pat_ident(lctx, e.span, val_ident); - let val_expr = expr_ident(lctx, e.span, val_ident, None, val_pat.id); - let ok_pat = pat_ok(lctx, e.span, val_pat); - - arm(hir_vec![ok_pat], val_expr) - }; - - // Err(err) => return Err(From::from(err)) - let err_arm = { - let err_ident = lctx.str_to_ident("err"); - let err_local = pat_ident(lctx, e.span, err_ident); - let from_expr = { - let path = std_path(lctx, &["convert", "From", "from"]); - let path = path_global(e.span, path); - let from = expr_path(lctx, path, None); - let err_expr = expr_ident(lctx, e.span, err_ident, None, err_local.id); - - expr_call(lctx, e.span, from, hir_vec![err_expr], None) + let into_iter = expr_path(self, into_iter_path, None); + expr_call(self, e.span, into_iter, hir_vec![head], None) }; - let err_expr = { - let path = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(e.span, path); - let err_ctor = expr_path(lctx, path, None); - expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) + + let match_expr = expr_match(self, + e.span, + into_iter_expr, + hir_vec![iter_arm], + hir::MatchSource::ForLoopDesugar, + None); + + // `{ let _result = ...; _result }` + // underscore prevents an unused_variables lint if the head diverges + let result_ident = self.str_to_ident("_result"); + let (let_stmt, let_stmt_binding) = + stmt_let(self, e.span, false, result_ident, match_expr, None); + + let result = expr_ident(self, e.span, result_ident, None, let_stmt_binding); + let block = block_all(self, e.span, hir_vec![let_stmt], Some(result)); + // add the attributes to the outer returned expr node + return expr_block(self, block, e.attrs.clone()); + } + + // Desugar ExprKind::Try + // From: `?` + ExprKind::Try(ref sub_expr) => { + // to: + // + // { + // match { + // Ok(val) => val, + // Err(err) => { + // return Err(From::from(err)) + // } + // } + // } + + // expand + let sub_expr = self.lower_expr(sub_expr); + + // Ok(val) => val + let ok_arm = { + let val_ident = self.str_to_ident("val"); + let val_pat = pat_ident(self, e.span, val_ident); + let val_expr = expr_ident(self, e.span, val_ident, None, val_pat.id); + let ok_pat = pat_ok(self, e.span, val_pat); + + arm(hir_vec![ok_pat], val_expr) }; - let err_pat = pat_err(lctx, e.span, err_local); - let ret_expr = expr(lctx, e.span, - hir::Expr_::ExprRet(Some(err_expr)), None); - arm(hir_vec![err_pat], ret_expr) - }; + // Err(err) => return Err(From::from(err)) + let err_arm = { + let err_ident = self.str_to_ident("err"); + let err_local = pat_ident(self, e.span, err_ident); + let from_expr = { + let path = std_path(self, &["convert", "From", "from"]); + let path = path_global(e.span, path); + let from = expr_path(self, path, None); + let err_expr = expr_ident(self, e.span, err_ident, None, err_local.id); + + expr_call(self, e.span, from, hir_vec![err_expr], None) + }; + let err_expr = { + let path = std_path(self, &["result", "Result", "Err"]); + let path = path_global(e.span, path); + let err_ctor = expr_path(self, path, None); + expr_call(self, e.span, err_ctor, hir_vec![from_expr], None) + }; + let err_pat = pat_err(self, e.span, err_local); + let ret_expr = expr(self, e.span, + hir::Expr_::ExprRet(Some(err_expr)), None); + + arm(hir_vec![err_pat], ret_expr) + }; - return expr_match(lctx, e.span, sub_expr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, None); - } + return expr_match(self, e.span, sub_expr, hir_vec![err_arm, ok_arm], + hir::MatchSource::TryDesugar, None); + } - ExprKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: e.span, - attrs: e.attrs.clone(), - }) -} + ExprKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: e.span, + attrs: e.attrs.clone(), + }) + } -fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { - match s.node { - StmtKind::Decl(ref d, id) => { - Spanned { - node: hir::StmtDecl(lower_decl(lctx, d), id), - span: s.span, + fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt { + match s.node { + StmtKind::Decl(ref d, id) => { + Spanned { + node: hir::StmtDecl(self.lower_decl(d), id), + span: s.span, + } } - } - StmtKind::Expr(ref e, id) => { - Spanned { - node: hir::StmtExpr(lower_expr(lctx, e), id), - span: s.span, + StmtKind::Expr(ref e, id) => { + Spanned { + node: hir::StmtExpr(self.lower_expr(e), id), + span: s.span, + } } - } - StmtKind::Semi(ref e, id) => { - Spanned { - node: hir::StmtSemi(lower_expr(lctx, e), id), - span: s.span, + StmtKind::Semi(ref e, id) => { + Spanned { + node: hir::StmtSemi(self.lower_expr(e), id), + span: s.span, + } } + StmtKind::Mac(..) => panic!("Shouldn't exist here"), } - StmtKind::Mac(..) => panic!("Shouldn't exist here"), } -} -fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { - match c { - CaptureBy::Value => hir::CaptureByValue, - CaptureBy::Ref => hir::CaptureByRef, + fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause { + match c { + CaptureBy::Value => hir::CaptureByValue, + CaptureBy::Ref => hir::CaptureByRef, + } } -} -fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { - match *v { - Visibility::Public => hir::Public, - Visibility::Crate(_) => hir::Visibility::Crate, - Visibility::Restricted { ref path, id } => - hir::Visibility::Restricted { path: P(lower_path(lctx, path)), id: id }, - Visibility::Inherited => hir::Inherited, + fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility { + match *v { + Visibility::Public => hir::Public, + Visibility::Crate(_) => hir::Visibility::Crate, + Visibility::Restricted { ref path, id } => + hir::Visibility::Restricted { path: P(self.lower_path(path)), id: id }, + Visibility::Inherited => hir::Inherited, + } } -} -fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { - match d { - Defaultness::Default => hir::Defaultness::Default, - Defaultness::Final => hir::Defaultness::Final, + fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness { + match d { + Defaultness::Default => hir::Defaultness::Default, + Defaultness::Final => hir::Defaultness::Final, + } } -} -fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { - match *b { - BlockCheckMode::Default => hir::DefaultBlock, - BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), + fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode { + match *b { + BlockCheckMode::Default => hir::DefaultBlock, + BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)), + } } -} -fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { - match *b { - BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), - BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), + fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingMode { + match *b { + BindingMode::ByRef(m) => hir::BindByRef(self.lower_mutability(m)), + BindingMode::ByValue(m) => hir::BindByValue(self.lower_mutability(m)), + } } -} -fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { - match u { - CompilerGenerated => hir::CompilerGenerated, - UserProvided => hir::UserProvided, + fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource { + match u { + CompilerGenerated => hir::CompilerGenerated, + UserProvided => hir::UserProvided, + } } -} -fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { - match i { - ImplPolarity::Positive => hir::ImplPolarity::Positive, - ImplPolarity::Negative => hir::ImplPolarity::Negative, + fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity { + match i { + ImplPolarity::Positive => hir::ImplPolarity::Positive, + ImplPolarity::Negative => hir::ImplPolarity::Negative, + } } -} -fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, - f: TraitBoundModifier) - -> hir::TraitBoundModifier { - match f { - TraitBoundModifier::None => hir::TraitBoundModifier::None, - TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier { + match f { + TraitBoundModifier::None => hir::TraitBoundModifier::None, + TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + } } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 66b1b28a0e505..492d36cfb31a5 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -37,7 +37,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc::hir::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::LoweringContext; use rustc_passes::{no_asm, loops, consts, rvalues, static_recursion}; use rustc_const_eval::check_match; use super::Compilation; @@ -787,8 +787,8 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let mut lcx = LoweringContext::new(sess, Some(krate), &mut resolver); - hir_map::Forest::new(lower_crate(&mut lcx, krate), dep_graph) + let krate = LoweringContext::new(sess, Some(krate), &mut resolver).lower_crate(krate); + hir_map::Forest::new(krate, dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ce525b716ff2c..8c17ef02615fe 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -57,7 +57,7 @@ use rustc_serialize::{Encodable, EncoderHelpers}; #[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::ast::NodeId; #[cfg(test)] use rustc::hir::print as pprust; -#[cfg(test)] use rustc::hir::lowering::{lower_item, LoweringContext, DummyResolver}; +#[cfg(test)] use rustc::hir::lowering::{LoweringContext, DummyResolver}; struct DecodeContext<'a, 'b, 'tcx: 'a> { tcx: &'a TyCtxt<'tcx>, @@ -1347,7 +1347,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo() {} ).unwrap())); }); @@ -1357,7 +1357,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); }); @@ -1367,7 +1367,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; return z; @@ -1387,10 +1387,10 @@ fn test_simplification() { ).unwrap(); let cx = mk_ctxt(); with_testing_context(|lcx| { - let hir_item = lower_item(lcx, &item); + let hir_item = lcx.lower_item(&item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); - let item_exp = InlinedItem::Item(P(lower_item(lcx, "e_item!(&cx, + let item_exp = InlinedItem::Item(P(lcx.lower_item("e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0f518900ea787..d4c08552edfc3 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -28,7 +28,7 @@ use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc::hir::lowering::{lower_crate, LoweringContext, DummyResolver}; +use rustc::hir::lowering::{LoweringContext, DummyResolver}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -98,8 +98,7 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let mut lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); - let krate = lower_crate(&mut lcx, &krate); + let krate = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver).lower_crate(&krate); let opts = scrape_test_config(&krate); From 3927ff4fecea17f56a57c59253afce3acdc89bec Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 01:15:11 +0000 Subject: [PATCH 07/42] Make the remaining functions in `hir::lowering` methods of `LoweringContext` --- src/librustc/hir/lowering.rs | 794 +++++++++++++++++------------------ 1 file changed, 383 insertions(+), 411 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0f65c5c64e491..0c7123a570e14 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -965,58 +965,55 @@ impl<'a> LoweringContext<'a> { let inplace_finalize = ["ops", "InPlace", "finalize"]; let make_call = |this: &mut LoweringContext, p, args| { - let path = core_path(this, e.span, p); - let path = expr_path(this, path, None); - expr_call(this, e.span, path, args, None) + let path = this.core_path(e.span, p); + let path = this.expr_path(path, None); + this.expr_call(e.span, path, args, None) }; let mk_stmt_let = |this: &mut LoweringContext, bind, expr| { - stmt_let(this, e.span, false, bind, expr, None) + this.stmt_let(e.span, false, bind, expr, None) }; let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| { - stmt_let(this, e.span, true, bind, expr, None) + this.stmt_let(e.span, true, bind, expr, None) }; // let placer = ; let (s1, placer_binding) = { - let placer_expr = signal_block_expr(self, - hir_vec![], - placer_expr, - e.span, - hir::PopUnstableBlock, - None); + let placer_expr = self.signal_block_expr(hir_vec![], + placer_expr, + e.span, + hir::PopUnstableBlock, + None); mk_stmt_let(self, placer_ident, placer_expr) }; // let mut place = Placer::make_place(placer); let (s2, place_binding) = { - let placer = expr_ident(self, e.span, placer_ident, None, placer_binding); + let placer = self.expr_ident(e.span, placer_ident, None, placer_binding); let call = make_call(self, &make_place, hir_vec![placer]); mk_stmt_let_mut(self, place_ident, call) }; // let p_ptr = Place::pointer(&mut place); let (s3, p_ptr_binding) = { - let agent = expr_ident(self, e.span, place_ident, None, place_binding); - let args = hir_vec![expr_mut_addr_of(self, e.span, agent, None)]; + let agent = self.expr_ident(e.span, place_ident, None, place_binding); + let args = hir_vec![self.expr_mut_addr_of(e.span, agent, None)]; 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 = signal_block_expr(self, - hir_vec![], - value_expr, - e.span, - hir::PopUnstableBlock, - None); - signal_block_expr(self, - hir_vec![], - value_expr, - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated), None) + let value_expr = self.signal_block_expr(hir_vec![], + value_expr, + e.span, + hir::PopUnstableBlock, + None); + self.signal_block_expr(hir_vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated), None) }; // push_unsafe!({ @@ -1024,28 +1021,26 @@ impl<'a> LoweringContext<'a> { // InPlace::finalize(place) // }) let expr = { - let ptr = expr_ident(self, e.span, p_ptr_ident, None, p_ptr_binding); + let ptr = self.expr_ident(e.span, p_ptr_ident, None, p_ptr_binding); let call_move_val_init = hir::StmtSemi( make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), self.next_id()); let call_move_val_init = respan(e.span, call_move_val_init); - let place = expr_ident(self, e.span, place_ident, None, place_binding); + let place = self.expr_ident(e.span, place_ident, None, place_binding); let call = make_call(self, &inplace_finalize, hir_vec![place]); - signal_block_expr(self, - hir_vec![call_move_val_init], - call, - e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated), None) + self.signal_block_expr(hir_vec![call_move_val_init], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated), None) }; - return signal_block_expr(self, - hir_vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock, - e.attrs.clone()); + return self.signal_block_expr(hir_vec![s1, s2, s3], + expr, + e.span, + hir::PushUnstableBlock, + e.attrs.clone()); } ExprKind::Vec(ref exprs) => { @@ -1110,7 +1105,7 @@ impl<'a> LoweringContext<'a> { rules: hir::DefaultBlock, span: span, }); - expr_block(self, blk, None) + self.expr_block(blk, None) } _ => self.lower_expr(els), } @@ -1162,47 +1157,42 @@ impl<'a> LoweringContext<'a> { ast_expr: &Expr, path: &[&str], fields: &[(&str, &P)]) -> P { - let strs = std_path(this, &iter::once(&"ops") + let strs = this.std_path(&iter::once(&"ops") .chain(path) .map(|s| *s) .collect::>()); - let structpath = path_global(ast_expr.span, strs); + let structpath = this.path_global(ast_expr.span, strs); let hir_expr = if fields.len() == 0 { - expr_path(this, - structpath, - ast_expr.attrs.clone()) + this.expr_path(structpath, ast_expr.attrs.clone()) } else { let fields = fields.into_iter().map(|&(s, e)| { let expr = this.lower_expr(&e); - let signal_block = signal_block_expr(this, - hir_vec![], - expr, - e.span, - hir::PopUnstableBlock, - None); - field(token::intern(s), signal_block, ast_expr.span) + let signal_block = this.signal_block_expr(hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + this.field(token::intern(s), signal_block, ast_expr.span) }).collect(); let attrs = ast_expr.attrs.clone(); - expr_struct(this, ast_expr.span, structpath, fields, None, attrs) + this.expr_struct(ast_expr.span, structpath, fields, None, attrs) }; - signal_block_expr(this, - hir_vec![], - hir_expr, - ast_expr.span, - hir::PushUnstableBlock, - None) + this.signal_block_expr(hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) } use syntax::ast::RangeLimits::*; return match (e1, e2, lims) { (&None, &None, HalfOpen) => - make_struct(self, e, &["RangeFull"], - &[]), + make_struct(self, e, &["RangeFull"], &[]), (&Some(ref e1), &None, HalfOpen) => make_struct(self, e, &["RangeFrom"], @@ -1303,8 +1293,9 @@ impl<'a> LoweringContext<'a> { // ` => ` let pat_arm = { let body = self.lower_block(body); - let body_expr = expr_block(self, body, None); - arm(hir_vec![self.lower_pat(pat)], body_expr) + let body_expr = self.expr_block(body, None); + let pat = self.lower_pat(pat); + self.arm(hir_vec![pat], body_expr) }; // `[_ if => ,]` @@ -1317,12 +1308,12 @@ impl<'a> LoweringContext<'a> { match els.node { // else if hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(self, e.span); + let pat_under = self.pat_wild(e.span); arms.push(hir::Arm { attrs: hir_vec![], pats: hir_vec![pat_under], guard: Some(cond), - body: expr_block(self, then, None), + body: self.expr_block(then, None), }); else_opt.map(|else_opt| (else_opt, true)) } @@ -1351,11 +1342,10 @@ impl<'a> LoweringContext<'a> { // `_ => [ | ()]` let else_arm = { - let pat_under = pat_wild(self, e.span); + let pat_under = self.pat_wild(e.span); let else_expr = - else_opt.unwrap_or_else( - || expr_tuple(self, e.span, hir_vec![], None)); - arm(hir_vec![pat_under], else_expr) + else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![], None)); + self.arm(hir_vec![pat_under], else_expr) }; let mut arms = Vec::with_capacity(else_if_arms.len() + 2); @@ -1365,14 +1355,13 @@ impl<'a> LoweringContext<'a> { let sub_expr = self.lower_expr(sub_expr); // add attributes to the outer returned expr node - return expr(self, - e.span, - hir::ExprMatch(sub_expr, - arms.into(), - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - }), - e.attrs.clone()); + return self.expr(e.span, + hir::ExprMatch(sub_expr, + arms.into(), + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + }), + e.attrs.clone()); } // Desugar ExprWhileLet @@ -1390,29 +1379,29 @@ impl<'a> LoweringContext<'a> { // ` => ` let pat_arm = { let body = self.lower_block(body); - let body_expr = expr_block(self, body, None); - arm(hir_vec![self.lower_pat(pat)], body_expr) + let body_expr = self.expr_block(body, None); + let pat = self.lower_pat(pat); + self.arm(hir_vec![pat], body_expr) }; // `_ => break` let break_arm = { - let pat_under = pat_wild(self, e.span); - let break_expr = expr_break(self, e.span, None); - arm(hir_vec![pat_under], break_expr) + let pat_under = self.pat_wild(e.span); + let break_expr = self.expr_break(e.span, None); + self.arm(hir_vec![pat_under], break_expr) }; // `match { ... }` let arms = hir_vec![pat_arm, break_arm]; let sub_expr = self.lower_expr(sub_expr); - let match_expr = expr(self, - e.span, - hir::ExprMatch(sub_expr, - arms, - hir::MatchSource::WhileLetDesugar), - None); + let match_expr = self.expr(e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar), + None); // `[opt_ident]: loop { ... }` - let loop_block = block_expr(self, match_expr); + let loop_block = self.block_expr(match_expr); let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| self.lower_ident(ident))); // add attributes to the outer returned expr node @@ -1455,84 +1444,81 @@ impl<'a> LoweringContext<'a> { attrs: None, }); let pat = self.lower_pat(pat); - let some_pat = pat_some(self, e.span, pat); + let some_pat = self.pat_some(e.span, pat); - arm(hir_vec![some_pat], body_expr) + self.arm(hir_vec![some_pat], body_expr) }; // `::std::option::Option::None => break` let break_arm = { - let break_expr = expr_break(self, e.span, None); - - arm(hir_vec![pat_none(self, e.span)], break_expr) + let break_expr = self.expr_break(e.span, None); + let pat = self.pat_none(e.span); + self.arm(hir_vec![pat], break_expr) }; // `mut iter` - let iter_pat = pat_ident_binding_mode(self, e.span, iter, - hir::BindByValue(hir::MutMutable)); + let iter_pat = self.pat_ident_binding_mode(e.span, iter, + hir::BindByValue(hir::MutMutable)); // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { let next_path = { - let strs = std_path(self, &["iter", "Iterator", "next"]); + let strs = self.std_path(&["iter", "Iterator", "next"]); - path_global(e.span, strs) + self.path_global(e.span, strs) }; - let iter = expr_ident(self, e.span, iter, None, iter_pat.id); - let ref_mut_iter = expr_mut_addr_of(self, e.span, iter, None); - let next_path = expr_path(self, next_path, None); - let next_expr = expr_call(self, - e.span, - next_path, - hir_vec![ref_mut_iter], - None); + let iter = self.expr_ident(e.span, iter, None, iter_pat.id); + let ref_mut_iter = self.expr_mut_addr_of(e.span, iter, None); + let next_path = self.expr_path(next_path, None); + let next_expr = self.expr_call(e.span, + next_path, + hir_vec![ref_mut_iter], + None); let arms = hir_vec![pat_arm, break_arm]; - expr(self, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), - None) + self.expr(e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), + None) }; // `[opt_ident]: loop { ... }` - let loop_block = block_expr(self, match_expr); + let loop_block = self.block_expr(match_expr); let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| self.lower_ident(ident))); let loop_expr = P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); // `mut iter => { ... }` - let iter_arm = arm(hir_vec![iter_pat], loop_expr); + let iter_arm = self.arm(hir_vec![iter_pat], loop_expr); // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { let into_iter_path = { - let strs = std_path(self, &["iter", "IntoIterator", "into_iter"]); + let strs = self.std_path(&["iter", "IntoIterator", "into_iter"]); - path_global(e.span, strs) + self.path_global(e.span, strs) }; - let into_iter = expr_path(self, into_iter_path, None); - expr_call(self, e.span, into_iter, hir_vec![head], None) + let into_iter = self.expr_path(into_iter_path, None); + self.expr_call(e.span, into_iter, hir_vec![head], None) }; - let match_expr = expr_match(self, - e.span, - into_iter_expr, - hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - None); + let match_expr = self.expr_match(e.span, + into_iter_expr, + hir_vec![iter_arm], + hir::MatchSource::ForLoopDesugar, + None); // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges let result_ident = self.str_to_ident("_result"); let (let_stmt, let_stmt_binding) = - stmt_let(self, e.span, false, result_ident, match_expr, None); + self.stmt_let(e.span, false, result_ident, match_expr, None); - let result = expr_ident(self, e.span, result_ident, None, let_stmt_binding); - let block = block_all(self, e.span, hir_vec![let_stmt], Some(result)); + let result = self.expr_ident(e.span, result_ident, None, let_stmt_binding); + let block = self.block_all(e.span, hir_vec![let_stmt], Some(result)); // add the attributes to the outer returned expr node - return expr_block(self, block, e.attrs.clone()); + return self.expr_block(block, e.attrs.clone()); } // Desugar ExprKind::Try @@ -1555,40 +1541,40 @@ impl<'a> LoweringContext<'a> { // Ok(val) => val let ok_arm = { let val_ident = self.str_to_ident("val"); - let val_pat = pat_ident(self, e.span, val_ident); - let val_expr = expr_ident(self, e.span, val_ident, None, val_pat.id); - let ok_pat = pat_ok(self, e.span, val_pat); + let val_pat = self.pat_ident(e.span, val_ident); + let val_expr = self.expr_ident(e.span, val_ident, None, val_pat.id); + let ok_pat = self.pat_ok(e.span, val_pat); - arm(hir_vec![ok_pat], val_expr) + self.arm(hir_vec![ok_pat], val_expr) }; // Err(err) => return Err(From::from(err)) let err_arm = { let err_ident = self.str_to_ident("err"); - let err_local = pat_ident(self, e.span, err_ident); + let err_local = self.pat_ident(e.span, err_ident); let from_expr = { - let path = std_path(self, &["convert", "From", "from"]); - let path = path_global(e.span, path); - let from = expr_path(self, path, None); - let err_expr = expr_ident(self, e.span, err_ident, None, err_local.id); + let path = self.std_path(&["convert", "From", "from"]); + let path = self.path_global(e.span, path); + let from = self.expr_path(path, None); + let err_expr = self.expr_ident(e.span, err_ident, None, err_local.id); - expr_call(self, e.span, from, hir_vec![err_expr], None) + self.expr_call(e.span, from, hir_vec![err_expr], None) }; let err_expr = { - let path = std_path(self, &["result", "Result", "Err"]); - let path = path_global(e.span, path); - let err_ctor = expr_path(self, path, None); - expr_call(self, e.span, err_ctor, hir_vec![from_expr], None) + let path = self.std_path(&["result", "Result", "Err"]); + let path = self.path_global(e.span, path); + let err_ctor = self.expr_path(path, None); + self.expr_call(e.span, err_ctor, hir_vec![from_expr], None) }; - let err_pat = pat_err(self, e.span, err_local); - let ret_expr = expr(self, e.span, - hir::Expr_::ExprRet(Some(err_expr)), None); + let err_pat = self.pat_err(e.span, err_local); + let ret_expr = self.expr(e.span, + hir::Expr_::ExprRet(Some(err_expr)), None); - arm(hir_vec![err_pat], ret_expr) + self.arm(hir_vec![err_pat], ret_expr) }; - return expr_match(self, e.span, sub_expr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, None); + return self.expr_match(e.span, sub_expr, hir_vec![err_arm, ok_arm], + hir::MatchSource::TryDesugar, None); } ExprKind::Mac(_) => panic!("Shouldn't exist here"), @@ -1680,310 +1666,296 @@ impl<'a> LoweringContext<'a> { TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, } } -} -// Helper methods for building HIR. + // Helper methods for building HIR. -fn arm(pats: hir::HirVec>, expr: P) -> hir::Arm { - hir::Arm { - attrs: hir_vec![], - pats: pats, - guard: None, - body: expr, + fn arm(&mut self, pats: hir::HirVec>, expr: P) -> hir::Arm { + hir::Arm { + attrs: hir_vec![], + pats: pats, + guard: None, + body: expr, + } } -} -fn field(name: Name, expr: P, span: Span) -> hir::Field { - hir::Field { - name: Spanned { - node: name, + fn field(&mut self, name: Name, expr: P, span: Span) -> hir::Field { + hir::Field { + name: Spanned { + node: name, + span: span, + }, span: span, - }, - span: span, - expr: expr, + expr: expr, + } } -} -fn expr_break(lctx: &mut LoweringContext, span: Span, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprBreak(None), attrs) -} + fn expr_break(&mut self, span: Span, attrs: ThinAttributes) -> P { + self.expr(span, hir::ExprBreak(None), attrs) + } -fn expr_call(lctx: &mut LoweringContext, - span: Span, - e: P, - args: hir::HirVec>, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprCall(e, args), attrs) -} + fn expr_call(&mut self, + span: Span, + e: P, + args: hir::HirVec>, + attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprCall(e, args), attrs) + } -fn expr_ident(lctx: &mut LoweringContext, span: Span, id: hir::Ident, - attrs: ThinAttributes, binding: NodeId) -> P { - let expr = expr(lctx, span, hir::ExprPath(None, path_ident(span, id)), attrs); + fn expr_ident(&mut self, span: Span, id: hir::Ident, attrs: ThinAttributes, binding: NodeId) + -> P { + let expr_path = hir::ExprPath(None, self.path_ident(span, id)); + let expr = self.expr(span, expr_path, attrs); - let def = lctx.resolver.definitions().map(|defs| { - Def::Local(defs.local_def_id(binding), binding) - }).unwrap_or(Def::Err); - lctx.resolver.record_resolution(expr.id, def); + let def = self.resolver.definitions().map(|defs| { + Def::Local(defs.local_def_id(binding), binding) + }).unwrap_or(Def::Err); + self.resolver.record_resolution(expr.id, def); - expr -} + expr + } -fn expr_mut_addr_of(lctx: &mut LoweringContext, span: Span, e: P, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) -} + fn expr_mut_addr_of(&mut self, span: Span, e: P, attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), attrs) + } -fn expr_path(lctx: &mut LoweringContext, path: hir::Path, - attrs: ThinAttributes) -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, true); - let expr = expr(lctx, path.span, hir::ExprPath(None, path), attrs); - lctx.resolver.record_resolution(expr.id, def); - expr -} + fn expr_path(&mut self, path: hir::Path, attrs: ThinAttributes) -> P { + let def = self.resolver.resolve_generated_global_path(&path, true); + let expr = self.expr(path.span, hir::ExprPath(None, path), attrs); + self.resolver.record_resolution(expr.id, def); + expr + } -fn expr_match(lctx: &mut LoweringContext, - span: Span, - arg: P, - arms: hir::HirVec, - source: hir::MatchSource, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) -} + fn expr_match(&mut self, + span: Span, + arg: P, + arms: hir::HirVec, + source: hir::MatchSource, + attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprMatch(arg, arms, source), attrs) + } -fn expr_block(lctx: &mut LoweringContext, b: P, - attrs: ThinAttributes) -> P { - expr(lctx, b.span, hir::ExprBlock(b), attrs) -} + fn expr_block(&mut self, b: P, attrs: ThinAttributes) -> P { + self.expr(b.span, hir::ExprBlock(b), attrs) + } -fn expr_tuple(lctx: &mut LoweringContext, sp: Span, exprs: hir::HirVec>, - attrs: ThinAttributes) -> P { - expr(lctx, sp, hir::ExprTup(exprs), attrs) -} + fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec>, attrs: ThinAttributes) + -> P { + self.expr(sp, hir::ExprTup(exprs), attrs) + } -fn expr_struct(lctx: &mut LoweringContext, - sp: Span, - path: hir::Path, - fields: hir::HirVec, - e: Option>, - attrs: ThinAttributes) -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, false); - let expr = expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs); - lctx.resolver.record_resolution(expr.id, def); - expr + fn expr_struct(&mut self, + sp: Span, + path: hir::Path, + fields: hir::HirVec, + e: Option>, + attrs: ThinAttributes) -> P { + let def = self.resolver.resolve_generated_global_path(&path, false); + let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs); + self.resolver.record_resolution(expr.id, def); + expr + } -} + fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P { + P(hir::Expr { + id: self.next_id(), + node: node, + span: span, + attrs: attrs, + }) + } -fn expr(lctx: &mut LoweringContext, span: Span, node: hir::Expr_, - attrs: ThinAttributes) -> P { - P(hir::Expr { - id: lctx.next_id(), - node: node, - span: span, - attrs: attrs, - }) -} + fn stmt_let(&mut self, + sp: Span, + mutbl: bool, + ident: hir::Ident, + ex: P, + attrs: ThinAttributes) + -> (hir::Stmt, NodeId) { + let pat = if mutbl { + self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable)) + } else { + self.pat_ident(sp, ident) + }; + let pat_id = pat.id; + let local = P(hir::Local { + pat: pat, + ty: None, + init: Some(ex), + id: self.next_id(), + span: sp, + attrs: attrs, + }); + let decl = respan(sp, hir::DeclLocal(local)); + (respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id) + } -fn stmt_let(lctx: &mut LoweringContext, - sp: Span, - mutbl: bool, - ident: hir::Ident, - ex: P, - attrs: ThinAttributes) - -> (hir::Stmt, NodeId) { - let pat = if mutbl { - pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable)) - } else { - pat_ident(lctx, sp, ident) - }; - let pat_id = pat.id; - let local = P(hir::Local { - pat: pat, - ty: None, - init: Some(ex), - id: lctx.next_id(), - span: sp, - attrs: attrs, - }); - let decl = respan(sp, hir::DeclLocal(local)); - (respan(sp, hir::StmtDecl(P(decl), lctx.next_id())), pat_id) -} + fn block_expr(&mut self, expr: P) -> P { + self.block_all(expr.span, hir::HirVec::new(), Some(expr)) + } -fn block_expr(lctx: &mut LoweringContext, expr: P) -> P { - block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) -} + fn block_all(&mut self, span: Span, stmts: hir::HirVec, expr: Option>) + -> P { + P(hir::Block { + stmts: stmts, + expr: expr, + id: self.next_id(), + rules: hir::DefaultBlock, + span: span, + }) + } -fn block_all(lctx: &mut LoweringContext, - span: Span, - stmts: hir::HirVec, - expr: Option>) - -> P { - P(hir::Block { - stmts: stmts, - expr: expr, - id: lctx.next_id(), - rules: hir::DefaultBlock, - span: span, - }) -} + fn pat_ok(&mut self, span: Span, pat: P) -> P { + let ok = self.std_path(&["result", "Result", "Ok"]); + let path = self.path_global(span, ok); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_ok(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let ok = std_path(lctx, &["result", "Result", "Ok"]); - let path = path_global(span, ok); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_err(&mut self, span: Span, pat: P) -> P { + let err = self.std_path(&["result", "Result", "Err"]); + let path = self.path_global(span, err); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_err(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let err = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(span, err); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_some(&mut self, span: Span, pat: P) -> P { + let some = self.std_path(&["option", "Option", "Some"]); + let path = self.path_global(span, some); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_some(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let some = std_path(lctx, &["option", "Option", "Some"]); - let path = path_global(span, some); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_none(&mut self, span: Span) -> P { + let none = self.std_path(&["option", "Option", "None"]); + let path = self.path_global(span, none); + self.pat_enum(span, path, hir_vec![]) + } -fn pat_none(lctx: &mut LoweringContext, span: Span) -> P { - let none = std_path(lctx, &["option", "Option", "None"]); - let path = path_global(span, none); - pat_enum(lctx, span, path, hir_vec![]) -} + fn pat_enum(&mut self, span: Span, path: hir::Path, subpats: hir::HirVec>) + -> P { + let def = self.resolver.resolve_generated_global_path(&path, true); + let pt = if subpats.is_empty() { + hir::PatKind::Path(path) + } else { + hir::PatKind::TupleStruct(path, Some(subpats)) + }; + let pat = self.pat(span, pt); + self.resolver.record_resolution(pat.id, def); + pat + } -fn pat_enum(lctx: &mut LoweringContext, - span: Span, - path: hir::Path, - subpats: hir::HirVec>) - -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, true); - let pt = if subpats.is_empty() { - hir::PatKind::Path(path) - } else { - hir::PatKind::TupleStruct(path, Some(subpats)) - }; - let pat = pat(lctx, span, pt); - lctx.resolver.record_resolution(pat.id, def); - pat -} + fn pat_ident(&mut self, span: Span, ident: hir::Ident) -> P { + self.pat_ident_binding_mode(span, ident, hir::BindByValue(hir::MutImmutable)) + } -fn pat_ident(lctx: &mut LoweringContext, span: Span, ident: hir::Ident) -> P { - pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) -} + fn pat_ident_binding_mode(&mut self, span: Span, ident: hir::Ident, bm: hir::BindingMode) + -> P { + let pat_ident = hir::PatKind::Ident(bm, + Spanned { + span: span, + node: ident, + }, + None); -fn pat_ident_binding_mode(lctx: &mut LoweringContext, - span: Span, - ident: hir::Ident, - bm: hir::BindingMode) - -> P { - let pat_ident = hir::PatKind::Ident(bm, - Spanned { - span: span, - node: ident, - }, - None); - - let pat = pat(lctx, span, pat_ident); - - let parent_def = lctx.parent_def; - let def = lctx.resolver.definitions().map(|defs| { - let def_path_data = DefPathData::Binding(ident.name); - let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); - Def::Local(DefId::local(def_index), pat.id) - }).unwrap_or(Def::Err); - lctx.resolver.record_resolution(pat.id, def); - - pat -} + let pat = self.pat(span, pat_ident); -fn pat_wild(lctx: &mut LoweringContext, span: Span) -> P { - pat(lctx, span, hir::PatKind::Wild) -} + let parent_def = self.parent_def; + let def = self.resolver.definitions().map(|defs| { + let def_path_data = DefPathData::Binding(ident.name); + let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); + Def::Local(DefId::local(def_index), pat.id) + }).unwrap_or(Def::Err); + self.resolver.record_resolution(pat.id, def); -fn pat(lctx: &mut LoweringContext, span: Span, pat: hir::PatKind) -> P { - P(hir::Pat { - id: lctx.next_id(), - node: pat, - span: span, - }) -} + pat + } -fn path_ident(span: Span, id: hir::Ident) -> hir::Path { - path(span, vec![id]) -} + fn pat_wild(&mut self, span: Span) -> P { + self.pat(span, hir::PatKind::Wild) + } -fn path(span: Span, strs: Vec) -> hir::Path { - path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} + fn pat(&mut self, span: Span, pat: hir::PatKind) -> P { + P(hir::Pat { + id: self.next_id(), + node: pat, + span: span, + }) + } -fn path_global(span: Span, strs: Vec) -> hir::Path { - path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} + fn path_ident(&mut self, span: Span, id: hir::Ident) -> hir::Path { + self.path(span, vec![id]) + } -fn path_all(sp: Span, - global: bool, - mut idents: Vec, - lifetimes: hir::HirVec, - types: hir::HirVec>, - bindings: hir::HirVec) - -> hir::Path { - let last_identifier = idents.pop().unwrap(); - let mut segments: Vec = idents.into_iter() - .map(|ident| { - hir::PathSegment { - identifier: ident, - parameters: hir::PathParameters::none(), - } - }) - .collect(); - segments.push(hir::PathSegment { - identifier: last_identifier, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - }), - }); - hir::Path { - span: sp, - global: global, - segments: segments.into(), + fn path(&mut self, span: Span, strs: Vec) -> hir::Path { + self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } -} -fn std_path(lctx: &mut LoweringContext, components: &[&str]) -> Vec { - let mut v = Vec::new(); - if let Some(s) = lctx.crate_root { - v.push(hir::Ident::from_name(token::intern(s))); + fn path_global(&mut self, span: Span, strs: Vec) -> hir::Path { + self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } - v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); - return v; -} -// Given suffix ["b","c","d"], returns path `::std::b::c::d` when -// `fld.cx.use_std`, and `::core::b::c::d` otherwise. -fn core_path(lctx: &mut LoweringContext, span: Span, components: &[&str]) -> hir::Path { - let idents = std_path(lctx, components); - path_global(span, idents) -} + fn path_all(&mut self, + sp: Span, + global: bool, + mut idents: Vec, + lifetimes: hir::HirVec, + types: hir::HirVec>, + bindings: hir::HirVec) + -> hir::Path { + let last_identifier = idents.pop().unwrap(); + let mut segments: Vec = idents.into_iter().map(|ident| { + hir::PathSegment { + identifier: ident, + parameters: hir::PathParameters::none(), + } + }).collect(); -fn signal_block_expr(lctx: &mut LoweringContext, - stmts: hir::HirVec, - expr: P, - span: Span, - rule: hir::BlockCheckMode, - attrs: ThinAttributes) - -> P { - let id = lctx.next_id(); - expr_block(lctx, - P(hir::Block { - rules: rule, - span: span, - id: id, - stmts: stmts, - expr: Some(expr), - }), - attrs) + segments.push(hir::PathSegment { + identifier: last_identifier, + parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { + lifetimes: lifetimes, + types: types, + bindings: bindings, + }), + }); + hir::Path { + span: sp, + global: global, + segments: segments.into(), + } + } + + fn std_path(&mut self, components: &[&str]) -> Vec { + let mut v = Vec::new(); + if let Some(s) = self.crate_root { + v.push(hir::Ident::from_name(token::intern(s))); + } + v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); + return v; + } + + // Given suffix ["b","c","d"], returns path `::std::b::c::d` when + // `fld.cx.use_std`, and `::core::b::c::d` otherwise. + fn core_path(&mut self, span: Span, components: &[&str]) -> hir::Path { + let idents = self.std_path(components); + self.path_global(span, idents) + } + + fn signal_block_expr(&mut self, + stmts: hir::HirVec, + expr: P, + span: Span, + rule: hir::BlockCheckMode, + attrs: ThinAttributes) + -> P { + let id = self.next_id(); + let block = P(hir::Block { + rules: rule, + span: span, + id: id, + stmts: stmts, + expr: Some(expr), + }); + self.expr_block(block, attrs) + } } From 33978b0728640f3345479bd3fc0055a36507cf32 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 05:29:13 +0000 Subject: [PATCH 08/42] Refactor `hir::lowering` API --- src/librustc/hir/lowering.rs | 35 ++++++++++++++++-------------- src/librustc_driver/driver.rs | 5 ++--- src/librustc_metadata/astencode.rs | 2 +- src/librustdoc/test.rs | 4 ++-- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0c7123a570e14..5ca99a7db67f5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -91,30 +91,33 @@ impl Resolver for DummyResolver { } } -impl<'a> LoweringContext<'a> { - pub fn new(id_assigner: &'a NodeIdAssigner, - c: Option<&Crate>, - resolver: &'a mut Resolver) - -> LoweringContext<'a> { - let crate_root = c.and_then(|c| { - if std_inject::no_core(c) { - None - } else if std_inject::no_std(c) { - Some("core") - } else { - Some("std") - } - }); +pub fn lower_crate(krate: &Crate, id_assigner: &NodeIdAssigner, resolver: &mut Resolver) + -> hir::Crate { + LoweringContext { + crate_root: if std_inject::no_core(krate) { + None + } else if std_inject::no_std(krate) { + Some("core") + } else { + Some("std") + }, + id_assigner: id_assigner, + parent_def: None, + resolver: resolver, + }.lower_crate(krate) +} +impl<'a> LoweringContext<'a> { + pub fn testing_context(id_assigner: &'a NodeIdAssigner, resolver: &'a mut Resolver) -> Self { LoweringContext { - crate_root: crate_root, + crate_root: None, id_assigner: id_assigner, parent_def: None, resolver: resolver, } } - pub fn lower_crate(&mut self, c: &Crate) -> hir::Crate { + fn lower_crate(&mut self, c: &Crate) -> hir::Crate { struct ItemLowerer<'lcx, 'interner: 'lcx> { items: BTreeMap, lctx: &'lcx mut LoweringContext<'interner>, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 492d36cfb31a5..01e2b410c1b24 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -37,7 +37,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc::hir::lowering::LoweringContext; +use rustc::hir::lowering::lower_crate; use rustc_passes::{no_asm, loops, consts, rvalues, static_recursion}; use rustc_const_eval::check_match; use super::Compilation; @@ -787,8 +787,7 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let krate = LoweringContext::new(sess, Some(krate), &mut resolver).lower_crate(krate); - hir_map::Forest::new(krate, dep_graph) + hir_map::Forest::new(lower_crate(krate, sess, &mut resolver), dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 8c17ef02615fe..2a847c4c19538 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1329,7 +1329,7 @@ fn mk_ctxt() -> parse::ParseSess { fn with_testing_context T>(f: F) -> T { let assigner = FakeNodeIdAssigner; let mut resolver = DummyResolver; - let mut lcx = LoweringContext::new(&assigner, None, &mut resolver); + let mut lcx = LoweringContext::testing_context(&assigner, &mut resolver); f(&mut lcx) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d4c08552edfc3..44c3ded4a115a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -28,7 +28,7 @@ use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc::hir::lowering::{LoweringContext, DummyResolver}; +use rustc::hir::lowering::{lower_crate, DummyResolver}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -98,7 +98,7 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let krate = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver).lower_crate(&krate); + let krate = lower_crate(&krate, &sess, &mut dummy_resolver); let opts = scrape_test_config(&krate); From 66404f34d255eb7304a6ecf8350589684e62951d Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Tue, 10 May 2016 11:06:30 +0200 Subject: [PATCH 09/42] Simplify text --- src/libcore/sync/atomic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index cf3e45cf3de79..e141a92c3ee3d 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -142,13 +142,13 @@ pub enum Ordering { #[stable(feature = "rust1", since = "1.0.0")] Relaxed, /// When coupled with a store, all previous writes become visible - /// to another thread that performs a load with `Acquire` ordering + /// to the other threads that perform a load with `Acquire` ordering /// on the same value. #[stable(feature = "rust1", since = "1.0.0")] Release, /// When coupled with a load, all subsequent loads will see data /// written before a store with `Release` ordering on the same value - /// in another thread. + /// in other threads. #[stable(feature = "rust1", since = "1.0.0")] Acquire, /// When coupled with a load, uses `Acquire` ordering, and with a store From 9ac468b841cf01e7b575f4c20d10df8096c31f7a Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 10 May 2016 15:34:25 +0200 Subject: [PATCH 10/42] Store a reference rather than a RefCell in LocalCrateReader. --- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/test.rs | 2 +- src/librustc_metadata/creader.rs | 9 ++++----- src/librustdoc/core.rs | 2 +- src/test/run-make/execution-engine/test.rs | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e72204e5e22de..8841480f7f644 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -148,7 +148,7 @@ pub fn compile_input(sess: &Session, time(sess.time_passes(), "external crate/lib resolution", - || LocalCrateReader::new(sess, &cstore, defs, &expanded_crate, &id) + || LocalCrateReader::new(sess, &cstore, &defs.borrow(), &expanded_crate, &id) .read_crates(&dep_graph)); time(sess.time_passes(), diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 869bbb723ef41..ed9a092b6ff2f 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -121,7 +121,7 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let krate = driver::assign_node_ids(&sess, krate); let defs = &RefCell::new(hir_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, defs, &krate, "test_crate").read_crates(&dep_graph); + LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, "test_crate").read_crates(&dep_graph); let _ignore = dep_graph.in_ignore(); let (_, resolutions, mut hir_forest) = { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 190e8552d199a..2b02a745bef74 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -46,7 +46,7 @@ pub struct LocalCrateReader<'a> { cstore: &'a CStore, creader: CrateReader<'a>, krate: &'a ast::Crate, - defintions: &'a RefCell, + defintions: &'a hir_map::Definitions, } pub struct CrateReader<'a> { @@ -843,7 +843,7 @@ impl<'a> CrateReader<'a> { impl<'a> LocalCrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, - defs: &'a RefCell, + defs: &'a hir_map::Definitions, krate: &'a ast::Crate, local_crate_name: &str) -> LocalCrateReader<'a> { @@ -902,9 +902,8 @@ impl<'a> LocalCrateReader<'a> { PathKind::Crate, true); - let defs = self.defintions.borrow(); - let def_id = defs.opt_local_def_id(i.id).unwrap(); - let len = defs.def_path(def_id.index).data.len(); + let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); + let len = self.defintions.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e5fc84037ce57..77a780805a695 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -154,7 +154,7 @@ pub fn run_core(search_paths: SearchPaths, let dep_graph = DepGraph::new(false); let defs = &RefCell::new(hir_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, &defs, &krate, &name).read_crates(&dep_graph); + LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, &name).read_crates(&dep_graph); // Lower ast -> hir and resolve. let (analysis, resolutions, mut hir_forest) = { diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 98412c08df520..f46846c34a5ef 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -241,7 +241,7 @@ fn compile_program(input: &str, sysroot: PathBuf) let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); let krate = driver::assign_node_ids(&sess, krate); let defs = RefCell::new(ast_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph); + LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, &id).read_crates(&dep_graph); let (analysis, resolutions, mut hir_forest) = { let defs = &mut *defs.borrow_mut(); driver::lower_and_resolve(&sess, &id, defs, &krate, dep_graph, MakeGlobMap::No) From 8d3531d3db513bd71ad1ac041ad9a2172ec34012 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 10 May 2016 15:36:50 +0200 Subject: [PATCH 11/42] Correct typo in LocalCrateReader::definitions. --- src/librustc_metadata/creader.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 2b02a745bef74..62c208dbcb2a4 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -46,7 +46,7 @@ pub struct LocalCrateReader<'a> { cstore: &'a CStore, creader: CrateReader<'a>, krate: &'a ast::Crate, - defintions: &'a hir_map::Definitions, + definitions: &'a hir_map::Definitions, } pub struct CrateReader<'a> { @@ -852,7 +852,7 @@ impl<'a> LocalCrateReader<'a> { cstore: cstore, creader: CrateReader::new(sess, cstore, local_crate_name), krate: krate, - defintions: defs, + definitions: defs, } } @@ -902,8 +902,8 @@ impl<'a> LocalCrateReader<'a> { PathKind::Crate, true); - let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); - let len = self.defintions.def_path(def_id.index).data.len(); + let def_id = self.definitions.opt_local_def_id(i.id).unwrap(); + let len = self.definitions.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { From f16eac928a7feec28825db36acd259aca2382381 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Thu, 5 May 2016 21:48:44 -0700 Subject: [PATCH 12/42] Make --emit dep-info work correctly with -Z no-analysis again. Previously, it would attempt to resolve some external crates that weren't necessary for dep-info output. Fixes #33231. --- src/librustc_driver/driver.rs | 62 ++++++++++++++----- src/librustc_driver/lib.rs | 26 ++++---- src/librustc_driver/pretty.rs | 22 +++---- .../run-make/dep-info-no-analysis/Makefile | 6 ++ .../run-make/dep-info-no-analysis/input.dd | 3 + .../run-make/dep-info-no-analysis/input.rs | 14 +++++ 6 files changed, 93 insertions(+), 40 deletions(-) create mode 100644 src/test/run-make/dep-info-no-analysis/Makefile create mode 100644 src/test/run-make/dep-info-no-analysis/input.dd create mode 100644 src/test/run-make/dep-info-no-analysis/input.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e72204e5e22de..0d5ecc53a7900 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -138,6 +138,20 @@ pub fn compile_input(sess: &Session, &id), Ok(())); + write_out_deps(sess, &outputs, &id); + + { controller_entry_point!(after_write_deps, + sess, + CompileState::state_after_write_deps(input, + sess, + outdir, + output, + &cstore, + &expanded_crate, + &id), + Ok(())); + } + let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); @@ -173,25 +187,22 @@ pub fn compile_input(sess: &Session, "indexing hir", move || hir_map::map_crate(hir_forest, defs)); - - write_out_deps(sess, &outputs, &id); - { let _ignore = hir_map.dep_graph.in_ignore(); - controller_entry_point!(after_write_deps, + controller_entry_point!(after_ast, sess, - CompileState::state_after_write_deps(input, - sess, - outdir, - output, - &arenas, - &cstore, - &hir_map, - &analysis, - &resolutions, - &expanded_crate, - &hir_map.krate(), - &id), + CompileState::state_after_ast(input, + sess, + outdir, + output, + &arenas, + &cstore, + &hir_map, + &analysis, + &resolutions, + &expanded_crate, + &hir_map.krate(), + &id), Ok(())); } @@ -311,6 +322,7 @@ pub struct CompileController<'a> { pub after_parse: PhaseController<'a>, pub after_expand: PhaseController<'a>, pub after_write_deps: PhaseController<'a>, + pub after_ast: PhaseController<'a>, pub after_analysis: PhaseController<'a>, pub after_llvm: PhaseController<'a>, @@ -323,6 +335,7 @@ impl<'a> CompileController<'a> { after_parse: PhaseController::basic(), after_expand: PhaseController::basic(), after_write_deps: PhaseController::basic(), + after_ast: PhaseController::basic(), after_analysis: PhaseController::basic(), after_llvm: PhaseController::basic(), make_glob_map: resolve::MakeGlobMap::No, @@ -430,6 +443,23 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> { } fn state_after_write_deps(input: &'a Input, + session: &'ast Session, + out_dir: &'a Option, + out_file: &'a Option, + cstore: &'a CStore, + krate: &'a ast::Crate, + crate_name: &'a str) + -> CompileState<'a, 'b, 'ast, 'tcx> { + CompileState { + crate_name: Some(crate_name), + cstore: Some(cstore), + expanded_crate: Some(krate), + out_file: out_file.as_ref().map(|s| &**s), + ..CompileState::empty(input, session, out_dir) + } + } + + fn state_after_ast(input: &'a Input, session: &'ast Session, out_dir: &'a Option, out_file: &'a Option, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 4da36be94e009..483ba044add62 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -461,23 +461,23 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { if let Some((ppm, opt_uii)) = parse_pretty(sess, matches) { if ppm.needs_ast_map(&opt_uii) { - control.after_write_deps.stop = Compilation::Stop; + control.after_ast.stop = Compilation::Stop; control.after_parse.callback = box move |state| { state.krate = Some(pretty::fold_crate(state.krate.take().unwrap(), ppm)); }; - control.after_write_deps.callback = box move |state| { - pretty::print_after_write_deps(state.session, - state.ast_map.unwrap(), - state.analysis.unwrap(), - state.resolutions.unwrap(), - state.input, - &state.expanded_crate.take().unwrap(), - state.crate_name.unwrap(), - ppm, - state.arenas.unwrap(), - opt_uii.clone(), - state.out_file); + control.after_ast.callback = box move |state| { + pretty::print_after_ast(state.session, + state.ast_map.unwrap(), + state.analysis.unwrap(), + state.resolutions.unwrap(), + state.input, + &state.expanded_crate.take().unwrap(), + state.crate_name.unwrap(), + ppm, + state.arenas.unwrap(), + opt_uii.clone(), + state.out_file); }; } else { control.after_parse.stop = Compilation::Stop; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 8d8984000c7e4..2fd015bf5b80e 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -812,17 +812,17 @@ pub fn print_after_parsing(sess: &Session, write_output(out, ofile); } -pub fn print_after_write_deps<'tcx, 'a: 'tcx>(sess: &'a Session, - ast_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, - resolutions: &Resolutions, - input: &Input, - krate: &ast::Crate, - crate_name: &str, - ppm: PpMode, - arenas: &'tcx ty::CtxtArenas<'tcx>, - opt_uii: Option, - ofile: Option<&Path>) { +pub fn print_after_ast<'tcx, 'a: 'tcx>(sess: &'a Session, + ast_map: &hir_map::Map<'tcx>, + analysis: &ty::CrateAnalysis, + resolutions: &Resolutions, + input: &Input, + krate: &ast::Crate, + crate_name: &str, + ppm: PpMode, + arenas: &'tcx ty::CtxtArenas<'tcx>, + opt_uii: Option, + ofile: Option<&Path>) { let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); diff --git a/src/test/run-make/dep-info-no-analysis/Makefile b/src/test/run-make/dep-info-no-analysis/Makefile new file mode 100644 index 0000000000000..8d31de3781c2d --- /dev/null +++ b/src/test/run-make/dep-info-no-analysis/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + $(RUSTC) -o $(TMPDIR)/input.dd -Z no-analysis --emit dep-info input.rs + sed -i "s@$(TMPDIR)/@@g" $(TMPDIR)/input.dd + diff -u $(TMPDIR)/input.dd input.dd diff --git a/src/test/run-make/dep-info-no-analysis/input.dd b/src/test/run-make/dep-info-no-analysis/input.dd new file mode 100644 index 0000000000000..f2c8676515b8a --- /dev/null +++ b/src/test/run-make/dep-info-no-analysis/input.dd @@ -0,0 +1,3 @@ +input.dd: input.rs + +input.rs: diff --git a/src/test/run-make/dep-info-no-analysis/input.rs b/src/test/run-make/dep-info-no-analysis/input.rs new file mode 100644 index 0000000000000..523b0f0670ce4 --- /dev/null +++ b/src/test/run-make/dep-info-no-analysis/input.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests that dep info can be emitted without resolving external crates. +extern crate not_there; + +fn main() {} From 105aa8c30fc97fc7bfadc23bbf35eee412e164cb Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Thu, 5 May 2016 22:06:56 -0700 Subject: [PATCH 13/42] Fix funky formatting. --- src/librustc_driver/driver.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 0d5ecc53a7900..731283abc10a2 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -140,17 +140,16 @@ pub fn compile_input(sess: &Session, write_out_deps(sess, &outputs, &id); - { controller_entry_point!(after_write_deps, - sess, - CompileState::state_after_write_deps(input, - sess, - outdir, - output, - &cstore, - &expanded_crate, - &id), - Ok(())); - } + controller_entry_point!(after_write_deps, + sess, + CompileState::state_after_write_deps(input, + sess, + outdir, + output, + &cstore, + &expanded_crate, + &id), + Ok(())); let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); From 64cca3ab2dfa7643fe6d67505001c43f7e8e2868 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Sun, 8 May 2016 10:08:09 -0700 Subject: [PATCH 14/42] Rename after_ast to after_hir_lowering. --- src/librustc_driver/driver.rs | 34 +++++++++++++++++----------------- src/librustc_driver/lib.rs | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 731283abc10a2..96aa0bb5de579 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -188,9 +188,9 @@ pub fn compile_input(sess: &Session, { let _ignore = hir_map.dep_graph.in_ignore(); - controller_entry_point!(after_ast, + controller_entry_point!(after_hir_lowering, sess, - CompileState::state_after_ast(input, + CompileState::state_after_hir_lowering(input, sess, outdir, output, @@ -321,7 +321,7 @@ pub struct CompileController<'a> { pub after_parse: PhaseController<'a>, pub after_expand: PhaseController<'a>, pub after_write_deps: PhaseController<'a>, - pub after_ast: PhaseController<'a>, + pub after_hir_lowering: PhaseController<'a>, pub after_analysis: PhaseController<'a>, pub after_llvm: PhaseController<'a>, @@ -334,7 +334,7 @@ impl<'a> CompileController<'a> { after_parse: PhaseController::basic(), after_expand: PhaseController::basic(), after_write_deps: PhaseController::basic(), - after_ast: PhaseController::basic(), + after_hir_lowering: PhaseController::basic(), after_analysis: PhaseController::basic(), after_llvm: PhaseController::basic(), make_glob_map: resolve::MakeGlobMap::No, @@ -458,19 +458,19 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> { } } - fn state_after_ast(input: &'a Input, - session: &'ast Session, - out_dir: &'a Option, - out_file: &'a Option, - arenas: &'ast ty::CtxtArenas<'ast>, - cstore: &'a CStore, - hir_map: &'a hir_map::Map<'ast>, - analysis: &'a ty::CrateAnalysis, - resolutions: &'a Resolutions, - krate: &'a ast::Crate, - hir_crate: &'a hir::Crate, - crate_name: &'a str) - -> CompileState<'a, 'b, 'ast, 'tcx> { + fn state_after_hir_lowering(input: &'a Input, + session: &'ast Session, + out_dir: &'a Option, + out_file: &'a Option, + arenas: &'ast ty::CtxtArenas<'ast>, + cstore: &'a CStore, + hir_map: &'a hir_map::Map<'ast>, + analysis: &'a ty::CrateAnalysis, + resolutions: &'a Resolutions, + krate: &'a ast::Crate, + hir_crate: &'a hir::Crate, + crate_name: &'a str) + -> CompileState<'a, 'b, 'ast, 'tcx> { CompileState { crate_name: Some(crate_name), arenas: Some(arenas), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 483ba044add62..796cf82c77511 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -461,12 +461,12 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { if let Some((ppm, opt_uii)) = parse_pretty(sess, matches) { if ppm.needs_ast_map(&opt_uii) { - control.after_ast.stop = Compilation::Stop; + control.after_hir_lowering.stop = Compilation::Stop; control.after_parse.callback = box move |state| { state.krate = Some(pretty::fold_crate(state.krate.take().unwrap(), ppm)); }; - control.after_ast.callback = box move |state| { + control.after_hir_lowering.callback = box move |state| { pretty::print_after_ast(state.session, state.ast_map.unwrap(), state.analysis.unwrap(), From a75fc0d23cd46157166b162ae0b1f15ba086a6f7 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Mon, 9 May 2016 08:31:43 -0700 Subject: [PATCH 15/42] Make the dep-info-no-analysis regex more robust on Windows. --- src/test/run-make/dep-info-no-analysis/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/dep-info-no-analysis/Makefile b/src/test/run-make/dep-info-no-analysis/Makefile index 8d31de3781c2d..66bb37d8bf33e 100644 --- a/src/test/run-make/dep-info-no-analysis/Makefile +++ b/src/test/run-make/dep-info-no-analysis/Makefile @@ -2,5 +2,5 @@ all: $(RUSTC) -o $(TMPDIR)/input.dd -Z no-analysis --emit dep-info input.rs - sed -i "s@$(TMPDIR)/@@g" $(TMPDIR)/input.dd + sed -i "s/^.*input.dd/input.dd/g" $(TMPDIR)/input.dd diff -u $(TMPDIR)/input.dd input.dd From e919f251800b792e15b3c72cdfb19e539cd74971 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 10 May 2016 15:34:52 +0200 Subject: [PATCH 16/42] Delay wrapping Definitions into a RefCell around LocalCrateReader. --- src/librustc_driver/driver.rs | 13 +++++++------ src/librustc_driver/test.rs | 9 +++++---- src/librustdoc/core.rs | 9 +++++---- src/test/run-make/execution-engine/test.rs | 11 ++++++----- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 8841480f7f644..3f9fa0a23c2d8 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -142,13 +142,13 @@ pub fn compile_input(sess: &Session, let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); // Collect defintions for def ids. - let defs = &RefCell::new(time(sess.time_passes(), - "collecting defs", - || hir_map::collect_definitions(&expanded_crate))); + let mut defs = time(sess.time_passes(), + "collecting defs", + || hir_map::collect_definitions(&expanded_crate)); time(sess.time_passes(), "external crate/lib resolution", - || LocalCrateReader::new(sess, &cstore, &defs.borrow(), &expanded_crate, &id) + || LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id) .read_crates(&dep_graph)); time(sess.time_passes(), @@ -156,8 +156,8 @@ pub fn compile_input(sess: &Session, || lint::check_ast_crate(sess, &expanded_crate)); let (analysis, resolutions, mut hir_forest) = { - let defs = &mut *defs.borrow_mut(); - lower_and_resolve(sess, &id, defs, &expanded_crate, dep_graph, control.make_glob_map) + lower_and_resolve(sess, &id, &mut defs, &expanded_crate, dep_graph, + control.make_glob_map) }; // Discard MTWT tables that aren't required past lowering to HIR. @@ -165,6 +165,7 @@ pub fn compile_input(sess: &Session, syntax::ext::mtwt::clear_tables(); } + let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); // Construct the HIR map diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index ed9a092b6ff2f..59713c66afcb6 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -120,15 +120,16 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let krate = driver::assign_node_ids(&sess, krate); - let defs = &RefCell::new(hir_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, "test_crate").read_crates(&dep_graph); + let mut defs = hir_map::collect_definitions(&krate); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, "test_crate").read_crates(&dep_graph); let _ignore = dep_graph.in_ignore(); let (_, resolutions, mut hir_forest) = { - let (defs, dep_graph) = (&mut *defs.borrow_mut(), dep_graph.clone()); - driver::lower_and_resolve(&sess, "test-crate", defs, &krate, dep_graph, MakeGlobMap::No) + driver::lower_and_resolve(&sess, "test-crate", &mut defs, &krate, dep_graph.clone(), + MakeGlobMap::No) }; + let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); let ast_map = hir_map::map_crate(&mut hir_forest, defs); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 77a780805a695..857a1176f496a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -153,15 +153,16 @@ pub fn run_core(search_paths: SearchPaths, let krate = driver::assign_node_ids(&sess, krate); let dep_graph = DepGraph::new(false); - let defs = &RefCell::new(hir_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, &name).read_crates(&dep_graph); + let mut defs = hir_map::collect_definitions(&krate); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &name).read_crates(&dep_graph); // Lower ast -> hir and resolve. let (analysis, resolutions, mut hir_forest) = { - let defs = &mut *defs.borrow_mut(); - driver::lower_and_resolve(&sess, &name, defs, &krate, dep_graph, resolve::MakeGlobMap::No) + driver::lower_and_resolve(&sess, &name, &mut defs, &krate, dep_graph, + resolve::MakeGlobMap::No) }; + let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); let hir_map = hir_map::map_crate(&mut hir_forest, defs); diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index f46846c34a5ef..0d10f31556644 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -240,14 +240,15 @@ fn compile_program(input: &str, sysroot: PathBuf) let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); let krate = driver::assign_node_ids(&sess, krate); - let defs = RefCell::new(ast_map::collect_definitions(&krate)); - LocalCrateReader::new(&sess, &cstore, &defs.borrow(), &krate, &id).read_crates(&dep_graph); + let mut defs = ast_map::collect_definitions(&krate); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph); let (analysis, resolutions, mut hir_forest) = { - let defs = &mut *defs.borrow_mut(); - driver::lower_and_resolve(&sess, &id, defs, &krate, dep_graph, MakeGlobMap::No) + driver::lower_and_resolve(&sess, &id, &mut defs, &krate, dep_graph, MakeGlobMap::No) }; + + let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); - let ast_map = ast_map::map_crate(&mut hir_forest, &defs); + let ast_map = ast_map::map_crate(&mut hir_forest, defs); abort_on_err(driver::phase_3_run_analysis_passes( &sess, ast_map, analysis, resolutions, &arenas, &id, From e5a91b7ba1a22e34c7d09105e7a115e696ffcd0f Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 10 May 2016 21:26:34 +0300 Subject: [PATCH 17/42] mir: don't attempt to promote Unpromotable constant temps. --- src/librustc_mir/transform/qualify_consts.rs | 24 +++++++++++++++----- src/test/run-pass/issue-33537.rs | 24 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/run-pass/issue-33537.rs diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 90823528973b9..e7693d2691bfd 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -65,13 +65,18 @@ bitflags! { // pointer comparisons, ptr-to-int casts, etc. const NOT_CONST = 1 << 6, + // Refers to temporaries which cannot be promoted as + // promote_consts decided they weren't simple enough. + const NOT_PROMOTABLE = 1 << 7, + // Borrows of temporaries can be promoted only // if they have none of the above qualifications. - const UNPROMOTABLE = !0, + const NEVER_PROMOTE = !0, // Const items can only have MUTABLE_INTERIOR - // without producing an error. - const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits + // and NOT_PROMOTABLE without producing an error. + const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits & + !Qualif::NOT_PROMOTABLE.bits } } @@ -502,6 +507,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { self.add(Qualif::NOT_CONST); } Lvalue::Temp(index) => { + if !self.temp_promotion_state[index as usize].is_promotable() { + self.add(Qualif::NOT_PROMOTABLE); + } + if let Some(qualif) = self.temp_qualif[index as usize] { self.add(qualif); } else { @@ -687,8 +696,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { // We might have a candidate for promotion. let candidate = Candidate::Ref(self.location); if self.mode == Mode::Fn || self.mode == Mode::ConstFn { - if !self.qualif.intersects(Qualif::UNPROMOTABLE) { - self.promotion_candidates.push(candidate); + if !self.qualif.intersects(Qualif::NEVER_PROMOTE) { + // We can only promote direct borrows of temps. + if let Lvalue::Temp(_) = *lvalue { + self.promotion_candidates.push(candidate); + } } } } @@ -780,7 +792,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { this.visit_operand(arg); if is_shuffle && i == 2 && this.mode == Mode::Fn { let candidate = Candidate::ShuffleIndices(bb); - if !this.qualif.intersects(Qualif::UNPROMOTABLE) { + if !this.qualif.intersects(Qualif::NEVER_PROMOTE) { this.promotion_candidates.push(candidate); } else { span_err!(this.tcx.sess, this.span, E0526, diff --git a/src/test/run-pass/issue-33537.rs b/src/test/run-pass/issue-33537.rs new file mode 100644 index 0000000000000..24f4c9f590b11 --- /dev/null +++ b/src/test/run-pass/issue-33537.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_fn)] + +const fn foo() -> *const i8 { + b"foo" as *const _ as *const i8 +} + +const fn bar() -> i32 { + *&{(1, 2, 3).1} +} + +fn main() { + assert_eq!(foo(), b"foo" as *const _ as *const i8); + assert_eq!(bar(), 2); +} From 85e02429b2ef07e11a40ebf6df28b37bcba528b2 Mon Sep 17 00:00:00 2001 From: Cristian Oliveira Date: Wed, 4 May 2016 00:40:53 -0300 Subject: [PATCH 18/42] Add error description for E0455 - Adding name attribute to the sample code - Fix description sentences --- src/librustc_metadata/diagnostics.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs index 8fa23de9a2d16..ae9f500c5de59 100644 --- a/src/librustc_metadata/diagnostics.rs +++ b/src/librustc_metadata/diagnostics.rs @@ -26,6 +26,27 @@ name. Example: ``` "##, +E0455: r##" +Linking with `kind=framework` is only supported when targeting OS X, +as frameworks are specific to that operating system. + +Erroneous code example: + +```compile_fail" +#[link(name = "FooCoreServices", kind = "framework")] extern {} +// OS used to compile is Linux for example +``` + +To solve this error you can use conditional compilation: + +``` +#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))] +extern {} +``` + +See more: https://doc.rust-lang.org/book/conditional-compilation.html +"##, + E0458: r##" An unknown "kind" was specified for a link attribute. Erroneous code example: @@ -73,7 +94,6 @@ well, and you link to them the same way. } register_diagnostics! { - E0455, // native frameworks are only available on OSX targets E0456, // plugin `..` is not available for triple `..` E0457, // plugin `..` only found in rlib format, but must be available... E0514, // metadata version mismatch From ba04a52b9677b8c472196a9c280808a63a69bf28 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Tue, 10 May 2016 19:21:44 -0700 Subject: [PATCH 19/42] Also rename the print_from_ast. --- src/librustc_driver/lib.rs | 22 +++++++++++----------- src/librustc_driver/pretty.rs | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 796cf82c77511..2a4b30e016f28 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -467,17 +467,17 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { state.krate = Some(pretty::fold_crate(state.krate.take().unwrap(), ppm)); }; control.after_hir_lowering.callback = box move |state| { - pretty::print_after_ast(state.session, - state.ast_map.unwrap(), - state.analysis.unwrap(), - state.resolutions.unwrap(), - state.input, - &state.expanded_crate.take().unwrap(), - state.crate_name.unwrap(), - ppm, - state.arenas.unwrap(), - opt_uii.clone(), - state.out_file); + pretty::print_after_hir_lowering(state.session, + state.ast_map.unwrap(), + state.analysis.unwrap(), + state.resolutions.unwrap(), + state.input, + &state.expanded_crate.take().unwrap(), + state.crate_name.unwrap(), + ppm, + state.arenas.unwrap(), + opt_uii.clone(), + state.out_file); }; } else { control.after_parse.stop = Compilation::Stop; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 2fd015bf5b80e..d3716af205396 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -812,17 +812,17 @@ pub fn print_after_parsing(sess: &Session, write_output(out, ofile); } -pub fn print_after_ast<'tcx, 'a: 'tcx>(sess: &'a Session, - ast_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis, - resolutions: &Resolutions, - input: &Input, - krate: &ast::Crate, - crate_name: &str, - ppm: PpMode, - arenas: &'tcx ty::CtxtArenas<'tcx>, - opt_uii: Option, - ofile: Option<&Path>) { +pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, + ast_map: &hir_map::Map<'tcx>, + analysis: &ty::CrateAnalysis, + resolutions: &Resolutions, + input: &Input, + krate: &ast::Crate, + crate_name: &str, + ppm: PpMode, + arenas: &'tcx ty::CtxtArenas<'tcx>, + opt_uii: Option, + ofile: Option<&Path>) { let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); From 7a9f4c22ff974ec68300f68c46df49d3f83329de Mon Sep 17 00:00:00 2001 From: ggomez Date: Tue, 10 May 2016 10:54:29 +0200 Subject: [PATCH 20/42] Add E0500 error explanation --- src/librustc_borrowck/diagnostics.rs | 48 +++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index 8d9b88e899be2..2c38bc36dc3d4 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -378,6 +378,53 @@ let c = &i; // still ok! ``` "##, +E0500: r##" +A borrowed variable was used in another closure. Example of erroneous code: + +```compile_fail +fn you_know_nothing(jon_snow: &mut i32) { + let nights_watch = || { + *jon_snow = 2; + }; + let starks = || { + *jon_snow = 3; // error: closure requires unique access to `jon_snow` + // but it is already borrowed + }; +} + +In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it +cannot be borrowed by the `starks` closure at the same time. To fix this issue, +you can put the closure in its own scope: + +``` +fn you_know_nothing(jon_snow: &mut i32) { + { + let nights_watch = || { + *jon_snow = 2; + }; + } // At this point, `jon_snow` is free. + let starks = || { + *jon_snow = 3; + }; +} +``` + +Or, if the type implements the `Clone` trait, you can clone it between +closures: + +``` +fn you_know_nothing(jon_snow: &mut i32) { + let mut jon_copy = jon_snow.clone(); + let nights_watch = || { + jon_copy = 2; + }; + let starks = || { + *jon_snow = 3; + }; +} +``` +"##, + E0501: r##" This error indicates that a mutable variable is being used while it is still captured by a closure. Because the closure has borrowed the variable, it is not @@ -753,7 +800,6 @@ fn main() { register_diagnostics! { E0385, // {} in an aliasable location E0388, // {} in a static location - E0500, // closure requires unique access to `..` but .. is already borrowed E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ... E0503, // cannot use `..` because it was mutably borrowed E0504, // cannot move `..` into closure because it is borrowed From 8d65591cf249a64bffa14ed49cb196af4eabac3c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 29 Apr 2016 10:39:28 -0700 Subject: [PATCH 21/42] rustbuild: Tighten dependencies of build scripts Ensure that `rerun-if-changed` is printed for all build scripts to ensure that they've all got the right list of dependencies. --- src/liballoc_jemalloc/build.rs | 16 ++++++++++++++++ src/libcore/build.rs | 3 +++ src/libstd/build.rs | 16 +++++++++++++--- src/rustc/libc_shim/build.rs | 3 +++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index 5d521913b48f3..33a675331ab9d 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + extern crate build_helper; extern crate gcc; @@ -18,6 +20,7 @@ use build_helper::run; fn main() { println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); @@ -40,6 +43,19 @@ fn main() { let cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) .collect::>().join(" "); + let mut stack = src_dir.join("../jemalloc") + .read_dir().unwrap() + .map(|e| e.unwrap()) + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } + } + let mut cmd = Command::new("sh"); cmd.arg(src_dir.join("../jemalloc/configure").to_str().unwrap() .replace("C:\\", "/c/") diff --git a/src/libcore/build.rs b/src/libcore/build.rs index a991ac0de1af1..255a367e58b45 100644 --- a/src/libcore/build.rs +++ b/src/libcore/build.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + fn main() { // Remove this whenever snapshots and rustbuild nightlies are synced. println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs") } diff --git a/src/libstd/build.rs b/src/libstd/build.rs index e879d440643f9..ff9dacbb6799b 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + extern crate gcc; extern crate build_helper; use std::env; -use std::fs; use std::path::PathBuf; use std::process::Command; @@ -20,6 +21,7 @@ use build_helper::run; fn main() { println!("cargo:rustc-cfg=cargobuild"); + println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").unwrap(); let host = env::var("HOST").unwrap(); @@ -65,8 +67,16 @@ fn build_libbacktrace(host: &str, target: &str) { println!("cargo:rustc-link-lib=static=backtrace"); println!("cargo:rustc-link-search=native={}/.libs", build_dir.display()); - if fs::metadata(&build_dir.join(".libs/libbacktrace.a")).is_ok() { - return + let mut stack = src_dir.read_dir().unwrap() + .map(|e| e.unwrap()) + .collect::>(); + while let Some(entry) = stack.pop() { + let path = entry.path(); + if entry.file_type().unwrap().is_dir() { + stack.extend(path.read_dir().unwrap().map(|e| e.unwrap())); + } else { + println!("cargo:rerun-if-changed={}", path.display()); + } } let compiler = gcc::Config::new().get_compiler(); diff --git a/src/rustc/libc_shim/build.rs b/src/rustc/libc_shim/build.rs index bc428d6908235..546f60482e7bc 100644 --- a/src/rustc/libc_shim/build.rs +++ b/src/rustc/libc_shim/build.rs @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(warnings)] + // See comments in Cargo.toml for why this exists fn main() { println!("cargo:rustc-cfg=stdbuild"); + println!("cargo:rerun-if-changed=build.rs"); } From 5511e6568f41b7ca9d57b0055c193be187e437d8 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 10 May 2016 15:43:51 +0200 Subject: [PATCH 22/42] Hand ownership of the Definitions to map_crate. --- src/librustc/hir/map/mod.rs | 6 +++--- src/librustc_driver/driver.rs | 1 - src/librustc_driver/test.rs | 2 -- src/librustdoc/core.rs | 1 - src/librustdoc/test.rs | 2 +- src/test/run-make/execution-engine/test.rs | 2 -- 6 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 92f8c9249c842..f0eb580cfd57e 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -196,7 +196,7 @@ pub struct Map<'ast> { /// plain old integers. map: RefCell>>, - definitions: &'ast RefCell, + definitions: RefCell, } impl<'ast> Map<'ast> { @@ -790,7 +790,7 @@ pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { } pub fn map_crate<'ast>(forest: &'ast mut Forest, - definitions: &'ast RefCell) + definitions: Definitions) -> Map<'ast> { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); @@ -816,7 +816,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest, forest: forest, dep_graph: forest.dep_graph.clone(), map: RefCell::new(map), - definitions: definitions, + definitions: RefCell::new(definitions), } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 3f9fa0a23c2d8..a979410ca94de 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -165,7 +165,6 @@ pub fn compile_input(sess: &Session, syntax::ext::mtwt::clear_tables(); } - let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); // Construct the HIR map diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 59713c66afcb6..270376bda766e 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -29,7 +29,6 @@ use rustc_metadata::cstore::CStore; use rustc_metadata::creader::LocalCrateReader; use rustc::hir::map as hir_map; use rustc::session::{self, config}; -use std::cell::RefCell; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -129,7 +128,6 @@ fn test_env(source_string: &str, MakeGlobMap::No) }; - let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); let ast_map = hir_map::map_crate(&mut hir_forest, defs); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 857a1176f496a..e5919a4b35ff6 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -162,7 +162,6 @@ pub fn run_core(search_paths: SearchPaths, resolve::MakeGlobMap::No) }; - let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); let hir_map = hir_map::map_crate(&mut hir_forest, defs); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index fc548924e2964..c57452b6e2fc3 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -95,7 +95,7 @@ pub fn run(input: &str, .expect("phase_2_configure_and_expand aborted in rustdoc!"); let krate = driver::assign_node_ids(&sess, krate); let dep_graph = DepGraph::new(false); - let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + let defs = hir_map::collect_definitions(&krate); let mut dummy_resolver = DummyResolver; let lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 0d10f31556644..a2893fa2f0dc0 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -20,7 +20,6 @@ extern crate rustc_metadata; extern crate rustc_resolve; #[macro_use] extern crate syntax; -use std::cell::RefCell; use std::ffi::{CStr, CString}; use std::mem::transmute; use std::path::PathBuf; @@ -246,7 +245,6 @@ fn compile_program(input: &str, sysroot: PathBuf) driver::lower_and_resolve(&sess, &id, &mut defs, &krate, dep_graph, MakeGlobMap::No) }; - let defs = &RefCell::new(defs); let arenas = ty::CtxtArenas::new(); let ast_map = ast_map::map_crate(&mut hir_forest, defs); From c0e321abcbc25c47e55a808628fb7e65b3fe0f98 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 10 May 2016 15:52:33 +0200 Subject: [PATCH 23/42] Make LocalCrateReader private to creader. --- src/librustc_driver/driver.rs | 5 ++-- src/librustc_driver/test.rs | 4 ++-- src/librustc_metadata/creader.rs | 27 +++++++++++++++------- src/librustdoc/core.rs | 4 ++-- src/test/run-make/execution-engine/test.rs | 4 ++-- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index a979410ca94de..d2a5e12009ec4 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -28,7 +28,7 @@ use rustc_borrowck as borrowck; use rustc_incremental; use rustc_resolve as resolve; use rustc_metadata::macro_import; -use rustc_metadata::creader::LocalCrateReader; +use rustc_metadata::creader::read_local_crates; use rustc_metadata::cstore::CStore; use rustc_trans::back::link; use rustc_trans::back::write; @@ -148,8 +148,7 @@ pub fn compile_input(sess: &Session, time(sess.time_passes(), "external crate/lib resolution", - || LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id) - .read_crates(&dep_graph)); + || read_local_crates(sess, &cstore, &defs, &expanded_crate, &id, &dep_graph)); time(sess.time_passes(), "early lint checks", diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 270376bda766e..5c62d236844ee 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -26,7 +26,7 @@ use rustc::traits::ProjectionMode; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc_metadata::cstore::CStore; -use rustc_metadata::creader::LocalCrateReader; +use rustc_metadata::creader::read_local_crates; use rustc::hir::map as hir_map; use rustc::session::{self, config}; use std::rc::Rc; @@ -120,7 +120,7 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let krate = driver::assign_node_ids(&sess, krate); let mut defs = hir_map::collect_definitions(&krate); - LocalCrateReader::new(&sess, &cstore, &defs, &krate, "test_crate").read_crates(&dep_graph); + read_local_crates(&sess, &cstore, &defs, &krate, "test_crate", &dep_graph); let _ignore = dep_graph.in_ignore(); let (_, resolutions, mut hir_forest) = { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 62c208dbcb2a4..63c6af704bbfe 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -41,7 +41,7 @@ use syntax::parse::token::InternedString; use syntax::visit; use log; -pub struct LocalCrateReader<'a> { +struct LocalCrateReader<'a> { sess: &'a Session, cstore: &'a CStore, creader: CrateReader<'a>, @@ -841,12 +841,12 @@ impl<'a> CrateReader<'a> { } impl<'a> LocalCrateReader<'a> { - pub fn new(sess: &'a Session, - cstore: &'a CStore, - defs: &'a hir_map::Definitions, - krate: &'a ast::Crate, - local_crate_name: &str) - -> LocalCrateReader<'a> { + fn new(sess: &'a Session, + cstore: &'a CStore, + defs: &'a hir_map::Definitions, + krate: &'a ast::Crate, + local_crate_name: &str) + -> LocalCrateReader<'a> { LocalCrateReader { sess: sess, cstore: cstore, @@ -859,7 +859,7 @@ impl<'a> LocalCrateReader<'a> { // Traverses an AST, reading all the information about use'd crates and // extern libraries necessary for later resolving, typechecking, linking, // etc. - pub fn read_crates(&mut self, dep_graph: &DepGraph) { + fn read_crates(&mut self, dep_graph: &DepGraph) { let _task = dep_graph.in_task(DepNode::CrateReader); self.process_crate(self.krate); @@ -981,6 +981,17 @@ impl<'a> LocalCrateReader<'a> { } } +/// Traverses an AST, reading all the information about use'd crates and extern +/// libraries necessary for later resolving, typechecking, linking, etc. +pub fn read_local_crates(sess: & Session, + cstore: & CStore, + defs: & hir_map::Definitions, + krate: & ast::Crate, + local_crate_name: &str, + dep_graph: &DepGraph) { + LocalCrateReader::new(sess, cstore, defs, krate, local_crate_name).read_crates(dep_graph) +} + /// Imports the codemap from an external crate into the codemap of the crate /// currently being compiled (the "local crate"). /// diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e5919a4b35ff6..67eb268af08f6 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -21,7 +21,7 @@ use rustc::lint; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; -use rustc_metadata::creader::LocalCrateReader; +use rustc_metadata::creader::read_local_crates; use syntax::{ast, codemap, errors}; use syntax::errors::emitter::ColorConfig; @@ -154,7 +154,7 @@ pub fn run_core(search_paths: SearchPaths, let dep_graph = DepGraph::new(false); let mut defs = hir_map::collect_definitions(&krate); - LocalCrateReader::new(&sess, &cstore, &defs, &krate, &name).read_crates(&dep_graph); + read_local_crates(&sess, &cstore, &defs, &krate, &name, &dep_graph); // Lower ast -> hir and resolve. let (analysis, resolutions, mut hir_forest) = { diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index a2893fa2f0dc0..0ad113b8d8b38 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -34,7 +34,7 @@ use rustc::session::config::{self, basic_options, build_configuration, Input, Op use rustc::session::build_session; use rustc_driver::{driver, abort_on_err}; use rustc_resolve::MakeGlobMap; -use rustc_metadata::creader::LocalCrateReader; +use rustc_metadata::creader::read_local_crates; use rustc_metadata::cstore::CStore; use libc::c_void; @@ -240,7 +240,7 @@ fn compile_program(input: &str, sysroot: PathBuf) let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); let krate = driver::assign_node_ids(&sess, krate); let mut defs = ast_map::collect_definitions(&krate); - LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph); + read_local_crates(&sess, &cstore, &defs, &krate, &id, &dep_graph); let (analysis, resolutions, mut hir_forest) = { driver::lower_and_resolve(&sess, &id, &mut defs, &krate, dep_graph, MakeGlobMap::No) }; From 00f6513259c12af733d22398b1ea77cff67b7beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 10 May 2016 21:03:47 +0200 Subject: [PATCH 24/42] Only break critical edges where actually needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, to prepare for MIR trans, we break _all_ critical edges, although we only actually need to do this for edges originating from a call that gets translated to an invoke instruction in LLVM. This has the unfortunate effect of undoing a bunch of the things that SimplifyCfg has done. A particularly bad case arises when you have a C-like enum with N variants and a derived PartialEq implementation. In that case, the match on the (&lhs, &rhs) tuple gets translated into nested matches with N arms each and a basic block each, resulting in N² basic blocks. SimplifyCfg reduces that to roughly 2*N basic blocks, but breaking the critical edges means that we go back to N². In nickel.rs, there is such an enum with roughly N=800. So we get about 640K basic blocks or 2.5M lines of LLVM IR. LLVM takes a while to reduce that to the final "disr_a == disr_b". So before this patch, we had 2.5M lines of IR with 640K basic blocks, which took about about 3.6s in LLVM to get optimized and translated. After this patch, we get about 650K lines with about 1.6K basic blocks and spent a little less than 0.2s in LLVM. cc #33111 --- src/librustc_driver/driver.rs | 2 +- .../transform/break_cleanup_edges.rs | 111 +++++++++++++++++ .../transform/break_critical_edges.rs | 117 ------------------ src/librustc_mir/transform/mod.rs | 2 +- 4 files changed, 113 insertions(+), 119 deletions(-) create mode 100644 src/librustc_mir/transform/break_cleanup_edges.rs delete mode 100644 src/librustc_mir/transform/break_critical_edges.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f0c2de2932775..519329a10d0a9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1009,7 +1009,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads); passes.push_pass(box mir::transform::remove_dead_blocks::RemoveDeadBlocks); passes.push_pass(box mir::transform::erase_regions::EraseRegions); - passes.push_pass(box mir::transform::break_critical_edges::BreakCriticalEdges); + passes.push_pass(box mir::transform::break_cleanup_edges::BreakCleanupEdges); passes.run_passes(tcx, &mut mir_map); }); diff --git a/src/librustc_mir/transform/break_cleanup_edges.rs b/src/librustc_mir/transform/break_cleanup_edges.rs new file mode 100644 index 0000000000000..0eb6223a71e54 --- /dev/null +++ b/src/librustc_mir/transform/break_cleanup_edges.rs @@ -0,0 +1,111 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::ty::TyCtxt; +use rustc::mir::repr::*; +use rustc::mir::transform::{MirPass, MirSource, Pass}; + +use rustc_data_structures::bitvec::BitVector; + +use pretty; + +use traversal; + +pub struct BreakCleanupEdges; + +/** + * Breaks outgoing critical edges for call terminators in the MIR. + * + * Critical edges are edges that are neither the only edge leaving a + * block, nor the only edge entering one. + * + * When you want something to happen "along" an edge, you can either + * do at the end of the predecessor block, or at the start of the + * successor block. Critical edges have to be broken in order to prevent + * "edge actions" from affecting other edges. We need this for calls that are + * translated to LLVM invoke instructions, because invoke is a block terminator + * in LLVM so we can't insert any code to handle the call's result into the + * block that performs the call. + * + * This function will break those edges by inserting new blocks along them. + * + * NOTE: Simplify CFG will happily undo most of the work this pass does. + * + */ + +impl<'tcx> MirPass<'tcx> for BreakCleanupEdges { + fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { + let mut pred_count = vec![0u32; mir.basic_blocks.len()]; + + // Build the precedecessor map for the MIR + for (_, data) in traversal::preorder(mir) { + if let Some(ref term) = data.terminator { + for &tgt in term.successors().iter() { + pred_count[tgt.index()] += 1; + } + } + } + + let cleanup_map : BitVector = mir.basic_blocks + .iter().map(|bb| bb.is_cleanup).collect(); + + // We need a place to store the new blocks generated + let mut new_blocks = Vec::new(); + + let bbs = mir.all_basic_blocks(); + let cur_len = mir.basic_blocks.len(); + + for &bb in &bbs { + let data = mir.basic_block_data_mut(bb); + + if let Some(ref mut term) = data.terminator { + if term_is_invoke(term) { + let term_span = term.span; + let term_scope = term.scope; + let succs = term.successors_mut(); + for tgt in succs { + let num_preds = pred_count[tgt.index()]; + if num_preds > 1 { + // It's a critical edge, break it + let goto = Terminator { + span: term_span, + scope: term_scope, + kind: TerminatorKind::Goto { target: *tgt } + }; + let mut data = BasicBlockData::new(Some(goto)); + data.is_cleanup = cleanup_map.contains(tgt.index()); + + // Get the index it will be when inserted into the MIR + let idx = cur_len + new_blocks.len(); + new_blocks.push(data); + *tgt = BasicBlock::new(idx); + } + } + } + } + } + + pretty::dump_mir(tcx, "break_cleanup_edges", &0, src, mir, None); + debug!("Broke {} N edges", new_blocks.len()); + + mir.basic_blocks.extend_from_slice(&new_blocks); + } +} + +impl Pass for BreakCleanupEdges {} + +// Returns true if the terminator is a call that would use an invoke in LLVM. +fn term_is_invoke(term: &Terminator) -> bool { + match term.kind { + TerminatorKind::Call { cleanup: Some(_), .. } | + TerminatorKind::Drop { unwind: Some(_), .. } => true, + _ => false + } +} diff --git a/src/librustc_mir/transform/break_critical_edges.rs b/src/librustc_mir/transform/break_critical_edges.rs deleted file mode 100644 index a6af30b7eec08..0000000000000 --- a/src/librustc_mir/transform/break_critical_edges.rs +++ /dev/null @@ -1,117 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use rustc::ty::TyCtxt; -use rustc::mir::repr::*; -use rustc::mir::transform::{MirPass, MirSource, Pass}; - -use rustc_data_structures::bitvec::BitVector; - -use traversal; - -pub struct BreakCriticalEdges; - -/** - * Breaks critical edges in the MIR. - * - * Critical edges are edges that are neither the only edge leaving a - * block, nor the only edge entering one. - * - * When you want something to happen "along" an edge, you can either - * do at the end of the predecessor block, or at the start of the - * successor block. Critical edges have to be broken in order to prevent - * "edge actions" from affecting other edges. - * - * This function will break those edges by inserting new blocks along them. - * - * A special case is Drop and Call terminators with unwind/cleanup successors, - * They use `invoke` in LLVM, which terminates a block, meaning that code cannot - * be inserted after them, so even if an edge is the only edge leaving a block - * like that, we still insert blocks if the edge is one of many entering the - * target. - * - * NOTE: Simplify CFG will happily undo most of the work this pass does. - * - */ - -impl<'tcx> MirPass<'tcx> for BreakCriticalEdges { - fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, mir: &mut Mir<'tcx>) { - break_critical_edges(mir); - } -} - -impl Pass for BreakCriticalEdges {} - -fn break_critical_edges(mir: &mut Mir) { - let mut pred_count = vec![0u32; mir.basic_blocks.len()]; - - // Build the precedecessor map for the MIR - for (_, data) in traversal::preorder(mir) { - if let Some(ref term) = data.terminator { - for &tgt in term.successors().iter() { - pred_count[tgt.index()] += 1; - } - } - } - - let cleanup_map : BitVector = mir.basic_blocks - .iter().map(|bb| bb.is_cleanup).collect(); - - // We need a place to store the new blocks generated - let mut new_blocks = Vec::new(); - - let bbs = mir.all_basic_blocks(); - let cur_len = mir.basic_blocks.len(); - - for &bb in &bbs { - let data = mir.basic_block_data_mut(bb); - - if let Some(ref mut term) = data.terminator { - let is_invoke = term_is_invoke(term); - let term_span = term.span; - let term_scope = term.scope; - let succs = term.successors_mut(); - if succs.len() > 1 || (succs.len() > 0 && is_invoke) { - for tgt in succs { - let num_preds = pred_count[tgt.index()]; - if num_preds > 1 { - // It's a critical edge, break it - let goto = Terminator { - span: term_span, - scope: term_scope, - kind: TerminatorKind::Goto { target: *tgt } - }; - let mut data = BasicBlockData::new(Some(goto)); - data.is_cleanup = cleanup_map.contains(tgt.index()); - - // Get the index it will be when inserted into the MIR - let idx = cur_len + new_blocks.len(); - new_blocks.push(data); - *tgt = BasicBlock::new(idx); - } - } - } - } - } - - debug!("Broke {} N edges", new_blocks.len()); - - mir.basic_blocks.extend_from_slice(&new_blocks); -} - -// Returns true if the terminator would use an invoke in LLVM. -fn term_is_invoke(term: &Terminator) -> bool { - match term.kind { - TerminatorKind::Call { cleanup: Some(_), .. } | - TerminatorKind::Drop { unwind: Some(_), .. } => true, - _ => false - } -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 51f5c3cd7f53d..0dcb7ef84d01d 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -13,6 +13,6 @@ pub mod simplify_cfg; pub mod erase_regions; pub mod no_landing_pads; pub mod type_check; -pub mod break_critical_edges; +pub mod break_cleanup_edges; pub mod promote_consts; pub mod qualify_consts; From 1ebb07ee24ad70117e46a9e5f446c3964aa25dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 14 Nov 2015 23:52:17 +0100 Subject: [PATCH 25/42] [MIR] Enhance the SimplifyCfg pass to merge consecutive blocks --- src/librustc_mir/transform/mod.rs | 1 + src/librustc_mir/transform/predecessor_map.rs | 68 +++++++ src/librustc_mir/transform/simplify_cfg.rs | 178 ++++++++++++------ 3 files changed, 188 insertions(+), 59 deletions(-) create mode 100644 src/librustc_mir/transform/predecessor_map.rs diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 51f5c3cd7f53d..cfa265918e727 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -12,6 +12,7 @@ pub mod remove_dead_blocks; pub mod simplify_cfg; pub mod erase_regions; pub mod no_landing_pads; +pub mod predecessor_map; pub mod type_check; pub mod break_critical_edges; pub mod promote_consts; diff --git a/src/librustc_mir/transform/predecessor_map.rs b/src/librustc_mir/transform/predecessor_map.rs new file mode 100644 index 0000000000000..cda75946095b4 --- /dev/null +++ b/src/librustc_mir/transform/predecessor_map.rs @@ -0,0 +1,68 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::mir::repr::*; +use rustc::mir::visit::Visitor; + +// A simple map to perform quick lookups of the predecessors of a BasicBlock. +// Since BasicBlocks usually only have a small number of predecessors, we use a +// simple vector. Also, if a block has the same target more than once, for +// example in a switch, it will appear in the target's predecessor list multiple +// times. This allows to update the map more easily when modifying the graph. +pub struct PredecessorMap { + map: Vec>, +} + +impl PredecessorMap { + pub fn from_mir(mir: &Mir) -> PredecessorMap { + let mut map = PredecessorMap { + map: vec![Vec::new(); mir.basic_blocks.len()], + }; + + PredecessorVisitor { predecessor_map: &mut map }.visit_mir(mir); + + map + } + + pub fn predecessors(&self, block: BasicBlock) -> &[BasicBlock] { + &self.map[block.index()] + } + + pub fn add_predecessor(&mut self, block: BasicBlock, predecessor: BasicBlock) { + self.map[block.index()].push(predecessor); + } + + pub fn remove_predecessor(&mut self, block: BasicBlock, predecessor: BasicBlock) { + let pos = self.map[block.index()].iter().position(|&p| p == predecessor).expect( + &format!("{:?} is not registered as a predecessor of {:?}", predecessor, block)); + + self.map[block.index()].swap_remove(pos); + } + + pub fn replace_predecessor(&mut self, block: BasicBlock, old: BasicBlock, new: BasicBlock) { + self.remove_predecessor(block, old); + self.add_predecessor(block, new); + } + + pub fn replace_successor(&mut self, block: BasicBlock, old: BasicBlock, new: BasicBlock) { + self.remove_predecessor(old, block); + self.add_predecessor(new, block); + } +} + +struct PredecessorVisitor<'a> { + predecessor_map: &'a mut PredecessorMap, +} + +impl<'a, 'tcx> Visitor<'tcx> for PredecessorVisitor<'a> { + fn visit_branch(&mut self, source: BasicBlock, target: BasicBlock) { + self.predecessor_map.add_predecessor(target, source); + } +} diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs index fa897384a542a..bb17bb006538f 100644 --- a/src/librustc_mir/transform/simplify_cfg.rs +++ b/src/librustc_mir/transform/simplify_cfg.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::TyCtxt; use rustc::mir::repr::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; use pretty; +use std::mem; +use super::predecessor_map::PredecessorMap; use super::remove_dead_blocks::RemoveDeadBlocks; pub struct SimplifyCfg; @@ -22,59 +25,133 @@ impl SimplifyCfg { pub fn new() -> SimplifyCfg { SimplifyCfg } +} + +impl<'tcx> MirPass<'tcx> for SimplifyCfg { + fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { + simplify_branches(mir); + RemoveDeadBlocks.run_pass(tcx, src, mir); + merge_consecutive_blocks(mir); + RemoveDeadBlocks.run_pass(tcx, src, mir); + pretty::dump_mir(tcx, "simplify_cfg", &0, src, mir, None); - fn remove_goto_chains(&self, mir: &mut Mir) -> bool { - // Find the target at the end of the jump chain, return None if there is a loop - fn final_target(mir: &Mir, mut target: BasicBlock) -> Option { - // Keep track of already seen blocks to detect loops - let mut seen: Vec = Vec::with_capacity(8); - - while mir.basic_block_data(target).statements.is_empty() { - // NB -- terminator may have been swapped with `None` - // below, in which case we have a cycle and just want - // to stop - if let Some(ref terminator) = mir.basic_block_data(target).terminator { - match terminator.kind { - TerminatorKind::Goto { target: next } => { - if seen.contains(&next) { - return None; + // FIXME: Should probably be moved into some kind of pass manager + mir.basic_blocks.shrink_to_fit(); + } +} + +impl Pass for SimplifyCfg {} + +fn merge_consecutive_blocks(mir: &mut Mir) { + let mut predecessor_map = PredecessorMap::from_mir(mir); + + loop { + let mut changed = false; + let mut seen = BitVector::new(mir.basic_blocks.len()); + let mut worklist = vec![START_BLOCK]; + while let Some(bb) = worklist.pop() { + // Temporarily take ownership of the terminator we're modifying to keep borrowck happy + let mut terminator = mir.basic_block_data_mut(bb).terminator.take() + .expect("invalid terminator state"); + + // See if we can merge the target block into this one + loop { + let mut inner_change = false; + + if let TerminatorKind::Goto { target } = terminator.kind { + // Don't bother trying to merge a block into itself + if target == bb { + break; + } + + let num_preds = predecessor_map.predecessors(target).len(); + let num_insts = mir.basic_block_data(target).statements.len(); + match mir.basic_block_data(target).terminator().kind { + _ if num_preds == 1 => { + inner_change = true; + let mut stmts = Vec::new(); + { + let target_data = mir.basic_block_data_mut(target); + mem::swap(&mut stmts, &mut target_data.statements); + mem::swap(&mut terminator, target_data.terminator_mut()); + } + + mir.basic_block_data_mut(bb).statements.append(&mut stmts); + + predecessor_map.replace_predecessor(target, bb, target); + for succ in terminator.successors().iter() { + predecessor_map.replace_predecessor(*succ, target, bb); } - seen.push(next); - target = next; } - _ => break + TerminatorKind::Goto { target: new_target } if num_insts == 0 => { + inner_change = true; + terminator.kind = TerminatorKind::Goto { target: new_target }; + predecessor_map.replace_successor(bb, target, new_target); + } + _ => {} + }; + } + + for target in terminator.successors_mut() { + let new_target = match final_target(mir, *target) { + Some(new_target) => new_target, + None if mir.basic_block_data(bb).statements.is_empty() => bb, + None => continue + }; + if *target != new_target { + inner_change = true; + predecessor_map.replace_successor(bb, *target, new_target); + *target = new_target; } - } else { - break + } + + changed |= inner_change; + if !inner_change { + break; } } - Some(target) + mir.basic_block_data_mut(bb).terminator = Some(terminator); + + for succ in mir.basic_block_data(bb).terminator().successors().iter() { + if seen.insert(succ.index()) { + worklist.push(*succ); + } + } } - let mut changed = false; - for bb in mir.all_basic_blocks() { - // Temporarily take ownership of the terminator we're modifying to keep borrowck happy - let mut terminator = mir.basic_block_data_mut(bb).terminator.take() - .expect("invalid terminator state"); - - debug!("remove_goto_chains: bb={:?} terminator={:?}", bb, terminator); - - for target in terminator.successors_mut() { - let new_target = match final_target(mir, *target) { - Some(new_target) => new_target, - None if mir.basic_block_data(bb).statements.is_empty() => bb, - None => continue - }; - changed |= *target != new_target; - *target = new_target; + if !changed { + break; + } + } +} + +// Find the target at the end of the jump chain, return None if there is a loop +fn final_target(mir: &Mir, mut target: BasicBlock) -> Option { + // Keep track of already seen blocks to detect loops + let mut seen: Vec = Vec::with_capacity(8); + + while mir.basic_block_data(target).statements.is_empty() { + // NB -- terminator may have been swapped with `None` in + // merge_consecutive_blocks, in which case we have a cycle and just want + // to stop + match mir.basic_block_data(target).terminator { + Some(Terminator { kind: TerminatorKind::Goto { target: next }, .. }) => { + if seen.contains(&next) { + return None; + } + seen.push(next); + target = next; } - mir.basic_block_data_mut(bb).terminator = Some(terminator); + _ => break } - changed } - fn simplify_branches(&self, mir: &mut Mir) -> bool { + Some(target) +} + +fn simplify_branches(mir: &mut Mir) { + loop { let mut changed = false; for bb in mir.all_basic_blocks() { @@ -106,25 +183,8 @@ impl SimplifyCfg { } } - changed - } -} - -impl<'tcx> MirPass<'tcx> for SimplifyCfg { - fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, mir: &mut Mir<'tcx>) { - let mut counter = 0; - let mut changed = true; - while changed { - pretty::dump_mir(tcx, "simplify_cfg", &counter, src, mir, None); - counter += 1; - changed = self.simplify_branches(mir); - changed |= self.remove_goto_chains(mir); - RemoveDeadBlocks.run_pass(tcx, src, mir); + if !changed { + break; } - // FIXME: Should probably be moved into some kind of pass manager - mir.basic_blocks.shrink_to_fit(); } } - -impl Pass for SimplifyCfg {} From 5541fdfcd1b94294fcd7d356c2948bb272d20b9f Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 11 May 2016 20:09:50 +0300 Subject: [PATCH 26/42] Use symlink_metadata in tidy to avoid panicking on broken symlinks. --- src/tools/tidy/src/bins.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 43475f203d57c..e91b8fb0967a8 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -35,7 +35,7 @@ pub fn check(path: &Path, bad: &mut bool) { return } - let metadata = t!(fs::metadata(&file), &file); + let metadata = t!(fs::symlink_metadata(&file), &file); if metadata.mode() & 0o111 != 0 { println!("binary checked into source: {}", file.display()); *bad = true; From 4e5a2e01cf7fd13dccac12deaf7868f3855e54c5 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Tue, 10 May 2016 23:25:34 -0700 Subject: [PATCH 27/42] Remove unification despite ambiguity in projection --- src/librustc/traits/project.rs | 58 +--------------------------------- 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 4c338219ffbf7..a67188713c628 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -218,10 +218,7 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>( obligation.cause.clone(), obligation.recursion_depth) { Some(n) => n, - None => { - consider_unification_despite_ambiguity(selcx, obligation); - return Ok(None); - } + None => return Ok(None), }; debug!("project_and_unify_type: normalized_ty={:?} obligations={:?}", @@ -240,59 +237,6 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>( } } -fn consider_unification_despite_ambiguity<'cx, 'gcx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, - obligation: &ProjectionObligation<'tcx>) -{ - debug!("consider_unification_despite_ambiguity(obligation={:?})", - obligation); - - let def_id = obligation.predicate.projection_ty.trait_ref.def_id; - match selcx.tcx().lang_items.fn_trait_kind(def_id) { - Some(_) => { } - None => { return; } - } - - let infcx = selcx.infcx(); - let self_ty = obligation.predicate.projection_ty.trait_ref.self_ty(); - let self_ty = infcx.shallow_resolve(self_ty); - debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}", - self_ty.sty); - match self_ty.sty { - ty::TyClosure(closure_def_id, substs) => { - let closure_typer = selcx.closure_typer(); - let closure_type = closure_typer.closure_type(closure_def_id, substs); - let ty::Binder((_, ret_type)) = - infcx.tcx.closure_trait_ref_and_return_type(def_id, - self_ty, - &closure_type.sig, - util::TupleArgumentsFlag::No); - // We don't have to normalize the return type here - this is only - // reached for TyClosure: Fn inputs where the closure kind is - // still unknown, which should only occur in typeck where the - // closure type is already normalized. - let (ret_type, _) = - infcx.replace_late_bound_regions_with_fresh_var( - obligation.cause.span, - infer::AssocTypeProjection(obligation.predicate.projection_ty.item_name), - &ty::Binder(ret_type)); - - debug!("consider_unification_despite_ambiguity: ret_type={:?}", - ret_type); - let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); - let obligation_ty = obligation.predicate.ty; - match infcx.eq_types(true, origin, obligation_ty, ret_type) { - Ok(InferOk { obligations, .. }) => { - // FIXME(#32730) propagate obligations - assert!(obligations.is_empty()); - } - Err(_) => { /* ignore errors */ } - } - } - _ => { } - } -} - /// Normalizes any associated type projections in `value`, replacing /// them with a fully resolved type where possible. The return value /// combines the normalized result and any additional obligations that From c91b1048847663fabf99cd48dd1d9bb1644bcd77 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 11 May 2016 20:30:20 +0100 Subject: [PATCH 28/42] Export OnceState from libstd --- src/libstd/sync/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index c20b422d40cf5..21008ee3989a7 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -31,7 +31,7 @@ pub use self::mutex::MUTEX_INIT; #[stable(feature = "rust1", since = "1.0.0")] pub use self::mutex::{Mutex, MutexGuard, StaticMutex}; #[stable(feature = "rust1", since = "1.0.0")] -pub use self::once::{Once, ONCE_INIT}; +pub use self::once::{Once, OnceState, ONCE_INIT}; #[stable(feature = "rust1", since = "1.0.0")] pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult}; #[stable(feature = "rust1", since = "1.0.0")] From 5cbfa1285d7f3e6f93a5cd204ef9efbaefe222ed Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 11 May 2016 20:42:26 +0100 Subject: [PATCH 29/42] Fix typo in std::sync::Once documentation --- src/libstd/sync/once.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index e228d236a3ca7..d8a4a69c73cd3 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -218,7 +218,6 @@ impl Once { /// The closure `f` is yielded a structure which can be used to query the /// state of this `Once` (whether initialization has previously panicked or /// not). - /// poisoned or not. #[unstable(feature = "once_poison", issue = "31688")] pub fn call_once_force(&'static self, f: F) where F: FnOnce(&OnceState) { // same as above, just with a different parameter to `call_inner`. From 49b2cdf47c983d5ea8a576346d08120f0e3af30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 11 May 2016 21:31:19 +0200 Subject: [PATCH 30/42] [MIR trans] Optimize trans for biased switches Currently, all switches in MIR are exhausitive, meaning that we can have a lot of arms that all go to the same basic block, the extreme case being an if-let expression which results in just 2 possible cases, be might end up with hundreds of arms for large enums. To improve this situation and give LLVM less code to chew on, we can detect whether there's a pre-dominant target basic block in a switch and then promote this to be the default target, not translating the corresponding arms at all. In combination with #33544 this makes unoptimized MIR trans of nickel.rs as fast as using old trans and greatly improves the times for optimized builds, which are only 30-40% slower instead of ~300%. cc #33111 --- src/librustc_trans/mir/block.rs | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index e1318396e317d..4e3386bc73677 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -24,6 +24,7 @@ use meth; use type_of; use glue; use type_::Type; +use rustc_data_structures::fnv::FnvHashMap; use super::{MirContext, TempRef, drop}; use super::constant::Const; @@ -95,17 +96,32 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { adt::trans_get_discr(bcx, &repr, discr_lvalue.llval, None, true) ); - // The else branch of the Switch can't be hit, so branch to an unreachable - // instruction so LLVM knows that - let unreachable_blk = self.unreachable_block(); - let switch = bcx.switch(discr, unreachable_blk.llbb, targets.len()); + let mut bb_hist = FnvHashMap(); + for target in targets { + *bb_hist.entry(target).or_insert(0) += 1; + } + let (default_bb, default_blk) = match bb_hist.iter().max_by_key(|&(_, c)| c) { + // If a single target basic blocks is predominant, promote that to be the + // default case for the switch instruction to reduce the size of the generated + // code. This is especially helpful in cases like an if-let on a huge enum. + // Note: This optimization is only valid for exhaustive matches. + Some((&&bb, &c)) if c > targets.len() / 2 => { + (Some(bb), self.blocks[bb.index()]) + } + // We're generating an exhaustive switch, so the else branch + // can't be hit. Branching to an unreachable instruction + // lets LLVM know this + _ => (None, self.unreachable_block()) + }; + let switch = bcx.switch(discr, default_blk.llbb, targets.len()); assert_eq!(adt_def.variants.len(), targets.len()); - for (adt_variant, target) in adt_def.variants.iter().zip(targets) { - let llval = bcx.with_block(|bcx| - adt::trans_case(bcx, &repr, Disr::from(adt_variant.disr_val)) - ); - let llbb = self.llblock(*target); - build::AddCase(switch, llval, llbb) + for (adt_variant, &target) in adt_def.variants.iter().zip(targets) { + if default_bb != Some(target) { + let llbb = self.llblock(target); + let llval = bcx.with_block(|bcx| adt::trans_case( + bcx, &repr, Disr::from(adt_variant.disr_val))); + build::AddCase(switch, llval, llbb) + } } } From fd70788e6d0439098ce31d75eda265721e8d3322 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 11 May 2016 22:45:49 +0300 Subject: [PATCH 31/42] Do not use const Rib for associated constants --- src/librustc_resolve/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fc048c86dc9dd..094348a000a93 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1949,9 +1949,7 @@ impl<'a> Resolver<'a> { this.check_trait_item(impl_item.ident.name, impl_item.span, |n, s| ResolutionError::ConstNotMemberOfTrait(n, s)); - this.with_constant_rib(|this| { - visit::walk_impl_item(this, impl_item); - }); + visit::walk_impl_item(this, impl_item); } ImplItemKind::Method(ref sig, _) => { // If this is a trait impl, ensure the method From 5af829b0d0fba866afa28607f5c97542c7d04d5c Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 12 May 2016 00:30:08 +0300 Subject: [PATCH 32/42] Gen right parameter envirnoment for assoc consts --- src/librustc/ty/mod.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 005d83da38dbf..114e81721ab28 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1260,7 +1260,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { match tcx.map.find(id) { Some(ast_map::NodeImplItem(ref impl_item)) => { match impl_item.node { - hir::ImplItemKind::Type(_) => { + hir::ImplItemKind::Type(_) | hir::ImplItemKind::Const(_, _) => { // associated types don't have their own entry (for some reason), // so for now just grab environment for the impl let impl_id = tcx.map.get_parent(id); @@ -1272,15 +1272,6 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { &predicates, tcx.region_maps.item_extent(id)) } - hir::ImplItemKind::Const(_, _) => { - let def_id = tcx.map.local_def_id(id); - let scheme = tcx.lookup_item_type(def_id); - let predicates = tcx.lookup_predicates(def_id); - tcx.construct_parameter_environment(impl_item.span, - &scheme.generics, - &predicates, - tcx.region_maps.item_extent(id)) - } hir::ImplItemKind::Method(_, ref body) => { let method_def_id = tcx.map.local_def_id(id); match tcx.impl_or_trait_item(method_def_id) { @@ -1303,7 +1294,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } Some(ast_map::NodeTraitItem(trait_item)) => { match trait_item.node { - hir::TypeTraitItem(..) => { + hir::TypeTraitItem(..) | hir::ConstTraitItem(..) => { // associated types don't have their own entry (for some reason), // so for now just grab environment for the trait let trait_id = tcx.map.get_parent(id); @@ -1315,15 +1306,6 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { &predicates, tcx.region_maps.item_extent(id)) } - hir::ConstTraitItem(..) => { - let def_id = tcx.map.local_def_id(id); - let scheme = tcx.lookup_item_type(def_id); - let predicates = tcx.lookup_predicates(def_id); - tcx.construct_parameter_environment(trait_item.span, - &scheme.generics, - &predicates, - tcx.region_maps.item_extent(id)) - } hir::MethodTraitItem(_, ref body) => { // Use call-site for extent (unless this is a // trait method with no default; then fallback From d3218fae7b5a4a0ba9b02903dc12d36ff94a1388 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 12 May 2016 00:48:47 +0300 Subject: [PATCH 33/42] =?UTF-8?q?Check=20the=20constants=E2=80=99=20parame?= =?UTF-8?q?ter=20environment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/librustc_typeck/check/mod.rs | 3 ++- .../associated-const-outer-ty-refs.rs | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/associated-const-outer-ty-refs.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f428023da9b82..648d1f94e6215 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1151,7 +1151,8 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, sp: Span, e: &'tcx hir::Expr, id: ast::NodeId) { - ccx.inherited(None).enter(|inh| { + let param_env = ParameterEnvironment::for_item(ccx.tcx, id); + ccx.inherited(Some(param_env)).enter(|inh| { let rty = ccx.tcx.node_id_to_type(id); let fcx = FnCtxt::new(&inh, ty::FnConverging(rty), e.id); let declty = fcx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(id)).ty; diff --git a/src/test/run-pass/associated-const-outer-ty-refs.rs b/src/test/run-pass/associated-const-outer-ty-refs.rs new file mode 100644 index 0000000000000..a603b225132d4 --- /dev/null +++ b/src/test/run-pass/associated-const-outer-ty-refs.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(associated_consts)] + +trait Lattice { + const BOTTOM: Self; +} + +// FIXME(#33573): this should work without the 'static lifetime bound. +impl Lattice for Option { + const BOTTOM: Option = None; +} + +fn main(){} From 6458b0454f66f9cf16a4b50b8e0874b950326ef3 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 12 May 2016 00:05:25 -0400 Subject: [PATCH 34/42] Cleanup formatting and wording for `std::env::temp_dir` docs. --- src/libstd/env.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 9dc6a26cdeed3..6956dc0d901a4 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -452,16 +452,16 @@ pub fn home_dir() -> Option { /// Returns the path of a temporary directory. /// -/// On Unix, returns the value of the 'TMPDIR' environment variable if it is -/// set, otherwise for non-Android it returns '/tmp'. If Android, since there -/// is no global temporary folder (it is usually allocated per-app), we return -/// '/data/local/tmp'. -/// -/// On Windows, returns the value of, in order, the 'TMP', 'TEMP', -/// 'USERPROFILE' environment variable if any are set and not the empty -/// string. Otherwise, tmpdir returns the path of the Windows directory. This -/// behavior is identical to that of [GetTempPath][msdn], which this function -/// uses internally. +/// On Unix, returns the value of the `TMPDIR` environment variable if it is +/// set, otherwise for non-Android it returns `/tmp`. If Android, since there +/// is no global temporary folder (it is usually allocated per-app), it returns +/// `/data/local/tmp`. +/// +/// On Windows, returns the value of, in order, the `TMP`, `TEMP`, +/// `USERPROFILE` environment variable if any are set and not the empty +/// string. Otherwise, `temp_dir` returns the path of the Windows directory. +/// This behavior is identical to that of [`GetTempPath`][msdn], which this +/// function uses internally. /// /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx /// From a7902b12e8045c1781c71e171f715344c38b6c01 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Thu, 12 May 2016 13:42:57 +0900 Subject: [PATCH 35/42] Tighten span for E0063 --- src/librustc_typeck/check/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f428023da9b82..1afc6e1e33edf 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3299,7 +3299,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expr_ty = self.instantiate_type(def.def_id(), path); self.write_ty(expr.id, expr_ty); - self.check_expr_struct_fields(expr_ty, expr.span, variant, fields, + self.check_expr_struct_fields(expr_ty, path.span, variant, fields, base_expr.is_none()); if let &Some(ref base_expr) = base_expr { self.check_expr_has_type(base_expr, expr_ty); From 843b174e93b253824a62fba3ac4be2753e30c9c2 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Mon, 2 May 2016 14:52:48 +0200 Subject: [PATCH 36/42] typeck: if a private field exists, also check for a public method For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten. Fixes: #26472 --- src/librustc_typeck/check/method/mod.rs | 5 +++-- src/librustc_typeck/check/mod.rs | 12 +++++++++--- src/test/compile-fail/issue-26472.rs | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/issue-26472.rs diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f27ae181f77e3..00eeefa0449ce 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -84,7 +84,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, method_name: ast::Name, self_ty: ty::Ty<'tcx>, - call_expr_id: ast::NodeId) + call_expr_id: ast::NodeId, + allow_private: bool) -> bool { let mode = probe::Mode::MethodCall; @@ -93,7 +94,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Err(NoMatch(..)) => false, Err(Ambiguity(..)) => true, Err(ClosureAmbiguity(..)) => true, - Err(PrivateMatch(..)) => true, + Err(PrivateMatch(..)) => allow_private, } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f428023da9b82..060075e6f0d90 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3045,12 +3045,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some((did, field_ty)) = private_candidate { let struct_path = self.tcx().item_path_str(did); - let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path); - self.tcx().sess.span_err(expr.span, &msg); self.write_ty(expr.id, field_ty); + let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path); + let mut err = self.tcx().sess.struct_span_err(expr.span, &msg); + // Also check if an accessible method exists, which is often what is meant. + if self.method_exists(field.span, field.node, expr_t, expr.id, false) { + err.note(&format!("a method `{}` also exists, perhaps you wish to call it", + field.node)); + } + err.emit(); } else if field.node == keywords::Invalid.name() { self.write_error(expr.id); - } else if self.method_exists(field.span, field.node, expr_t, expr.id) { + } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) { self.type_error_struct(field.span, |actual| { format!("attempted to take value of method `{}` on type \ `{}`", field.node, actual) diff --git a/src/test/compile-fail/issue-26472.rs b/src/test/compile-fail/issue-26472.rs new file mode 100644 index 0000000000000..0d59a897ef1af --- /dev/null +++ b/src/test/compile-fail/issue-26472.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod sub { + pub struct S { len: usize } + impl S { + pub fn new() -> S { S { len: 0 } } + pub fn len(&self) -> usize { self.len } + } +} + +fn main() { + let s = sub::S::new(); + let v = s.len; + //~^ ERROR field `len` of struct `sub::S` is private + //~| NOTE a method `len` also exists, perhaps you wish to call it +} From c3310327552163e2d19bea1f38287dab22d38028 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 9 May 2016 23:09:25 +0900 Subject: [PATCH 37/42] Better handling of tab in error --- src/libsyntax/errors/snippet/mod.rs | 10 ++++++++-- src/libsyntax/errors/snippet/test.rs | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/errors/snippet/mod.rs b/src/libsyntax/errors/snippet/mod.rs index 237e6823e0f87..0699c6f4ac2a9 100644 --- a/src/libsyntax/errors/snippet/mod.rs +++ b/src/libsyntax/errors/snippet/mod.rs @@ -312,9 +312,15 @@ impl StyledBuffer { self.text[line][col] = chr; self.styles[line][col] = style; } else { - while self.text[line].len() < col { - self.text[line].push(' '); + let mut i = self.text[line].len(); + while i < col { + let s = match self.text[0].get(i) { + Some(&'\t') => '\t', + _ => ' ' + }; + self.text[line].push(s); self.styles[line].push(Style::NoStyle); + i += 1; } self.text[line].push(chr); self.styles[line].push(style); diff --git a/src/libsyntax/errors/snippet/test.rs b/src/libsyntax/errors/snippet/test.rs index 5a888b488191b..62ce3fa9dd5e9 100644 --- a/src/libsyntax/errors/snippet/test.rs +++ b/src/libsyntax/errors/snippet/test.rs @@ -79,6 +79,30 @@ fn make_string(lines: &[RenderedLine]) -> String { .collect() } +#[test] +fn tab() { + let file_text = " +fn foo() { +\tbar; +} +"; + + let cm = Rc::new(CodeMap::new()); + let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let span_bar = cm.span_substr(&foo, file_text, "bar", 0); + + let mut snippet = SnippetData::new(cm, Some(span_bar)); + snippet.push(span_bar, true, None); + + let lines = snippet.render_lines(); + let text = make_string(&lines); + assert_eq!(&text[..], &" + --> foo.rs:3:2 +3 |> \tbar; + |> \t^^^ +"[1..]); +} + #[test] fn one_line() { let file_text = r#" From df4fe5fbd44d8b4d698397dc8a05db56fbd9ab42 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Thu, 12 May 2016 10:40:10 -0400 Subject: [PATCH 38/42] update "reason" for fnbox feature gate It isn't "newly introduced" anymore. --- src/liballoc/boxed.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 7bdf9eaccc323..20645dc90a810 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -525,14 +525,14 @@ impl ExactSizeIterator for Box {} /// } /// ``` #[rustc_paren_sugar] -#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")] +#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] pub trait FnBox { type Output; fn call_box(self: Box, args: A) -> Self::Output; } -#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")] +#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl FnBox for F where F: FnOnce { type Output = F::Output; @@ -542,7 +542,7 @@ impl FnBox for F where F: FnOnce } } -#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")] +#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl<'a, A, R> FnOnce for Box + 'a> { type Output = R; @@ -551,7 +551,7 @@ impl<'a, A, R> FnOnce for Box + 'a> { } } -#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")] +#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl<'a, A, R> FnOnce for Box + Send + 'a> { type Output = R; From b9fce76f470ca95e6801c19a82ebac874d34e92f Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Thu, 12 May 2016 10:59:37 -0400 Subject: [PATCH 39/42] fix tidy --- src/liballoc/boxed.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 20645dc90a810..10e4ea1c3f055 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -525,14 +525,16 @@ impl ExactSizeIterator for Box {} /// } /// ``` #[rustc_paren_sugar] -#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", + reason = "will be deprecated if and when Box becomes usable", issue = "28796")] pub trait FnBox { type Output; fn call_box(self: Box, args: A) -> Self::Output; } -#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", + reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl FnBox for F where F: FnOnce { type Output = F::Output; @@ -542,7 +544,8 @@ impl FnBox for F where F: FnOnce } } -#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", + reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl<'a, A, R> FnOnce for Box + 'a> { type Output = R; @@ -551,7 +554,8 @@ impl<'a, A, R> FnOnce for Box + 'a> { } } -#[unstable(feature = "fnbox", reason = "will be deprecated if and when Box becomes usable", issue = "28796")] +#[unstable(feature = "fnbox", + reason = "will be deprecated if and when Box becomes usable", issue = "28796")] impl<'a, A, R> FnOnce for Box + Send + 'a> { type Output = R; From bb9062a2967a5b772788aa14f742d8927ac040ba Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 29 Apr 2016 14:23:15 -0700 Subject: [PATCH 40/42] rustbuild: Add support for crate tests + doctests This commit adds support to rustbuild to run crate unit tests (those defined by `#[test]`) as well as documentation tests. All tests are powered by `cargo test` under the hood. Each step requires the `libtest` library is built for that corresponding stage. Ideally the `test` crate would be a dev-dependency, but for now it's just easier to ensure that we sequence everything in the right order. Currently no filtering is implemented, so there's not actually a method of testing *only* libstd or *only* libcore, but rather entire swaths of crates are tested all at once. A few points of note here are: * The `coretest` and `collectionstest` crates are just listed as `[[test]]` entires for `cargo test` to naturally pick up. This mean that `cargo test -p core` actually runs all the tests for libcore. * Libraries that aren't tested all mention `test = false` in their `Cargo.toml` * Crates aren't currently allowed to have dev-dependencies due to rust-lang/cargo#860, but we can likely alleviate this restriction once workspaces are implemented. cc #31590 --- src/bootstrap/build/check.rs | 79 +++++++++++++++++++++++++++++++- src/bootstrap/build/mod.rs | 11 ++++- src/bootstrap/build/step.rs | 15 ++++++ src/bootstrap/rustc.rs | 15 ++++-- src/bootstrap/rustdoc.rs | 10 +++- src/liballoc/Cargo.toml | 1 - src/libcollections/Cargo.toml | 5 +- src/libcore/Cargo.toml | 4 ++ src/libflate/lib.rs | 12 +---- src/libpanic_abort/Cargo.toml | 1 + src/libpanic_unwind/Cargo.toml | 1 + src/librand/Cargo.toml | 1 - src/librustc_bitflags/Cargo.toml | 1 + src/librustc_borrowck/Cargo.toml | 1 + src/librustc_lint/Cargo.toml | 1 + src/librustc_resolve/Cargo.toml | 1 + src/librustc_trans/Cargo.toml | 1 + src/librustc_typeck/Cargo.toml | 1 + src/libstd/Cargo.toml | 1 - src/libunwind/Cargo.toml | 1 + src/rustc/Cargo.toml | 2 + src/rustc/libc_shim/Cargo.toml | 1 + src/rustc/std_shim/Cargo.toml | 2 + src/rustc/test_shim/Cargo.toml | 2 + 24 files changed, 147 insertions(+), 23 deletions(-) diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs index 0cd96881b5874..f12b0dadeacc1 100644 --- a/src/bootstrap/build/check.rs +++ b/src/bootstrap/build/check.rs @@ -13,13 +13,16 @@ //! This file implements the various regression test suites that we execute on //! our CI. -use std::fs; +use std::env; +use std::fs::{self, File}; +use std::io::prelude::*; use std::path::{PathBuf, Path}; use std::process::Command; use build_helper::output; +use bootstrap::{dylib_path, dylib_path_var}; -use build::{Build, Compiler}; +use build::{Build, Compiler, Mode}; /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler. /// @@ -222,3 +225,75 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) { cmd.arg("--test-args").arg(build.flags.args.join(" ")); build.run(&mut cmd); } + +/// Run all unit tests plus documentation tests for an entire crate DAG defined +/// by a `Cargo.toml` +/// +/// This is what runs tests for crates like the standard library, compiler, etc. +/// It essentially is the driver for running `cargo test`. +/// +/// Currently this runs all tests for a DAG by passing a bunch of `-p foo` +/// arguments, and those arguments are discovered from `Cargo.lock`. +pub fn krate(build: &Build, + compiler: &Compiler, + target: &str, + mode: Mode) { + let (name, path, features) = match mode { + Mode::Libstd => ("libstd", "src/rustc/std_shim", build.std_features()), + Mode::Libtest => ("libtest", "src/rustc/test_shim", String::new()), + Mode::Librustc => ("librustc", "src/rustc", build.rustc_features()), + _ => panic!("can only test libraries"), + }; + println!("Testing {} stage{} ({} -> {})", name, compiler.stage, + compiler.host, target); + + // Build up the base `cargo test` command. + let mut cargo = build.cargo(compiler, mode, target, "test"); + cargo.arg("--manifest-path") + .arg(build.src.join(path).join("Cargo.toml")) + .arg("--features").arg(features); + + // Generate a list of `-p` arguments to pass to the `cargo test` invocation + // by crawling the corresponding Cargo.lock file. + let lockfile = build.src.join(path).join("Cargo.lock"); + let mut contents = String::new(); + t!(t!(File::open(&lockfile)).read_to_string(&mut contents)); + let mut lines = contents.lines(); + while let Some(line) = lines.next() { + let prefix = "name = \""; + if !line.starts_with(prefix) { + continue + } + lines.next(); // skip `version = ...` + + // skip crates.io or otherwise non-path crates + if let Some(line) = lines.next() { + if line.starts_with("source") { + continue + } + } + + let crate_name = &line[prefix.len()..line.len() - 1]; + + // Right now jemalloc is our only target-specific crate in the sense + // that it's not present on all platforms. Custom skip it here for now, + // but if we add more this probably wants to get more generalized. + if crate_name.contains("jemalloc") { + continue + } + + cargo.arg("-p").arg(crate_name); + } + + // The tests are going to run with the *target* libraries, so we need to + // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent. + // + // Note that to run the compiler we need to run with the *host* libraries, + // but our wrapper scripts arrange for that to be the case anyway. + let mut dylib_path = dylib_path(); + dylib_path.insert(0, build.sysroot_libdir(compiler, target)); + cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + cargo.args(&build.flags.args); + + build.run(&mut cargo); +} diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index b38532fb3dfa7..44f161fb487f4 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -380,6 +380,15 @@ impl Build { check::compiletest(self, &compiler, target.target, "run-make", "run-make") } + CheckCrateStd { compiler } => { + check::krate(self, &compiler, target.target, Mode::Libstd) + } + CheckCrateTest { compiler } => { + check::krate(self, &compiler, target.target, Mode::Libtest) + } + CheckCrateRustc { compiler } => { + check::krate(self, &compiler, target.target, Mode::Librustc) + } DistDocs { stage } => dist::docs(self, stage, target.target), DistMingw { _dummy } => dist::mingw(self, target.target), @@ -485,6 +494,7 @@ impl Build { self.config.rust_debug_assertions.to_string()) .env("RUSTC_SNAPSHOT", &self.rustc) .env("RUSTC_SYSROOT", self.sysroot(compiler)) + .env("RUSTC_LIBDIR", self.rustc_libdir(compiler)) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()) .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) @@ -520,7 +530,6 @@ impl Build { if self.config.rust_optimize { cargo.arg("--release"); } - self.add_rustc_lib_path(compiler, &mut cargo); return cargo } diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 4a336589b44c5..c494d965a19c3 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -120,6 +120,9 @@ macro_rules! targets { (check_docs, CheckDocs { compiler: Compiler<'a> }), (check_error_index, CheckErrorIndex { compiler: Compiler<'a> }), (check_rmake, CheckRMake { compiler: Compiler<'a> }), + (check_crate_std, CheckCrateStd { compiler: Compiler<'a> }), + (check_crate_test, CheckCrateTest { compiler: Compiler<'a> }), + (check_crate_rustc, CheckCrateRustc { compiler: Compiler<'a> }), // Distribution targets, creating tarballs (dist, Dist { stage: u32 }), @@ -376,6 +379,9 @@ impl<'a> Step<'a> { self.check_cfail(compiler), self.check_rfail(compiler), self.check_pfail(compiler), + self.check_crate_std(compiler), + self.check_crate_test(compiler), + self.check_crate_rustc(compiler), self.check_codegen(compiler), self.check_codegen_units(compiler), self.check_debuginfo(compiler), @@ -437,6 +443,15 @@ impl<'a> Step<'a> { Source::CheckErrorIndex { compiler } => { vec![self.libstd(compiler), self.tool_error_index(compiler.stage)] } + Source::CheckCrateStd { compiler } => { + vec![self.libtest(compiler)] + } + Source::CheckCrateTest { compiler } => { + vec![self.libtest(compiler)] + } + Source::CheckCrateRustc { compiler } => { + vec![self.libtest(compiler)] + } Source::ToolLinkchecker { stage } | Source::ToolTidy { stage } => { diff --git a/src/bootstrap/rustc.rs b/src/bootstrap/rustc.rs index 046bc34438c42..97decedf91dce 100644 --- a/src/bootstrap/rustc.rs +++ b/src/bootstrap/rustc.rs @@ -29,6 +29,7 @@ extern crate bootstrap; use std::env; use std::ffi::OsString; +use std::path::PathBuf; use std::process::Command; fn main() { @@ -43,16 +44,22 @@ fn main() { // have the standard library built yet and may not be able to produce an // executable. Otherwise we just use the standard compiler we're // bootstrapping with. - let rustc = if target.is_none() { - env::var_os("RUSTC_SNAPSHOT").unwrap() + let (rustc, libdir) = if target.is_none() { + ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR") } else { - env::var_os("RUSTC_REAL").unwrap() + ("RUSTC_REAL", "RUSTC_LIBDIR") }; let stage = env::var("RUSTC_STAGE").unwrap(); + let rustc = env::var_os(rustc).unwrap(); + let libdir = env::var_os(libdir).unwrap(); + let mut dylib_path = bootstrap::dylib_path(); + dylib_path.insert(0, PathBuf::from(libdir)); + let mut cmd = Command::new(rustc); cmd.args(&args) - .arg("--cfg").arg(format!("stage{}", stage)); + .arg("--cfg").arg(format!("stage{}", stage)) + .env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we diff --git a/src/bootstrap/rustdoc.rs b/src/bootstrap/rustdoc.rs index 8c618196113ba..88ac26d32f6c3 100644 --- a/src/bootstrap/rustdoc.rs +++ b/src/bootstrap/rustdoc.rs @@ -12,17 +12,25 @@ //! //! See comments in `src/bootstrap/rustc.rs` for more information. +extern crate bootstrap; + use std::env; use std::process::Command; +use std::path::PathBuf; fn main() { let args = env::args_os().skip(1).collect::>(); let rustdoc = env::var_os("RUSTDOC_REAL").unwrap(); + let libdir = env::var_os("RUSTC_LIBDIR").unwrap(); + + let mut dylib_path = bootstrap::dylib_path(); + dylib_path.insert(0, PathBuf::from(libdir)); let mut cmd = Command::new(rustdoc); cmd.args(&args) .arg("--cfg").arg(format!("stage{}", env::var("RUSTC_STAGE").unwrap())) - .arg("--cfg").arg("dox"); + .arg("--cfg").arg("dox") + .env(bootstrap::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); std::process::exit(match cmd.status() { Ok(s) => s.code().unwrap_or(1), Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index 5da0f1a10b977..0889ca9fc84d4 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -6,7 +6,6 @@ version = "0.0.0" [lib] name = "alloc" path = "lib.rs" -test = false [dependencies] core = { path = "../libcore" } diff --git a/src/libcollections/Cargo.toml b/src/libcollections/Cargo.toml index 18e322ff74f6c..65d456e750f6f 100644 --- a/src/libcollections/Cargo.toml +++ b/src/libcollections/Cargo.toml @@ -6,9 +6,12 @@ version = "0.0.0" [lib] name = "collections" path = "lib.rs" -test = false [dependencies] alloc = { path = "../liballoc" } core = { path = "../libcore" } rustc_unicode = { path = "../librustc_unicode" } + +[[test]] +name = "collectionstest" +path = "../libcollectionstest/lib.rs" diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index 98f941f0057a3..02fe574b81edd 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -8,3 +8,7 @@ build = "build.rs" name = "core" path = "lib.rs" test = false + +[[test]] +name = "coretest" +path = "../libcoretest/lib.rs" diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 1cc008c5ee9ce..b578b064d67ca 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -27,11 +27,7 @@ #![feature(libc)] #![feature(staged_api)] #![feature(unique)] -#![cfg_attr(test, feature(rustc_private, rand))] - -#[cfg(test)] -#[macro_use] -extern crate log; +#![cfg_attr(test, feature(rand))] extern crate libc; @@ -175,14 +171,8 @@ mod tests { for _ in 0..2000 { input.extend_from_slice(r.choose(&words).unwrap()); } - debug!("de/inflate of {} bytes of random word-sequences", - input.len()); let cmp = deflate_bytes(&input); let out = inflate_bytes(&cmp).unwrap(); - debug!("{} bytes deflated to {} ({:.1}% size)", - input.len(), - cmp.len(), - 100.0 * ((cmp.len() as f64) / (input.len() as f64))); assert_eq!(&*input, &*out); } } diff --git a/src/libpanic_abort/Cargo.toml b/src/libpanic_abort/Cargo.toml index a7905703f596f..9d62be64fc4ec 100644 --- a/src/libpanic_abort/Cargo.toml +++ b/src/libpanic_abort/Cargo.toml @@ -5,6 +5,7 @@ version = "0.0.0" [lib] path = "lib.rs" +test = false [dependencies] core = { path = "../libcore" } diff --git a/src/libpanic_unwind/Cargo.toml b/src/libpanic_unwind/Cargo.toml index 27edecd6f9668..18f37a8bb174e 100644 --- a/src/libpanic_unwind/Cargo.toml +++ b/src/libpanic_unwind/Cargo.toml @@ -5,6 +5,7 @@ version = "0.0.0" [lib] path = "lib.rs" +test = false [dependencies] alloc = { path = "../liballoc" } diff --git a/src/librand/Cargo.toml b/src/librand/Cargo.toml index 784654c085990..86b061db05413 100644 --- a/src/librand/Cargo.toml +++ b/src/librand/Cargo.toml @@ -6,7 +6,6 @@ version = "0.0.0" [lib] name = "rand" path = "lib.rs" -test = false [dependencies] core = { path = "../libcore" } diff --git a/src/librustc_bitflags/Cargo.toml b/src/librustc_bitflags/Cargo.toml index 926ed5960d68a..d1e66dcf9351b 100644 --- a/src/librustc_bitflags/Cargo.toml +++ b/src/librustc_bitflags/Cargo.toml @@ -7,3 +7,4 @@ version = "0.0.0" name = "rustc_bitflags" path = "lib.rs" test = false +doctest = false diff --git a/src/librustc_borrowck/Cargo.toml b/src/librustc_borrowck/Cargo.toml index 6da87f97fb79f..fbc267aaa6a06 100644 --- a/src/librustc_borrowck/Cargo.toml +++ b/src/librustc_borrowck/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_borrowck" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 3f0cd397e769c..7674cc529bef8 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_lint" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 217445715a81b..a63460d912d7d 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_resolve" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index ccb430fbb782f..9a0580472b401 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_trans" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] arena = { path = "../libarena" } diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index e9dabf16eaece..a0c4c7534fab2 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0" name = "rustc_typeck" path = "lib.rs" crate-type = ["dylib"] +test = false [dependencies] log = { path = "../liblog" } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 6d33fb311cff0..eded6e24f3ef5 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -8,7 +8,6 @@ build = "build.rs" name = "std" path = "lib.rs" crate-type = ["dylib", "rlib"] -test = false [dependencies] alloc = { path = "../liballoc" } diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index dca222c49d0a1..b537c6b1b71c1 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -7,6 +7,7 @@ build = "build.rs" [lib] name = "unwind" path = "lib.rs" +test = false [dependencies] core = { path = "../libcore" } diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 7431c35efba01..24499cb8f08c2 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -13,6 +13,8 @@ path = "rustdoc.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere. diff --git a/src/rustc/libc_shim/Cargo.toml b/src/rustc/libc_shim/Cargo.toml index a7860b50e08ff..8fc713e0f1bb3 100644 --- a/src/rustc/libc_shim/Cargo.toml +++ b/src/rustc/libc_shim/Cargo.toml @@ -15,6 +15,7 @@ build = "build.rs" [lib] name = "libc" path = "../../liblibc/src/lib.rs" +test = false [dependencies] core = { path = "../../libcore" } diff --git a/src/rustc/std_shim/Cargo.toml b/src/rustc/std_shim/Cargo.toml index 1ce3937157da0..5602ef866b83a 100644 --- a/src/rustc/std_shim/Cargo.toml +++ b/src/rustc/std_shim/Cargo.toml @@ -30,6 +30,8 @@ path = "lib.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere. diff --git a/src/rustc/test_shim/Cargo.toml b/src/rustc/test_shim/Cargo.toml index bf5766504867c..87f2ccd51e885 100644 --- a/src/rustc/test_shim/Cargo.toml +++ b/src/rustc/test_shim/Cargo.toml @@ -14,6 +14,8 @@ path = "lib.rs" [profile.release] opt-level = 2 +[profile.bench] +opt-level = 2 # These options are controlled from our rustc wrapper script, so turn them off # here and have them controlled elsewhere. From 215b2603f1a4a1f82e8a454addf36f104742b147 Mon Sep 17 00:00:00 2001 From: Pavel Sountsov Date: Thu, 12 May 2016 09:32:17 -0700 Subject: [PATCH 41/42] Fix the sed invocation to also work with BSD sed. --- src/test/run-make/dep-info-no-analysis/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/dep-info-no-analysis/Makefile b/src/test/run-make/dep-info-no-analysis/Makefile index 66bb37d8bf33e..5d2cfadfd020a 100644 --- a/src/test/run-make/dep-info-no-analysis/Makefile +++ b/src/test/run-make/dep-info-no-analysis/Makefile @@ -2,5 +2,5 @@ all: $(RUSTC) -o $(TMPDIR)/input.dd -Z no-analysis --emit dep-info input.rs - sed -i "s/^.*input.dd/input.dd/g" $(TMPDIR)/input.dd + sed -i'.bak' 's/^.*input.dd/input.dd/g' $(TMPDIR)/input.dd diff -u $(TMPDIR)/input.dd input.dd From aa00e3a552d453f8af0d033d6207a0e09d159d2e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 May 2016 14:19:26 -0400 Subject: [PATCH 42/42] re-introduce a cache for ast-ty-to-ty It turns out that `ast_ty_to_ty` is supposed to be updating the `def` after it finishes, but at some point in the past it stopped doing so. This was never noticed because of the `ast_ty_to_ty_cache`, but that cache was recently removed. This PR fixes the code to update the def properly, but apparently that is not quite enough to make the operation idempotent, so for now we reintroduce the cache too. Fixes #33425. --- src/librustc_resolve/lib.rs | 2 + src/librustc_typeck/astconv.rs | 58 +++++++++++++------ src/librustc_typeck/check/mod.rs | 21 ++++--- src/librustc_typeck/collect.rs | 12 +++- src/librustc_typeck/lib.rs | 6 +- .../associated-types-in-bound-type-arg.rs | 26 +++++++++ 6 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 src/test/run-pass/associated-types-in-bound-type-arg.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fc048c86dc9dd..9cec3a5179496 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2544,6 +2544,8 @@ impl<'a> Resolver<'a> { /// returned value. See `hir::def::PathResolution` for more info. fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace) -> Result { + debug!("resolve_path(id={:?} path={:?}, path_depth={:?})", id, path, path_depth); + let span = path.span; let segments = &path.segments[..path.segments.len() - path_depth]; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 725d40889ceec..c8e247fb9181c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -64,10 +64,10 @@ use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope, ElisionFailureInfo, ElidedLifetime}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; -use util::nodemap::FnvHashSet; +use util::nodemap::{NodeMap, FnvHashSet}; use rustc_const_math::ConstInt; - +use std::cell::RefCell; use syntax::{abi, ast}; use syntax::codemap::{Span, Pos}; use syntax::errors::DiagnosticBuilder; @@ -81,6 +81,9 @@ use rustc_back::slice; pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; + /// A cache used for the result of `ast_ty_to_ty_cache` + fn ast_ty_to_ty_cache(&self) -> &RefCell>>; + /// Identify the type scheme for an item with a type, like a type /// alias, fn, or struct. This allows you to figure out the set of /// type parameters defined on the item. @@ -1416,13 +1419,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope: &RegionScope, span: Span, param_mode: PathParamMode, - def: &Def, + def: Def, opt_self_ty: Option>, base_segments: &[hir::PathSegment]) -> Ty<'tcx> { let tcx = self.tcx(); - match *def { + debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, base_segments={:?})", + def, opt_self_ty, base_segments); + + match def { Def::Trait(trait_def_id) => { // N.B. this case overlaps somewhat with // TyObjectSum, see that fn for details @@ -1515,20 +1521,27 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope: &RegionScope, span: Span, param_mode: PathParamMode, - def: &Def, + mut def: Def, opt_self_ty: Option>, base_segments: &[hir::PathSegment], assoc_segments: &[hir::PathSegment]) - -> Ty<'tcx> { + -> (Ty<'tcx>, Def) { + debug!("finish_resolving_def_to_ty(def={:?}, \ + base_segments={:?}, \ + assoc_segments={:?})", + def, + base_segments, + assoc_segments); let mut ty = self.base_def_to_ty(rscope, span, param_mode, def, opt_self_ty, base_segments); - let mut def = *def; + debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", ty); // If any associated type segments remain, attempt to resolve them. for segment in assoc_segments { + debug!("finish_resolving_def_to_ty: segment={:?}", segment); if ty.sty == ty::TyError { break; } @@ -1540,7 +1553,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ty = a_ty; def = a_def; } - ty + (ty, def) } /// Parses the programmer's textual representation of a type into our @@ -1551,7 +1564,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let tcx = self.tcx(); - match ast_ty.node { + let cache = self.ast_ty_to_ty_cache(); + match cache.borrow().get(&ast_ty.id) { + Some(ty) => { return ty; } + None => { } + } + + let result_ty = match ast_ty.node { hir::TyVec(ref ty) => { tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty)) } @@ -1599,6 +1618,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.conv_ty_poly_trait_ref(rscope, ast_ty.span, bounds) } hir::TyPath(ref maybe_qself, ref path) => { + debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path); let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) { d } else if let Some(hir::QSelf { position: 0, .. }) = *maybe_qself { @@ -1615,13 +1635,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let opt_self_ty = maybe_qself.as_ref().map(|qself| { self.ast_ty_to_ty(rscope, &qself.ty) }); - let ty = self.finish_resolving_def_to_ty(rscope, - ast_ty.span, - PathParamMode::Explicit, - &def, - opt_self_ty, - &path.segments[..base_ty_end], - &path.segments[base_ty_end..]); + let (ty, _def) = self.finish_resolving_def_to_ty(rscope, + ast_ty.span, + PathParamMode::Explicit, + def, + opt_self_ty, + &path.segments[..base_ty_end], + &path.segments[base_ty_end..]); if path_res.depth != 0 && ty.sty != ty::TyError { // Write back the new resolution. @@ -1675,7 +1695,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // handled specially and will not descend into this routine. self.ty_infer(None, None, None, ast_ty.span) } - } + }; + + cache.borrow_mut().insert(ast_ty.id, result_ty); + + result_ty } pub fn ty_of_arg(&self, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f428023da9b82..6dfad749982b6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -346,6 +346,8 @@ impl UnsafetyState { #[derive(Clone)] pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { + ast_ty_to_ty_cache: RefCell>>, + body_id: ast::NodeId, // This flag is set to true if, during the writeback phase, we encounter @@ -1262,6 +1264,10 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } + fn ast_ty_to_ty_cache(&self) -> &RefCell>> { + &self.ast_ty_to_ty_cache + } + fn get_item_type_scheme(&self, _: Span, id: DefId) -> Result, ErrorReported> { @@ -1434,6 +1440,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { body_id: ast::NodeId) -> FnCtxt<'a, 'gcx, 'tcx> { FnCtxt { + ast_ty_to_ty_cache: RefCell::new(NodeMap()), body_id: body_id, writeback_errors: Cell::new(false), err_count_on_creation: inh.tcx.sess.err_count(), @@ -3845,15 +3852,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if path_res.depth == 0 { Some((opt_self_ty, &path.segments, path_res.base_def)) } else { - let mut def = path_res.base_def; + let def = path_res.base_def; let ty_segments = path.segments.split_last().unwrap().1; let base_ty_end = path.segments.len() - path_res.depth; - let ty = AstConv::finish_resolving_def_to_ty(self, self, span, - PathParamMode::Optional, - &mut def, - opt_self_ty, - &ty_segments[..base_ty_end], - &ty_segments[base_ty_end..]); + let (ty, _def) = AstConv::finish_resolving_def_to_ty(self, self, span, + PathParamMode::Optional, + def, + opt_self_ty, + &ty_segments[..base_ty_end], + &ty_segments[base_ty_end..]); let item_segment = path.segments.last().unwrap(); let item_name = item_segment.identifier.name; let def = match self.resolve_ufcs(span, item_name, ty, node_id) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 797a1509ebee5..f9a22e2a577b4 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -78,11 +78,12 @@ use rscope::*; use rustc::dep_graph::DepNode; use rustc::hir::map as hir_map; use util::common::{ErrorReported, MemoizationMap}; -use util::nodemap::FnvHashMap; +use util::nodemap::{NodeMap, FnvHashMap}; use {CrateCtxt, write_ty_to_tcx}; use rustc_const_math::ConstInt; +use std::cell::RefCell; use std::collections::HashSet; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::rc::Rc; @@ -146,7 +147,10 @@ impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> impl<'a,'tcx> CrateCtxt<'a,'tcx> { fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> { - ItemCtxt { ccx: self, param_bounds: param_bounds } + ItemCtxt { + ccx: self, + param_bounds: param_bounds, + } } fn cycle_check(&self, @@ -298,6 +302,10 @@ impl<'a,'tcx> ItemCtxt<'a,'tcx> { impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.ccx.tcx } + fn ast_ty_to_ty_cache(&self) -> &RefCell>> { + &self.ccx.ast_ty_to_ty_cache + } + fn get_item_type_scheme(&self, span: Span, id: DefId) -> Result, ErrorReported> { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b88b3c9802d30..f41da95c13537 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -116,6 +116,7 @@ use syntax::ast; use syntax::abi::Abi; use std::cell::RefCell; +use util::nodemap::NodeMap; // NB: This module needs to be declared first so diagnostics are // registered before they are used. @@ -136,7 +137,9 @@ pub struct TypeAndSubsts<'tcx> { } pub struct CrateCtxt<'a, 'tcx: 'a> { - // A mapping from method call sites to traits that have that method. + ast_ty_to_ty_cache: RefCell>>, + + /// A mapping from method call sites to traits that have that method. pub trait_map: hir::TraitMap, /// A vector of every trait accessible in the whole crate @@ -334,6 +337,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> CompileResult { let time_passes = tcx.sess.time_passes(); let ccx = CrateCtxt { + ast_ty_to_ty_cache: RefCell::new(NodeMap()), trait_map: trait_map, all_traits: RefCell::new(None), stack: RefCell::new(Vec::new()), diff --git a/src/test/run-pass/associated-types-in-bound-type-arg.rs b/src/test/run-pass/associated-types-in-bound-type-arg.rs new file mode 100644 index 0000000000000..18803d15719e8 --- /dev/null +++ b/src/test/run-pass/associated-types-in-bound-type-arg.rs @@ -0,0 +1,26 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test the case where we resolve `C::Result` and the trait bound +// itself includes a `Self::Item` shorthand. +// +// Regression test for issue #33425. + +trait ParallelIterator { + type Item; + fn drive_unindexed(self, consumer: C) -> C::Result + where C: Consumer; +} + +pub trait Consumer { + type Result; +} + +fn main() { }