From 0d395841fc5141462c88a4167b2f675405d3a8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Jun 2016 18:29:16 -0700 Subject: [PATCH 01/86] Detect double reference when applying binary op ```rust let vr = v.iter().filter(|x| { x % 2 == 0 }); ``` will now yield the following compiler output: ```bash ERROR binary operation `%` cannot be applied to type `&&_` NOTE this is a reference of a reference to a type that `%` can be applied to, you need to dereference this variable once for this operation to work NOTE an implementation of `std::ops::Rem` might be missing for `&&_` ``` The first NOTE is new. Bug #33877 --- src/librustc_typeck/check/op.rs | 17 +++++++++++++++- .../compile-fail/binary-op-on-double-ref.rs | 20 +++++++++++++++++++ .../compile-fail/str-concat-on-double-ref.rs | 19 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/binary-op-on-double-ref.rs create mode 100644 src/test/compile-fail/str-concat-on-double-ref.rs diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index d1a9b8ef85ae4..4202f65c44d4f 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -12,7 +12,7 @@ use super::FnCtxt; use hir::def_id::DefId; -use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue}; +use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue, TypeVariants}; use rustc::infer::type_variable::TypeVariableOrigin; use syntax::ast; use syntax::symbol::Symbol; @@ -204,6 +204,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "binary operation `{}` cannot be applied to type `{}`", op.node.as_str(), lhs_ty); + + if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty { + if self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty_var], + token::intern(name), trait_def_id, + lhs_expr).is_ok() { + err.span_note( + lhs_expr.span, + &format!( + "this is a reference of type that `{}` can be applied to, \ + you need to dereference this variable once for this \ + operation to work", + op.node.as_str())); + } + } + let missing_trait = match op.node { hir::BiAdd => Some("std::ops::Add"), hir::BiSub => Some("std::ops::Sub"), diff --git a/src/test/compile-fail/binary-op-on-double-ref.rs b/src/test/compile-fail/binary-op-on-double-ref.rs new file mode 100644 index 0000000000000..5cc8e0f9988fc --- /dev/null +++ b/src/test/compile-fail/binary-op-on-double-ref.rs @@ -0,0 +1,20 @@ +// Copyright 2012-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. + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; + let vr = v.iter().filter(|x| { + x % 2 == 0 + //~^ ERROR binary operation `%` cannot be applied to type `&&_` + //~| NOTE this is a reference of type that `%` can be applied to + //~| NOTE an implementation of `std::ops::Rem` might be missing for `&&_` + }); + println!("{:?}", vr); +} diff --git a/src/test/compile-fail/str-concat-on-double-ref.rs b/src/test/compile-fail/str-concat-on-double-ref.rs new file mode 100644 index 0000000000000..d79ab6b805c82 --- /dev/null +++ b/src/test/compile-fail/str-concat-on-double-ref.rs @@ -0,0 +1,19 @@ +// Copyright 2012-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. + +fn main() { + let a: &String = &"1".to_owned(); + let b: &str = &"2"; + let c = a + b; + //~^ ERROR binary operation `+` cannot be applied to type `&std::string::String` + //~| NOTE this is a reference of type that `+` can be applied to + //~| NOTE an implementation of `std::ops::Add` might be missing for `&std::string::String` + println!("{:?}", c); +} From b8669dff556a03ca37b39cbb81be65c94d24defe Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 26 Dec 2016 13:27:51 -0500 Subject: [PATCH 02/86] Ensure type is copyable before emitting note suggesting adding manual deref. drive-by: fix merge conflict; fix test expected error output post rebase. --- src/librustc_typeck/check/op.rs | 5 +++-- src/test/compile-fail/binary-op-on-double-ref.rs | 4 ++-- src/test/compile-fail/str-concat-on-double-ref.rs | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 4202f65c44d4f..925d28247b610 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -206,8 +206,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { lhs_ty); if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty { - if self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty_var], - token::intern(name), trait_def_id, + if !self.infcx.type_moves_by_default(ty_mut.ty, lhs_expr.span) && + self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty_var], + Symbol::intern(name), trait_def_id, lhs_expr).is_ok() { err.span_note( lhs_expr.span, diff --git a/src/test/compile-fail/binary-op-on-double-ref.rs b/src/test/compile-fail/binary-op-on-double-ref.rs index 5cc8e0f9988fc..a49cfaa17606d 100644 --- a/src/test/compile-fail/binary-op-on-double-ref.rs +++ b/src/test/compile-fail/binary-op-on-double-ref.rs @@ -12,9 +12,9 @@ fn main() { let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; let vr = v.iter().filter(|x| { x % 2 == 0 - //~^ ERROR binary operation `%` cannot be applied to type `&&_` + //~^ ERROR binary operation `%` cannot be applied to type `&&{integer}` //~| NOTE this is a reference of type that `%` can be applied to - //~| NOTE an implementation of `std::ops::Rem` might be missing for `&&_` + //~| NOTE an implementation of `std::ops::Rem` might be missing for `&&{integer}` }); println!("{:?}", vr); } diff --git a/src/test/compile-fail/str-concat-on-double-ref.rs b/src/test/compile-fail/str-concat-on-double-ref.rs index d79ab6b805c82..f85422f76d40e 100644 --- a/src/test/compile-fail/str-concat-on-double-ref.rs +++ b/src/test/compile-fail/str-concat-on-double-ref.rs @@ -13,7 +13,6 @@ fn main() { let b: &str = &"2"; let c = a + b; //~^ ERROR binary operation `+` cannot be applied to type `&std::string::String` - //~| NOTE this is a reference of type that `+` can be applied to //~| NOTE an implementation of `std::ops::Add` might be missing for `&std::string::String` println!("{:?}", c); } From 5f118b954e2aeced356511167319a31fc0503f47 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 5 Jan 2017 09:02:14 -0500 Subject: [PATCH 03/86] travis: Gate on some minimal support for incremental compilation. This commit adds a travis job that builds a stage2 compiler in incremental mode (but with empty incremental compilation cache). Building incrementally with an empty cache makes sure that the compiler doesn't crash in dependency tracking during bootstrapping. --- .travis.yml | 1 + .../docker/x86_64-gnu-incremental/Dockerfile | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/ci/docker/x86_64-gnu-incremental/Dockerfile diff --git a/.travis.yml b/.travis.yml index abd0a8fe346f0..b6656bec6052d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,7 @@ matrix: - env: IMAGE=x86_64-gnu-llvm-3.7 ALLOW_PR=1 RUST_BACKTRACE=1 - env: IMAGE=x86_64-musl DEPLOY=1 - env: IMAGE=x86_64-gnu-distcheck + - env: IMAGE=x86_64-gnu-incremental # OSX builders - env: > diff --git a/src/ci/docker/x86_64-gnu-incremental/Dockerfile b/src/ci/docker/x86_64-gnu-incremental/Dockerfile new file mode 100644 index 0000000000000..3e084f4a3c302 --- /dev/null +++ b/src/ci/docker/x86_64-gnu-incremental/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + sudo \ + gdb \ + xz-utils + +ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783 +RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \ + tar xJf - -C /usr/local/bin --strip-components=1 + +RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ + dpkg -i dumb-init_*.deb && \ + rm dumb-init_*.deb +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu +ENV RUSTFLAGS -Zincremental=/tmp/rust-incr-cache +ENV RUST_CHECK_TARGET check From b795abeb1dc0f6d27e49d980a48936b687754b28 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 17 Jan 2017 21:18:29 +0300 Subject: [PATCH 04/86] Refactor parsing of generic arguments/parameters and where clauses --- src/librustc_passes/ast_validation.rs | 26 + src/librustc_typeck/collect.rs | 5 +- src/librustdoc/clean/mod.rs | 7 +- src/libsyntax/parse/parser.rs | 681 +++++++----------- src/libsyntax/parse/token.rs | 23 + .../attrs-with-no-formal-in-generics-2.rs | 9 +- .../generic-non-trailing-defaults.rs | 20 + src/test/compile-fail/issue-20616-1.rs | 2 +- src/test/compile-fail/issue-20616-2.rs | 2 +- src/test/compile-fail/issue-20616-3.rs | 2 +- src/test/compile-fail/issue-20616-4.rs | 2 +- src/test/compile-fail/issue-20616-5.rs | 2 +- src/test/compile-fail/issue-20616-6.rs | 2 +- src/test/compile-fail/issue-20616-7.rs | 2 +- src/test/compile-fail/issue-20616-8.rs | 2 +- src/test/compile-fail/issue-20616-9.rs | 2 +- src/test/parse-fail/issue-14303-path.rs | 1 - ...-trailing-defaults.rs => issue-17904-2.rs} | 6 +- src/test/parse-fail/issue-17904.rs | 3 +- src/test/parse-fail/issue-32214.rs | 5 +- src/test/parse-fail/lifetime-semicolon.rs | 3 +- .../where-clauses-no-bounds-or-predicates.rs | 4 +- 22 files changed, 342 insertions(+), 469 deletions(-) create mode 100644 src/test/compile-fail/generic-non-trailing-defaults.rs rename src/test/parse-fail/{generic-non-trailing-defaults.rs => issue-17904-2.rs} (74%) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index b7b027102b2af..9720bb8426475 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -146,6 +146,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { TyKind::TraitObject(ref bounds) => { self.no_questions_in_bounds(bounds, "trait object types", false); } + TyKind::ImplTrait(ref bounds) => { + if !bounds.iter() + .any(|b| if let TraitTyParamBound(..) = *b { true } else { false }) { + self.err_handler().span_err(ty.span, "at least one trait must be specified"); + } + } _ => {} } @@ -284,6 +290,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_vis(self, vis) } + + fn visit_generics(&mut self, g: &'a Generics) { + let mut seen_default = None; + for ty_param in &g.ty_params { + if ty_param.default.is_some() { + seen_default = Some(ty_param.span); + } else if let Some(span) = seen_default { + self.err_handler() + .span_err(span, "type parameters with a default must be trailing"); + break + } + } + for predicate in &g.where_clause.predicates { + if let WherePredicate::EqPredicate(ref predicate) = *predicate { + self.err_handler().span_err(predicate.span, "equality constraints are not yet \ + supported in where clauses (#20041)"); + } + } + visit::walk_generics(self, g) + } } pub fn check_crate(session: &Session, krate: &Crate) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d403ac4343531..b9ee1c2b84cb0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1833,11 +1833,8 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } } - &hir::WherePredicate::EqPredicate(ref eq_pred) => { + &hir::WherePredicate::EqPredicate(..) => { // FIXME(#20041) - span_bug!(eq_pred.span, - "Equality constraints are not yet \ - implemented (#20041)") } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a77485477b159..77f0482e11318 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -842,8 +842,11 @@ impl Clean for hir::WherePredicate { } } - hir::WherePredicate::EqPredicate(_) => { - unimplemented!() // FIXME(#20041) + hir::WherePredicate::EqPredicate(ref wrp) => { + WherePredicate::EqPredicate { + lhs: wrp.lhs_ty.clean(cx), + rhs: wrp.rhs_ty.clean(cx) + } } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2a0a73859987b..c589f1a7aaaa0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -22,7 +22,7 @@ use ast::{Expr, ExprKind, RangeLimits}; use ast::{Field, FnDecl}; use ast::{ForeignItem, ForeignItemKind, FunctionRetTy}; use ast::{Ident, ImplItem, Item, ItemKind}; -use ast::{Lit, LitKind, UintTy}; +use ast::{Lifetime, LifetimeDef, Lit, LitKind, UintTy}; use ast::Local; use ast::MacStmtStyle; use ast::Mac_; @@ -638,13 +638,7 @@ impl<'a> Parser<'a> { let lo = span.lo + BytePos(1); Ok(self.bump_with(token::Eq, lo, span.hi)) } - _ => { - let gt_str = Parser::token_to_string(&token::Gt); - let this_token_str = self.this_token_to_string(); - Err(self.fatal(&format!("expected `{}`, found `{}`", - gt_str, - this_token_str))) - } + _ => self.unexpected() } } @@ -971,20 +965,11 @@ impl<'a> Parser<'a> { Parses whatever can come after a `for` keyword in a type. The `for` hasn't been consumed. - Deprecated: - - - for <'lt> |S| -> T - - Eventually: - - for <'lt> [unsafe] [extern "ABI"] fn (S) -> T - - for <'lt> path::foo(a, b) - + - for <'lt> path::foo(a, b) + Trait + 'a */ - // parse <'lt> let lo = self.span.lo; - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; // examine next token to decide to do @@ -993,9 +978,9 @@ impl<'a> Parser<'a> { } else { let hi = self.span.hi; let trait_ref = self.parse_trait_ref()?; - let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs, - trait_ref: trait_ref, - span: mk_sp(lo, hi)}; + let poly_trait_ref = PolyTraitRef { bound_lifetimes: lifetime_defs, + trait_ref: trait_ref, + span: mk_sp(lo, hi)}; let other_bounds = if self.eat(&token::BinOp(token::Plus)) { self.parse_ty_param_bounds()? } else { @@ -1010,18 +995,9 @@ impl<'a> Parser<'a> { } pub fn parse_impl_trait_type(&mut self) -> PResult<'a, TyKind> { - /* - Parses whatever can come after a `impl` keyword in a type. - The `impl` has already been consumed. - */ - - let bounds = self.parse_ty_param_bounds()?; - - if !bounds.iter().any(|b| if let TraitTyParamBound(..) = *b { true } else { false }) { - self.span_err(self.prev_span, "at least one trait must be specified"); - } - - Ok(ast::TyKind::ImplTrait(bounds)) + // Parses whatever can come after a `impl` keyword in a type. + // The `impl` has already been consumed. + Ok(ast::TyKind::ImplTrait(self.parse_ty_param_bounds()?)) } pub fn parse_ty_path(&mut self) -> PResult<'a, TyKind> { @@ -1029,7 +1005,7 @@ impl<'a> Parser<'a> { } /// parse a TyKind::BareFn type: - pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) + pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec) -> PResult<'a, TyKind> { /* @@ -1201,13 +1177,6 @@ impl<'a> Parser<'a> { }) } - /// Parse a possibly mutable type - pub fn parse_mt(&mut self) -> PResult<'a, MutTy> { - let mutbl = self.parse_mutability()?; - let t = self.parse_ty_no_plus()?; - Ok(MutTy { ty: t, mutbl: mutbl }) - } - /// Parse optional return type [ -> TY ] in function decl pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> { if self.eat(&token::RArrow) { @@ -1259,8 +1228,8 @@ impl<'a> Parser<'a> { pprust::ty_to_string(&lhs)); err.span_label(lhs.span, &format!("expected a path")); let hi = bounds.iter().map(|x| match *x { - ast::TraitTyParamBound(ref tr, _) => tr.span.hi, - ast::RegionTyParamBound(ref r) => r.span.hi, + TraitTyParamBound(ref tr, _) => tr.span.hi, + RegionTyParamBound(ref r) => r.span.hi, }).max_by_key(|x| x.to_usize()); let full_span = hi.map(|hi| Span { lo: lhs.span.lo, @@ -1308,9 +1277,7 @@ impl<'a> Parser<'a> { let lo = self.span.lo; - let t = if self.check(&token::OpenDelim(token::Paren)) { - self.bump(); - + let t = if self.eat(&token::OpenDelim(token::Paren)) { // (t) is a parenthesized ty // (t,) is the type of a tuple with only one field, // of type t @@ -1318,9 +1285,8 @@ impl<'a> Parser<'a> { let mut last_comma = false; while self.token != token::CloseDelim(token::Paren) { ts.push(self.parse_ty()?); - if self.check(&token::Comma) { + if self.eat(&token::Comma) { last_comma = true; - self.bump(); } else { last_comma = false; break; @@ -1335,13 +1301,11 @@ impl<'a> Parser<'a> { } } else if self.eat(&token::Not) { TyKind::Never - } else if self.check(&token::BinOp(token::Star)) { + } else if self.eat(&token::BinOp(token::Star)) { // STAR POINTER (bare pointer?) - self.bump(); TyKind::Ptr(self.parse_ptr()?) - } else if self.check(&token::OpenDelim(token::Bracket)) { + } else if self.eat(&token::OpenDelim(token::Bracket)) { // VECTOR - self.expect(&token::OpenDelim(token::Bracket))?; let t = self.parse_ty()?; // Parse the `; e` in `[ i32; e ]` @@ -1353,13 +1317,15 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Bracket))?; t } else if self.check(&token::BinOp(token::And)) || - self.token == token::AndAnd { + self.check(&token::AndAnd) { // BORROWED POINTER self.expect_and()?; self.parse_borrowed_pointee()? } else if self.check_keyword(keywords::For) { + // FIXME plus priority self.parse_for_in_type()? } else if self.eat_keyword(keywords::Impl) { + // FIXME plus priority self.parse_impl_trait_type()? } else if self.token_is_bare_fn_keyword() { // BARE FUNCTION @@ -1372,10 +1338,7 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Paren))?; TyKind::Typeof(e) } else if self.eat_lt() { - - let (qself, path) = - self.parse_qualified_path(PathStyle::Type)?; - + let (qself, path) = self.parse_qualified_path(PathStyle::Type)?; TyKind::Path(Some(qself), path) } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Type)?; @@ -1405,10 +1368,10 @@ impl<'a> Parser<'a> { pub fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { // look for `&'lt` or `&'foo ` and interpret `foo` as the region name: - let opt_lifetime = self.parse_opt_lifetime()?; - - let mt = self.parse_mt()?; - return Ok(TyKind::Rptr(opt_lifetime, mt)); + let opt_lifetime = self.eat_lifetime(); + let mutbl = self.parse_mutability()?; + let ty = self.parse_ty_no_plus()?; + return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty: ty, mutbl: mutbl })); } pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> { @@ -1504,8 +1467,7 @@ impl<'a> Parser<'a> { } pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option>> { - if self.check(&token::Semi) { - self.bump(); + if self.eat(&token::Semi) { Ok(Some(self.parse_expr()?)) } else { Ok(None) @@ -1727,7 +1689,8 @@ impl<'a> Parser<'a> { // Parse types, optionally. let parameters = if self.eat_lt() { - let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?; + let (lifetimes, types, bindings) = self.parse_generic_args()?; + self.expect_gt()?; ast::AngleBracketedParameterData { lifetimes: lifetimes, types: types, @@ -1785,7 +1748,8 @@ impl<'a> Parser<'a> { // Check for a type segment. if self.eat_lt() { // Consumed `a::b::<`, go look for types - let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?; + let (lifetimes, types, bindings) = self.parse_generic_args()?; + self.expect_gt()?; segments.push(ast::PathSegment { identifier: identifier, parameters: ast::AngleBracketedParameterData { @@ -1827,121 +1791,18 @@ impl<'a> Parser<'a> { } } - /// parses 0 or 1 lifetime - pub fn parse_opt_lifetime(&mut self) -> PResult<'a, Option> { - match self.token { - token::Lifetime(..) => { - Ok(Some(self.parse_lifetime()?)) - } - _ => { - Ok(None) - } - } - } - - /// Parses a single lifetime - /// Matches lifetime = LIFETIME - pub fn parse_lifetime(&mut self) -> PResult<'a, ast::Lifetime> { + /// Parse single lifetime 'a or nothing. + pub fn eat_lifetime(&mut self) -> Option { match self.token { - token::Lifetime(i) => { - let span = self.span; + token::Lifetime(ident) => { self.bump(); - return Ok(ast::Lifetime { + Some(Lifetime { id: ast::DUMMY_NODE_ID, - span: span, - name: i.name - }); - } - _ => { - return Err(self.fatal("expected a lifetime name")); - } - } - } - - /// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def = - /// lifetime [':' lifetimes]` - /// - /// If `followed_by_ty_params` is None, then we are in a context - /// where only lifetime parameters are allowed, and thus we should - /// error if we encounter attributes after the bound lifetimes. - /// - /// If `followed_by_ty_params` is Some(r), then there may be type - /// parameter bindings after the lifetimes, so we should pass - /// along the parsed attributes to be attached to the first such - /// type parmeter. - pub fn parse_lifetime_defs(&mut self, - followed_by_ty_params: Option<&mut Vec>) - -> PResult<'a, Vec> - { - let mut res = Vec::new(); - loop { - let attrs = self.parse_outer_attributes()?; - match self.token { - token::Lifetime(_) => { - let lifetime = self.parse_lifetime()?; - let bounds = - if self.eat(&token::Colon) { - self.parse_lifetimes(token::BinOp(token::Plus))? - } else { - Vec::new() - }; - res.push(ast::LifetimeDef { attrs: attrs.into(), - lifetime: lifetime, - bounds: bounds }); - } - - _ => { - if let Some(recv) = followed_by_ty_params { - assert!(recv.is_empty()); - *recv = attrs; - debug!("parse_lifetime_defs ret {:?}", res); - return Ok(res); - } else if !attrs.is_empty() { - let msg = "trailing attribute after lifetime parameters"; - return Err(self.fatal(msg)); - } - } - } - - match self.token { - token::Comma => { self.bump();} - token::Gt => { return Ok(res); } - token::BinOp(token::Shr) => { return Ok(res); } - _ => { - let this_token_str = self.this_token_to_string(); - let msg = format!("expected `,` or `>` after lifetime \ - name, found `{}`", - this_token_str); - return Err(self.fatal(&msg[..])); - } - } - } - } - - /// matches lifetimes = ( lifetime ) | ( lifetime , lifetimes ) actually, it matches the empty - /// one too, but putting that in there messes up the grammar.... - /// - /// Parses zero or more comma separated lifetimes. Expects each lifetime to be followed by - /// either a comma or `>`. Used when parsing type parameter lists, where we expect something - /// like `<'a, 'b, T>`. - pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<'a, Vec> { - - let mut res = Vec::new(); - loop { - match self.token { - token::Lifetime(_) => { - res.push(self.parse_lifetime()?); - } - _ => { - return Ok(res); - } - } - - if self.token != sep { - return Ok(res); + span: self.prev_span, + name: ident.name + }) } - - self.bump(); + _ => None } } @@ -2458,7 +2319,9 @@ impl<'a> Parser<'a> { -> PResult<'a, P> { let (_, tys, bindings) = if self.eat(&token::ModSep) { self.expect_lt()?; - self.parse_generic_values_after_lt()? + let args = self.parse_generic_args()?; + self.expect_gt()?; + args } else { (Vec::new(), Vec::new(), Vec::new()) }; @@ -4075,69 +3938,76 @@ impl<'a> Parser<'a> { }).emit(); } - // Parses a sequence of bounds if a `:` is found, - // otherwise returns empty list. - fn parse_colon_then_ty_param_bounds(&mut self) -> PResult<'a, TyParamBounds> - { - if !self.eat(&token::Colon) { - Ok(Vec::new()) - } else { - self.parse_ty_param_bounds() - } - } - - // matches bounds = ( boundseq )? - // where boundseq = ( polybound + boundseq ) | polybound - // and polybound = ( 'for' '<' 'region '>' )? bound - // and bound = 'region | trait_ref + // Parse bounds of a type parameter `BOUND + BOUND + BOUND` without trailing `+`. + // BOUND = TY_BOUND | LT_BOUND + // LT_BOUND = LIFETIME (e.g. `'a`) + // TY_BOUND = [?] [for] SIMPLE_PATH (e.g. `?for<'a: 'b> m::Trait<'a>`) fn parse_ty_param_bounds(&mut self) -> PResult<'a, TyParamBounds> { - let mut result = vec![]; + let mut bounds = Vec::new(); loop { - let question_span = self.span; - let ate_question = self.eat(&token::Question); - match self.token { - token::Lifetime(lifetime) => { - if ate_question { - self.span_err(question_span, - "`?` may only modify trait bounds, not lifetime bounds"); - } - result.push(RegionTyParamBound(ast::Lifetime { - id: ast::DUMMY_NODE_ID, - span: self.span, - name: lifetime.name - })); - self.bump(); + let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None }; + if let Some(lifetime) = self.eat_lifetime() { + if let Some(question_span) = question { + self.span_err(question_span, + "`?` may only modify trait bounds, not lifetime bounds"); } - _ if self.token.is_path_start() || self.token.is_keyword(keywords::For) => { - let poly_trait_ref = self.parse_poly_trait_ref()?; - let modifier = if ate_question { - TraitBoundModifier::Maybe - } else { - TraitBoundModifier::None - }; - result.push(TraitTyParamBound(poly_trait_ref, modifier)) - } - _ => break, + bounds.push(RegionTyParamBound(lifetime)); + } else if self.token.is_keyword(keywords::For) || self.token.is_path_start() { + let poly_trait_ref = self.parse_poly_trait_ref()?; + let modifier = if question.is_some() { + TraitBoundModifier::Maybe + } else { + TraitBoundModifier::None + }; + bounds.push(TraitTyParamBound(poly_trait_ref, modifier)); + } else { + break } - if !self.eat(&token::BinOp(token::Plus)) { - break; + // Trailing plus is not allowed for now and we have to detect it. + let is_bound_start = |token: &token::Token| { + token == &token::Question || token.is_lifetime() || + token.is_keyword(keywords::For) || token.is_path_start() + }; + if self.check(&token::BinOp(token::Plus)) && self.look_ahead(1, is_bound_start) { + self.bump(); + } else { + break } } - return Ok(result); + return Ok(bounds); + } + + // Parse bounds of a type parameter `BOUND + BOUND + BOUND` without trailing `+`. + // BOUND = LT_BOUND (e.g. `'a`) + fn parse_lt_param_bounds(&mut self) -> Vec { + let mut lifetimes = Vec::new(); + while let Some(lifetime) = self.eat_lifetime() { + lifetimes.push(lifetime); + if self.check(&token::BinOp(token::Plus)) && self.look_ahead(1, |t| t.is_lifetime()) { + self.bump(); + } else { + break + } + } + lifetimes } /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )? - fn parse_ty_param(&mut self, preceding_attrs: Vec) -> PResult<'a, TyParam> { + fn parse_ty_param(&mut self, preceding_attrs: Vec) -> PResult<'a, TyParam> { let span = self.span; let ident = self.parse_ident()?; - let bounds = self.parse_colon_then_ty_param_bounds()?; + // Parse optional colon and param bounds. + let bounds = if self.eat(&token::Colon) { + self.parse_ty_param_bounds()? + } else { + Vec::new() + }; - let default = if self.check(&token::Eq) { - self.bump(); + let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None @@ -4153,6 +4023,51 @@ impl<'a> Parser<'a> { }) } + /// Parses (possibly empty) list of lifetime and type parameters, possibly including + /// trailing comma and erroneous trailing attributes. + pub fn parse_generic_params(&mut self) -> PResult<'a, (Vec, Vec)> { + let mut lifetime_defs = Vec::new(); + let mut ty_params = Vec::new(); + let mut seen_ty_param = false; + loop { + let attrs = self.parse_outer_attributes()?; + if let Some(lifetime) = self.eat_lifetime() { + // Parse lifetime parameter. + let bounds = if self.eat(&token::Colon) { + self.parse_lt_param_bounds() + } else { + Vec::new() + }; + lifetime_defs.push(LifetimeDef { + attrs: attrs.into(), + lifetime: lifetime, + bounds: bounds, + }); + if seen_ty_param { + self.span_err(self.prev_span, + "lifetime parameters must be declared prior to type parameters"); + } + } else if self.token.is_ident() { + // Parse type parameter. + ty_params.push(self.parse_ty_param(attrs)?); + seen_ty_param = true; + } else { + // Check for trailing attributes and stop parsing. + if !attrs.is_empty() { + let param_kind = if seen_ty_param { "type" } else { "lifetime" }; + self.span_err(attrs[0].span, + &format!("trailing attribute after {} parameters", param_kind)); + } + break + } + + if !self.eat(&token::Comma) { + break + } + } + Ok((lifetime_defs, ty_params)) + } + /// Parse a set of optional generic type parameter declarations. Where /// clauses are not parsed here, and must be added later via /// `parse_where_clause()`. @@ -4162,45 +4077,11 @@ impl<'a> Parser<'a> { /// where typaramseq = ( typaram ) | ( typaram , typaramseq ) pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> { maybe_whole!(self, NtGenerics, |x| x); - let span_lo = self.span.lo; - if self.eat(&token::Lt) { - // Upon encountering attribute in generics list, we do not - // know if it is attached to lifetime or to type param. - // - // Solution: 1. eagerly parse attributes in tandem with - // lifetime defs, 2. store last set of parsed (and unused) - // attributes in `attrs`, and 3. pass in those attributes - // when parsing formal type param after lifetime defs. - let mut attrs = vec![]; - let lifetime_defs = self.parse_lifetime_defs(Some(&mut attrs))?; - let mut seen_default = false; - let mut post_lifetime_attrs = Some(attrs); - let ty_params = self.parse_seq_to_gt(Some(token::Comma), |p| { - p.forbid_lifetime()?; - // Move out of `post_lifetime_attrs` if present. O/w - // not first type param: parse attributes anew. - let attrs = match post_lifetime_attrs.as_mut() { - None => p.parse_outer_attributes()?, - Some(attrs) => mem::replace(attrs, vec![]), - }; - post_lifetime_attrs = None; - let ty_param = p.parse_ty_param(attrs)?; - if ty_param.default.is_some() { - seen_default = true; - } else if seen_default { - let prev_span = p.prev_span; - p.span_err(prev_span, - "type parameters with a default must be trailing"); - } - Ok(ty_param) - })?; - if let Some(attrs) = post_lifetime_attrs { - if !attrs.is_empty() { - self.span_err(attrs[0].span, - "trailing attribute after lifetime parameters"); - } - } + let span_lo = self.span.lo; + if self.eat_lt() { + let (lifetime_defs, ty_params) = self.parse_generic_params()?; + self.expect_gt()?; Ok(ast::Generics { lifetimes: lifetime_defs, ty_params: ty_params, @@ -4215,85 +4096,53 @@ impl<'a> Parser<'a> { } } - fn parse_generic_values_after_lt(&mut self) -> PResult<'a, (Vec, - Vec>, - Vec)> { - let span_lo = self.span.lo; - let lifetimes = self.parse_lifetimes(token::Comma)?; - - let missing_comma = !lifetimes.is_empty() && - !self.token.is_like_gt() && - self.prev_token_kind != PrevTokenKind::Comma; - - if missing_comma { - - let msg = format!("expected `,` or `>` after lifetime \ - name, found `{}`", - self.this_token_to_string()); - let mut err = self.diagnostic().struct_span_err(self.span, &msg); - - let span_hi = self.span.hi; - let span_hi = match self.parse_ty_no_plus() { - Ok(..) => self.span.hi, - Err(ref mut err) => { - self.cancel(err); - span_hi - } - }; - - let msg = format!("did you mean a single argument type &'a Type, \ - or did you mean the comma-separated arguments \ - 'a, Type?"); - err.span_note(mk_sp(span_lo, span_hi), &msg); - return Err(err); - } - - // First parse types. - let (types, returned) = self.parse_seq_to_gt_or_return( - Some(token::Comma), - |p| { - p.forbid_lifetime()?; - if p.look_ahead(1, |t| t == &token::Eq) { - Ok(None) - } else { - Ok(Some(p.parse_ty()?)) + /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, + /// possibly including trailing comma. + fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec>, Vec)> { + let mut lifetimes = Vec::new(); + let mut types = Vec::new(); + let mut bindings = Vec::new(); + let mut seen_type = false; + let mut seen_binding = false; + loop { + let eq_is_next = self.look_ahead(1, |t| t == &token::Eq); // borrowck workaround + if let Some(lifetime) = self.eat_lifetime() { + // Parse lifetime argument. + lifetimes.push(lifetime); + if seen_type || seen_binding { + self.span_err(self.prev_span, + "lifetime parameters must be declared prior to type parameters"); } - } - )?; - - // If we found the `>`, don't continue. - if !returned { - return Ok((lifetimes, types, Vec::new())); - } - - // Then parse type bindings. - let bindings = self.parse_seq_to_gt( - Some(token::Comma), - |p| { - p.forbid_lifetime()?; - let lo = p.span.lo; - let ident = p.parse_ident()?; - p.expect(&token::Eq)?; - let ty = p.parse_ty_no_plus()?; - let hi = ty.span.hi; - let span = mk_sp(lo, hi); - return Ok(TypeBinding{id: ast::DUMMY_NODE_ID, + } else if self.token.is_ident() && eq_is_next { + // Parse associated type binding. + let lo = self.span.lo; + let ident = self.parse_ident()?; + self.bump(); + let ty = self.parse_ty()?; + bindings.push(TypeBinding { + id: ast::DUMMY_NODE_ID, ident: ident, ty: ty, - span: span, + span: mk_sp(lo, self.prev_span.hi), }); + seen_binding = true; + } else if self.token.can_begin_type() { + // Parse type argument. + types.push(self.parse_ty()?); + if seen_binding { + self.span_err(types[types.len() - 1].span, + "type parameters must be declared prior to associated type bindings"); + } + seen_type = true; + } else { + break } - )?; - Ok((lifetimes, types, bindings)) - } - fn forbid_lifetime(&mut self) -> PResult<'a, ()> { - if self.token.is_lifetime() { - let span = self.span; - return Err(self.diagnostic().struct_span_err(span, "lifetime parameters must be \ - declared prior to type parameters")) + if !self.eat(&token::Comma) { + break + } } - Ok(()) + Ok((lifetimes, types, bindings)) } /// Parses an optional `where` clause and places it in `generics`. @@ -4301,7 +4150,7 @@ impl<'a> Parser<'a> { /// ```ignore /// where T : Trait + 'b, 'a : 'b /// ``` - pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> { + pub fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { maybe_whole!(self, NtWhereClause, |x| x); let mut where_clause = WhereClause { @@ -4313,7 +4162,7 @@ impl<'a> Parser<'a> { return Ok(where_clause); } - // This is a temporary hack. + // This is a temporary future proofing. // // We are considering adding generics to the `where` keyword as an alternative higher-rank // parameter syntax (as in `where<'a>` or `where`. To avoid that being a breaking @@ -4330,106 +4179,64 @@ impl<'a> Parser<'a> { } } - let mut parsed_something = false; loop { let lo = self.span.lo; - match self.token { - token::OpenDelim(token::Brace) => { - break - } - - token::Lifetime(..) => { - let bounded_lifetime = - self.parse_lifetime()?; - - self.expect(&token::Colon)?; - - let bounds = - self.parse_lifetimes(token::BinOp(token::Plus))?; - - let hi = self.prev_span.hi; - let span = mk_sp(lo, hi); - - where_clause.predicates.push(ast::WherePredicate::RegionPredicate( - ast::WhereRegionPredicate { - span: span, - lifetime: bounded_lifetime, - bounds: bounds + if let Some(lifetime) = self.eat_lifetime() { + // Bounds starting with a colon are mandatory, but possibly empty. + self.expect(&token::Colon)?; + let bounds = self.parse_lt_param_bounds(); + where_clause.predicates.push(ast::WherePredicate::RegionPredicate( + ast::WhereRegionPredicate { + span: mk_sp(lo, self.prev_span.hi), + lifetime: lifetime, + bounds: bounds, + } + )); + } else if self.token.can_begin_type() { + // Parse optional `for<'a, 'b>`. + // This `for` is parsed greedily and applies to the whole predicate, + // the bounded type can have its own `for` applying only to it. + // Example 1: for<'a> Trait1<'a>: Trait2<'a /*ok*/> + // Example 2: (for<'a> Trait1<'a>): Trait2<'a /*not ok*/> + // Example 3: for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /*ok*/, 'b /*not ok*/> + let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + + // Parse type with mandatory colon and (possibly empty) bounds, + // or with mandatory equality sign and the second type. + let ty = self.parse_ty()?; + if self.eat(&token::Colon) { + let bounds = self.parse_ty_param_bounds()?; + where_clause.predicates.push(ast::WherePredicate::BoundPredicate( + ast::WhereBoundPredicate { + span: mk_sp(lo, self.prev_span.hi), + bound_lifetimes: lifetime_defs, + bounded_ty: ty, + bounds: bounds, } )); - - parsed_something = true; - } - - _ => { - let bound_lifetimes = if self.eat_keyword(keywords::For) { - // Higher ranked constraint. - self.expect(&token::Lt)?; - let lifetime_defs = self.parse_lifetime_defs(None)?; - self.expect_gt()?; - lifetime_defs - } else { - vec![] - }; - - let bounded_ty = self.parse_ty_no_plus()?; - - if self.eat(&token::Colon) { - let bounds = self.parse_ty_param_bounds()?; - let hi = self.prev_span.hi; - let span = mk_sp(lo, hi); - - if bounds.is_empty() { - self.span_err(span, - "each predicate in a `where` clause must have \ - at least one bound in it"); + // FIXME: Decide what should be used here, `=` or `==`. + } else if self.eat(&token::Eq) || self.eat(&token::EqEq) { + let rhs_ty = self.parse_ty()?; + where_clause.predicates.push(ast::WherePredicate::EqPredicate( + ast::WhereEqPredicate { + span: mk_sp(lo, self.prev_span.hi), + lhs_ty: ty, + rhs_ty: rhs_ty, + id: ast::DUMMY_NODE_ID, } - - where_clause.predicates.push(ast::WherePredicate::BoundPredicate( - ast::WhereBoundPredicate { - span: span, - bound_lifetimes: bound_lifetimes, - bounded_ty: bounded_ty, - bounds: bounds, - })); - - parsed_something = true; - } else if self.eat(&token::Eq) { - // let ty = try!(self.parse_ty_no_plus()); - let hi = self.prev_span.hi; - let span = mk_sp(lo, hi); - // where_clause.predicates.push( - // ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { - // id: ast::DUMMY_NODE_ID, - // span: span, - // path: panic!("NYI"), //bounded_ty, - // ty: ty, - // })); - // parsed_something = true; - // // FIXME(#18433) - self.span_err(span, - "equality constraints are not yet supported \ - in where clauses (#20041)"); - } else { - let prev_span = self.prev_span; - self.span_err(prev_span, - "unexpected token in `where` clause"); - } + )); + } else { + return self.unexpected(); } - }; + } else { + break + } if !self.eat(&token::Comma) { break } } - if !parsed_something { - let prev_span = self.prev_span; - self.span_err(prev_span, - "a `where` clause must have at least one predicate \ - in it"); - } - Ok(where_clause) } @@ -4528,13 +4335,13 @@ impl<'a> Parser<'a> { } else if self.look_ahead(1, |t| t.is_lifetime()) && isolated_self(self, 2) { self.bump(); - let lt = self.parse_lifetime()?; + let lt = self.eat_lifetime().expect("not a lifetime"); (SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self)) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) && isolated_self(self, 3) { self.bump(); - let lt = self.parse_lifetime()?; + let lt = self.eat_lifetime().expect("not a lifetime"); self.bump(); (SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self)) } else { @@ -4836,8 +4643,12 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let mut tps = self.parse_generics()?; - // Parse supertrait bounds. - let bounds = self.parse_colon_then_ty_param_bounds()?; + // Parse optional colon and supertrait bounds. + let bounds = if self.eat(&token::Colon) { + self.parse_ty_param_bounds()? + } else { + Vec::new() + }; tps.where_clause = self.parse_where_clause()?; @@ -4928,17 +4739,21 @@ impl<'a> Parser<'a> { /// Parse a::B fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> { - Ok(ast::TraitRef { + Ok(TraitRef { path: self.parse_path(PathStyle::Type)?, ref_id: ast::DUMMY_NODE_ID, }) } - fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec> { + fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec> { if self.eat_keyword(keywords::For) { - self.expect(&token::Lt)?; - let lifetime_defs = self.parse_lifetime_defs(None)?; + self.expect_lt()?; + let (lifetime_defs, ty_params) = self.parse_generic_params()?; self.expect_gt()?; + if !ty_params.is_empty() { + self.span_err(ty_params[0].span, + "only lifetime parameters can be used in this context"); + } Ok(lifetime_defs) } else { Ok(Vec::new()) @@ -4950,7 +4765,7 @@ impl<'a> Parser<'a> { let lo = self.span.lo; let lifetime_defs = self.parse_late_bound_lifetime_defs()?; - Ok(ast::PolyTraitRef { + Ok(PolyTraitRef { bound_lifetimes: lifetime_defs, trait_ref: self.parse_trait_ref()?, span: mk_sp(lo, self.prev_span.hi), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index bf790b96e37f6..d9e47a6b56e8f 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -187,6 +187,29 @@ impl Token { } } + /// Returns `true` if the token can appear at the start of a type. + pub fn can_begin_type(&self) -> bool { + match *self { + OpenDelim(Paren) => true, // tuple + OpenDelim(Bracket) => true, // array + Ident(..) => true, // type name or keyword + Underscore => true, // placeholder + Not => true, // never + BinOp(Star) => true, // raw pointer + BinOp(And) => true, // reference + AndAnd => true, // double reference + Lt | BinOp(Shl) => true, // associated path + ModSep => true, // global path + Interpolated(ref nt) => match **nt { + NtTy(..) => true, + NtIdent(..) => true, + NtPath(..) => true, + _ => false, + }, + _ => false, + } + } + /// Returns `true` if the token is any literal pub fn is_lit(&self) -> bool { match *self { diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs index a38a7bfb93785..5e09473ab77da 100644 --- a/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs @@ -17,10 +17,7 @@ struct RefAny<'a, T>(&'a T); -impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> { - //~^ ERROR expected identifier, found `>` -} +impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {} +//~^ ERROR trailing attribute after type parameters -fn main() { - -} +fn main() {} diff --git a/src/test/compile-fail/generic-non-trailing-defaults.rs b/src/test/compile-fail/generic-non-trailing-defaults.rs new file mode 100644 index 0000000000000..77e5520326379 --- /dev/null +++ b/src/test/compile-fail/generic-non-trailing-defaults.rs @@ -0,0 +1,20 @@ +// 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. + +struct Heap; + +struct Vec; +//~^ ERROR type parameters with a default must be trailing + +struct Foo, C>; +//~^ ERROR type parameters with a default must be trailing +//~| ERROR type parameters with a default cannot use forward declared identifiers + +fn main() {} diff --git a/src/test/compile-fail/issue-20616-1.rs b/src/test/compile-fail/issue-20616-1.rs index 5b4f9942d28b6..a1949df661a34 100644 --- a/src/test/compile-fail/issue-20616-1.rs +++ b/src/test/compile-fail/issue-20616-1.rs @@ -16,7 +16,7 @@ type Type_1_<'a, T> = &'a T; -type Type_1<'a T> = &'a T; //~ error: expected `,` or `>` after lifetime name, found `T` +type Type_1<'a T> = &'a T; //~ error: expected one of `,`, `:`, or `>`, found `T` //type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` diff --git a/src/test/compile-fail/issue-20616-2.rs b/src/test/compile-fail/issue-20616-2.rs index 65305ff3ac82f..87b836d687274 100644 --- a/src/test/compile-fail/issue-20616-2.rs +++ b/src/test/compile-fail/issue-20616-2.rs @@ -19,7 +19,7 @@ type Type_1_<'a, T> = &'a T; //type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` -type Type_2 = Type_1_<'static ()>; //~ error: expected `,` or `>` after lifetime name, found `(` +type Type_2 = Type_1_<'static ()>; //~ error: expected one of `,` or `>`, found `(` //type Type_3 = Box; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-3.rs b/src/test/compile-fail/issue-20616-3.rs index 101f81019d97c..9a5972a7a1641 100644 --- a/src/test/compile-fail/issue-20616-3.rs +++ b/src/test/compile-fail/issue-20616-3.rs @@ -22,7 +22,7 @@ type Type_1_<'a, T> = &'a T; //type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` -type Type_3 = Box; //~ error: expected type, found `,` +type Type_3 = Box; //~ error: expected `>`, found `,` //type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-4.rs b/src/test/compile-fail/issue-20616-4.rs index 6450e9ed68cb7..1567698e476ba 100644 --- a/src/test/compile-fail/issue-20616-4.rs +++ b/src/test/compile-fail/issue-20616-4.rs @@ -25,7 +25,7 @@ type Type_1_<'a, T> = &'a T; //type Type_3 = Box; // error: expected type, found `,` -type Type_4 = Type_1_<'static,, T>; //~ error: expected type, found `,` +type Type_4 = Type_1_<'static,, T>; //~ error: expected `>`, found `,` type Type_5_<'a> = Type_1_<'a, ()>; diff --git a/src/test/compile-fail/issue-20616-5.rs b/src/test/compile-fail/issue-20616-5.rs index d1840427ad8b2..c5a0624574d0e 100644 --- a/src/test/compile-fail/issue-20616-5.rs +++ b/src/test/compile-fail/issue-20616-5.rs @@ -31,7 +31,7 @@ type Type_1_<'a, T> = &'a T; type Type_5_<'a> = Type_1_<'a, ()>; -type Type_5<'a> = Type_1_<'a, (),,>; //~ error: expected type, found `,` +type Type_5<'a> = Type_1_<'a, (),,>; //~ error: expected `>`, found `,` //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-6.rs b/src/test/compile-fail/issue-20616-6.rs index b0b5bc653f6d0..56578409546ff 100644 --- a/src/test/compile-fail/issue-20616-6.rs +++ b/src/test/compile-fail/issue-20616-6.rs @@ -34,7 +34,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` -type Type_6 = Type_5_<'a,,>; //~ error: expected type, found `,` +type Type_6 = Type_5_<'a,,>; //~ error: expected `>`, found `,` //type Type_7 = Box<(),,>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-7.rs b/src/test/compile-fail/issue-20616-7.rs index 0958f8b4ed22c..ecd0a467cf6b0 100644 --- a/src/test/compile-fail/issue-20616-7.rs +++ b/src/test/compile-fail/issue-20616-7.rs @@ -37,7 +37,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` -type Type_7 = Box<(),,>; //~ error: expected type, found `,` +type Type_7 = Box<(),,>; //~ error: expected `>`, found `,` //type Type_8<'a,,> = &'a (); // error: expected ident, found `,` diff --git a/src/test/compile-fail/issue-20616-8.rs b/src/test/compile-fail/issue-20616-8.rs index d6cf9acae9b0b..535672c65e46e 100644 --- a/src/test/compile-fail/issue-20616-8.rs +++ b/src/test/compile-fail/issue-20616-8.rs @@ -40,7 +40,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_7 = Box<(),,>; // error: expected type, found `,` -type Type_8<'a,,> = &'a (); //~ error: expected identifier, found `,` +type Type_8<'a,,> = &'a (); //~ error: expected `>`, found `,` //type Type_9 = Box; // error: expected identifier, found `,` diff --git a/src/test/compile-fail/issue-20616-9.rs b/src/test/compile-fail/issue-20616-9.rs index d64cec446ef3d..b666a8b67aa3f 100644 --- a/src/test/compile-fail/issue-20616-9.rs +++ b/src/test/compile-fail/issue-20616-9.rs @@ -43,4 +43,4 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` -type Type_9 = Box; //~ error: expected identifier, found `,` +type Type_9 = Box; //~ error: expected `>`, found `,` diff --git a/src/test/parse-fail/issue-14303-path.rs b/src/test/parse-fail/issue-14303-path.rs index 431a917c2d9f4..f0d1feffec80b 100644 --- a/src/test/parse-fail/issue-14303-path.rs +++ b/src/test/parse-fail/issue-14303-path.rs @@ -12,4 +12,3 @@ fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {} //~^ ERROR lifetime parameters must be declared prior to type parameters -//~^^ ERROR expected pattern, found `'c` diff --git a/src/test/parse-fail/generic-non-trailing-defaults.rs b/src/test/parse-fail/issue-17904-2.rs similarity index 74% rename from src/test/parse-fail/generic-non-trailing-defaults.rs rename to src/test/parse-fail/issue-17904-2.rs index 2bb593258ae4b..3f41c0edd2e6f 100644 --- a/src/test/parse-fail/generic-non-trailing-defaults.rs +++ b/src/test/parse-fail/issue-17904-2.rs @@ -10,10 +10,6 @@ // compile-flags: -Z parse-only -Z continue-parse-after-error -struct Heap; - -struct Vec; //~ ERROR type parameters with a default must be trailing - -struct Foo, C>; //~ ERROR type parameters with a default must be trailing +struct Bar { x: T } where T: Copy //~ ERROR expected item, found `where` fn main() {} diff --git a/src/test/parse-fail/issue-17904.rs b/src/test/parse-fail/issue-17904.rs index de5aeb02ab788..ae28ac76acb98 100644 --- a/src/test/parse-fail/issue-17904.rs +++ b/src/test/parse-fail/issue-17904.rs @@ -13,7 +13,6 @@ struct Baz where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax. struct Baz where U: Eq(U) -> R; // Notice this parses as well. struct Baz(U) where U: Eq; // This rightfully signals no error as well. -struct Foo where T: Copy, (T); //~ ERROR unexpected token in `where` clause -struct Bar { x: T } where T: Copy //~ ERROR expected item, found `where` +struct Foo where T: Copy, (T); //~ ERROR expected one of `+`, `:`, `==`, or `=`, found `;` fn main() {} diff --git a/src/test/parse-fail/issue-32214.rs b/src/test/parse-fail/issue-32214.rs index 3ba59c8ee946b..9e20009409368 100644 --- a/src/test/parse-fail/issue-32214.rs +++ b/src/test/parse-fail/issue-32214.rs @@ -10,8 +10,7 @@ // compile-flags: -Z parse-only -Z continue-parse-after-error -pub fn test >() { - //~^ ERROR expected `=`, found `>` -} +pub fn test >() {} +//~^ ERROR type parameters must be declared prior to associated type bindings fn main() { } diff --git a/src/test/parse-fail/lifetime-semicolon.rs b/src/test/parse-fail/lifetime-semicolon.rs index 7010d0e7debf2..e1975952fca3e 100644 --- a/src/test/parse-fail/lifetime-semicolon.rs +++ b/src/test/parse-fail/lifetime-semicolon.rs @@ -15,5 +15,4 @@ struct Foo<'a, 'b> { } fn foo<'a, 'b>(x: &mut Foo<'a; 'b>) {} -//~^ ERROR expected `,` or `>` after lifetime name, found `;` -//~^^ NOTE did you mean a single argument type &'a Type, or did you mean the comma-separated +//~^ ERROR expected one of `,` or `>`, found `;` diff --git a/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs index 78d9745408735..cf67b518fff91 100644 --- a/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs +++ b/src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs @@ -10,13 +10,13 @@ // compile-flags: -Z parse-only -Z continue-parse-after-error +// Empty predicate list is OK fn equal1(_: &T, _: &T) -> bool where { -//~^ ERROR a `where` clause must have at least one predicate in it true } +// Empty bound list is OK fn equal2(_: &T, _: &T) -> bool where T: { -//~^ ERROR each predicate in a `where` clause must have at least one bound true } From a8f5047430aa78c2d1ff30b5960cdbde24daab84 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 18 Jan 2017 17:41:57 +0300 Subject: [PATCH 05/86] Add tests --- src/test/compile-fail/impl-trait/no-trait.rs | 15 ++++++++++++ .../where-equality-constraints.rs | 16 +++++++++++++ .../compile-fail/where-lifetime-resolution.rs | 23 +++++++++++++++++++ src/test/parse-fail/bounds-lifetime-1.rs | 15 ++++++++++++ src/test/parse-fail/bounds-lifetime-2.rs | 15 ++++++++++++ src/test/parse-fail/bounds-lifetime-3.rs | 15 ++++++++++++ .../parse-fail/bounds-lifetime-where-1.rs | 15 ++++++++++++ .../parse-fail/bounds-lifetime-where-2.rs | 15 ++++++++++++ src/test/parse-fail/bounds-lifetime-where.rs | 21 +++++++++++++++++ src/test/parse-fail/bounds-lifetime.rs | 23 +++++++++++++++++++ src/test/parse-fail/bounds-type-where-1.rs | 16 +++++++++++++ src/test/parse-fail/bounds-type-where.rs | 21 +++++++++++++++++ src/test/parse-fail/bounds-type.rs | 23 +++++++++++++++++++ 13 files changed, 233 insertions(+) create mode 100644 src/test/compile-fail/impl-trait/no-trait.rs create mode 100644 src/test/compile-fail/where-equality-constraints.rs create mode 100644 src/test/compile-fail/where-lifetime-resolution.rs create mode 100644 src/test/parse-fail/bounds-lifetime-1.rs create mode 100644 src/test/parse-fail/bounds-lifetime-2.rs create mode 100644 src/test/parse-fail/bounds-lifetime-3.rs create mode 100644 src/test/parse-fail/bounds-lifetime-where-1.rs create mode 100644 src/test/parse-fail/bounds-lifetime-where-2.rs create mode 100644 src/test/parse-fail/bounds-lifetime-where.rs create mode 100644 src/test/parse-fail/bounds-lifetime.rs create mode 100644 src/test/parse-fail/bounds-type-where-1.rs create mode 100644 src/test/parse-fail/bounds-type-where.rs create mode 100644 src/test/parse-fail/bounds-type.rs diff --git a/src/test/compile-fail/impl-trait/no-trait.rs b/src/test/compile-fail/impl-trait/no-trait.rs new file mode 100644 index 0000000000000..ce61c5bf63d83 --- /dev/null +++ b/src/test/compile-fail/impl-trait/no-trait.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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(conservative_impl_trait)] + +fn f() -> impl 'static {} //~ ERROR at least one trait must be specified + +fn main() {} diff --git a/src/test/compile-fail/where-equality-constraints.rs b/src/test/compile-fail/where-equality-constraints.rs new file mode 100644 index 0000000000000..5b2fe2901c4ce --- /dev/null +++ b/src/test/compile-fail/where-equality-constraints.rs @@ -0,0 +1,16 @@ +// Copyright 2017 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. + +fn f() where u8 = u16 {} +//~^ ERROR equality constraints are not yet supported in where clauses +fn g() where for<'a> &(u8,) == u16, {} +//~^ ERROR equality constraints are not yet supported in where clauses + +fn main() {} diff --git a/src/test/compile-fail/where-lifetime-resolution.rs b/src/test/compile-fail/where-lifetime-resolution.rs new file mode 100644 index 0000000000000..f4c6842206db1 --- /dev/null +++ b/src/test/compile-fail/where-lifetime-resolution.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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. + +trait Trait1 {} +trait Trait2 {} + +fn f() where + for<'a> Trait1<'a>: Trait1<'a>, // OK + (for<'a> Trait1<'a>): Trait1<'a>, + //~^ ERROR use of undeclared lifetime name `'a` + for<'a> for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, + //~^ ERROR use of undeclared lifetime name `'b` + //~| ERROR nested quantification of lifetimes +{} + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-1.rs b/src/test/parse-fail/bounds-lifetime-1.rs new file mode 100644 index 0000000000000..824d243d5f846 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-1.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A = for<'a 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `'b` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-2.rs b/src/test/parse-fail/bounds-lifetime-2.rs new file mode 100644 index 0000000000000..3c67dda70f562 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-2.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A = for<'a + 'b> fn(); //~ ERROR expected one of `,`, `:`, or `>`, found `+` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-3.rs b/src/test/parse-fail/bounds-lifetime-3.rs new file mode 100644 index 0000000000000..be7c197245e49 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-3.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A = for<,> fn(); //~ ERROR expected `>`, found `,` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where-1.rs b/src/test/parse-fail/bounds-lifetime-where-1.rs new file mode 100644 index 0000000000000..aae9d72998750 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-where-1.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A where 'a; //~ ERROR expected `:`, found `;` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where-2.rs b/src/test/parse-fail/bounds-lifetime-where-2.rs new file mode 100644 index 0000000000000..97dcd5cc5f8c8 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-where-2.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A where , = u8; //~ ERROR expected `=`, found `,` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where.rs b/src/test/parse-fail/bounds-lifetime-where.rs new file mode 100644 index 0000000000000..f7f56446006a5 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime-where.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A where 'a: 'b + 'c = u8; // OK +type A where 'a: 'b, = u8; // OK +type A where 'a: = u8; // OK +type A where 'a:, = u8; // OK +type A where 'a: 'b + 'c = u8; // OK +type A where = u8; // OK +type A where 'a: 'b + = u8; //~ ERROR expected one of `,` or `=`, found `+` + +fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime.rs b/src/test/parse-fail/bounds-lifetime.rs new file mode 100644 index 0000000000000..71547b543c357 --- /dev/null +++ b/src/test/parse-fail/bounds-lifetime.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only -Z continue-parse-after-error + +type A = for<'a: 'b + 'c> fn(); // OK +type A = for<'a: 'b,> fn(); // OK +type A = for<'a:> fn(); // OK +type A = for<'a:,> fn(); // OK +type A = for<'a> fn(); // OK +type A = for<> fn(); // OK + +type A = for<'a, T> fn(); //~ ERROR only lifetime parameters can be used in this context +type A = for<'a: 'b +> fn(); //~ ERROR expected one of `,` or `>`, found `+` + +fn main() {} diff --git a/src/test/parse-fail/bounds-type-where-1.rs b/src/test/parse-fail/bounds-type-where-1.rs new file mode 100644 index 0000000000000..52b5035abda3a --- /dev/null +++ b/src/test/parse-fail/bounds-type-where-1.rs @@ -0,0 +1,16 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A where T, = u8; +//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` + +fn main() {} diff --git a/src/test/parse-fail/bounds-type-where.rs b/src/test/parse-fail/bounds-type-where.rs new file mode 100644 index 0000000000000..789a0934a83cb --- /dev/null +++ b/src/test/parse-fail/bounds-type-where.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only + +type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK +type A where T: Trait, = u8; // OK +type A where T: = u8; // OK +type A where T:, = u8; // OK +type A where T: Trait + Trait = u8; // OK +type A where = u8; // OK +type A where T: Trait + = u8; //~ ERROR expected one of `(`, `,`, `::`, `<`, or `=`, found `+` + +fn main() {} diff --git a/src/test/parse-fail/bounds-type.rs b/src/test/parse-fail/bounds-type.rs new file mode 100644 index 0000000000000..6e339429eed33 --- /dev/null +++ b/src/test/parse-fail/bounds-type.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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. + +// compile-flags: -Z parse-only -Z continue-parse-after-error + +struct S< + T: 'a + Tr, // OK + T: Tr + 'a, // OK + T: 'a, // OK + T:, // OK + T: ?for<'a: 'b + 'c> Trait, // OK + T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds + T: Tr +, //~ ERROR expected one of `(`, `,`, `::`, `<`, `=`, or `>`, found `+` +>; + +fn main() {} From 375cb2eec70f239b477c6b88852c8258765b5420 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 18 Jan 2017 19:01:04 +0300 Subject: [PATCH 06/86] Improve some expected/found error messages from parser --- src/libsyntax/parse/parser.rs | 61 +++++++++++++++---- src/test/compile-fail/issue-20616-3.rs | 2 +- src/test/compile-fail/issue-20616-4.rs | 3 +- src/test/compile-fail/issue-20616-5.rs | 3 +- src/test/compile-fail/issue-20616-6.rs | 3 +- src/test/compile-fail/issue-20616-7.rs | 2 +- src/test/compile-fail/issue-20616-8.rs | 2 +- src/test/compile-fail/issue-20616-9.rs | 2 +- src/test/parse-fail/bounds-lifetime-3.rs | 2 +- .../parse-fail/bounds-lifetime-where-2.rs | 2 +- 10 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c589f1a7aaaa0..939f126640d99 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -192,14 +192,22 @@ pub enum TokenType { Token(token::Token), Keyword(keywords::Keyword), Operator, + Lifetime, + Ident, + Path, + Type, } impl TokenType { fn to_string(&self) -> String { match *self { TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)), - TokenType::Operator => "an operator".to_string(), TokenType::Keyword(kw) => format!("`{}`", kw.name()), + TokenType::Operator => "an operator".to_string(), + TokenType::Lifetime => "lifetime".to_string(), + TokenType::Ident => "identifier".to_string(), + TokenType::Path => "path".to_string(), + TokenType::Type => "type".to_string(), } } } @@ -552,6 +560,33 @@ impl<'a> Parser<'a> { } } + fn check_ident(&mut self) -> bool { + if self.token.is_ident() { + true + } else { + self.expected_tokens.push(TokenType::Ident); + false + } + } + + fn check_path(&mut self) -> bool { + if self.token.is_path_start() { + true + } else { + self.expected_tokens.push(TokenType::Path); + false + } + } + + fn check_type(&mut self) -> bool { + if self.token.can_begin_type() { + true + } else { + self.expected_tokens.push(TokenType::Type); + false + } + } + /// Expect and consume an `&`. If `&&` is seen, replace it with a single /// `&` and continue. If an `&` is not seen, signal an error. fn expect_and(&mut self) -> PResult<'a, ()> { @@ -1802,7 +1837,10 @@ impl<'a> Parser<'a> { name: ident.name }) } - _ => None + _ => { + self.expected_tokens.push(TokenType::Lifetime); + None + } } } @@ -3953,7 +3991,7 @@ impl<'a> Parser<'a> { "`?` may only modify trait bounds, not lifetime bounds"); } bounds.push(RegionTyParamBound(lifetime)); - } else if self.token.is_keyword(keywords::For) || self.token.is_path_start() { + } else {if self.check_keyword(keywords::For) || self.check_path() { let poly_trait_ref = self.parse_poly_trait_ref()?; let modifier = if question.is_some() { TraitBoundModifier::Maybe @@ -3963,7 +4001,7 @@ impl<'a> Parser<'a> { bounds.push(TraitTyParamBound(poly_trait_ref, modifier)); } else { break - } + }} // Trailing plus is not allowed for now and we have to detect it. let is_bound_start = |token: &token::Token| { @@ -4047,7 +4085,7 @@ impl<'a> Parser<'a> { self.span_err(self.prev_span, "lifetime parameters must be declared prior to type parameters"); } - } else if self.token.is_ident() { + } else {if self.check_ident() { // Parse type parameter. ty_params.push(self.parse_ty_param(attrs)?); seen_ty_param = true; @@ -4059,7 +4097,7 @@ impl<'a> Parser<'a> { &format!("trailing attribute after {} parameters", param_kind)); } break - } + }} if !self.eat(&token::Comma) { break @@ -4105,7 +4143,6 @@ impl<'a> Parser<'a> { let mut seen_type = false; let mut seen_binding = false; loop { - let eq_is_next = self.look_ahead(1, |t| t == &token::Eq); // borrowck workaround if let Some(lifetime) = self.eat_lifetime() { // Parse lifetime argument. lifetimes.push(lifetime); @@ -4113,7 +4150,7 @@ impl<'a> Parser<'a> { self.span_err(self.prev_span, "lifetime parameters must be declared prior to type parameters"); } - } else if self.token.is_ident() && eq_is_next { + } else {if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { // Parse associated type binding. let lo = self.span.lo; let ident = self.parse_ident()?; @@ -4126,7 +4163,7 @@ impl<'a> Parser<'a> { span: mk_sp(lo, self.prev_span.hi), }); seen_binding = true; - } else if self.token.can_begin_type() { + } else if self.check_type() { // Parse type argument. types.push(self.parse_ty()?); if seen_binding { @@ -4136,7 +4173,7 @@ impl<'a> Parser<'a> { seen_type = true; } else { break - } + }} if !self.eat(&token::Comma) { break @@ -4192,7 +4229,7 @@ impl<'a> Parser<'a> { bounds: bounds, } )); - } else if self.token.can_begin_type() { + } else {if self.check_type() { // Parse optional `for<'a, 'b>`. // This `for` is parsed greedily and applies to the whole predicate, // the bounded type can have its own `for` applying only to it. @@ -4230,7 +4267,7 @@ impl<'a> Parser<'a> { } } else { break - } + }} if !self.eat(&token::Comma) { break diff --git a/src/test/compile-fail/issue-20616-3.rs b/src/test/compile-fail/issue-20616-3.rs index 9a5972a7a1641..e5ed46d2cb3b0 100644 --- a/src/test/compile-fail/issue-20616-3.rs +++ b/src/test/compile-fail/issue-20616-3.rs @@ -22,7 +22,7 @@ type Type_1_<'a, T> = &'a T; //type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` -type Type_3 = Box; //~ error: expected `>`, found `,` +type Type_3 = Box; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` //type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-4.rs b/src/test/compile-fail/issue-20616-4.rs index 1567698e476ba..9b731289e138b 100644 --- a/src/test/compile-fail/issue-20616-4.rs +++ b/src/test/compile-fail/issue-20616-4.rs @@ -25,7 +25,8 @@ type Type_1_<'a, T> = &'a T; //type Type_3 = Box; // error: expected type, found `,` -type Type_4 = Type_1_<'static,, T>; //~ error: expected `>`, found `,` +type Type_4 = Type_1_<'static,, T>; +//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` type Type_5_<'a> = Type_1_<'a, ()>; diff --git a/src/test/compile-fail/issue-20616-5.rs b/src/test/compile-fail/issue-20616-5.rs index c5a0624574d0e..5e3b024da9a07 100644 --- a/src/test/compile-fail/issue-20616-5.rs +++ b/src/test/compile-fail/issue-20616-5.rs @@ -31,7 +31,8 @@ type Type_1_<'a, T> = &'a T; type Type_5_<'a> = Type_1_<'a, ()>; -type Type_5<'a> = Type_1_<'a, (),,>; //~ error: expected `>`, found `,` +type Type_5<'a> = Type_1_<'a, (),,>; +//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-6.rs b/src/test/compile-fail/issue-20616-6.rs index 56578409546ff..b6ee26f9f62b8 100644 --- a/src/test/compile-fail/issue-20616-6.rs +++ b/src/test/compile-fail/issue-20616-6.rs @@ -34,7 +34,8 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` -type Type_6 = Type_5_<'a,,>; //~ error: expected `>`, found `,` +type Type_6 = Type_5_<'a,,>; +//~^ error: expected one of `>`, identifier, lifetime, or type, found `,` //type Type_7 = Box<(),,>; // error: expected type, found `,` diff --git a/src/test/compile-fail/issue-20616-7.rs b/src/test/compile-fail/issue-20616-7.rs index ecd0a467cf6b0..fef3dd4e31d5a 100644 --- a/src/test/compile-fail/issue-20616-7.rs +++ b/src/test/compile-fail/issue-20616-7.rs @@ -37,7 +37,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` -type Type_7 = Box<(),,>; //~ error: expected `>`, found `,` +type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,` //type Type_8<'a,,> = &'a (); // error: expected ident, found `,` diff --git a/src/test/compile-fail/issue-20616-8.rs b/src/test/compile-fail/issue-20616-8.rs index 535672c65e46e..b7bef47c4f442 100644 --- a/src/test/compile-fail/issue-20616-8.rs +++ b/src/test/compile-fail/issue-20616-8.rs @@ -40,7 +40,7 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_7 = Box<(),,>; // error: expected type, found `,` -type Type_8<'a,,> = &'a (); //~ error: expected `>`, found `,` +type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,` //type Type_9 = Box; // error: expected identifier, found `,` diff --git a/src/test/compile-fail/issue-20616-9.rs b/src/test/compile-fail/issue-20616-9.rs index b666a8b67aa3f..5c16d24cef854 100644 --- a/src/test/compile-fail/issue-20616-9.rs +++ b/src/test/compile-fail/issue-20616-9.rs @@ -43,4 +43,4 @@ type Type_5_<'a> = Type_1_<'a, ()>; //type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` -type Type_9 = Box; //~ error: expected `>`, found `,` +type Type_9 = Box; //~ error: expected one of `>`, identifier, or lifetime, found `,` diff --git a/src/test/parse-fail/bounds-lifetime-3.rs b/src/test/parse-fail/bounds-lifetime-3.rs index be7c197245e49..e04431598156c 100644 --- a/src/test/parse-fail/bounds-lifetime-3.rs +++ b/src/test/parse-fail/bounds-lifetime-3.rs @@ -10,6 +10,6 @@ // compile-flags: -Z parse-only -type A = for<,> fn(); //~ ERROR expected `>`, found `,` +type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,` fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where-2.rs b/src/test/parse-fail/bounds-lifetime-where-2.rs index 97dcd5cc5f8c8..ffcacdf357df5 100644 --- a/src/test/parse-fail/bounds-lifetime-where-2.rs +++ b/src/test/parse-fail/bounds-lifetime-where-2.rs @@ -10,6 +10,6 @@ // compile-flags: -Z parse-only -type A where , = u8; //~ ERROR expected `=`, found `,` +type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,` fn main() {} From 65aeafa24f1542c23643a67172b7b2fec4f290cc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 24 Jan 2017 22:55:45 +0300 Subject: [PATCH 07/86] parser: Permit trailing +'s in bound lists --- src/libsyntax/parse/parser.rs | 14 +++----------- src/test/parse-fail/bounds-lifetime-3.rs | 15 --------------- src/test/parse-fail/bounds-lifetime-where-2.rs | 15 --------------- src/test/parse-fail/bounds-lifetime-where.rs | 3 ++- src/test/parse-fail/bounds-lifetime.rs | 3 ++- src/test/parse-fail/bounds-type-where-1.rs | 16 ---------------- src/test/parse-fail/bounds-type-where.rs | 4 +++- src/test/parse-fail/bounds-type.rs | 2 +- 8 files changed, 11 insertions(+), 61 deletions(-) delete mode 100644 src/test/parse-fail/bounds-lifetime-3.rs delete mode 100644 src/test/parse-fail/bounds-lifetime-where-2.rs delete mode 100644 src/test/parse-fail/bounds-type-where-1.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 939f126640d99..9e3c1dcef8a6e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4003,14 +4003,7 @@ impl<'a> Parser<'a> { break }} - // Trailing plus is not allowed for now and we have to detect it. - let is_bound_start = |token: &token::Token| { - token == &token::Question || token.is_lifetime() || - token.is_keyword(keywords::For) || token.is_path_start() - }; - if self.check(&token::BinOp(token::Plus)) && self.look_ahead(1, is_bound_start) { - self.bump(); - } else { + if !self.eat(&token::BinOp(token::Plus)) { break } } @@ -4024,9 +4017,8 @@ impl<'a> Parser<'a> { let mut lifetimes = Vec::new(); while let Some(lifetime) = self.eat_lifetime() { lifetimes.push(lifetime); - if self.check(&token::BinOp(token::Plus)) && self.look_ahead(1, |t| t.is_lifetime()) { - self.bump(); - } else { + + if !self.eat(&token::BinOp(token::Plus)) { break } } diff --git a/src/test/parse-fail/bounds-lifetime-3.rs b/src/test/parse-fail/bounds-lifetime-3.rs deleted file mode 100644 index e04431598156c..0000000000000 --- a/src/test/parse-fail/bounds-lifetime-3.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 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. - -// compile-flags: -Z parse-only - -type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,` - -fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where-2.rs b/src/test/parse-fail/bounds-lifetime-where-2.rs deleted file mode 100644 index ffcacdf357df5..0000000000000 --- a/src/test/parse-fail/bounds-lifetime-where-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 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. - -// compile-flags: -Z parse-only - -type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,` - -fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime-where.rs b/src/test/parse-fail/bounds-lifetime-where.rs index f7f56446006a5..0a30818bc96ae 100644 --- a/src/test/parse-fail/bounds-lifetime-where.rs +++ b/src/test/parse-fail/bounds-lifetime-where.rs @@ -16,6 +16,7 @@ type A where 'a: = u8; // OK type A where 'a:, = u8; // OK type A where 'a: 'b + 'c = u8; // OK type A where = u8; // OK -type A where 'a: 'b + = u8; //~ ERROR expected one of `,` or `=`, found `+` +type A where 'a: 'b + = u8; // OK +type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,` fn main() {} diff --git a/src/test/parse-fail/bounds-lifetime.rs b/src/test/parse-fail/bounds-lifetime.rs index 71547b543c357..5113a6b4803fc 100644 --- a/src/test/parse-fail/bounds-lifetime.rs +++ b/src/test/parse-fail/bounds-lifetime.rs @@ -16,8 +16,9 @@ type A = for<'a:> fn(); // OK type A = for<'a:,> fn(); // OK type A = for<'a> fn(); // OK type A = for<> fn(); // OK +type A = for<'a: 'b +> fn(); // OK type A = for<'a, T> fn(); //~ ERROR only lifetime parameters can be used in this context -type A = for<'a: 'b +> fn(); //~ ERROR expected one of `,` or `>`, found `+` +type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,` fn main() {} diff --git a/src/test/parse-fail/bounds-type-where-1.rs b/src/test/parse-fail/bounds-type-where-1.rs deleted file mode 100644 index 52b5035abda3a..0000000000000 --- a/src/test/parse-fail/bounds-type-where-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 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. - -// compile-flags: -Z parse-only - -type A where T, = u8; -//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` - -fn main() {} diff --git a/src/test/parse-fail/bounds-type-where.rs b/src/test/parse-fail/bounds-type-where.rs index 789a0934a83cb..9dc5d8277446d 100644 --- a/src/test/parse-fail/bounds-type-where.rs +++ b/src/test/parse-fail/bounds-type-where.rs @@ -16,6 +16,8 @@ type A where T: = u8; // OK type A where T:, = u8; // OK type A where T: Trait + Trait = u8; // OK type A where = u8; // OK -type A where T: Trait + = u8; //~ ERROR expected one of `(`, `,`, `::`, `<`, or `=`, found `+` +type A where T: Trait + = u8; // OK +type A where T, = u8; +//~^ ERROR expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,` fn main() {} diff --git a/src/test/parse-fail/bounds-type.rs b/src/test/parse-fail/bounds-type.rs index 6e339429eed33..c224b44a14bf1 100644 --- a/src/test/parse-fail/bounds-type.rs +++ b/src/test/parse-fail/bounds-type.rs @@ -16,8 +16,8 @@ struct S< T: 'a, // OK T:, // OK T: ?for<'a: 'b + 'c> Trait, // OK + T: Tr +, // OK T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds - T: Tr +, //~ ERROR expected one of `(`, `,`, `::`, `<`, `=`, or `>`, found `+` >; fn main() {} From 4186037aaa1a6aa3ba15a10130b424e7508bd276 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sun, 22 Jan 2017 00:28:17 +0200 Subject: [PATCH 08/86] Make backtraces work on Windows GNU targets again. This is done by adding a function that can return a filename to pass to backtrace_create_state. The filename is obtained in a safe way by first getting the filename, locking the file so it can't be moved, and then getting the filename again and making sure it's the same. See: https://github.com/rust-lang/rust/pull/37359#issuecomment-260123399 Issue: #33985 --- src/libstd/sys/unix/backtrace/mod.rs | 7 ++++ src/libstd/sys/windows/backtrace.rs | 48 +++++++++++++++++++++++ src/libstd/sys/windows/c.rs | 23 +++++++++++ src/libstd/sys/windows/mod.rs | 46 ++++++++++++++++++++++ src/libstd/sys_common/gnu/libbacktrace.rs | 17 +++++++- src/test/run-pass/backtrace-debuginfo.rs | 2 - src/test/run-pass/backtrace.rs | 4 -- 7 files changed, 140 insertions(+), 7 deletions(-) diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index d7c05e513f68c..e3f1b23f7a24b 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -83,9 +83,16 @@ /// to symbols. This is a bit of a hokey implementation as-is, but it works for /// all unix platforms we support right now, so it at least gets the job done. +use io; +use fs; + pub use self::tracing::write; // tracing impls: mod tracing; // symbol resolvers: mod printing; + +pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) +} diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index 82a44c1c1103b..e6182cda58a28 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -30,9 +30,13 @@ use io; use libc::c_void; use mem; use ptr; +use path::PathBuf; +use fs::{OpenOptions, File}; +use sys::ext::fs::OpenOptionsExt; use sys::c; use sys::dynamic_lib::DynamicLibrary; use sys::mutex::Mutex; +use sys::handle::Handle; macro_rules! sym { ($lib:expr, $e:expr, $t:ident) => ( @@ -157,3 +161,47 @@ unsafe fn _write(w: &mut Write) -> io::Result<()> { Ok(()) } + +fn query_full_process_image_name() -> io::Result { + unsafe { + let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, + c::FALSE, + c::GetCurrentProcessId())); + super::fill_utf16_buf(|buf, mut sz| { + if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { + 0 + } else { + sz + } + }, super::os2path) + } +} + +fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { + // We query the current image name, open the file without FILE_SHARE_DELETE so it + // can't be moved and then get the current image name again. If the names are the + // same than we have successfully locked the file + let image_name1 = query_full_process_image_name()?; + let file = OpenOptions::new() + .read(true) + .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) + .open(&image_name1)?; + let image_name2 = query_full_process_image_name()?; + + if image_name1 != image_name2 { + return Err(io::Error::new(io::ErrorKind::Other, + "executable moved while trying to lock it")); + } + + Ok((image_name1, file)) +} + +// Get the executable filename for libbacktrace +// This returns the path in the ANSI code page and a File which should remain open +// for as long as the path should remain valid +pub fn get_executable_filename() -> io::Result<(Vec, File)> { + let (executable, file) = lock_and_get_executable_filename()?; + let u16_executable = super::to_u16s(executable.into_os_string())?; + Ok((super::wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, + &u16_executable, true)?, file)) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index dc7b2fc9a6bab..c6fac6d1759b1 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -69,6 +69,7 @@ pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; +pub type LPSTR = *mut CHAR; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; @@ -157,6 +158,7 @@ pub const WSAECONNREFUSED: c_int = 10061; pub const MAX_PROTOCOL_CHAIN: DWORD = 7; +pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; pub const TOKEN_READ: DWORD = 0x20008; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; @@ -218,6 +220,10 @@ pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200; pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400; pub const STARTF_USESTDHANDLES: DWORD = 0x00000100; +pub const CP_ACP: UINT = 0; + +pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; + pub const AF_INET: c_int = 2; pub const AF_INET6: c_int = 23; pub const SD_BOTH: c_int = 2; @@ -888,6 +894,9 @@ extern "system" { pNumArgs: *mut c_int) -> *mut *mut u16; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; + pub fn OpenProcess(dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwProcessId: DWORD) -> HANDLE; pub fn OpenProcessToken(ProcessHandle: HANDLE, DesiredAccess: DWORD, TokenHandle: *mut HANDLE) -> BOOL; @@ -973,6 +982,14 @@ extern "system" { pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn WideCharToMultiByte(CodePage: UINT, + dwFlags: DWORD, + lpWideCharStr: LPCWSTR, + cchWideChar: c_int, + lpMultiByteStr: LPSTR, + cbMultiByte: c_int, + lpDefaultChar: LPCSTR, + lpUsedDefaultChar: LPBOOL) -> c_int; pub fn closesocket(socket: SOCKET) -> c_int; pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, @@ -1136,6 +1153,12 @@ compat_fn! { _dwFlags: DWORD) -> DWORD { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } + pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, + _dwFlags: DWORD, + _lpExeName: LPWSTR, + _lpdwSize: LPDWORD) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index defc41c5f46a3..4468cf574b38a 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -10,6 +10,7 @@ #![allow(missing_docs, bad_style)] +use ptr; use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; use os::windows::ffi::{OsStrExt, OsStringExt}; @@ -171,6 +172,51 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } +fn wide_char_to_multi_byte(code_page: u32, + flags: u32, + s: &[u16], + no_default_char: bool) + -> io::Result> { + unsafe { + let mut size = c::WideCharToMultiByte(code_page, + flags, + s.as_ptr(), + s.len() as i32, + ptr::null_mut(), + 0, + ptr::null(), + ptr::null_mut()); + if size == 0 { + return Err(io::Error::last_os_error()); + } + + let mut buf = Vec::with_capacity(size as usize); + buf.set_len(size as usize); + + let mut used_default_char = c::FALSE; + size = c::WideCharToMultiByte(code_page, + flags, + s.as_ptr(), + s.len() as i32, + buf.as_mut_ptr(), + buf.len() as i32, + ptr::null(), + if no_default_char { &mut used_default_char } + else { ptr::null_mut() }); + if size == 0 { + return Err(io::Error::last_os_error()); + } + if no_default_char && used_default_char == c::TRUE { + return Err(io::Error::new(io::ErrorKind::InvalidData, + "string cannot be converted to requested code page")); + } + + buf.set_len(size as usize); + + Ok(buf) + } +} + pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { match v.iter().position(|c| *c == 0) { // don't include the 0 diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs index b5802afc10943..94d206f3ac3c1 100644 --- a/src/libstd/sys_common/gnu/libbacktrace.rs +++ b/src/libstd/sys_common/gnu/libbacktrace.rs @@ -16,6 +16,7 @@ use sys_common::backtrace::{output, output_fileline}; pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, symaddr: *mut libc::c_void) -> io::Result<()> { use ffi::CStr; + use mem; use ptr; //////////////////////////////////////////////////////////////////////// @@ -124,7 +125,21 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, unsafe fn init_state() -> *mut backtrace_state { static mut STATE: *mut backtrace_state = ptr::null_mut(); if !STATE.is_null() { return STATE } - STATE = backtrace_create_state(ptr::null(), 0, error_cb, + + let filename = match ::sys::backtrace::get_executable_filename() { + Ok((filename, file)) => { + // filename is purposely leaked here since libbacktrace requires + // it to stay allocated permanently, file is also leaked so that + // the file stays locked + let filename_ptr = filename.as_ptr(); + mem::forget(filename); + mem::forget(file); + filename_ptr + }, + Err(_) => ptr::null(), + }; + + STATE = backtrace_create_state(filename, 0, error_cb, ptr::null_mut()); STATE } diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 72cf109fd5974..626eccfc9ec86 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -37,7 +37,6 @@ macro_rules! dump_and_die { target_os = "ios", target_os = "android", all(target_os = "linux", target_arch = "arm"), - target_os = "windows", target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", @@ -173,4 +172,3 @@ fn main() { run_test(&args[0]); } } - diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 75c665b04a123..834ce984e6632 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -104,10 +104,6 @@ fn runtest(me: &str) { } fn main() { - if cfg!(windows) && cfg!(target_env = "gnu") { - return - } - let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "fail" { foo(); From af46d69b8a3d553a4d33e0c9d296b845c404e499 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 15 Jan 2017 08:42:33 +0100 Subject: [PATCH 09/86] Remove Reflect * Remove the Reflect trait * Remove the "reflect" lang feature --- src/libcore/lib.rs | 1 - src/libcore/marker.rs | 56 ----------------- src/librustc/traits/select.rs | 60 +------------------ src/libsyntax/feature_gate.rs | 6 +- src/test/compile-fail/reflect-assoc.rs | 37 ------------ src/test/compile-fail/reflect-object-param.rs | 49 --------------- src/test/compile-fail/reflect.rs | 41 ------------- src/tools/tidy/src/features.rs | 2 +- 8 files changed, 5 insertions(+), 247 deletions(-) delete mode 100644 src/test/compile-fail/reflect-assoc.rs delete mode 100644 src/test/compile-fail/reflect-object-param.rs delete mode 100644 src/test/compile-fail/reflect.rs diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 35324f7b5968f..98871bd084e3c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -82,7 +82,6 @@ #![feature(no_core)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] -#![feature(reflect)] #![feature(unwind_attributes)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 798f1e6cbeb84..ede22ccddc62f 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -553,59 +553,3 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} } - -/// Types that can be reflected over. -/// -/// By "reflection" we mean use of the [`Any`][any] trait, or related -/// machinery such as [`TypeId`][typeid]. -/// -/// `Reflect` is implemented for all types. Its purpose is to ensure -/// that when you write a generic function that will employ reflection, -/// that must be reflected (no pun intended) in the generic bounds of -/// that function. -/// -/// ``` -/// #![feature(reflect_marker)] -/// use std::marker::Reflect; -/// use std::any::Any; -/// -/// # #[allow(dead_code)] -/// fn foo(x: &T) { -/// let any: &Any = x; -/// if any.is::() { println!("u32"); } -/// } -/// ``` -/// -/// Without the bound `T: Reflect`, `foo` would not typecheck. (As -/// a matter of style, it would be preferable to write `T: Any`, -/// because `T: Any` implies `T: Reflect` and `T: 'static`, but we -/// use `Reflect` here for illustrative purposes.) -/// -/// The `Reflect` bound serves to alert `foo`'s caller to the -/// fact that `foo` may behave differently depending on whether -/// `T` is `u32` or not. The ability for a caller to reason about what -/// a function may do based solely on what generic bounds are declared -/// is often called the "[parametricity property][param]". Despite the -/// use of `Reflect`, Rust lacks true parametricity because a generic -/// function can, at the very least, call [`mem::size_of`][size_of] -/// without employing any trait bounds whatsoever. -/// -/// [any]: ../any/trait.Any.html -/// [typeid]: ../any/struct.TypeId.html -/// [param]: http://en.wikipedia.org/wiki/Parametricity -/// [size_of]: ../mem/fn.size_of.html -#[rustc_reflect_like] -#[unstable(feature = "reflect_marker", - reason = "requires RFC and more experience", - issue = "27749")] -#[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")] -#[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \ - ensure all type parameters are bounded by `Any`"] -pub trait Reflect {} - -#[unstable(feature = "reflect_marker", - reason = "requires RFC and more experience", - issue = "27749")] -#[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")] -#[allow(deprecated)] -impl Reflect for .. { } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 23cfc2517590c..4990bb9f521d3 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -204,7 +204,6 @@ enum SelectionCandidate<'tcx> { ParamCandidate(ty::PolyTraitRef<'tcx>), ImplCandidate(DefId), DefaultImplCandidate(DefId), - DefaultImplObjectCandidate(DefId), /// This is a trait matching with a projected type as `Self`, and /// we found an applicable bound in the trait definition. @@ -237,9 +236,6 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> { } ImplCandidate(def_id) => ImplCandidate(def_id), DefaultImplCandidate(def_id) => DefaultImplCandidate(def_id), - DefaultImplObjectCandidate(def_id) => { - DefaultImplObjectCandidate(def_id) - } ProjectionCandidate => ProjectionCandidate, FnPointerCandidate => FnPointerCandidate, ObjectCandidate => ObjectCandidate, @@ -1431,17 +1427,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match self_ty.sty { ty::TyDynamic(..) => { // For object types, we don't know what the closed - // over types are. For most traits, this means we - // conservatively say nothing; a candidate may be - // added by `assemble_candidates_from_object_ty`. - // However, for the kind of magic reflect trait, - // we consider it to be implemented even for - // object types, because it just lets you reflect - // onto the object type, not into the object's - // interior. - if self.tcx().has_attr(def_id, "rustc_reflect_like") { - candidates.vec.push(DefaultImplObjectCandidate(def_id)); - } + // over types are. This means we conservatively + // say nothing; a candidate may be added by + // `assemble_candidates_from_object_ty`. } ty::TyParam(..) | ty::TyProjection(..) | @@ -1671,7 +1659,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { FnPointerCandidate | BuiltinObjectCandidate | BuiltinUnsizeCandidate | - DefaultImplObjectCandidate(..) | BuiltinCandidate { .. } => { // We have a where-clause so don't go around looking // for impls. @@ -1998,11 +1985,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Ok(VtableDefaultImpl(data)) } - DefaultImplObjectCandidate(trait_def_id) => { - let data = self.confirm_default_impl_object_candidate(obligation, trait_def_id); - Ok(VtableDefaultImpl(data)) - } - ImplCandidate(impl_def_id) => { Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id))) } @@ -2138,42 +2120,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { self.vtable_default_impl(obligation, trait_def_id, ty::Binder(types)) } - fn confirm_default_impl_object_candidate(&mut self, - obligation: &TraitObligation<'tcx>, - trait_def_id: DefId) - -> VtableDefaultImplData> - { - debug!("confirm_default_impl_object_candidate({:?}, {:?})", - obligation, - trait_def_id); - - assert!(self.tcx().has_attr(trait_def_id, "rustc_reflect_like")); - - // OK to skip binder, it is reintroduced below - let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); - match self_ty.sty { - ty::TyDynamic(ref data, ..) => { - // OK to skip the binder, it is reintroduced below - let principal = data.principal().unwrap(); - let input_types = principal.input_types(); - let assoc_types = data.projection_bounds() - .map(|pb| pb.skip_binder().ty); - let all_types: Vec<_> = input_types.chain(assoc_types) - .collect(); - - // reintroduce the two binding levels we skipped, then flatten into one - let all_types = ty::Binder(ty::Binder(all_types)); - let all_types = self.tcx().flatten_late_bound_regions(&all_types); - - self.vtable_default_impl(obligation, trait_def_id, all_types) - } - _ => { - bug!("asked to confirm default object implementation for non-object type: {:?}", - self_ty); - } - } - } - /// See `confirm_default_impl_candidate` fn vtable_default_impl(&mut self, obligation: &TraitObligation<'tcx>, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c25020caf857e..83cd7e2fc18a4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -124,7 +124,6 @@ declare_features! ( (active, advanced_slice_patterns, "1.0.0", Some(23121)), (active, box_syntax, "1.0.0", Some(27779)), (active, placement_in_syntax, "1.0.0", Some(27779)), - (active, reflect, "1.0.0", Some(27749)), (active, unboxed_closures, "1.0.0", Some(29625)), (active, allocator, "1.0.0", Some(27389)), @@ -334,6 +333,7 @@ declare_features! ( (removed, managed_boxes, "1.0.0", None), // Allows use of unary negate on unsigned integers, e.g. -e for e: u8 (removed, negate_unsigned, "1.0.0", Some(29645)), + (removed, reflect, "1.0.0", Some(27749)), // A way to temporarily opt out of opt in copy. This will *never* be accepted. (removed, opt_out_copy, "1.0.0", None), (removed, quad_precision_float, "1.0.0", None), @@ -731,10 +731,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "unboxed_closures", "unboxed_closures are still evolving", cfg_fn!(unboxed_closures))), - ("rustc_reflect_like", Whitelisted, Gated(Stability::Unstable, - "reflect", - "defining reflective traits is still evolving", - cfg_fn!(reflect))), ("windows_subsystem", Whitelisted, Gated(Stability::Unstable, "windows_subsystem", diff --git a/src/test/compile-fail/reflect-assoc.rs b/src/test/compile-fail/reflect-assoc.rs deleted file mode 100644 index 47da97daaffda..0000000000000 --- a/src/test/compile-fail/reflect-assoc.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 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(reflect_marker)] - -// Test that types that appear in assoc bindings in an object -// type are subject to the reflect check. - -use std::marker::Reflect; -use std::io::Write; - -trait Get { - type Output; - fn get(self) -> Self::Output; -} - -struct Struct(T); - -fn is_reflect() { } - -fn a() { - is_reflect::>>(); //~ ERROR E0277 -} - -fn ok_a() { - is_reflect::>>(); // OK -} - -fn main() { -} diff --git a/src/test/compile-fail/reflect-object-param.rs b/src/test/compile-fail/reflect-object-param.rs deleted file mode 100644 index be0dbd801b796..0000000000000 --- a/src/test/compile-fail/reflect-object-param.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 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(reflect_marker)] - -// Test that types that appear in input types in an object type are -// subject to the reflect check. - -use std::marker::Reflect; -use std::io::Write; - -trait Get { - fn get(self) -> T; -} - -struct Struct(T); - -fn is_reflect() { } - -fn a() { - is_reflect::(); //~ ERROR E0277 -} - -fn ok_a() { - is_reflect::(); // OK -} - -fn b() { - is_reflect::>>(); //~ ERROR E0277 -} - -fn ok_b() { - is_reflect::>>(); // OK -} - -fn c() { - is_reflect::>>>(); //~ ERROR E0277 -} - -fn main() { - is_reflect::>>>(); // OK -} diff --git a/src/test/compile-fail/reflect.rs b/src/test/compile-fail/reflect.rs deleted file mode 100644 index 28ff7c82c2e0a..0000000000000 --- a/src/test/compile-fail/reflect.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 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(reflect_marker)] - -// Test that there is no way to get a generic type `T` to be -// considered as `Reflect` (or accessible via something that is -// considered `Reflect`) without a reflect bound, but that any -// concrete type works fine. Note that object types are tested -// separately. - -use std::marker::Reflect; -use std::io::Write; - -struct Struct(T); - -fn is_reflect() { } - -fn c() { - is_reflect::>(); //~ ERROR E0277 -} - -fn ok_c() { - is_reflect::>(); // OK -} - -fn d() { - is_reflect::<(i32, T)>(); //~ ERROR E0277 -} - -fn main() { - is_reflect::<&i32>(); // OK - is_reflect::>(); // OK -} diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index ee8113e80e575..154ebd3649bcd 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -167,7 +167,7 @@ pub fn check(path: &Path, bad: &mut bool) { // FIXME get this whitelist empty. let whitelist = vec![ "abi_ptx", "simd", "macro_reexport", - "static_recursion", "reflect", "quote", + "static_recursion", "quote", "cfg_target_has_atomic", "staged_api", "const_indexing", "unboxed_closures", "stmt_expr_attributes", "cfg_target_thread_local", "unwind_attributes", From 5056a43752a34ec633fb71ff395f518bfc7ce52c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 12 Nov 2016 15:33:16 +0300 Subject: [PATCH 10/86] Stabilize Self and associated types in struct expressions and patterns --- src/librustc_typeck/check/mod.rs | 10 ------ src/libsyntax/feature_gate.rs | 6 ++-- .../struct-path-associated-type.rs | 2 -- .../struct-path-self-feature-gate.rs | 31 ------------------- .../struct-path-self-type-mismatch.rs | 2 -- src/test/compile-fail/struct-path-self.rs | 2 -- .../run-pass/struct-path-associated-type.rs | 2 -- src/test/run-pass/struct-path-self.rs | 2 -- 8 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 src/test/compile-fail/struct-path-self-feature-gate.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e240c70aaa3a5..265f764176859 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3328,16 +3328,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => { - match def { - Def::AssociatedTy(..) | Def::SelfTy(..) - if !self.tcx.sess.features.borrow().more_struct_aliases => { - emit_feature_err(&self.tcx.sess.parse_sess, - "more_struct_aliases", path_span, GateIssue::Language, - "`Self` and associated types in struct \ - expressions and patterns are unstable"); - } - _ => {} - } match ty.sty { ty::TyAdt(adt, substs) if !adt.is_enum() => { Some((adt.struct_variant(), adt.did, substs)) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c25020caf857e..b99300f6195a8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -295,10 +295,6 @@ declare_features! ( // The #![windows_subsystem] attribute (active, windows_subsystem, "1.14.0", Some(37499)), - // Allows using `Self` and associated types in struct expressions and patterns. - (active, more_struct_aliases, "1.14.0", Some(37544)), - - // Allows #[link(..., cfg(..))] (active, link_cfg, "1.14.0", Some(37406)), @@ -378,6 +374,8 @@ declare_features! ( // Allows `..` in tuple (struct) patterns (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)), (accepted, item_like_imports, "1.14.0", Some(35120)), + // Allows using `Self` and associated types in struct expressions and patterns. + (accepted, more_struct_aliases, "1.14.0", Some(37544)), ); // (changing above list without updating src/doc/reference.md makes @cmr sad) diff --git a/src/test/compile-fail/struct-path-associated-type.rs b/src/test/compile-fail/struct-path-associated-type.rs index ecaf269fcb1ae..660ac44ce0b53 100644 --- a/src/test/compile-fail/struct-path-associated-type.rs +++ b/src/test/compile-fail/struct-path-associated-type.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(more_struct_aliases)] - struct S; trait Tr { diff --git a/src/test/compile-fail/struct-path-self-feature-gate.rs b/src/test/compile-fail/struct-path-self-feature-gate.rs deleted file mode 100644 index c40d057495591..0000000000000 --- a/src/test/compile-fail/struct-path-self-feature-gate.rs +++ /dev/null @@ -1,31 +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. - -// gate-test-more_struct_aliases - -struct S; - -trait Tr { - type A; -} - -fn f>() { - let _ = T::A {}; - //~^ ERROR `Self` and associated types in struct expressions and patterns are unstable -} - -impl S { - fn f() { - let _ = Self {}; - //~^ ERROR `Self` and associated types in struct expressions and patterns are unstable - } -} - -fn main() {} diff --git a/src/test/compile-fail/struct-path-self-type-mismatch.rs b/src/test/compile-fail/struct-path-self-type-mismatch.rs index 8352bd6751f50..f694e7d277c7f 100644 --- a/src/test/compile-fail/struct-path-self-type-mismatch.rs +++ b/src/test/compile-fail/struct-path-self-type-mismatch.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(more_struct_aliases)] - struct Foo { inner: A } trait Bar { fn bar(); } diff --git a/src/test/compile-fail/struct-path-self.rs b/src/test/compile-fail/struct-path-self.rs index aeac199227b75..067d6ac22dc6f 100644 --- a/src/test/compile-fail/struct-path-self.rs +++ b/src/test/compile-fail/struct-path-self.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(more_struct_aliases)] - struct S; trait Tr { diff --git a/src/test/run-pass/struct-path-associated-type.rs b/src/test/run-pass/struct-path-associated-type.rs index 292761dfd005f..b033ed5c80210 100644 --- a/src/test/run-pass/struct-path-associated-type.rs +++ b/src/test/run-pass/struct-path-associated-type.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(more_struct_aliases)] - struct S { a: T, b: U, diff --git a/src/test/run-pass/struct-path-self.rs b/src/test/run-pass/struct-path-self.rs index b569ab62c1bfa..c7a282c2a2fa0 100644 --- a/src/test/run-pass/struct-path-self.rs +++ b/src/test/run-pass/struct-path-self.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(more_struct_aliases)] - use std::ops::Add; struct S { From 197f037652bffe7e62be4c7f861c247946549619 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 24 Jan 2017 11:03:37 -0500 Subject: [PATCH 11/86] incr.comp.: Make cross-crate tracking for incr. comp. opt-in. --- src/librustc/session/config.rs | 2 ++ src/librustc_incremental/persist/preds.rs | 8 ++++-- src/librustc_incremental/persist/save.rs | 26 +++++++++++-------- .../auxiliary/point.rs | 2 ++ .../callee_caller_cross_crate/auxiliary/a.rs | 2 ++ .../change_private_fn_cc/auxiliary/point.rs | 2 ++ .../auxiliary/point.rs | 2 ++ .../auxiliary/a.rs | 2 ++ .../rlib_cross_crate/auxiliary/a.rs | 1 + .../auxiliary/a.rs | 2 ++ .../type_alias_cross_crate/auxiliary/a.rs | 2 ++ 11 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 7d8f7fcefe639..7419d74287b97 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -899,6 +899,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "attempt to recover from parse errors (experimental)"), incremental: Option = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation (experimental)"), + incremental_cc: bool = (false, parse_bool, [UNTRACKED], + "enable cross-crate incremental compilation (even more experimental)"), incremental_info: bool = (false, parse_bool, [UNTRACKED], "print high-level information about incremental reuse (or the lack thereof)"), incremental_dump_hash: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_incremental/persist/preds.rs b/src/librustc_incremental/persist/preds.rs index b2a4a2772ec26..327927b2f7749 100644 --- a/src/librustc_incremental/persist/preds.rs +++ b/src/librustc_incremental/persist/preds.rs @@ -33,8 +33,12 @@ pub struct Predecessors<'query> { impl<'q> Predecessors<'q> { pub fn new(query: &'q DepGraphQuery, hcx: &mut HashContext) -> Self { - // Find nodes for which we want to know the full set of preds let tcx = hcx.tcx; + + let collect_for_metadata = tcx.sess.opts.debugging_opts.incremental_cc || + tcx.sess.opts.debugging_opts.query_dep_graph; + + // Find nodes for which we want to know the full set of preds let node_count = query.graph.len_nodes(); // Set up some data structures the cache predecessor search needs: @@ -52,7 +56,7 @@ impl<'q> Predecessors<'q> { .enumerate() .filter(|&(_, node)| match node.data { DepNode::WorkProduct(_) => true, - DepNode::MetaData(ref def_id) => def_id.is_local(), + DepNode::MetaData(ref def_id) => collect_for_metadata && def_id.is_local(), // if -Z query-dep-graph is passed, save more extended data // to enable better unit testing diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 356eb845fed9a..f626905f27d4a 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -55,17 +55,21 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let preds = Predecessors::new(&query, &mut hcx); let mut current_metadata_hashes = FxHashMap(); - // IMPORTANT: We are saving the metadata hashes *before* the dep-graph, - // since metadata-encoding might add new entries to the - // DefIdDirectory (which is saved in the dep-graph file). - save_in(sess, - metadata_hash_export_path(sess), - |e| encode_metadata_hashes(tcx, - svh, - &preds, - &mut builder, - &mut current_metadata_hashes, - e)); + if sess.opts.debugging_opts.incremental_cc || + sess.opts.debugging_opts.query_dep_graph { + // IMPORTANT: We are saving the metadata hashes *before* the dep-graph, + // since metadata-encoding might add new entries to the + // DefIdDirectory (which is saved in the dep-graph file). + save_in(sess, + metadata_hash_export_path(sess), + |e| encode_metadata_hashes(tcx, + svh, + &preds, + &mut builder, + &mut current_metadata_hashes, + e)); + } + save_in(sess, dep_graph_path(sess), |e| encode_dep_graph(&preds, &mut builder, e)); diff --git a/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs b/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs index adc2b23441ef8..1064c97b744a4 100644 --- a/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs +++ b/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs b/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs index d802c9a8352eb..a02b71a753cc3 100644 --- a/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + #![crate_type="rlib"] #[cfg(rpass1)] diff --git a/src/test/incremental/change_private_fn_cc/auxiliary/point.rs b/src/test/incremental/change_private_fn_cc/auxiliary/point.rs index dcc1ced635fbf..08eef2a73f68f 100644 --- a/src/test/incremental/change_private_fn_cc/auxiliary/point.rs +++ b/src/test/incremental/change_private_fn_cc/auxiliary/point.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs b/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs index 8df1cf54da2b9..e69dc51119e92 100644 --- a/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs +++ b/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs b/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs index 4d84e844dedbb..39547fb7359f5 100644 --- a/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs +++ b/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + #![allow(warnings)] #![crate_name = "a"] #![crate_type = "rlib"] diff --git a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs index ff5fd63471449..3ecd9aff3f8cd 100644 --- a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc // no-prefer-dynamic #![crate_type="rlib"] diff --git a/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs b/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs index 2ddcaf157210d..d14ebf78d8222 100644 --- a/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + #![crate_type="rlib"] #[cfg(rpass1)] diff --git a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs index e1dba1317703d..0393bcda99156 100644 --- a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z incremental-cc + #![crate_type="rlib"] #[cfg(rpass1)] From 82a280597d967dc3ec8686f160a0afea4ad45837 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 14 Jan 2017 19:59:10 +0200 Subject: [PATCH 12/86] end temporary lifetimes being extended by `let X: &_` hints Fixes #36082. --- src/librustc/infer/mod.rs | 5 - src/librustc/middle/expr_use_visitor.rs | 1 + src/librustc/middle/mem_categorization.rs | 30 +++-- src/librustc/middle/region.rs | 62 +++++++-- .../borrowck/gather_loans/lifetime.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 13 +- src/librustc_mir/build/expr/as_constant.rs | 3 +- src/librustc_mir/build/expr/as_temp.rs | 7 + src/librustc_mir/hair/cx/block.rs | 3 +- src/librustc_mir/hair/cx/expr.rs | 121 +++++++++++------- src/librustc_mir/hair/mod.rs | 3 + src/librustc_typeck/check/regionck.rs | 5 +- src/librustc_typeck/check/upvar.rs | 4 +- src/test/compile-fail/issue-36082.rs | 27 ++++ 14 files changed, 205 insertions(+), 81 deletions(-) create mode 100644 src/test/compile-fail/issue-36082.rs diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b44e1563ee7ed..ccb46d3a16273 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -23,7 +23,6 @@ use hir; use middle::free_region::FreeRegionMap; use middle::mem_categorization as mc; use middle::mem_categorization::McResult; -use middle::region::CodeExtent; use middle::lang_items; use mir::tcx::LvalueTy; use ty::subst::{Kind, Subst, Substs}; @@ -1622,10 +1621,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) } - pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx.region_maps.temporary_scope(rvalue_id) - } - pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option> { self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0eacbba3fdd44..2130752b4d052 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -296,6 +296,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { arg.id, arg.pat.span, fn_body_scope_r, // Args live only as long as the fn body. + fn_body_scope_r, arg_ty); self.walk_irrefutable_pat(arg_cmt, &arg.pat); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 92e69d7d72957..a74c976cc3296 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -88,7 +88,8 @@ use std::rc::Rc; #[derive(Clone, PartialEq)] pub enum Categorization<'tcx> { - Rvalue(&'tcx ty::Region), // temporary val, argument is its scope + // temporary val, argument is its scope + Rvalue(&'tcx ty::Region, &'tcx ty::Region), StaticItem, Upvar(Upvar), // upvar referenced by closure env Local(ast::NodeId), // local variable @@ -760,11 +761,18 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { /// Returns the lifetime of a temporary created by expr with id `id`. /// This could be `'static` if `id` is part of a constant expression. - pub fn temporary_scope(&self, id: ast::NodeId) -> &'tcx ty::Region { - self.tcx().mk_region(match self.infcx.temporary_scope(id) { + pub fn temporary_scope(&self, id: ast::NodeId) -> (&'tcx ty::Region, &'tcx ty::Region) + { + let (scope, old_scope) = + self.tcx().region_maps.old_and_new_temporary_scope(id); + (self.tcx().mk_region(match scope { + Some(scope) => ty::ReScope(scope), + None => ty::ReStatic + }), + self.tcx().mk_region(match old_scope { Some(scope) => ty::ReScope(scope), None => ty::ReStatic - }) + })) } pub fn cat_rvalue_node(&self, @@ -785,12 +793,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // Compute maximum lifetime of this rvalue. This is 'static if // we can promote to a constant, otherwise equal to enclosing temp // lifetime. - let re = if promotable { - self.tcx().mk_region(ty::ReStatic) + let (re, old_re) = if promotable { + (self.tcx().mk_region(ty::ReStatic), + self.tcx().mk_region(ty::ReStatic)) } else { self.temporary_scope(id) }; - let ret = self.cat_rvalue(id, span, re, expr_ty); + let ret = self.cat_rvalue(id, span, re, old_re, expr_ty); debug!("cat_rvalue_node ret {:?}", ret); ret } @@ -799,11 +808,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { cmt_id: ast::NodeId, span: Span, temp_scope: &'tcx ty::Region, + old_temp_scope: &'tcx ty::Region, expr_ty: Ty<'tcx>) -> cmt<'tcx> { let ret = Rc::new(cmt_ { id:cmt_id, span:span, - cat:Categorization::Rvalue(temp_scope), + cat:Categorization::Rvalue(temp_scope, old_temp_scope), mutbl:McDeclared, ty:expr_ty, note: NoteNone @@ -1386,7 +1396,9 @@ impl<'tcx> fmt::Debug for Categorization<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Categorization::StaticItem => write!(f, "static"), - Categorization::Rvalue(r) => write!(f, "rvalue({:?})", r), + Categorization::Rvalue(r, or) => { + write!(f, "rvalue({:?}, {:?})", r, or) + } Categorization::Local(id) => { let name = ty::tls::with(|tcx| tcx.local_var_name_str(id)); write!(f, "local({})", name) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index faf4a448b7a84..ebc5b4cfa9b08 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -272,6 +272,13 @@ pub struct RegionMaps { /// block (see `terminating_scopes`). rvalue_scopes: RefCell>, + /// Records the value of rvalue scopes before they were shrunk by + /// #36082, for error reporting. + /// + /// FIXME: this should be temporary. Remove this by 1.18.0 or + /// so. + shrunk_rvalue_scopes: RefCell>, + /// Encodes the hierarchy of fn bodies. Every fn body (including /// closures) forms its own distinct region hierarchy, rooted in /// the block that is the fn body. This map points from the id of @@ -419,11 +426,7 @@ impl RegionMaps { e(child, parent) } } - pub fn each_rvalue_scope(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) { - for (child, parent) in self.rvalue_scopes.borrow().iter() { - e(child, parent) - } - } + /// Records that `sub_fn` is defined within `sup_fn`. These ids /// should be the id of the block that is the fn body, which is /// also the root of the region hierarchy for that fn. @@ -457,6 +460,12 @@ impl RegionMaps { self.rvalue_scopes.borrow_mut().insert(var, lifetime); } + fn record_shrunk_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) { + debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime); + assert!(var != lifetime.node_id(self)); + self.shrunk_rvalue_scopes.borrow_mut().insert(var, lifetime); + } + pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. self.scope_map.borrow()[id.0 as usize].into_option() @@ -476,6 +485,30 @@ impl RegionMaps { } } + pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option, bool) { + let temporary_scope = self.temporary_scope(expr_id); + let was_shrunk = match self.shrunk_rvalue_scopes.borrow().get(&expr_id) { + Some(&s) => { + info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})", + expr_id, temporary_scope, s); + temporary_scope != Some(s) + } + _ => false + }; + info!("temporary_scope2({:?}) - was_shrunk={:?}", expr_id, was_shrunk); + (temporary_scope, was_shrunk) + } + + pub fn old_and_new_temporary_scope(&self, expr_id: ast::NodeId) -> + (Option, Option) + { + let temporary_scope = self.temporary_scope(expr_id); + (temporary_scope, + self.shrunk_rvalue_scopes + .borrow().get(&expr_id).cloned() + .or(temporary_scope)) + } + pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option { //! Returns the scope when temp created by expr_id will be cleaned up @@ -929,8 +962,10 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, let is_borrow = if let Some(ref ty) = local.ty { is_borrowed_ty(&ty) } else { false }; - if is_binding_pat(&local.pat) || is_borrow { - record_rvalue_scope(visitor, &expr, blk_scope); + if is_binding_pat(&local.pat) { + record_rvalue_scope(visitor, &expr, blk_scope, false); + } else if is_borrow { + record_rvalue_scope(visitor, &expr, blk_scope, true); } } @@ -995,7 +1030,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, match expr.node { hir::ExprAddrOf(_, ref subexpr) => { record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); - record_rvalue_scope(visitor, &subexpr, blk_id); + record_rvalue_scope(visitor, &subexpr, blk_id, false); } hir::ExprStruct(_, ref fields, _) => { for field in fields { @@ -1040,7 +1075,8 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, /// Note: ET is intended to match "rvalues or lvalues based on rvalues". fn record_rvalue_scope<'a>(visitor: &mut RegionResolutionVisitor, expr: &'a hir::Expr, - blk_scope: CodeExtent) { + blk_scope: CodeExtent, + is_shrunk: bool) { let mut expr = expr; loop { // Note: give all the expressions matching `ET` with the @@ -1048,7 +1084,12 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, // because in trans if we must compile e.g. `*rvalue()` // into a temporary, we request the temporary scope of the // outer expression. - visitor.region_maps.record_rvalue_scope(expr.id, blk_scope); + if is_shrunk { + // this changed because of #36082 + visitor.region_maps.record_shrunk_rvalue_scope(expr.id, blk_scope); + } else { + visitor.region_maps.record_rvalue_scope(expr.id, blk_scope); + } match expr.node { hir::ExprAddrOf(_, ref subexpr) | @@ -1225,6 +1266,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps { scope_map: RefCell::new(vec![]), var_map: RefCell::new(NodeMap()), rvalue_scopes: RefCell::new(NodeMap()), + shrunk_rvalue_scopes: RefCell::new(NodeMap()), fn_tree: RefCell::new(NodeMap()), }; let root_extent = maps.bogus_code_extent( diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 5970d6e4f2f65..bbfb7e5874ea0 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { //! rooting etc, and presuming `cmt` is not mutated. match cmt.cat { - Categorization::Rvalue(temp_scope) => { + Categorization::Rvalue(temp_scope, _) => { temp_scope } Categorization::Upvar(..) => { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index c0e038d183dad..738647ab981d6 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -967,7 +967,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { err_mutbl => self.note_and_explain_mutbl_error(db, &err, &error_span), err_out_of_scope(super_scope, sub_scope, cause) => { let (value_kind, value_msg) = match err.cmt.cat { - mc::Categorization::Rvalue(_) => + mc::Categorization::Rvalue(..) => ("temporary value", "temporary value created here"), _ => ("borrowed value", "borrow occurs here") @@ -1061,6 +1061,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { if let Some(_) = statement_scope_span(self.tcx, super_scope) { db.note("consider using a `let` binding to increase its lifetime"); } + + + + match err.cmt.cat { + mc::Categorization::Rvalue(r, or) if r != or => { + db.note("\ +before rustc 1.16, this temporary lived longer - see issue #39283 \ +(https://github.com/rust-lang/rust/issues/39283)"); + } + _ => {} + } } err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index 6230123a9ca17..7caf8a778d409 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -26,7 +26,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> { let this = self; - let Expr { ty, temp_lifetime: _, span, kind } = expr; + let Expr { ty, temp_lifetime: _, temp_lifetime_was_shrunk: _, span, kind } + = expr; match kind { ExprKind::Scope { extent: _, value } => this.as_constant(value), diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index fb12e08affd2d..0ae4bcc4205d4 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -39,6 +39,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let expr_span = expr.span; let source_info = this.source_info(expr_span); + if expr.temp_lifetime_was_shrunk && this.hir.needs_drop(expr_ty) { + this.hir.tcx().sess.span_warn( + expr_span, + "this temporary used to live longer - see issue #39283 \ +(https://github.com/rust-lang/rust/issues/39283)"); + } + if temp_lifetime.is_some() { this.cfg.push(block, Statement { source_info: source_info, diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 4b3d62fd6d6ef..ba6b9361a83f4 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -83,10 +83,11 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { let block_ty = cx.tables().node_id_to_type(block.id); - let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(block.id); let expr = Expr { ty: block_ty, temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, span: block.span, kind: ExprKind::Block { body: block }, }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index cdf7cae3020c8..0b40b6c0ad364 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -27,7 +27,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { type Output = Expr<'tcx>; fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> { - let temp_lifetime = cx.tcx.region_maps.temporary_scope(self.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(self.id); let expr_extent = cx.tcx.region_maps.node_extent(self.id); debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span); @@ -45,6 +45,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { Some((ty::adjustment::Adjust::ReifyFnPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::ReifyFnPointer { source: expr.to_ref() }, @@ -53,6 +54,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { Some((ty::adjustment::Adjust::UnsafeFnPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() }, @@ -61,6 +63,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { Some((ty::adjustment::Adjust::NeverToAny, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::NeverToAny { source: expr.to_ref() }, @@ -69,6 +72,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { Some((ty::adjustment::Adjust::MutToConstPointer, adjusted_ty)) => { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::Cast { source: expr.to_ref() }, @@ -98,6 +102,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, @@ -123,6 +128,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: kind, @@ -135,6 +141,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { ty::adjustment::AutoBorrow::Ref(r, m) => { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::Borrow { @@ -152,6 +159,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { let region = cx.tcx.mk_region(region); expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, @@ -166,6 +174,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::Cast { source: expr.to_ref() }, @@ -177,6 +186,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { if unsize { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: adjusted_ty, span: self.span, kind: ExprKind::Unsize { source: expr.to_ref() }, @@ -188,6 +198,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { // Next, wrap this up in the expr's scope. expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: expr.ty, span: self.span, kind: ExprKind::Scope { @@ -200,6 +211,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { if let Some(extent) = cx.tcx.region_maps.opt_destruction_extent(self.id) { expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: expr.ty, span: self.span, kind: ExprKind::Scope { @@ -218,7 +230,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { let expr_ty = cx.tables().expr_ty(expr); - let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); let kind = match expr.node { // Here comes the interesting stuff: @@ -260,6 +272,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let tupled_args = Expr { ty: sig.inputs()[1], temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, span: expr.span, kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() }, }; @@ -670,6 +683,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: expr_ty, span: expr.span, kind: kind, @@ -681,9 +695,10 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, method_call: ty::MethodCall) -> Expr<'tcx> { let callee = cx.tables().method_map[&method_call]; - let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: callee.ty, span: expr.span, kind: ExprKind::Literal { @@ -761,7 +776,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); match def { Def::Local(def_id) => { @@ -813,15 +828,17 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Expr { ty: closure_ty, temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, span: expr.span, kind: ExprKind::Deref { arg: Expr { - ty: ref_closure_ty, - temp_lifetime: temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef, - } - .to_ref(), + ty: ref_closure_ty, + temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, + span: expr.span, + kind: ExprKind::SelfRef, + } + .to_ref(), }, } } @@ -834,15 +851,16 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Expr { ty: closure_ty, temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, span: expr.span, kind: ExprKind::Deref { arg: Expr { - ty: ref_closure_ty, - temp_lifetime: temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef, - } - .to_ref(), + ty: ref_closure_ty, + temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, + span: expr.span, + kind: ExprKind::SelfRef, + }.to_ref(), }, } } @@ -850,6 +868,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, Expr { ty: closure_ty, temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, span: expr.span, kind: ExprKind::SelfRef, } @@ -879,16 +898,16 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty::UpvarCapture::ByRef(borrow) => { ExprKind::Deref { arg: Expr { - temp_lifetime: temp_lifetime, - ty: cx.tcx.mk_ref(borrow.region, - ty::TypeAndMut { - ty: var_ty, - mutbl: borrow.kind.to_mutbl_lossy(), - }), - span: expr.span, - kind: field_kind, - } - .to_ref(), + temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, + ty: cx.tcx.mk_ref(borrow.region, + ty::TypeAndMut { + ty: var_ty, + mutbl: borrow.kind.to_mutbl_lossy(), + }), + span: expr.span, + kind: field_kind, + }.to_ref(), } } } @@ -944,7 +963,8 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, PassArgs::ByRef => { let region = cx.tcx.node_scope_region(expr.id); - let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); + let (temp_lifetime, was_shrunk) = + cx.tcx.region_maps.temporary_scope2(expr.id); argrefs.extend(args.iter() .map(|arg| { let arg_ty = cx.tables().expr_ty_adjusted(arg); @@ -954,16 +974,17 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, mutbl: hir::MutImmutable, }); Expr { - temp_lifetime: temp_lifetime, - ty: adjusted_ty, - span: expr.span, - kind: ExprKind::Borrow { - region: region, - borrow_kind: BorrowKind::Shared, - arg: arg.to_ref(), - }, - } - .to_ref() + temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, + ty: adjusted_ty, + span: expr.span, + kind: ExprKind::Borrow { + region: region, + borrow_kind: BorrowKind::Shared, + arg: arg.to_ref(), + }, + } + .to_ref() })) } } @@ -995,10 +1016,11 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type - let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(expr.id); let ref_kind = overloaded_operator(cx, expr, method_call, pass_args, receiver, args); let ref_expr = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: ref_ty, span: expr.span, kind: ref_kind, @@ -1019,10 +1041,11 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_expr_id: closure_expr.id, }; let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap(); - let temp_lifetime = cx.tcx.region_maps.temporary_scope(closure_expr.id); + let (temp_lifetime, was_shrunk) = cx.tcx.region_maps.temporary_scope2(closure_expr.id); let var_ty = cx.tables().node_id_to_type(id_var); let captured_var = Expr { temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, ty: var_ty, span: closure_expr.span, kind: convert_var(cx, closure_expr, freevar.def), @@ -1036,16 +1059,16 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty::BorrowKind::MutBorrow => BorrowKind::Mut, }; Expr { - temp_lifetime: temp_lifetime, - ty: freevar_ty, - span: closure_expr.span, - kind: ExprKind::Borrow { - region: upvar_borrow.region, - borrow_kind: borrow_kind, - arg: captured_var.to_ref(), - }, - } - .to_ref() + temp_lifetime: temp_lifetime, + temp_lifetime_was_shrunk: was_shrunk, + ty: freevar_ty, + span: closure_expr.span, + kind: ExprKind::Borrow { + region: upvar_borrow.region, + borrow_kind: borrow_kind, + arg: captured_var.to_ref(), + }, + }.to_ref() } } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index f57d442752d99..01dc01c5ecfd4 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -97,6 +97,9 @@ pub struct Expr<'tcx> { /// temporary; should be None only if in a constant context pub temp_lifetime: Option, + /// whether this temp lifetime was shrunk by #36082. + pub temp_lifetime_was_shrunk: bool, + /// span of the expression in the source pub span: Span, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index bd63eb6ad25ef..c26278bfc243d 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -996,7 +996,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { cmt: mc::cmt<'tcx>, span: Span) { match cmt.cat { - Categorization::Rvalue(region) => { + Categorization::Rvalue(region, _) => { match *region { ty::ReScope(rvalue_scope) => { let typ = self.resolve_type(cmt.ty); @@ -1113,7 +1113,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { for arg in args { let arg_ty = self.node_ty(arg.id); let re_scope = self.tcx.mk_region(ty::ReScope(body_scope)); - let arg_cmt = mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty); + let arg_cmt = mc.cat_rvalue( + arg.id, arg.pat.span, re_scope, re_scope, arg_ty); debug!("arg_ty={:?} arg_cmt={:?} arg={:?}", arg_ty, arg_cmt, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 95da5a97f6750..ce3689e4b715f 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -339,7 +339,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { Categorization::Deref(.., mc::UnsafePtr(..)) | Categorization::StaticItem | - Categorization::Rvalue(_) | + Categorization::Rvalue(..) | Categorization::Local(_) | Categorization::Upvar(..) => { return; @@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { Categorization::Deref(.., mc::UnsafePtr(..)) | Categorization::StaticItem | - Categorization::Rvalue(_) | + Categorization::Rvalue(..) | Categorization::Local(_) | Categorization::Upvar(..) => { } diff --git a/src/test/compile-fail/issue-36082.rs b/src/test/compile-fail/issue-36082.rs new file mode 100644 index 0000000000000..cec4b2d15dcd3 --- /dev/null +++ b/src/test/compile-fail/issue-36082.rs @@ -0,0 +1,27 @@ +// 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 std::cell::RefCell; + +fn main() { + let mut r = 0; + let s = 0; + let x = RefCell::new((&mut r,s)); + + let val: &_ = x.borrow().0; + //~^ WARNING this temporary used to live longer - see issue #39283 + //~^^ ERROR borrowed value does not live long enough + //~| temporary value dropped here while still borrowed + //~| temporary value created here + //~| consider using a `let` binding to increase its lifetime + //~| before rustc 1.16, this temporary lived longer - see issue #39283 + println!("{}", val); +} +//~^ temporary value needs to live until here From 2b7a23ed304d4298247b030eea0820018c05cd30 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 25 Jan 2017 14:48:20 +0800 Subject: [PATCH 13/86] Hide uninhabitedness checks behind feature gate --- src/librustc/ty/inhabitedness/mod.rs | 6 +-- src/librustc_const_eval/_match.rs | 17 +++++-- src/librustc_mir/build/matches/simplify.rs | 30 ++++++----- .../uninhabited-matches-feature-gated.rs | 50 +++++++++++++++++++ ...ninhabited-reference-type-feature-gated.rs | 19 ------- 5 files changed, 81 insertions(+), 41 deletions(-) create mode 100644 src/test/compile-fail/uninhabited-matches-feature-gated.rs delete mode 100644 src/test/compile-fail/uninhabited-reference-type-feature-gated.rs diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 92395e3c381aa..6c49493a65559 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -191,11 +191,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } TyRef(_, ref tm) => { - if tcx.sess.features.borrow().never_type { - tm.ty.uninhabited_from(visited, tcx) - } else { - DefIdForest::empty() - } + tm.ty.uninhabited_from(visited, tcx) } _ => DefIdForest::empty(), diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index bb5dacf71e175..1770a112cdf23 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -379,19 +379,24 @@ impl<'tcx> Witness<'tcx> { fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, pcx: PatternContext<'tcx>) -> Vec { + let check_inhabited = cx.tcx.sess.features.borrow().never_type; debug!("all_constructors({:?})", pcx.ty); match pcx.ty.sty { ty::TyBool => [true, false].iter().map(|b| ConstantValue(ConstVal::Bool(*b))).collect(), ty::TySlice(ref sub_ty) => { - if sub_ty.is_uninhabited_from(cx.module, cx.tcx) { + if sub_ty.is_uninhabited_from(cx.module, cx.tcx) + && check_inhabited + { vec![Slice(0)] } else { (0..pcx.max_slice_length+1).map(|length| Slice(length)).collect() } } ty::TyArray(ref sub_ty, length) => { - if length == 0 || !sub_ty.is_uninhabited_from(cx.module, cx.tcx) { + if length == 0 || !(sub_ty.is_uninhabited_from(cx.module, cx.tcx) + && check_inhabited) + { vec![Slice(length)] } else { vec![] @@ -403,7 +408,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, let forest = v.uninhabited_from(&mut visited, cx.tcx, substs, AdtKind::Enum); - if forest.contains(cx.tcx, cx.module) { + if forest.contains(cx.tcx, cx.module) + && check_inhabited + { None } else { Some(Variant(v.did)) @@ -411,7 +418,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, }).collect() } _ => { - if pcx.ty.is_uninhabited_from(cx.module, cx.tcx) { + if pcx.ty.is_uninhabited_from(cx.module, cx.tcx) + && check_inhabited + { vec![] } else { vec![Single] diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index b071834122367..e94d35195c213 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -99,20 +99,24 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { - let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| { - i == variant_index || { - let mut visited = FxHashSet::default(); - let node_set = v.uninhabited_from(&mut visited, - self.hir.tcx(), - substs, - adt_def.adt_kind()); - !node_set.is_empty() + if self.hir.tcx().sess.features.borrow().never_type { + let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| { + i == variant_index || { + let mut visited = FxHashSet::default(); + let node_set = v.uninhabited_from(&mut visited, + self.hir.tcx(), + substs, + adt_def.adt_kind()); + !node_set.is_empty() + } + }); + if irrefutable { + let lvalue = match_pair.lvalue.downcast(adt_def, variant_index); + candidate.match_pairs.extend(self.field_match_pairs(lvalue, subpatterns)); + Ok(()) + } else { + Err(match_pair) } - }); - if irrefutable { - let lvalue = match_pair.lvalue.downcast(adt_def, variant_index); - candidate.match_pairs.extend(self.field_match_pairs(lvalue, subpatterns)); - Ok(()) } else { Err(match_pair) } diff --git a/src/test/compile-fail/uninhabited-matches-feature-gated.rs b/src/test/compile-fail/uninhabited-matches-feature-gated.rs new file mode 100644 index 0000000000000..0f8b0a6c238d0 --- /dev/null +++ b/src/test/compile-fail/uninhabited-matches-feature-gated.rs @@ -0,0 +1,50 @@ +// 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(slice_patterns)] + +enum Void {} + +fn main() { + let x: Result = Ok(23); + let _ = match x { //~ ERROR non-exhaustive + Ok(n) => n, + }; + + let x: &Void = unsafe { std::mem::uninitialized() }; + let _ = match x {}; + //~^ ERROR non-exhaustive + + let x: (Void,) = unsafe { std::mem::uninitialized() }; + let _ = match x {}; + //~^ ERROR non-exhaustive + + let x: [Void; 1] = unsafe { std::mem::uninitialized() }; + let _ = match x {}; + //~^ ERROR non-exhaustive + + let x: &[Void] = unsafe { std::mem::uninitialized() }; + let _ = match x { //~ ERROR non-exhaustive + &[] => (), + }; + + let x: Void = unsafe { std::mem::uninitialized() }; + let _ = match x {}; // okay + + let x: Result = Ok(23); + let _ = match x { //~ ERROR non-exhaustive + Ok(x) => x, + }; + + let x: Result = Ok(23); + let Ok(x) = x; + //~^ ERROR refutable +} + diff --git a/src/test/compile-fail/uninhabited-reference-type-feature-gated.rs b/src/test/compile-fail/uninhabited-reference-type-feature-gated.rs deleted file mode 100644 index 8f246eddbcde4..0000000000000 --- a/src/test/compile-fail/uninhabited-reference-type-feature-gated.rs +++ /dev/null @@ -1,19 +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. - -enum Void {} - -fn main() { - let x: Result = Ok(23); - let _ = match x { //~ ERROR non-exhaustive - Ok(n) => n, - }; -} - From 9e8785f01757a50e321e85adeb659a9aff6fc00e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 Jan 2017 14:37:04 -0800 Subject: [PATCH 14/86] rustbuild: Add manifest generation in-tree This commit adds a new tool, `build-manifest`, which is used to generate a distribution manifest of all produced artifacts. This tool is intended to replace the `build-rust-manifest.py` script that's currently located on the buildmaster. The intention is that we'll have a builder which periodically: * Downloads all artifacts for a commit * Runs `./x.py dist hash-and-sign`. This will generate `sha256` and `asc` files as well as TOML manifests. * Upload all generated hashes and manifests to the directory the artifacts came from. * Upload *all* artifacts (tarballs and hashes and manifests) to an archived location. * If necessary, upload all artifacts to the main location. This script is intended to just be the second step here where orchestrating uploads and such will all happen externally from the build system itself. --- src/Cargo.lock | 8 + src/Cargo.toml | 1 + src/bootstrap/config.rs | 19 ++ src/bootstrap/config.toml.example | 30 ++ src/bootstrap/dist.rs | 33 ++- src/bootstrap/step.rs | 10 + src/tools/build-manifest/Cargo.toml | 8 + src/tools/build-manifest/src/main.rs | 404 +++++++++++++++++++++++++++ 8 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 src/tools/build-manifest/Cargo.toml create mode 100644 src/tools/build-manifest/src/main.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 7db243c5eb9d0..93bbf0f227b1b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -50,6 +50,14 @@ dependencies = [ "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "build-manifest" +version = "0.1.0" +dependencies = [ + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "build_helper" version = "0.1.0" diff --git a/src/Cargo.toml b/src/Cargo.toml index 8fb5c70c41bf1..0db26ea5ae021 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -10,6 +10,7 @@ members = [ "tools/linkchecker", "tools/rustbook", "tools/tidy", + "tools/build-manifest", ] # Curiously, compiletest will segfault if compiled with opt-level=3 on 64-bit diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 7d1abcfa6f6e7..e035f8157ffde 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -78,6 +78,11 @@ pub struct Config { pub cargo: Option, pub local_rebuild: bool, + // dist misc + pub dist_sign_folder: Option, + pub dist_upload_addr: Option, + pub dist_gpg_password_file: Option, + // libstd features pub debug_jemalloc: bool, pub use_jemalloc: bool, @@ -123,6 +128,7 @@ struct TomlConfig { llvm: Option, rust: Option, target: Option>, + dist: Option, } /// TOML representation of various global build decisions. @@ -166,6 +172,13 @@ struct Llvm { targets: Option, } +#[derive(RustcDecodable, Default, Clone)] +struct Dist { + sign_folder: Option, + gpg_password_file: Option, + upload_addr: Option, +} + #[derive(RustcDecodable)] enum StringOrBool { String(String), @@ -352,6 +365,12 @@ impl Config { } } + if let Some(ref t) = toml.dist { + config.dist_sign_folder = t.sign_folder.clone().map(PathBuf::from); + config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from); + config.dist_upload_addr = t.upload_addr.clone(); + } + return config } diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 4b859482562d2..a53419ad7fd78 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -242,3 +242,33 @@ # that this option only makes sense for MUSL targets that produce statically # linked binaries #musl-root = "..." + +# ============================================================================= +# Distribution options +# +# These options are related to distribution, mostly for the Rust project itself. +# You probably won't need to concern yourself with any of these options +# ============================================================================= +[dist] + +# This is the folder of artifacts that the build system will sign. All files in +# this directory will be signed with the default gpg key using the system `gpg` +# binary. The `asc` and `sha256` files will all be output into the standard dist +# output folder (currently `build/dist`) +# +# This folder should be populated ahead of time before the build system is +# invoked. +#sign-folder = "path/to/folder/to/sign" + +# This is a file which contains the password of the default gpg key. This will +# be passed to `gpg` down the road when signing all files in `sign-folder` +# above. This should be stored in plaintext. +#gpg-password-file = "path/to/gpg/password" + +# The remote address that all artifacts will eventually be uploaded to. The +# build system generates manifests which will point to these urls, and for the +# manifests to be correct they'll have to have the right URLs encoded. +# +# Note that this address should not contain a trailing slash as file names will +# be appended to it. +#upload-addr = "https://example.com/folder" diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e5f0505952318..71a5f313bbd26 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -22,7 +22,7 @@ use std::env; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::{PathBuf, Path}; -use std::process::Command; +use std::process::{Command, Stdio}; use build_helper::output; @@ -876,3 +876,34 @@ fn add_env(build: &Build, cmd: &mut Command, target: &str) { cmd.env("CFG_PLATFORM", "x86"); } } + +pub fn hash_and_sign(build: &Build) { + let compiler = Compiler::new(0, &build.config.build); + let mut cmd = build.tool_cmd(&compiler, "build-manifest"); + let sign = build.config.dist_sign_folder.as_ref().unwrap_or_else(|| { + panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n") + }); + let addr = build.config.dist_upload_addr.as_ref().unwrap_or_else(|| { + panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") + }); + let file = build.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| { + panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n") + }); + let mut pass = String::new(); + t!(t!(File::open(&file)).read_to_string(&mut pass)); + + let today = output(Command::new("date").arg("+%Y-%m-%d")); + + cmd.arg(sign); + cmd.arg(distdir(build)); + cmd.arg(today.trim()); + cmd.arg(package_vers(build)); + cmd.arg(addr); + + t!(fs::create_dir_all(distdir(build))); + + let mut child = t!(cmd.stdin(Stdio::piped()).spawn()); + t!(child.stdin.take().unwrap().write_all(pass.as_bytes())); + let status = t!(child.wait()); + assert!(status.success()); +} diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 697b14c6050cc..3932a7cf8c563 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -513,6 +513,9 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { rules.build("tool-compiletest", "src/tools/compiletest") .dep(|s| s.name("libtest")) .run(move |s| compile::tool(build, s.stage, s.target, "compiletest")); + rules.build("tool-build-manifest", "src/tools/build-manifest") + .dep(|s| s.name("libstd")) + .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest")); // ======================================================================== // Documentation targets @@ -633,6 +636,13 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .dep(|d| d.name("dist-cargo")) .run(move |s| dist::extended(build, s.stage, s.target)); + rules.dist("dist-sign", "hash-and-sign") + .host(true) + .only_build(true) + .only_host_build(true) + .dep(move |s| s.name("tool-build-manifest").target(&build.config.build).stage(0)) + .run(move |_| dist::hash_and_sign(build)); + rules.verify(); return rules; } diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml new file mode 100644 index 0000000000000..4b876753b1fea --- /dev/null +++ b/src/tools/build-manifest/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "build-manifest" +version = "0.1.0" +authors = ["Alex Crichton "] + +[dependencies] +toml = "0.1" +rustc-serialize = "0.3" diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs new file mode 100644 index 0000000000000..8c15a6630a33c --- /dev/null +++ b/src/tools/build-manifest/src/main.rs @@ -0,0 +1,404 @@ +// Copyright 2017 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. + +extern crate toml; +extern crate rustc_serialize; + +use std::collections::HashMap; +use std::env; +use std::fs::File; +use std::io::{self, Read, Write}; +use std::path::{PathBuf, Path}; +use std::process::{Command, Stdio}; + +static HOSTS: &'static [&'static str] = &[ + "aarch64-unknown-linux-gnu", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "armv7-unknown-linux-gnueabihf", + "i686-apple-darwin", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "mips-unknown-linux-gnu", + "mips64-unknown-linux-gnuabi64", + "mips64el-unknown-linux-gnuabi64", + "mipsel-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-unknown-freebsd", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-netbsd", +]; + +static TARGETS: &'static [&'static str] = &[ + "aarch64-apple-ios", + "aarch64-linux-android", + "aarch64-unknown-linux-gnu", + "arm-linux-androideabi", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "arm-unknown-linux-musleabi", + "arm-unknown-linux-musleabihf", + "armv7-apple-ios", + "armv7-linux-androideabi", + "armv7-unknown-linux-gnueabihf", + "armv7-unknown-linux-musleabihf", + "armv7s-apple-ios", + "asmjs-unknown-emscripten", + "i386-apple-ios", + "i586-pc-windows-msvc", + "i586-unknown-linux-gnu", + "i686-apple-darwin", + "i686-linux-android", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "i686-unknown-freebsd", + "i686-unknown-linux-gnu", + "i686-unknown-linux-musl", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips64-unknown-linux-gnuabi64", + "mips64el-unknown-linux-gnuabi64", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "wasm32-unknown-emscripten", + "x86_64-apple-darwin", + "x86_64-apple-ios", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + "x86_64-rumprun-netbsd", + "x86_64-unknown-freebsd", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd", +]; + +static MINGW: &'static [&'static str] = &[ + "i686-pc-windows-gnu", + "x86_64-pc-windows-gnu", +]; + +#[derive(RustcEncodable)] +struct Manifest { + manifest_version: String, + date: String, + pkg: HashMap, +} + +#[derive(RustcEncodable)] +struct Package { + version: String, + target: HashMap, +} + +#[derive(RustcEncodable)] +struct Target { + available: bool, + url: Option, + hash: Option, + components: Option>, + extensions: Option>, +} + +#[derive(RustcEncodable)] +struct Component { + pkg: String, + target: String, +} + +macro_rules! t { + ($e:expr) => (match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}", stringify!($e), e), + }) +} + +struct Builder { + channel: String, + input: PathBuf, + output: PathBuf, + gpg_passphrase: String, + digests: HashMap, + s3_address: String, + date: String, + rust_version: String, + cargo_version: String, +} + +fn main() { + let mut args = env::args().skip(1); + let input = PathBuf::from(args.next().unwrap()); + let output = PathBuf::from(args.next().unwrap()); + let date = args.next().unwrap(); + let channel = args.next().unwrap(); + let s3_address = args.next().unwrap(); + let mut passphrase = String::new(); + t!(io::stdin().read_to_string(&mut passphrase)); + + Builder { + channel: channel, + input: input, + output: output, + gpg_passphrase: passphrase, + digests: HashMap::new(), + s3_address: s3_address, + date: date, + rust_version: String::new(), + cargo_version: String::new(), + }.build(); +} + +impl Builder { + fn build(&mut self) { + self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu"); + self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu"); + + self.digest_and_sign(); + let manifest = self.build_manifest(); + let manifest = toml::encode(&manifest).to_string(); + + let filename = format!("channel-rust-{}.toml", self.channel); + self.write_manifest(&manifest, &filename); + + if self.channel != "beta" && self.channel != "nightly" { + self.write_manifest(&manifest, "channel-rust-stable.toml"); + } + } + + fn digest_and_sign(&mut self) { + for file in t!(self.input.read_dir()).map(|e| t!(e).path()) { + let filename = file.file_name().unwrap().to_str().unwrap(); + let digest = self.hash(&file); + self.sign(&file); + assert!(self.digests.insert(filename.to_string(), digest).is_none()); + } + } + + fn build_manifest(&mut self) -> Manifest { + let mut manifest = Manifest { + manifest_version: "2".to_string(), + date: self.date.to_string(), + pkg: HashMap::new(), + }; + + self.package("rustc", &mut manifest.pkg, HOSTS); + self.package("cargo", &mut manifest.pkg, HOSTS); + self.package("rust-mingw", &mut manifest.pkg, MINGW); + self.package("rust-std", &mut manifest.pkg, TARGETS); + self.package("rust-docs", &mut manifest.pkg, TARGETS); + self.package("rust-src", &mut manifest.pkg, &["*"]); + + let mut pkg = Package { + version: self.cached_version("rust").to_string(), + target: HashMap::new(), + }; + for host in HOSTS { + let filename = self.filename("rust", host); + let digest = match self.digests.remove(&filename) { + Some(digest) => digest, + None => { + pkg.target.insert(host.to_string(), Target { + available: false, + url: None, + hash: None, + components: None, + extensions: None, + }); + continue + } + }; + let mut components = Vec::new(); + let mut extensions = Vec::new(); + + // rustc/rust-std/cargo are all required, and so is rust-mingw if it's + // available for the target. + components.extend(vec![ + Component { pkg: "rustc".to_string(), target: host.to_string() }, + Component { pkg: "rust-std".to_string(), target: host.to_string() }, + Component { pkg: "cargo".to_string(), target: host.to_string() }, + ]); + if host.contains("pc-windows-gnu") { + components.push(Component { + pkg: "rust-mingw".to_string(), + target: host.to_string(), + }); + } + + // Docs, other standard libraries, and the source package are all + // optional. + extensions.push(Component { + pkg: "rust-docs".to_string(), + target: host.to_string(), + }); + for target in TARGETS { + if target != host { + extensions.push(Component { + pkg: "rust-std".to_string(), + target: target.to_string(), + }); + } + } + extensions.push(Component { + pkg: "rust-src".to_string(), + target: "*".to_string(), + }); + + pkg.target.insert(host.to_string(), Target { + available: true, + url: Some(self.url("rust", host)), + hash: Some(to_hex(digest.as_ref())), + components: Some(components), + extensions: Some(extensions), + }); + } + manifest.pkg.insert("rust".to_string(), pkg); + + return manifest + } + + fn package(&mut self, + pkgname: &str, + dst: &mut HashMap, + targets: &[&str]) { + let targets = targets.iter().map(|name| { + let filename = self.filename(pkgname, name); + let digest = match self.digests.remove(&filename) { + Some(digest) => digest, + None => { + return (name.to_string(), Target { + available: false, + url: None, + hash: None, + components: None, + extensions: None, + }) + } + }; + + (name.to_string(), Target { + available: true, + url: Some(self.url(pkgname, name)), + hash: Some(digest), + components: None, + extensions: None, + }) + }).collect(); + + dst.insert(pkgname.to_string(), Package { + version: self.cached_version(pkgname).to_string(), + target: targets, + }); + } + + fn url(&self, component: &str, target: &str) -> String { + format!("{}/{}/{}", + self.s3_address, + self.date, + self.filename(component, target)) + } + + fn filename(&self, component: &str, target: &str) -> String { + if component == "rust-src" { + format!("rust-src-{}.tar.gz", self.channel) + } else { + format!("{}-{}-{}.tar.gz", component, self.channel, target) + } + } + + fn cached_version(&self, component: &str) -> &str { + if component == "cargo" { + &self.cargo_version + } else { + &self.rust_version + } + } + + fn version(&self, component: &str, target: &str) -> String { + let mut cmd = Command::new("tar"); + let filename = self.filename(component, target); + cmd.arg("xf") + .arg(self.input.join(&filename)) + .arg(format!("{}/version", filename.replace(".tar.gz", ""))) + .arg("-O"); + let version = t!(cmd.output()); + if !version.status.success() { + panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}", + cmd, + String::from_utf8_lossy(&version.stdout), + String::from_utf8_lossy(&version.stderr)); + } + String::from_utf8_lossy(&version.stdout).trim().to_string() + } + + fn hash(&self, path: &Path) -> String { + let sha = t!(Command::new("shasum") + .arg("-a").arg("256") + .arg(path) + .output()); + assert!(sha.status.success()); + + let filename = path.file_name().unwrap().to_str().unwrap(); + let sha256 = self.output.join(format!("{}.sha256", filename)); + t!(t!(File::create(&sha256)).write_all(&sha.stdout)); + + let stdout = String::from_utf8_lossy(&sha.stdout); + stdout.split_whitespace().next().unwrap().to_string() + } + + fn sign(&self, path: &Path) { + let filename = path.file_name().unwrap().to_str().unwrap(); + let asc = self.output.join(format!("{}.asc", filename)); + println!("signing: {:?}", path); + let mut cmd = Command::new("gpg"); + cmd.arg("--no-tty") + .arg("--yes") + .arg("--passphrase-fd").arg("0") + .arg("--armor") + .arg("--output").arg(&asc) + .arg("--detach-sign").arg(path) + .stdin(Stdio::piped()); + let mut child = t!(cmd.spawn()); + t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes())); + assert!(t!(child.wait()).success()); + } + + fn write_manifest(&self, manifest: &str, name: &str) { + let dst = self.output.join(name); + t!(t!(File::create(&dst)).write_all(manifest.as_bytes())); + self.hash(&dst); + self.sign(&dst); + } +} + +fn to_hex(digest: &[u8]) -> String { + let mut ret = String::new(); + for byte in digest { + ret.push(hex((byte & 0xf0) >> 4)); + ret.push(hex(byte & 0xf)); + } + return ret; + + fn hex(b: u8) -> char { + match b { + 0...9 => (b'0' + b) as char, + _ => (b'a' + b - 10) as char, + } + } +} From 2a3568f14bafa2bf62c50fd8589b48be6e31991d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 10 Jan 2017 10:23:21 -0500 Subject: [PATCH 15/86] Fix wording around sort guarantees Fixes #38524 --- src/libcollections/slice.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index e704f400d49e3..e4bc05c7ff01f 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1064,8 +1064,11 @@ impl [T] { /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. /// - /// This sort is stable and `O(n log n)` worst-case, but allocates - /// temporary storage half the size of `self`. + /// This sort is stable and `O(n log n)` worst-case. + /// + /// # Current Implementation + /// + /// The current implementation allocates temporary storage half the size of `self`. /// /// # Examples /// From c2b153b133d244015e4d174d893e75a733db12df Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Sat, 14 Jan 2017 01:46:30 +0100 Subject: [PATCH 16/86] Expand the sort docs --- src/libcollections/slice.rs | 44 +++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index e4bc05c7ff01f..211394180e861 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1064,11 +1064,17 @@ impl [T] { /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. /// - /// This sort is stable and `O(n log n)` worst-case. + /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// - /// # Current Implementation + /// # Current implementation /// - /// The current implementation allocates temporary storage half the size of `self`. + /// The current algorithm is an adaptive, iterative merge sort inspired by + /// [timsort](https://en.wikipedia.org/wiki/Timsort). + /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of + /// two or more sorted sequences concatenated one after another. + /// + /// Also, it allocates temporary storage half the size of `self`, but for short slices a + /// non-allocating insertion sort is used instead. /// /// # Examples /// @@ -1086,11 +1092,19 @@ impl [T] { self.sort_by(|a, b| a.cmp(b)) } - /// Sorts the slice, in place, using `f` to extract a key by which to - /// order the sort by. + /// Sorts the slice using `f` to extract a key to compare elements by. + /// + /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. + /// + /// # Current implementation + /// + /// The current algorithm is an adaptive, iterative merge sort inspired by + /// [timsort](https://en.wikipedia.org/wiki/Timsort). + /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of + /// two or more sorted sequences concatenated one after another. /// - /// This sort is stable and `O(n log n)` worst-case, but allocates - /// temporary storage half the size of `self`. + /// Also, it allocates temporary storage half the size of `self`, but for short slices a + /// non-allocating insertion sort is used instead. /// /// # Examples /// @@ -1108,11 +1122,19 @@ impl [T] { self.sort_by(|a, b| f(a).cmp(&f(b))) } - /// Sorts the slice, in place, using `compare` to compare - /// elements. + /// Sorts the slice using `compare` to compare elements. + /// + /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. + /// + /// # Current implementation + /// + /// The current algorithm is an adaptive, iterative merge sort inspired by + /// [timsort](https://en.wikipedia.org/wiki/Timsort). + /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of + /// two or more sorted sequences concatenated one after another. /// - /// This sort is stable and `O(n log n)` worst-case, but allocates - /// temporary storage half the size of `self`. + /// Also, it allocates temporary storage half the size of `self`, but for short slices a + /// non-allocating insertion sort is used instead. /// /// # Examples /// From 11ede684ee2e3eee4b3586174b2d5008b58a86cf Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Tue, 17 Jan 2017 01:11:06 +0100 Subject: [PATCH 17/86] Fix: insertion_len -> max_insertion --- src/libcollections/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 211394180e861..18e4a23fa8d67 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1560,7 +1560,7 @@ fn merge_sort(v: &mut [T], mut compare: F) // FIXME #12092: These numbers are platform-specific and need more extensive testing/tuning. // - // If `v` has length up to `insertion_len`, simply switch to insertion sort because it is going + // If `v` has length up to `max_insertion`, simply switch to insertion sort because it is going // to perform better than merge sort. For bigger types `T`, the threshold is smaller. // // Short runs are extended using insertion sort to span at least `min_run` elements, in order From e02f923e37402273a4971e2c015842ecc4c5f0d9 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Fri, 20 Jan 2017 09:11:11 +0100 Subject: [PATCH 18/86] Remove trailing whitespace --- src/libcollections/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 18e4a23fa8d67..fc49c9f56438c 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1067,7 +1067,7 @@ impl [T] { /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// /// # Current implementation - /// + /// /// The current algorithm is an adaptive, iterative merge sort inspired by /// [timsort](https://en.wikipedia.org/wiki/Timsort). /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of From 8944582d1d51f64d38a88791a30e1b2d415ef123 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 25 Jan 2017 11:55:30 -0800 Subject: [PATCH 19/86] travis: Upload all artifacts in build/dist Previously we only uploaded tarballs, but this modifies Travis/AppVeyor to upload everything. We shouldn't have anything else in there to worry about and otherwise we need to be sure to pick up pkg/msi/exe installers. --- .travis.yml | 4 ++-- appveyor.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index bbe0cdfb6f8f0..0f73f67224b76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -124,9 +124,9 @@ before_deploy: - mkdir -p deploy/$TRAVIS_COMMIT - > if [ "$TRAVIS_OS_NAME" == "osx" ]; then - cp build/dist/*.tar.gz deploy/$TRAVIS_COMMIT; + cp -r build/dist deploy/$TRAVIS_COMMIT; else - cp obj/build/dist/*.tar.gz deploy/$TRAVIS_COMMIT; + cp -r obj/build/dist deploy/$TRAVIS_COMMIT; fi deploy: diff --git a/appveyor.yml b/appveyor.yml index f158d788d16af..418cdcb07af4e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -137,7 +137,7 @@ branches: before_deploy: - ps: | New-Item -Path deploy -ItemType directory - Get-ChildItem -Path build\dist -Filter '*.tar.gz' | Move-Item -Destination deploy + Get-ChildItem -Path build\dist | Move-Item -Destination deploy Get-ChildItem -Path deploy | Foreach-Object { Push-AppveyorArtifact $_.FullName -FileName ${env:APPVEYOR_REPO_COMMIT}/$_ } @@ -151,7 +151,7 @@ deploy: bucket: rust-lang-ci set_public: true region: us-east-1 - artifact: /.*\.tar.gz/ + artifact: /.*/ folder: rustc-builds on: branch: auto From c6b65ac7480b25be5d7157e0a13b3677c5538104 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 11 Jan 2017 15:46:11 -0500 Subject: [PATCH 20/86] process trait/impl items directly from the visitor callback The current setup processes impl/trait items while visiting the impl/trait. This means we basically have this setup: -> TypeckItemBody(Impl) -> Tables(ImplItem{0,1,2,3}) But this was largely an artifact of the older code. By moving the processing of items into method dedicated for their use, we produce this setup: -> TypeckItemBody(ImplItem0) -> Tables(ImplItem0) ... -> TypeckItemBody(ImplItem3) -> Tables(ImplItem3) --- src/librustc_typeck/check/mod.rs | 88 +++++++------------ .../dep_graph_crosscontaminate_tables.rs | 25 ++++++ 2 files changed, 58 insertions(+), 55 deletions(-) create mode 100644 src/test/compile-fail/dep_graph_crosscontaminate_tables.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e240c70aaa3a5..02f5d77f249ce 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -570,16 +570,43 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { } impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { - fn visit_item(&mut self, i: &'tcx hir::Item) { - check_item_body(self.ccx, i); + fn visit_item(&mut self, item: &'tcx hir::Item) { + match item.node { + hir::ItemFn(ref decl, .., body_id) => { + check_bare_fn(self.ccx, &decl, body_id, item.id, item.span); + } + _ => { } + } } - fn visit_trait_item(&mut self, _item: &'tcx hir::TraitItem) { - // done as part of `visit_item` above + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { + match trait_item.node { + hir::TraitItemKind::Const(_, Some(expr)) => { + check_const(self.ccx, expr, trait_item.id) + } + hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => { + check_bare_fn(self.ccx, &sig.decl, body_id, trait_item.id, trait_item.span); + } + hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | + hir::TraitItemKind::Const(_, None) | + hir::TraitItemKind::Type(..) => { + // Nothing to do. + } + } } - fn visit_impl_item(&mut self, _item: &'tcx hir::ImplItem) { - // done as part of `visit_item` above + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + match impl_item.node { + hir::ImplItemKind::Const(_, expr) => { + check_const(self.ccx, expr, impl_item.id) + } + hir::ImplItemKind::Method(ref sig, body_id) => { + check_bare_fn(self.ccx, &sig.decl, body_id, impl_item.id, impl_item.span); + } + hir::ImplItemKind::Type(_) => { + // Nothing to do here. + } + } } } @@ -897,55 +924,6 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } -pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { - debug!("check_item_body(it.id={}, it.name={})", - it.id, - ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id))); - let _indenter = indenter(); - match it.node { - hir::ItemFn(ref decl, .., body_id) => { - check_bare_fn(ccx, &decl, body_id, it.id, it.span); - } - hir::ItemImpl(.., ref impl_item_refs) => { - debug!("ItemImpl {} with id {}", it.name, it.id); - - for impl_item_ref in impl_item_refs { - let impl_item = ccx.tcx.map.impl_item(impl_item_ref.id); - match impl_item.node { - hir::ImplItemKind::Const(_, expr) => { - check_const(ccx, expr, impl_item.id) - } - hir::ImplItemKind::Method(ref sig, body_id) => { - check_bare_fn(ccx, &sig.decl, body_id, impl_item.id, impl_item.span); - } - hir::ImplItemKind::Type(_) => { - // Nothing to do here. - } - } - } - } - hir::ItemTrait(.., ref trait_item_refs) => { - for trait_item_ref in trait_item_refs { - let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id); - match trait_item.node { - hir::TraitItemKind::Const(_, Some(expr)) => { - check_const(ccx, expr, trait_item.id) - } - hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => { - check_bare_fn(ccx, &sig.decl, body_id, trait_item.id, trait_item.span); - } - hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | - hir::TraitItemKind::Const(_, None) | - hir::TraitItemKind::Type(..) => { - // Nothing to do. - } - } - } - } - _ => {/* nothing to do */ } - } -} - fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId, item: &hir::Item) { diff --git a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs new file mode 100644 index 0000000000000..06fea1a8f2969 --- /dev/null +++ b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs @@ -0,0 +1,25 @@ +#![feature(rustc_attrs)] + +struct Foo { + x: u8 +} + +impl Foo { + // Changing the item `new`... + #[rustc_if_this_changed(HirBody)] + fn new() -> Foo { + Foo { x: 0 } + } + + // ...should not cause us to recompute the tables for `with`! + #[rustc_then_this_would_need(Tables)] //~ ERROR no path + fn with(x: u8) -> Foo { + Foo { x: x } + } +} + +fn main() { + let f = Foo::new(); + let g = Foo::with(22); + assert_eq!(f.x, g.x - 22); +} From a0151e834b72ede8e12aea5884d4ce4001f80c76 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 11 Jan 2017 16:13:07 -0500 Subject: [PATCH 21/86] pacify the mercilous tidy --- .../compile-fail/dep_graph_crosscontaminate_tables.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs index 06fea1a8f2969..4a9d9cf1c0586 100644 --- a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs +++ b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs @@ -1,3 +1,13 @@ +// 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(rustc_attrs)] struct Foo { From 01195df2ab821c13469b03099955ec76d424f211 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Jan 2017 12:01:18 -0500 Subject: [PATCH 22/86] fix the test case by supplying proper options --- src/test/compile-fail/dep_graph_crosscontaminate_tables.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs index 4a9d9cf1c0586..88c06aa78c299 100644 --- a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs +++ b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs @@ -8,6 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test that the `Tables` nodes for impl items are independent from +// one another. + +// compile-flags: -Z query-dep-graph + #![feature(rustc_attrs)] struct Foo { From 1c0c2af3dc15cfa5dfab4d8327262bc04d120ce0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 12 Jan 2017 18:11:02 -0500 Subject: [PATCH 23/86] merge TypeckItemBody and Tables depnodes --- src/librustc/dep_graph/README.md | 28 ++++++++++--------- src/librustc/dep_graph/dep_node.rs | 3 -- .../persist/dirty_clean.rs | 6 ++-- src/librustc_incremental/persist/preds.rs | 2 +- src/librustc_typeck/check/mod.rs | 4 +-- .../dep-graph-assoc-type-trans.rs | 2 +- .../compile-fail/dep-graph-caller-callee.rs | 4 +-- ...graph-trait-impl-two-traits-same-method.rs | 4 +-- .../dep-graph-trait-impl-two-traits.rs | 4 +-- src/test/compile-fail/dep-graph-trait-impl.rs | 10 +++---- .../struct_point.rs | 10 +++---- .../callee_caller_cross_crate/b.rs | 4 +-- .../change_add_field/struct_point.rs | 14 +++++----- .../incremental/change_crate_order/main.rs | 2 +- .../change_private_fn/struct_point.rs | 10 +++---- .../change_private_fn_cc/struct_point.rs | 10 +++---- .../struct_point.rs | 10 +++---- .../struct_point.rs | 10 +++---- .../struct_point.rs | 10 +++---- .../struct_point.rs | 10 +++---- src/test/incremental/dirty_clean.rs | 8 +++--- src/test/incremental/hello_world.rs | 4 +-- src/test/incremental/rlib_cross_crate/b.rs | 8 +++--- src/test/incremental/string_constant.rs | 6 ++-- src/test/incremental/struct_add_field.rs | 6 ++-- .../incremental/struct_change_field_name.rs | 6 ++-- .../incremental/struct_change_field_type.rs | 6 ++-- .../struct_change_field_type_cross_crate/b.rs | 6 ++-- src/test/incremental/struct_change_nothing.rs | 6 ++-- src/test/incremental/struct_remove_field.rs | 6 ++-- .../incremental/type_alias_cross_crate/b.rs | 8 +++--- 31 files changed, 113 insertions(+), 114 deletions(-) diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index d2b94db689bc4..372f7e2d4482f 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -326,15 +326,15 @@ The idea is that you can annotate a test like: #[rustc_if_this_changed] fn foo() { } -#[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK +#[rustc_then_this_would_need(Tables)] //~ ERROR OK fn bar() { foo(); } -#[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path +#[rustc_then_this_would_need(Tables)] //~ ERROR no path fn baz() { } ``` This will check whether there is a path in the dependency graph from -`Hir(foo)` to `TypeckItemBody(bar)`. An error is reported for each +`Hir(foo)` to `Tables(bar)`. An error is reported for each `#[rustc_then_this_would_need]` annotation that indicates whether a path exists. `//~ ERROR` annotations can then be used to test if a path is found (as demonstrated above). @@ -371,27 +371,27 @@ A node is considered to match a filter if all of those strings appear in its label. So, for example: ``` -RUST_DEP_GRAPH_FILTER='-> TypeckItemBody' +RUST_DEP_GRAPH_FILTER='-> Tables' ``` -would select the predecessors of all `TypeckItemBody` nodes. Usually though you -want the `TypeckItemBody` node for some particular fn, so you might write: +would select the predecessors of all `Tables` nodes. Usually though you +want the `Tables` node for some particular fn, so you might write: ``` -RUST_DEP_GRAPH_FILTER='-> TypeckItemBody & bar' +RUST_DEP_GRAPH_FILTER='-> Tables & bar' ``` -This will select only the `TypeckItemBody` nodes for fns with `bar` in their name. +This will select only the `Tables` nodes for fns with `bar` in their name. Perhaps you are finding that when you change `foo` you need to re-type-check `bar`, but you don't think you should have to. In that case, you might do: ``` -RUST_DEP_GRAPH_FILTER='Hir&foo -> TypeckItemBody & bar' +RUST_DEP_GRAPH_FILTER='Hir&foo -> Tables & bar' ``` This will dump out all the nodes that lead from `Hir(foo)` to -`TypeckItemBody(bar)`, from which you can (hopefully) see the source +`Tables(bar)`, from which you can (hopefully) see the source of the erroneous edge. #### Tracking down incorrect edges @@ -417,8 +417,8 @@ dep-graph as described in the previous section and open `dep-graph.txt` to see something like: Hir(foo) -> Collect(bar) - Collect(bar) -> TypeckItemBody(bar) - + Collect(bar) -> Tables(bar) + That first edge looks suspicious to you. So you set `RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and then observe the backtrace. Voila, bug fixed! @@ -440,4 +440,6 @@ To achieve this, the HIR map will detect if the def-id originates in an inlined node and add a dependency to a suitable `MetaData` node instead. If you are reading a HIR node and are not sure if it may be inlined or not, you can use `tcx.map.read(node_id)` and it will detect -whether the node is inlined or not and do the right thing. +whether the node is inlined or not and do the right thing. You can +also use `tcx.map.is_inlined_def_id()` and +`tcx.map.is_inlined_node_id()` to test. diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index a68876b5ae9c0..bc5113b61d753 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -78,7 +78,6 @@ pub enum DepNode { Variance, WfCheck(D), TypeckItemType(D), - TypeckItemBody(D), Dropck, DropckImpl(D), UnusedTraitCheck, @@ -158,7 +157,6 @@ impl DepNode { HirBody, TransCrateItem, TypeckItemType, - TypeckItemBody, AssociatedItems, ItemSignature, AssociatedItemDefIds, @@ -216,7 +214,6 @@ impl DepNode { CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck), WfCheck(ref d) => op(d).map(WfCheck), TypeckItemType(ref d) => op(d).map(TypeckItemType), - TypeckItemBody(ref d) => op(d).map(TypeckItemBody), DropckImpl(ref d) => op(d).map(DropckImpl), CheckConst(ref d) => op(d).map(CheckConst), IntrinsicCheck(ref d) => op(d).map(IntrinsicCheck), diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 481462dff86e4..b719a759b93ae 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -14,11 +14,11 @@ //! we will check that a suitable node for that item either appears //! or does not appear in the dep-graph, as appropriate: //! -//! - `#[rustc_dirty(label="TypeckItemBody", cfg="rev2")]` if we are +//! - `#[rustc_dirty(label="Tables", cfg="rev2")]` if we are //! in `#[cfg(rev2)]`, then there MUST NOT be a node -//! `DepNode::TypeckItemBody(X)` where `X` is the def-id of the +//! `DepNode::Tables(X)` where `X` is the def-id of the //! current node. -//! - `#[rustc_clean(label="TypeckItemBody", cfg="rev2")]` same as above, +//! - `#[rustc_clean(label="Tables", cfg="rev2")]` same as above, //! except that the node MUST exist. //! //! Errors are reported if we are in the suitable configuration but diff --git a/src/librustc_incremental/persist/preds.rs b/src/librustc_incremental/persist/preds.rs index b2a4a2772ec26..454edbc4d3444 100644 --- a/src/librustc_incremental/persist/preds.rs +++ b/src/librustc_incremental/persist/preds.rs @@ -56,7 +56,7 @@ impl<'q> Predecessors<'q> { // if -Z query-dep-graph is passed, save more extended data // to enable better unit testing - DepNode::TypeckItemBody(_) | + DepNode::Tables(_) | DepNode::TransCrateItem(_) => tcx.sess.opts.debugging_opts.query_dep_graph, _ => false, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 02f5d77f249ce..ae3578616bc75 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -628,14 +628,14 @@ pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult { pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult { ccx.tcx.sess.track_errors(|| { let mut visit = CheckItemBodiesVisitor { ccx: ccx }; - ccx.tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemBody, &mut visit); + ccx.tcx.visit_all_item_likes_in_krate(DepNode::Tables, &mut visit); // Process deferred obligations, now that all functions // bodies have been fully inferred. for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() { // Use the same DepNode as for the body of the original function/item. let def_id = ccx.tcx.map.local_def_id(item_id); - let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckItemBody(def_id)); + let _task = ccx.tcx.dep_graph.in_task(DepNode::Tables(def_id)); let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id); ccx.tcx.infer_ctxt(param_env, Reveal::NotSpecializable).enter(|infcx| { diff --git a/src/test/compile-fail/dep-graph-assoc-type-trans.rs b/src/test/compile-fail/dep-graph-assoc-type-trans.rs index b56be9e5683a8..ddfd2b6617146 100644 --- a/src/test/compile-fail/dep-graph-assoc-type-trans.rs +++ b/src/test/compile-fail/dep-graph-assoc-type-trans.rs @@ -35,7 +35,7 @@ mod x { mod y { use Foo; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn use_char_assoc() { // Careful here: in the representation, ::T gets diff --git a/src/test/compile-fail/dep-graph-caller-callee.rs b/src/test/compile-fail/dep-graph-caller-callee.rs index 0d6954ab9df62..8fda05e80856b 100644 --- a/src/test/compile-fail/dep-graph-caller-callee.rs +++ b/src/test/compile-fail/dep-graph-caller-callee.rs @@ -27,7 +27,7 @@ mod y { use x; // These dependencies SHOULD exist: - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn y() { x::x(); @@ -39,7 +39,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path + #[rustc_then_this_would_need(Tables)] //~ ERROR no path #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path pub fn z() { y::y(); diff --git a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs index 5e4f43af669ca..75e20d75704f4 100644 --- a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs +++ b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs @@ -39,7 +39,7 @@ mod x { mod y { use {Foo, Bar}; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK pub fn with_char() { char::method('a'); } @@ -48,7 +48,7 @@ mod y { mod z { use y; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path + #[rustc_then_this_would_need(Tables)] //~ ERROR no path pub fn z() { y::with_char(); } diff --git a/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs b/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs index 2ec7573cb81dc..42318d16e3354 100644 --- a/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs +++ b/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs @@ -38,7 +38,7 @@ mod x { mod y { use {Foo, Bar}; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path + #[rustc_then_this_would_need(Tables)] //~ ERROR no path pub fn call_bar() { char::bar('a'); } @@ -47,7 +47,7 @@ mod y { mod z { use y; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path + #[rustc_then_this_would_need(Tables)] //~ ERROR no path pub fn z() { y::call_bar(); } diff --git a/src/test/compile-fail/dep-graph-trait-impl.rs b/src/test/compile-fail/dep-graph-trait-impl.rs index d87d7a6be1c28..c3a7445eb4357 100644 --- a/src/test/compile-fail/dep-graph-trait-impl.rs +++ b/src/test/compile-fail/dep-graph-trait-impl.rs @@ -34,25 +34,25 @@ mod x { mod y { use Foo; - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn with_char() { char::method('a'); } - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_char() { take_foo::('a'); } - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn with_u32() { u32::method(22); } - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR OK + #[rustc_then_this_would_need(Tables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_u32() { take_foo::(22); @@ -66,7 +66,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(TypeckItemBody)] //~ ERROR no path + #[rustc_then_this_would_need(Tables)] //~ ERROR no path #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path pub fn z() { y::with_char(); diff --git a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs index 489427ba1c126..817d42c74a672 100644 --- a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs +++ b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs @@ -32,7 +32,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -43,7 +43,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_free_fn { use point::{self, Point}; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; point::distance_squared(&x); @@ -54,7 +54,7 @@ mod fn_calls_free_fn { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -64,7 +64,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -74,7 +74,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/callee_caller_cross_crate/b.rs b/src/test/incremental/callee_caller_cross_crate/b.rs index e8b187b5454f6..094fbdc84f2a8 100644 --- a/src/test/incremental/callee_caller_cross_crate/b.rs +++ b/src/test/incremental/callee_caller_cross_crate/b.rs @@ -16,12 +16,12 @@ extern crate a; -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn call_function0() { a::function0(77); } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn call_function1() { a::function1(77); } diff --git a/src/test/incremental/change_add_field/struct_point.rs b/src/test/incremental/change_add_field/struct_point.rs index 261eb38a51aeb..3e9d4dcb3fabd 100644 --- a/src/test/incremental/change_add_field/struct_point.rs +++ b/src/test/incremental/change_add_field/struct_point.rs @@ -79,7 +79,7 @@ mod point { mod fn_with_type_in_sig { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn boop(p: Option<&Point>) -> f32 { p.map(|p| p.total()).unwrap_or(0.0) } @@ -95,7 +95,7 @@ mod fn_with_type_in_sig { mod call_fn_with_type_in_sig { use fn_with_type_in_sig; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn bip() -> f32 { fn_with_type_in_sig::boop(None) } @@ -111,7 +111,7 @@ mod call_fn_with_type_in_sig { mod fn_with_type_in_body { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn boop() -> f32 { Point::origin().total() } @@ -124,7 +124,7 @@ mod fn_with_type_in_body { mod call_fn_with_type_in_body { use fn_with_type_in_body; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn bip() -> f32 { fn_with_type_in_body::boop() } @@ -134,7 +134,7 @@ mod call_fn_with_type_in_body { mod fn_make_struct { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn make_origin(p: Point) -> Point { Point { ..p } } @@ -144,7 +144,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -154,7 +154,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_crate_order/main.rs b/src/test/incremental/change_crate_order/main.rs index bd8742ff38e01..69236643e0ba4 100644 --- a/src/test/incremental/change_crate_order/main.rs +++ b/src/test/incremental/change_crate_order/main.rs @@ -28,7 +28,7 @@ extern crate a; use a::A; use b::B; -//? #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +//? #[rustc_clean(label="Tables", cfg="rpass2")] pub fn main() { A + B; } diff --git a/src/test/incremental/change_private_fn/struct_point.rs b/src/test/incremental/change_private_fn/struct_point.rs index 678bc10f1e56f..4b1b3ede47d97 100644 --- a/src/test/incremental/change_private_fn/struct_point.rs +++ b/src/test/incremental/change_private_fn/struct_point.rs @@ -59,7 +59,7 @@ mod point { mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -70,7 +70,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -81,7 +81,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -91,7 +91,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -101,7 +101,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_fn_cc/struct_point.rs b/src/test/incremental/change_private_fn_cc/struct_point.rs index ded87dd27f410..dc73969201b2c 100644 --- a/src/test/incremental/change_private_fn_cc/struct_point.rs +++ b/src/test/incremental/change_private_fn_cc/struct_point.rs @@ -31,7 +31,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -42,7 +42,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -53,7 +53,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -63,7 +63,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -73,7 +73,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_impl_method/struct_point.rs b/src/test/incremental/change_private_impl_method/struct_point.rs index 46e5a88eef940..c89a7233f8dec 100644 --- a/src/test/incremental/change_private_impl_method/struct_point.rs +++ b/src/test/incremental/change_private_impl_method/struct_point.rs @@ -59,7 +59,7 @@ mod point { mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -70,7 +70,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -81,7 +81,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -91,7 +91,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -101,7 +101,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_impl_method_cc/struct_point.rs b/src/test/incremental/change_private_impl_method_cc/struct_point.rs index 4d9ca77969bd7..04d01218546e1 100644 --- a/src/test/incremental/change_private_impl_method_cc/struct_point.rs +++ b/src/test/incremental/change_private_impl_method_cc/struct_point.rs @@ -32,7 +32,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -43,7 +43,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn dirty() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -54,7 +54,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -64,7 +64,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -74,7 +74,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs index e0047e5ec6455..d39cf09eb831e 100644 --- a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs @@ -50,7 +50,7 @@ mod point { mod fn_calls_changed_method { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_origin(); @@ -61,7 +61,7 @@ mod fn_calls_changed_method { mod fn_calls_another_method { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.x(); @@ -72,7 +72,7 @@ mod fn_calls_another_method { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -82,7 +82,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -92,7 +92,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs index 54e06e16998cd..4b35355056e8f 100644 --- a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs @@ -61,7 +61,7 @@ mod point { mod fn_calls_changed_method { use point::Point; - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_point(None); @@ -72,7 +72,7 @@ mod fn_calls_changed_method { mod fn_calls_another_method { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.x(); @@ -83,7 +83,7 @@ mod fn_calls_another_method { mod fn_make_struct { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -93,7 +93,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -103,7 +103,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/dirty_clean.rs b/src/test/incremental/dirty_clean.rs index 64b7f2951d274..06c962b4d7b92 100644 --- a/src/test/incremental/dirty_clean.rs +++ b/src/test/incremental/dirty_clean.rs @@ -35,20 +35,20 @@ mod x { mod y { use x; - #[rustc_clean(label="TypeckItemBody", cfg="cfail2")] + #[rustc_clean(label="Tables", cfg="cfail2")] #[rustc_clean(label="TransCrateItem", cfg="cfail2")] pub fn y() { - //[cfail2]~^ ERROR `TypeckItemBody("y::y")` not found in dep graph, but should be clean + //[cfail2]~^ ERROR `Tables("y::y")` not found in dep graph, but should be clean //[cfail2]~| ERROR `TransCrateItem("y::y")` not found in dep graph, but should be clean x::x(); } } mod z { - #[rustc_dirty(label="TypeckItemBody", cfg="cfail2")] + #[rustc_dirty(label="Tables", cfg="cfail2")] #[rustc_dirty(label="TransCrateItem", cfg="cfail2")] pub fn z() { - //[cfail2]~^ ERROR `TypeckItemBody("z::z")` found in dep graph, but should be dirty + //[cfail2]~^ ERROR `Tables("z::z")` found in dep graph, but should be dirty //[cfail2]~| ERROR `TransCrateItem("z::z")` found in dep graph, but should be dirty } } diff --git a/src/test/incremental/hello_world.rs b/src/test/incremental/hello_world.rs index b7f90c09b565c..e87fea2028025 100644 --- a/src/test/incremental/hello_world.rs +++ b/src/test/incremental/hello_world.rs @@ -31,7 +31,7 @@ mod x { mod y { use x; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn yyyy() { x::xxxx(); } @@ -40,7 +40,7 @@ mod y { mod z { use y; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] pub fn z() { y::yyyy(); } diff --git a/src/test/incremental/rlib_cross_crate/b.rs b/src/test/incremental/rlib_cross_crate/b.rs index 21b654bdf584b..ecf19d7a55373 100644 --- a/src/test/incremental/rlib_cross_crate/b.rs +++ b/src/test/incremental/rlib_cross_crate/b.rs @@ -22,15 +22,15 @@ extern crate a; -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] -#[rustc_clean(label="TypeckItemBody", cfg="rpass3")] +#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22; x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] -#[rustc_clean(label="TypeckItemBody", cfg="rpass3")] +#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass3")] pub fn use_Y() { let x: a::Y = 'c'; } diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs index 8651a67bae221..08dc4d33229c2 100644 --- a/src/test/incremental/string_constant.rs +++ b/src/test/incremental/string_constant.rs @@ -27,7 +27,7 @@ mod x { } #[cfg(rpass2)] - #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] + #[rustc_dirty(label="Tables", cfg="rpass2")] #[rustc_dirty(label="TransCrateItem", cfg="rpass2")] pub fn x() { println!("{}", "2"); @@ -37,7 +37,7 @@ mod x { mod y { use x; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] #[rustc_clean(label="TransCrateItem", cfg="rpass2")] pub fn y() { x::x(); @@ -47,7 +47,7 @@ mod y { mod z { use y; - #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] + #[rustc_clean(label="Tables", cfg="rpass2")] #[rustc_clean(label="TransCrateItem", cfg="rpass2")] pub fn z() { y::y(); diff --git a/src/test/incremental/struct_add_field.rs b/src/test/incremental/struct_add_field.rs index da1b32cd73d6e..159f594e8c043 100644 --- a/src/test/incremental/struct_add_field.rs +++ b/src/test/incremental/struct_add_field.rs @@ -31,17 +31,17 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_name.rs b/src/test/incremental/struct_change_field_name.rs index cb43d12740584..ca011f1fdd083 100644 --- a/src/test/incremental/struct_change_field_name.rs +++ b/src/test/incremental/struct_change_field_name.rs @@ -34,7 +34,7 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="TypeckItemBody", cfg="cfail2")] +#[rustc_dirty(label="Tables", cfg="cfail2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; //[cfail2]~^ ERROR struct `X` has no field named `x` @@ -42,13 +42,13 @@ pub fn use_X() -> u32 { //[cfail2]~^ ERROR no field `x` on type `X` } -#[rustc_dirty(label="TypeckItemBody", cfg="cfail2")] +#[rustc_dirty(label="Tables", cfg="cfail2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 //[cfail2]~^ ERROR no field `x` on type `X` } -#[rustc_clean(label="TypeckItemBody", cfg="cfail2")] +#[rustc_clean(label="Tables", cfg="cfail2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type.rs b/src/test/incremental/struct_change_field_type.rs index 65f3b1b4f368f..7237496af2cac 100644 --- a/src/test/incremental/struct_change_field_type.rs +++ b/src/test/incremental/struct_change_field_type.rs @@ -34,19 +34,19 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_EmbedX(x: EmbedX) -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type_cross_crate/b.rs b/src/test/incremental/struct_change_field_type_cross_crate/b.rs index 95e15d0b7f9a0..b490ea41238fd 100644 --- a/src/test/incremental/struct_change_field_type_cross_crate/b.rs +++ b/src/test/incremental/struct_change_field_type_cross_crate/b.rs @@ -18,18 +18,18 @@ extern crate a; use a::*; -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_nothing.rs b/src/test/incremental/struct_change_nothing.rs index 2bc636153f735..214cfacc6e7b0 100644 --- a/src/test/incremental/struct_change_nothing.rs +++ b/src/test/incremental/struct_change_nothing.rs @@ -34,19 +34,19 @@ pub struct Y { pub y: char } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_EmbedX(x: EmbedX) -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_remove_field.rs b/src/test/incremental/struct_remove_field.rs index a7ed79d1a5a35..fac2a7f634ce5 100644 --- a/src/test/incremental/struct_remove_field.rs +++ b/src/test/incremental/struct_remove_field.rs @@ -35,17 +35,17 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] +#[rustc_dirty(label="Tables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/type_alias_cross_crate/b.rs b/src/test/incremental/type_alias_cross_crate/b.rs index 09d4db331980d..fce759cc0b4b0 100644 --- a/src/test/incremental/type_alias_cross_crate/b.rs +++ b/src/test/incremental/type_alias_cross_crate/b.rs @@ -16,15 +16,15 @@ extern crate a; -#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] -#[rustc_clean(label="TypeckItemBody", cfg="rpass3")] +#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22; x as u32 } -#[rustc_clean(label="TypeckItemBody", cfg="rpass2")] -#[rustc_clean(label="TypeckItemBody", cfg="rpass3")] +#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="Tables", cfg="rpass3")] pub fn use_Y() { let x: a::Y = 'c'; } From 80b5f98d038346f9d4283b19fb117534d289e60f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 25 Jan 2017 15:56:30 -0500 Subject: [PATCH 24/86] remove outdated text --- src/librustc/dep_graph/README.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index 372f7e2d4482f..8e6d63d55dfcc 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -422,24 +422,3 @@ to see something like: That first edge looks suspicious to you. So you set `RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and then observe the backtrace. Voila, bug fixed! - -### Inlining of HIR nodes - -For the time being, at least, we still sometimes "inline" HIR nodes -from other crates into the current HIR map. This creates a weird -scenario where the same logical item (let's call it `X`) has two -def-ids: the original def-id `X` and a new, inlined one `X'`. `X'` is -in the current crate, but it's not like other HIR nodes: in -particular, when we restart compilation, it will not be available to -hash. Therefore, we do not want `Hir(X')` nodes appearing in our -graph. Instead, we want a "read" of `Hir(X')` to be represented as a -read of `MetaData(X)`, since the metadata for `X` is where the inlined -representation originated in the first place. - -To achieve this, the HIR map will detect if the def-id originates in -an inlined node and add a dependency to a suitable `MetaData` node -instead. If you are reading a HIR node and are not sure if it may be -inlined or not, you can use `tcx.map.read(node_id)` and it will detect -whether the node is inlined or not and do the right thing. You can -also use `tcx.map.is_inlined_def_id()` and -`tcx.map.is_inlined_node_id()` to test. From 282f7a3c44a428c26155b4686ad95e802fcd4158 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 25 Jan 2017 16:24:00 -0500 Subject: [PATCH 25/86] rename `Tables` to `TypeckTables` --- src/librustc/cfg/construct.rs | 2 +- src/librustc/dep_graph/README.md | 22 ++++----- src/librustc/dep_graph/dep_node.rs | 6 +-- src/librustc/infer/mod.rs | 48 +++++++++---------- src/librustc/lint/context.rs | 4 +- src/librustc/middle/dead.rs | 4 +- src/librustc/middle/effect.rs | 4 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/reachable.rs | 4 +- src/librustc/ty/context.rs | 14 +++--- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 6 +-- src/librustc_const_eval/check_match.rs | 2 +- src/librustc_const_eval/eval.rs | 14 +++--- src/librustc_const_eval/pattern.rs | 6 +-- src/librustc_driver/pretty.rs | 4 +- .../persist/dirty_clean.rs | 6 +-- src/librustc_incremental/persist/preds.rs | 2 +- src/librustc_metadata/astencode.rs | 2 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_passes/consts.rs | 4 +- src/librustc_privacy/lib.rs | 4 +- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_typeck/check/mod.rs | 6 +-- src/librustc_typeck/check/writeback.rs | 4 +- .../dep-graph-assoc-type-trans.rs | 2 +- .../compile-fail/dep-graph-caller-callee.rs | 4 +- ...graph-trait-impl-two-traits-same-method.rs | 4 +- .../dep-graph-trait-impl-two-traits.rs | 4 +- src/test/compile-fail/dep-graph-trait-impl.rs | 10 ++-- .../dep_graph_crosscontaminate_tables.rs | 4 +- .../struct_point.rs | 10 ++-- .../callee_caller_cross_crate/b.rs | 4 +- .../change_add_field/struct_point.rs | 14 +++--- .../incremental/change_crate_order/main.rs | 2 +- .../change_private_fn/struct_point.rs | 10 ++-- .../change_private_fn_cc/struct_point.rs | 10 ++-- .../struct_point.rs | 10 ++-- .../struct_point.rs | 10 ++-- .../struct_point.rs | 10 ++-- .../struct_point.rs | 10 ++-- src/test/incremental/dirty_clean.rs | 8 ++-- src/test/incremental/hello_world.rs | 4 +- src/test/incremental/rlib_cross_crate/b.rs | 8 ++-- src/test/incremental/string_constant.rs | 6 +-- src/test/incremental/struct_add_field.rs | 6 +-- .../incremental/struct_change_field_name.rs | 6 +-- .../incremental/struct_change_field_type.rs | 6 +-- .../struct_change_field_type_cross_crate/b.rs | 6 +-- src/test/incremental/struct_change_nothing.rs | 6 +-- src/test/incremental/struct_remove_field.rs | 6 +-- .../incremental/type_alias_cross_crate/b.rs | 8 ++-- 52 files changed, 183 insertions(+), 183 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 35afdd75cb8c4..6f2b9ca0c4220 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -18,7 +18,7 @@ use hir::{self, PatKind}; struct CFGBuilder<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, graph: CFGGraph, fn_exit: CFGIndex, loop_scopes: Vec, diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index 8e6d63d55dfcc..daed41f04700d 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -326,15 +326,15 @@ The idea is that you can annotate a test like: #[rustc_if_this_changed] fn foo() { } -#[rustc_then_this_would_need(Tables)] //~ ERROR OK +#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK fn bar() { foo(); } -#[rustc_then_this_would_need(Tables)] //~ ERROR no path +#[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path fn baz() { } ``` This will check whether there is a path in the dependency graph from -`Hir(foo)` to `Tables(bar)`. An error is reported for each +`Hir(foo)` to `TypeckTables(bar)`. An error is reported for each `#[rustc_then_this_would_need]` annotation that indicates whether a path exists. `//~ ERROR` annotations can then be used to test if a path is found (as demonstrated above). @@ -371,27 +371,27 @@ A node is considered to match a filter if all of those strings appear in its label. So, for example: ``` -RUST_DEP_GRAPH_FILTER='-> Tables' +RUST_DEP_GRAPH_FILTER='-> TypeckTables' ``` -would select the predecessors of all `Tables` nodes. Usually though you -want the `Tables` node for some particular fn, so you might write: +would select the predecessors of all `TypeckTables` nodes. Usually though you +want the `TypeckTables` node for some particular fn, so you might write: ``` -RUST_DEP_GRAPH_FILTER='-> Tables & bar' +RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar' ``` -This will select only the `Tables` nodes for fns with `bar` in their name. +This will select only the `TypeckTables` nodes for fns with `bar` in their name. Perhaps you are finding that when you change `foo` you need to re-type-check `bar`, but you don't think you should have to. In that case, you might do: ``` -RUST_DEP_GRAPH_FILTER='Hir&foo -> Tables & bar' +RUST_DEP_GRAPH_FILTER='Hir&foo -> TypeckTables & bar' ``` This will dump out all the nodes that lead from `Hir(foo)` to -`Tables(bar)`, from which you can (hopefully) see the source +`TypeckTables(bar)`, from which you can (hopefully) see the source of the erroneous edge. #### Tracking down incorrect edges @@ -417,7 +417,7 @@ dep-graph as described in the previous section and open `dep-graph.txt` to see something like: Hir(foo) -> Collect(bar) - Collect(bar) -> Tables(bar) + Collect(bar) -> TypeckTables(bar) That first edge looks suspicious to you. So you set `RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index bc5113b61d753..d9fd0b9a1f939 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -112,7 +112,7 @@ pub enum DepNode { SizedConstraint(D), AssociatedItemDefIds(D), InherentImpls(D), - Tables(D), + TypeckTables(D), // The set of impls for a given trait. Ultimately, it would be // nice to get more fine-grained here (e.g., to include a @@ -161,7 +161,7 @@ impl DepNode { ItemSignature, AssociatedItemDefIds, InherentImpls, - Tables, + TypeckTables, TraitImpls, ReprHints, } @@ -229,7 +229,7 @@ impl DepNode { SizedConstraint(ref d) => op(d).map(SizedConstraint), AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds), InherentImpls(ref d) => op(d).map(InherentImpls), - Tables(ref d) => op(d).map(Tables), + TypeckTables(ref d) => op(d).map(TypeckTables), TraitImpls(ref d) => op(d).map(TraitImpls), TraitItems(ref d) => op(d).map(TraitItems), ReprHints(ref d) => op(d).map(ReprHints), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b44e1563ee7ed..4e64dda1a3044 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -76,23 +76,23 @@ pub type Bound = Option; pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" pub type FixupResult = Result; // "fixup result" -/// A version of &ty::Tables which can be `Missing` (not needed), +/// A version of &ty::TypeckTables which can be `Missing` (not needed), /// `InProgress` (during typeck) or `Interned` (result of typeck). /// Only the `InProgress` version supports `borrow_mut`. #[derive(Copy, Clone)] pub enum InferTables<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - Interned(&'a ty::Tables<'gcx>), - InProgress(&'a RefCell>), + Interned(&'a ty::TypeckTables<'gcx>), + InProgress(&'a RefCell>), Missing } pub enum InferTablesRef<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - Interned(&'a ty::Tables<'gcx>), - InProgress(Ref<'a, ty::Tables<'tcx>>) + Interned(&'a ty::TypeckTables<'gcx>), + InProgress(Ref<'a, ty::TypeckTables<'tcx>>) } impl<'a, 'gcx, 'tcx> Deref for InferTablesRef<'a, 'gcx, 'tcx> { - type Target = ty::Tables<'tcx>; + type Target = ty::TypeckTables<'tcx>; fn deref(&self) -> &Self::Target { match *self { InferTablesRef::Interned(tables) => tables, @@ -112,7 +112,7 @@ impl<'a, 'gcx, 'tcx> InferTables<'a, 'gcx, 'tcx> { } } - pub fn expect_interned(self) -> &'a ty::Tables<'gcx> { + pub fn expect_interned(self) -> &'a ty::TypeckTables<'gcx> { match self { InferTables::Interned(tables) => tables, InferTables::InProgress(_) => { @@ -124,7 +124,7 @@ impl<'a, 'gcx, 'tcx> InferTables<'a, 'gcx, 'tcx> { } } - pub fn borrow_mut(self) -> RefMut<'a, ty::Tables<'tcx>> { + pub fn borrow_mut(self) -> RefMut<'a, ty::TypeckTables<'tcx>> { match self { InferTables::Interned(_) => { bug!("InferTables: infcx.tables.borrow_mut() outside of type-checking"); @@ -407,15 +407,15 @@ impl fmt::Display for FixupError { pub trait InferEnv<'a, 'tcx> { fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>); } impl<'a, 'tcx> InferEnv<'a, 'tcx> for () { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>) { (None, None, None) } @@ -423,26 +423,26 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for () { impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParameterEnvironment<'tcx> { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>) { (None, None, Some(self)) } } -impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::Tables<'tcx>, ty::ParameterEnvironment<'tcx>) { +impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>) { (Some(self.0), None, Some(self.1)) } } -impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::Tables<'tcx>, ty::ParameterEnvironment<'tcx>) { +impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) { fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>) { (None, Some(self.0), Some(self.1)) } @@ -450,8 +450,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::Tables<'tcx>, ty::ParameterEnvironmen impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId { fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> (Option<&'a ty::Tables<'tcx>>, - Option>, + -> (Option<&'a ty::TypeckTables<'tcx>>, + Option>, Option>) { let item_id = tcx.map.body_owner(self); (Some(tcx.item_tables(tcx.map.local_def_id(item_id))), @@ -466,8 +466,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId { pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { global_tcx: TyCtxt<'a, 'gcx, 'gcx>, arena: DroplessArena, - fresh_tables: Option>>, - tables: Option<&'a ty::Tables<'gcx>>, + fresh_tables: Option>>, + tables: Option<&'a ty::TypeckTables<'gcx>>, param_env: Option>, projection_mode: Reveal, } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4b731ed7a706a..5ac000923e071 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -337,7 +337,7 @@ pub struct LateContext<'a, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Side-tables for the body we are in. - pub tables: &'a ty::Tables<'tcx>, + pub tables: &'a ty::TypeckTables<'tcx>, /// The crate being checked. pub krate: &'a hir::Crate, @@ -1212,7 +1212,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let lint_store = mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), LintStore::new()); let mut cx = LateContext { tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), krate: krate, access_levels: access_levels, lints: lint_store, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 5af62d0172f5c..38fbe650a89bd 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -49,7 +49,7 @@ fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct MarkSymbolVisitor<'a, 'tcx: 'a> { worklist: Vec, tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, live_symbols: Box>, struct_has_extern_repr: bool, ignore_non_const_paths: bool, @@ -392,7 +392,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut symbol_visitor = MarkSymbolVisitor { worklist: worklist, tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), live_symbols: box FxHashSet(), struct_has_extern_repr: false, ignore_non_const_paths: false, diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index c42e8fcb08ced..f90d9143e9d57 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -52,7 +52,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool { struct EffectCheckVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, /// Whether we're in an unsafe context. unsafe_context: UnsafeContext, @@ -245,7 +245,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut visitor = EffectCheckVisitor { tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), unsafe_context: UnsafeContext::new(SafeContext), }; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 5307b4ec77452..e0521f98416bc 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -512,7 +512,7 @@ const ACC_USE: u32 = 4; struct Liveness<'a, 'tcx: 'a> { ir: &'a mut IrMaps<'a, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, s: Specials, successors: Vec, users: Vec, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 6eaf3448d0284..385dd3d9bf764 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -79,7 +79,7 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct ReachableContext<'a, 'tcx: 'a> { // The type context. tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, // The set of items which must be exported in the linkage sense. reachable_symbols: NodeSet, // A worklist of item IDs. Each item ID in this worklist will be inlined @@ -370,7 +370,7 @@ pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }); let mut reachable_context = ReachableContext { tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), reachable_symbols: NodeSet(), worklist: Vec::new(), any_library: any_library, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3df64ebd1581b..c32e40c6cef22 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -65,7 +65,7 @@ pub struct GlobalArenas<'tcx> { trait_def: TypedArena, adt_def: TypedArena, mir: TypedArena>>, - tables: TypedArena>, + tables: TypedArena>, } impl<'tcx> GlobalArenas<'tcx> { @@ -192,7 +192,7 @@ pub struct CommonTypes<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -pub struct Tables<'tcx> { +pub struct TypeckTables<'tcx> { /// Resolved definitions for `::X` associated paths. pub type_relative_path_defs: NodeMap, @@ -234,9 +234,9 @@ pub struct Tables<'tcx> { pub fru_field_types: NodeMap>> } -impl<'tcx> Tables<'tcx> { - pub fn empty() -> Tables<'tcx> { - Tables { +impl<'tcx> TypeckTables<'tcx> { + pub fn empty() -> TypeckTables<'tcx> { + TypeckTables { type_relative_path_defs: NodeMap(), node_types: FxHashMap(), item_substs: NodeMap(), @@ -402,7 +402,7 @@ pub struct GlobalCtxt<'tcx> { free_region_maps: RefCell>, // FIXME: jroesch make this a refcell - pub tables: RefCell>>, + pub tables: RefCell>>, /// Maps from a trait item to the trait item "descriptor" pub associated_items: RefCell>>, @@ -654,7 +654,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.global_arenas.mir.alloc(RefCell::new(mir)) } - pub fn alloc_tables(self, tables: ty::Tables<'gcx>) -> &'gcx ty::Tables<'gcx> { + pub fn alloc_tables(self, tables: ty::TypeckTables<'gcx>) -> &'gcx ty::TypeckTables<'gcx> { self.global_arenas.tables.alloc(tables) } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 59d22d270b15d..c0cf1d724273e 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -48,4 +48,4 @@ dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc> } dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell> } dep_map_ty! { ClosureKinds: ItemSignature(DefId) -> ty::ClosureKind } dep_map_ty! { ClosureTypes: ItemSignature(DefId) -> ty::ClosureTy<'tcx> } -dep_map_ty! { Tables: Tables(DefId) -> &'tcx ty::Tables<'tcx> } +dep_map_ty! { TypeckTables: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx> } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a88b1e3ece964..697ab6ee491d4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -69,7 +69,7 @@ pub use self::sty::TypeVariants::*; pub use self::contents::TypeContents; pub use self::context::{TyCtxt, GlobalArenas, tls}; -pub use self::context::{Lift, Tables}; +pub use self::context::{Lift, TypeckTables}; pub use self::trait_def::{TraitDef, TraitFlags}; @@ -1917,11 +1917,11 @@ impl BorrowKind { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - pub fn body_tables(self, body: hir::BodyId) -> &'gcx Tables<'gcx> { + pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> { self.item_tables(self.map.body_owner_def_id(body)) } - pub fn item_tables(self, def_id: DefId) -> &'gcx Tables<'gcx> { + pub fn item_tables(self, def_id: DefId) -> &'gcx TypeckTables<'gcx> { self.tables.memoize(def_id, || { if def_id.is_local() { // Closures' tables come from their outermost function, diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 52f332a30c03b..a6452a3f0310a 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -69,7 +69,7 @@ fn create_e0004<'a>(sess: &'a Session, sp: Span, error_message: String) -> Diagn struct MatchVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, param_env: &'a ty::ParameterEnvironment<'tcx> } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index c899d2109f51c..2325c37bc4050 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -52,7 +52,7 @@ macro_rules! math { fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, variant_def: DefId) - -> Option<(&'tcx Expr, Option<&'a ty::Tables<'tcx>>)> { + -> Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>)> { if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) { let enum_node_id = tcx.map.get_parent(variant_node_id); if let Some(ast_map::NodeItem(it)) = tcx.map.find(enum_node_id) { @@ -81,7 +81,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, substs: Option<&'tcx Substs<'tcx>>) -> Option<(&'tcx Expr, - Option<&'a ty::Tables<'tcx>>, + Option<&'a ty::TypeckTables<'tcx>>, Option>)> { if let Some(node_id) = tcx.map.as_local_node_id(def_id) { match tcx.map.find(node_id) { @@ -154,7 +154,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Option<(&'tcx hir::Body, Option<&'a ty::Tables<'tcx>>)> + -> Option<(&'tcx hir::Body, Option<&'a ty::TypeckTables<'tcx>>)> { if let Some(node_id) = tcx.map.as_local_node_id(def_id) { FnLikeNode::from_node(tcx.map.get(node_id)).and_then(|fn_like| { @@ -226,7 +226,7 @@ pub fn note_const_eval_err<'a, 'tcx>( pub struct ConstContext<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: Option<&'a ty::Tables<'tcx>>, + tables: Option<&'a ty::TypeckTables<'tcx>>, fn_args: Option> } @@ -240,7 +240,7 @@ impl<'a, 'tcx> ConstContext<'a, 'tcx> { } } - pub fn with_tables(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::Tables<'tcx>) -> Self { + pub fn with_tables(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &'a ty::TypeckTables<'tcx>) -> Self { ConstContext { tcx: tcx, tables: Some(tables), @@ -920,10 +920,10 @@ fn infer<'a, 'tcx>(i: ConstInt, fn resolve_trait_associated_const<'a, 'tcx: 'a>( tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item_id: DefId, - default_value: Option<(&'tcx Expr, Option<&'a ty::Tables<'tcx>>, Option>)>, + default_value: Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>, Option>)>, trait_id: DefId, rcvr_substs: &'tcx Substs<'tcx> -) -> Option<(&'tcx Expr, Option<&'a ty::Tables<'tcx>>, Option>)> +) -> Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>, Option>)> { let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, rcvr_substs)); debug!("resolve_trait_associated_const: trait_ref={:?}", diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 3235e06b8065f..24c795befa3c8 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -264,13 +264,13 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { pub struct PatternContext<'a, 'gcx: 'tcx, 'tcx: 'a> { pub tcx: TyCtxt<'a, 'gcx, 'tcx>, - pub tables: &'a ty::Tables<'gcx>, + pub tables: &'a ty::TypeckTables<'gcx>, pub errors: Vec, } impl<'a, 'gcx, 'tcx> Pattern<'tcx> { pub fn from_hir(tcx: TyCtxt<'a, 'gcx, 'tcx>, - tables: &'a ty::Tables<'gcx>, + tables: &'a ty::TypeckTables<'gcx>, pat: &hir::Pat) -> Self { let mut pcx = PatternContext::new(tcx, tables); let result = pcx.lower_pattern(pat); @@ -283,7 +283,7 @@ impl<'a, 'gcx, 'tcx> Pattern<'tcx> { } impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, tables: &'a ty::Tables<'gcx>) -> Self { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, tables: &'a ty::TypeckTables<'gcx>) -> Self { PatternContext { tcx: tcx, tables: tables, errors: vec![] } } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 3c8a529bdaee8..c5e0e8fb45f64 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -237,7 +237,7 @@ impl PpSourceMode { arenas, id, |tcx, _, _, _| { - let empty_tables = ty::Tables::empty(); + let empty_tables = ty::TypeckTables::empty(); let annotation = TypedAnnotation { tcx: tcx, tables: Cell::new(&empty_tables) @@ -493,7 +493,7 @@ impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> { struct TypedAnnotation<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - tables: Cell<&'a ty::Tables<'tcx>>, + tables: Cell<&'a ty::TypeckTables<'tcx>>, } impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index b719a759b93ae..4cefc16efe5ab 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -14,11 +14,11 @@ //! we will check that a suitable node for that item either appears //! or does not appear in the dep-graph, as appropriate: //! -//! - `#[rustc_dirty(label="Tables", cfg="rev2")]` if we are +//! - `#[rustc_dirty(label="TypeckTables", cfg="rev2")]` if we are //! in `#[cfg(rev2)]`, then there MUST NOT be a node -//! `DepNode::Tables(X)` where `X` is the def-id of the +//! `DepNode::TypeckTables(X)` where `X` is the def-id of the //! current node. -//! - `#[rustc_clean(label="Tables", cfg="rev2")]` same as above, +//! - `#[rustc_clean(label="TypeckTables", cfg="rev2")]` same as above, //! except that the node MUST exist. //! //! Errors are reported if we are in the suitable configuration but diff --git a/src/librustc_incremental/persist/preds.rs b/src/librustc_incremental/persist/preds.rs index 454edbc4d3444..c75a325941f15 100644 --- a/src/librustc_incremental/persist/preds.rs +++ b/src/librustc_incremental/persist/preds.rs @@ -56,7 +56,7 @@ impl<'q> Predecessors<'q> { // if -Z query-dep-graph is passed, save more extended data // to enable better unit testing - DepNode::Tables(_) | + DepNode::TypeckTables(_) | DepNode::TransCrateItem(_) => tcx.sess.opts.debugging_opts.query_dep_graph, _ => false, diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 3c14d38cc3821..ef7bb80312eb5 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -21,7 +21,7 @@ use rustc_serialize::Encodable; #[derive(RustcEncodable, RustcDecodable)] pub struct Ast<'tcx> { pub body: Lazy, - pub tables: Lazy>, + pub tables: Lazy>, pub nested_bodies: LazySeq, pub rvalue_promotable_to_static: bool, } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 4b553a71b8325..533d804a23651 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -170,7 +170,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { self.tcx } - pub fn tables(&self) -> &'a ty::Tables<'gcx> { + pub fn tables(&self) -> &'a ty::TypeckTables<'gcx> { self.infcx.tables.expect_interned() } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 4bdc113e51698..fa148da2e3996 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -60,7 +60,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> { promotable: bool, mut_rvalue_borrows: NodeSet, param_env: ty::ParameterEnvironment<'tcx>, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, } impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { @@ -462,7 +462,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.visit_all_item_likes_in_krate(DepNode::CheckConst, &mut CheckCrateVisitor { tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), in_fn: false, promotable: false, mut_rvalue_borrows: NodeSet(), diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index ff4c92bb40ef5..445da5a8c3f4e 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -392,7 +392,7 @@ struct PrivacyVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, curitem: DefId, in_foreign: bool, - tables: &'a ty::Tables<'tcx>, + tables: &'a ty::TypeckTables<'tcx>, } impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { @@ -1212,7 +1212,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, curitem: DefId::local(CRATE_DEF_INDEX), in_foreign: false, tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), }; intravisit::walk_crate(&mut visitor, krate); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 0fbe29880b999..ded59cfccf134 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -84,7 +84,7 @@ pub mod recorder { pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, - tables: &'l ty::Tables<'tcx>, + tables: &'l ty::TypeckTables<'tcx>, analysis: &'l ty::CrateAnalysis<'tcx>, span_utils: SpanUtils<'tcx>, } @@ -899,7 +899,7 @@ pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx, 'tcx>, let save_ctxt = SaveContext { tcx: tcx, - tables: &ty::Tables::empty(), + tables: &ty::TypeckTables::empty(), analysis: analysis, span_utils: SpanUtils::new(&tcx.sess), }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ae3578616bc75..7a9df90c1a613 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -483,7 +483,7 @@ pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> CrateCtxt<'a, 'gcx> { pub fn inherited(&'a self, id: ast::NodeId) -> InheritedBuilder<'a, 'gcx, 'tcx> { - let tables = ty::Tables::empty(); + let tables = ty::TypeckTables::empty(); let param_env = ParameterEnvironment::for_item(self.tcx, id); InheritedBuilder { ccx: self, @@ -628,14 +628,14 @@ pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult { pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult { ccx.tcx.sess.track_errors(|| { let mut visit = CheckItemBodiesVisitor { ccx: ccx }; - ccx.tcx.visit_all_item_likes_in_krate(DepNode::Tables, &mut visit); + ccx.tcx.visit_all_item_likes_in_krate(DepNode::TypeckTables, &mut visit); // Process deferred obligations, now that all functions // bodies have been fully inferred. for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() { // Use the same DepNode as for the body of the original function/item. let def_id = ccx.tcx.map.local_def_id(item_id); - let _task = ccx.tcx.dep_graph.in_task(DepNode::Tables(def_id)); + let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckTables(def_id)); let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id); ccx.tcx.infer_ctxt(param_env, Reveal::NotSpecializable).enter(|infcx| { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 02ac7c196b5cb..172c1dfe35eae 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -68,7 +68,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> { fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, - tables: ty::Tables<'gcx>, + tables: ty::TypeckTables<'gcx>, // Mapping from free regions of the function to the // early-bound versions of them, visible from the @@ -81,7 +81,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>) -> WritebackCx<'cx, 'gcx, 'tcx> { let mut wbcx = WritebackCx { fcx: fcx, - tables: ty::Tables::empty(), + tables: ty::TypeckTables::empty(), free_to_bound_regions: DefIdMap() }; diff --git a/src/test/compile-fail/dep-graph-assoc-type-trans.rs b/src/test/compile-fail/dep-graph-assoc-type-trans.rs index ddfd2b6617146..fe76a4d439f37 100644 --- a/src/test/compile-fail/dep-graph-assoc-type-trans.rs +++ b/src/test/compile-fail/dep-graph-assoc-type-trans.rs @@ -35,7 +35,7 @@ mod x { mod y { use Foo; - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn use_char_assoc() { // Careful here: in the representation, ::T gets diff --git a/src/test/compile-fail/dep-graph-caller-callee.rs b/src/test/compile-fail/dep-graph-caller-callee.rs index 8fda05e80856b..9cb87886809a8 100644 --- a/src/test/compile-fail/dep-graph-caller-callee.rs +++ b/src/test/compile-fail/dep-graph-caller-callee.rs @@ -27,7 +27,7 @@ mod y { use x; // These dependencies SHOULD exist: - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn y() { x::x(); @@ -39,7 +39,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path pub fn z() { y::y(); diff --git a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs index 75e20d75704f4..7dd02f57b366e 100644 --- a/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs +++ b/src/test/compile-fail/dep-graph-trait-impl-two-traits-same-method.rs @@ -39,7 +39,7 @@ mod x { mod y { use {Foo, Bar}; - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK pub fn with_char() { char::method('a'); } @@ -48,7 +48,7 @@ mod y { mod z { use y; - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path pub fn z() { y::with_char(); } diff --git a/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs b/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs index 42318d16e3354..6b3525333bcbc 100644 --- a/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs +++ b/src/test/compile-fail/dep-graph-trait-impl-two-traits.rs @@ -38,7 +38,7 @@ mod x { mod y { use {Foo, Bar}; - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path pub fn call_bar() { char::bar('a'); } @@ -47,7 +47,7 @@ mod y { mod z { use y; - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path pub fn z() { y::call_bar(); } diff --git a/src/test/compile-fail/dep-graph-trait-impl.rs b/src/test/compile-fail/dep-graph-trait-impl.rs index c3a7445eb4357..c0f9f0546260a 100644 --- a/src/test/compile-fail/dep-graph-trait-impl.rs +++ b/src/test/compile-fail/dep-graph-trait-impl.rs @@ -34,25 +34,25 @@ mod x { mod y { use Foo; - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn with_char() { char::method('a'); } - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_char() { take_foo::('a'); } - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn with_u32() { u32::method(22); } - #[rustc_then_this_would_need(Tables)] //~ ERROR OK + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR OK pub fn take_foo_with_u32() { take_foo::(22); @@ -66,7 +66,7 @@ mod z { // These are expected to yield errors, because changes to `x` // affect the BODY of `y`, but not its signature. - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path #[rustc_then_this_would_need(TransCrateItem)] //~ ERROR no path pub fn z() { y::with_char(); diff --git a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs index 88c06aa78c299..2520e3a095e1d 100644 --- a/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs +++ b/src/test/compile-fail/dep_graph_crosscontaminate_tables.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that the `Tables` nodes for impl items are independent from +// Test that the `TypeckTables` nodes for impl items are independent from // one another. // compile-flags: -Z query-dep-graph @@ -27,7 +27,7 @@ impl Foo { } // ...should not cause us to recompute the tables for `with`! - #[rustc_then_this_would_need(Tables)] //~ ERROR no path + #[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path fn with(x: u8) -> Foo { Foo { x: x } } diff --git a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs index 817d42c74a672..40067efd57595 100644 --- a/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs +++ b/src/test/incremental/add_private_fn_at_krate_root_cc/struct_point.rs @@ -32,7 +32,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -43,7 +43,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_free_fn { use point::{self, Point}; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; point::distance_squared(&x); @@ -54,7 +54,7 @@ mod fn_calls_free_fn { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -64,7 +64,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -74,7 +74,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/callee_caller_cross_crate/b.rs b/src/test/incremental/callee_caller_cross_crate/b.rs index 094fbdc84f2a8..9e56d34636ff0 100644 --- a/src/test/incremental/callee_caller_cross_crate/b.rs +++ b/src/test/incremental/callee_caller_cross_crate/b.rs @@ -16,12 +16,12 @@ extern crate a; -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn call_function0() { a::function0(77); } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn call_function1() { a::function1(77); } diff --git a/src/test/incremental/change_add_field/struct_point.rs b/src/test/incremental/change_add_field/struct_point.rs index 3e9d4dcb3fabd..e18b30a8c7242 100644 --- a/src/test/incremental/change_add_field/struct_point.rs +++ b/src/test/incremental/change_add_field/struct_point.rs @@ -79,7 +79,7 @@ mod point { mod fn_with_type_in_sig { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn boop(p: Option<&Point>) -> f32 { p.map(|p| p.total()).unwrap_or(0.0) } @@ -95,7 +95,7 @@ mod fn_with_type_in_sig { mod call_fn_with_type_in_sig { use fn_with_type_in_sig; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn bip() -> f32 { fn_with_type_in_sig::boop(None) } @@ -111,7 +111,7 @@ mod call_fn_with_type_in_sig { mod fn_with_type_in_body { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn boop() -> f32 { Point::origin().total() } @@ -124,7 +124,7 @@ mod fn_with_type_in_body { mod call_fn_with_type_in_body { use fn_with_type_in_body; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn bip() -> f32 { fn_with_type_in_body::boop() } @@ -134,7 +134,7 @@ mod call_fn_with_type_in_body { mod fn_make_struct { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn make_origin(p: Point) -> Point { Point { ..p } } @@ -144,7 +144,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -154,7 +154,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_crate_order/main.rs b/src/test/incremental/change_crate_order/main.rs index 69236643e0ba4..5ee75d44f1d15 100644 --- a/src/test/incremental/change_crate_order/main.rs +++ b/src/test/incremental/change_crate_order/main.rs @@ -28,7 +28,7 @@ extern crate a; use a::A; use b::B; -//? #[rustc_clean(label="Tables", cfg="rpass2")] +//? #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn main() { A + B; } diff --git a/src/test/incremental/change_private_fn/struct_point.rs b/src/test/incremental/change_private_fn/struct_point.rs index 4b1b3ede47d97..abfd55ba52cc7 100644 --- a/src/test/incremental/change_private_fn/struct_point.rs +++ b/src/test/incremental/change_private_fn/struct_point.rs @@ -59,7 +59,7 @@ mod point { mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -70,7 +70,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -81,7 +81,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -91,7 +91,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -101,7 +101,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_fn_cc/struct_point.rs b/src/test/incremental/change_private_fn_cc/struct_point.rs index dc73969201b2c..a6d029515d742 100644 --- a/src/test/incremental/change_private_fn_cc/struct_point.rs +++ b/src/test/incremental/change_private_fn_cc/struct_point.rs @@ -31,7 +31,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -42,7 +42,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -53,7 +53,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -63,7 +63,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -73,7 +73,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_impl_method/struct_point.rs b/src/test/incremental/change_private_impl_method/struct_point.rs index c89a7233f8dec..d8c6cafe596a6 100644 --- a/src/test/incremental/change_private_impl_method/struct_point.rs +++ b/src/test/incremental/change_private_impl_method/struct_point.rs @@ -59,7 +59,7 @@ mod point { mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -70,7 +70,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -81,7 +81,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -91,7 +91,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -101,7 +101,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_private_impl_method_cc/struct_point.rs b/src/test/incremental/change_private_impl_method_cc/struct_point.rs index 04d01218546e1..05c076b9f4bc3 100644 --- a/src/test/incremental/change_private_impl_method_cc/struct_point.rs +++ b/src/test/incremental/change_private_impl_method_cc/struct_point.rs @@ -32,7 +32,7 @@ extern crate point; mod fn_calls_methods_in_same_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let x = Point { x: 2.0, y: 2.0 }; x.distance_from_origin(); @@ -43,7 +43,7 @@ mod fn_calls_methods_in_same_impl { mod fn_calls_methods_in_another_impl { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn dirty() { let mut x = Point { x: 2.0, y: 2.0 }; x.translate(3.0, 3.0); @@ -54,7 +54,7 @@ mod fn_calls_methods_in_another_impl { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -64,7 +64,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -74,7 +74,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs index d39cf09eb831e..5b29ee1435f9a 100644 --- a/src/test/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_body/struct_point.rs @@ -50,7 +50,7 @@ mod point { mod fn_calls_changed_method { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_origin(); @@ -61,7 +61,7 @@ mod fn_calls_changed_method { mod fn_calls_another_method { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.x(); @@ -72,7 +72,7 @@ mod fn_calls_another_method { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -82,7 +82,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -92,7 +92,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs index 4b35355056e8f..f8db6c69a76f9 100644 --- a/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/src/test/incremental/change_pub_inherent_method_sig/struct_point.rs @@ -61,7 +61,7 @@ mod point { mod fn_calls_changed_method { use point::Point; - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.distance_from_point(None); @@ -72,7 +72,7 @@ mod fn_calls_changed_method { mod fn_calls_another_method { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn check() { let p = Point { x: 2.0, y: 2.0 }; p.x(); @@ -83,7 +83,7 @@ mod fn_calls_another_method { mod fn_make_struct { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn make_origin() -> Point { Point { x: 2.0, y: 2.0 } } @@ -93,7 +93,7 @@ mod fn_make_struct { mod fn_read_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn get_x(p: Point) -> f32 { p.x } @@ -103,7 +103,7 @@ mod fn_read_field { mod fn_write_field { use point::Point; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn inc_x(p: &mut Point) { p.x += 1.0; } diff --git a/src/test/incremental/dirty_clean.rs b/src/test/incremental/dirty_clean.rs index 06c962b4d7b92..9f20128de4f55 100644 --- a/src/test/incremental/dirty_clean.rs +++ b/src/test/incremental/dirty_clean.rs @@ -35,20 +35,20 @@ mod x { mod y { use x; - #[rustc_clean(label="Tables", cfg="cfail2")] + #[rustc_clean(label="TypeckTables", cfg="cfail2")] #[rustc_clean(label="TransCrateItem", cfg="cfail2")] pub fn y() { - //[cfail2]~^ ERROR `Tables("y::y")` not found in dep graph, but should be clean + //[cfail2]~^ ERROR `TypeckTables("y::y")` not found in dep graph, but should be clean //[cfail2]~| ERROR `TransCrateItem("y::y")` not found in dep graph, but should be clean x::x(); } } mod z { - #[rustc_dirty(label="Tables", cfg="cfail2")] + #[rustc_dirty(label="TypeckTables", cfg="cfail2")] #[rustc_dirty(label="TransCrateItem", cfg="cfail2")] pub fn z() { - //[cfail2]~^ ERROR `Tables("z::z")` found in dep graph, but should be dirty + //[cfail2]~^ ERROR `TypeckTables("z::z")` found in dep graph, but should be dirty //[cfail2]~| ERROR `TransCrateItem("z::z")` found in dep graph, but should be dirty } } diff --git a/src/test/incremental/hello_world.rs b/src/test/incremental/hello_world.rs index e87fea2028025..2d65e0aa657a6 100644 --- a/src/test/incremental/hello_world.rs +++ b/src/test/incremental/hello_world.rs @@ -31,7 +31,7 @@ mod x { mod y { use x; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn yyyy() { x::xxxx(); } @@ -40,7 +40,7 @@ mod y { mod z { use y; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn z() { y::yyyy(); } diff --git a/src/test/incremental/rlib_cross_crate/b.rs b/src/test/incremental/rlib_cross_crate/b.rs index ecf19d7a55373..9849e93d3ff9e 100644 --- a/src/test/incremental/rlib_cross_crate/b.rs +++ b/src/test/incremental/rlib_cross_crate/b.rs @@ -22,15 +22,15 @@ extern crate a; -#[rustc_dirty(label="Tables", cfg="rpass2")] -#[rustc_clean(label="Tables", cfg="rpass3")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22; x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] -#[rustc_clean(label="Tables", cfg="rpass3")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass3")] pub fn use_Y() { let x: a::Y = 'c'; } diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs index 08dc4d33229c2..669d001cc63d6 100644 --- a/src/test/incremental/string_constant.rs +++ b/src/test/incremental/string_constant.rs @@ -27,7 +27,7 @@ mod x { } #[cfg(rpass2)] - #[rustc_dirty(label="Tables", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] #[rustc_dirty(label="TransCrateItem", cfg="rpass2")] pub fn x() { println!("{}", "2"); @@ -37,7 +37,7 @@ mod x { mod y { use x; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] #[rustc_clean(label="TransCrateItem", cfg="rpass2")] pub fn y() { x::x(); @@ -47,7 +47,7 @@ mod y { mod z { use y; - #[rustc_clean(label="Tables", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] #[rustc_clean(label="TransCrateItem", cfg="rpass2")] pub fn z() { y::y(); diff --git a/src/test/incremental/struct_add_field.rs b/src/test/incremental/struct_add_field.rs index 159f594e8c043..42681eb2be45d 100644 --- a/src/test/incremental/struct_add_field.rs +++ b/src/test/incremental/struct_add_field.rs @@ -31,17 +31,17 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_name.rs b/src/test/incremental/struct_change_field_name.rs index ca011f1fdd083..63df407d5c02a 100644 --- a/src/test/incremental/struct_change_field_name.rs +++ b/src/test/incremental/struct_change_field_name.rs @@ -34,7 +34,7 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="Tables", cfg="cfail2")] +#[rustc_dirty(label="TypeckTables", cfg="cfail2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; //[cfail2]~^ ERROR struct `X` has no field named `x` @@ -42,13 +42,13 @@ pub fn use_X() -> u32 { //[cfail2]~^ ERROR no field `x` on type `X` } -#[rustc_dirty(label="Tables", cfg="cfail2")] +#[rustc_dirty(label="TypeckTables", cfg="cfail2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 //[cfail2]~^ ERROR no field `x` on type `X` } -#[rustc_clean(label="Tables", cfg="cfail2")] +#[rustc_clean(label="TypeckTables", cfg="cfail2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type.rs b/src/test/incremental/struct_change_field_type.rs index 7237496af2cac..67b3416397948 100644 --- a/src/test/incremental/struct_change_field_type.rs +++ b/src/test/incremental/struct_change_field_type.rs @@ -34,19 +34,19 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_EmbedX(x: EmbedX) -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_field_type_cross_crate/b.rs b/src/test/incremental/struct_change_field_type_cross_crate/b.rs index b490ea41238fd..9660f47da35c1 100644 --- a/src/test/incremental/struct_change_field_type_cross_crate/b.rs +++ b/src/test/incremental/struct_change_field_type_cross_crate/b.rs @@ -18,18 +18,18 @@ extern crate a; use a::*; -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_change_nothing.rs b/src/test/incremental/struct_change_nothing.rs index 214cfacc6e7b0..e2d4045874431 100644 --- a/src/test/incremental/struct_change_nothing.rs +++ b/src/test/incremental/struct_change_nothing.rs @@ -34,19 +34,19 @@ pub struct Y { pub y: char } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_X() -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_EmbedX(x: EmbedX) -> u32 { let x: X = X { x: 22 }; x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/struct_remove_field.rs b/src/test/incremental/struct_remove_field.rs index fac2a7f634ce5..fba965ff5a005 100644 --- a/src/test/incremental/struct_remove_field.rs +++ b/src/test/incremental/struct_remove_field.rs @@ -35,17 +35,17 @@ pub struct Y { pub y: char } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_X(x: X) -> u32 { x.x as u32 } -#[rustc_dirty(label="Tables", cfg="rpass2")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] pub fn use_EmbedX(embed: EmbedX) -> u32 { embed.x.x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] pub fn use_Y() { let x: Y = Y { y: 'c' }; } diff --git a/src/test/incremental/type_alias_cross_crate/b.rs b/src/test/incremental/type_alias_cross_crate/b.rs index fce759cc0b4b0..ee35a4d9b9c6e 100644 --- a/src/test/incremental/type_alias_cross_crate/b.rs +++ b/src/test/incremental/type_alias_cross_crate/b.rs @@ -16,15 +16,15 @@ extern crate a; -#[rustc_dirty(label="Tables", cfg="rpass2")] -#[rustc_clean(label="Tables", cfg="rpass3")] +#[rustc_dirty(label="TypeckTables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass3")] pub fn use_X() -> u32 { let x: a::X = 22; x as u32 } -#[rustc_clean(label="Tables", cfg="rpass2")] -#[rustc_clean(label="Tables", cfg="rpass3")] +#[rustc_clean(label="TypeckTables", cfg="rpass2")] +#[rustc_clean(label="TypeckTables", cfg="rpass3")] pub fn use_Y() { let x: a::Y = 'c'; } From 671b1c1d895c54903a10555196b789ebd5ff2c90 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 25 Jan 2017 15:37:20 -0800 Subject: [PATCH 26/86] std: Stabilize APIs for the 1.16.0 release This commit applies the stabilization/deprecations of the 1.16.0 release, as tracked by the rust-lang/rust issue tracker and the final-comment-period tag. The following APIs were stabilized: * `VecDeque::truncate` * `VecDeque::resize` * `String::insert_str` * `Duration::checked_{add,sub,div,mul}` * `str::replacen` * `SocketAddr::is_ipv{4,6}` * `IpAddr::is_ipv{4,6}` * `str::repeat` * `Vec::dedup_by` * `Vec::dedup_by_key` * `Result::unwrap_or_default` * `<*const T>::wrapping_offset` * `<*mut T>::wrapping_offset` * `CommandExt::creation_flags` (on Windows) * `File::set_permissions` * `String::split_off` The following APIs were deprecated * `EnumSet` - replaced with other ecosystem abstractions, long since unstable Closes #27788 Closes #35553 Closes #35774 Closes #36436 Closes #36949 Closes #37079 Closes #37087 Closes #37516 Closes #37827 Closes #37916 Closes #37966 Closes #38080 --- src/libcollections/enum_set.rs | 2 + src/libcollections/lib.rs | 1 + src/libcollections/str.rs | 10 +- src/libcollections/string.rs | 9 +- src/libcollections/vec.rs | 7 +- src/libcollections/vec_deque.rs | 12 +- src/libcollectionstest/enum_set.rs | 268 -------------------------- src/libcollectionstest/lib.rs | 6 - src/libcore/ptr.rs | 6 +- src/libcore/result.rs | 4 +- src/libcoretest/lib.rs | 1 - src/libserialize/collection_impls.rs | 29 --- src/libserialize/lib.rs | 1 - src/libstd/fs.rs | 3 +- src/libstd/net/addr.rs | 8 +- src/libstd/net/ip.rs | 8 +- src/libstd/sys/windows/ext/process.rs | 6 +- src/libstd/time/duration.rs | 16 +- 18 files changed, 26 insertions(+), 371 deletions(-) delete mode 100644 src/libcollectionstest/enum_set.rs diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 87bc5e59ef78c..78b6107977781 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -17,6 +17,8 @@ reason = "matches collection reform specification, \ waiting for dust to settle", issue = "37966")] +#![rustc_deprecated(since = "1.16.0", reason = "long since replaced")] +#![allow(deprecated)] use core::marker; use core::fmt; diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 561d8860dc880..39de87c08407f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -79,6 +79,7 @@ pub use btree_set::BTreeSet; #[doc(no_inline)] pub use linked_list::LinkedList; #[doc(no_inline)] +#[allow(deprecated)] pub use enum_set::EnumSet; #[doc(no_inline)] pub use vec_deque::VecDeque; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 70cedce9a905e..458d5114829f4 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1607,7 +1607,6 @@ impl str { /// Basic usage: /// /// ``` - /// # #![feature(str_replacen)] /// let s = "foo foo 123 foo"; /// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2)); /// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3)); @@ -1617,13 +1616,10 @@ impl str { /// When the pattern doesn't match: /// /// ``` - /// # #![feature(str_replacen)] /// let s = "this is old"; /// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10)); /// ``` - #[unstable(feature = "str_replacen", - issue = "36436", - reason = "only need to replace first N matches")] + #[stable(feature = "str_replacen", since = "1.16.0")] pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String { // Hope to reduce the times of re-allocation let mut result = String::with_capacity(32); @@ -1795,11 +1791,9 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(repeat_str)] - /// /// assert_eq!("abc".repeat(4), String::from("abcabcabcabc")); /// ``` - #[unstable(feature = "repeat_str", issue = "37079")] + #[stable(feature = "repeat_str", since = "1.16.0")] pub fn repeat(&self, n: usize) -> String { let mut s = String::with_capacity(self.len() * n); s.extend((0..n).map(|_| self)); diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 5210c25b4e5c8..b184a8603e6bd 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1166,8 +1166,6 @@ impl String { /// Basic usage: /// /// ``` - /// #![feature(insert_str)] - /// /// let mut s = String::from("bar"); /// /// s.insert_str(0, "foo"); @@ -1175,9 +1173,7 @@ impl String { /// assert_eq!("foobar", s); /// ``` #[inline] - #[unstable(feature = "insert_str", - reason = "recent addition", - issue = "35553")] + #[stable(feature = "insert_str", since = "1.16.0")] pub fn insert_str(&mut self, idx: usize, string: &str) { assert!(self.is_char_boundary(idx)); @@ -1270,7 +1266,6 @@ impl String { /// # Examples /// /// ``` - /// # #![feature(string_split_off)] /// # fn main() { /// let mut hello = String::from("Hello, World!"); /// let world = hello.split_off(7); @@ -1279,7 +1274,7 @@ impl String { /// # } /// ``` #[inline] - #[unstable(feature = "string_split_off", issue = "38080")] + #[stable(feature = "string_split_off", since = "1.16.0")] pub fn split_off(&mut self, mid: usize) -> String { assert!(self.is_char_boundary(mid)); let other = self.vec.split_off(mid); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index c5b904c8a2f0e..1f8fd32da9ab8 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -820,15 +820,13 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(dedup_by)] - /// /// let mut vec = vec![10, 20, 21, 30, 20]; /// /// vec.dedup_by_key(|i| *i / 10); /// /// assert_eq!(vec, [10, 20, 30, 20]); /// ``` - #[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")] + #[stable(feature = "dedup_by", since = "1.16.0")] #[inline] pub fn dedup_by_key(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq { self.dedup_by(|a, b| key(a) == key(b)) @@ -841,7 +839,6 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(dedup_by)] /// use std::ascii::AsciiExt; /// /// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"]; @@ -850,7 +847,7 @@ impl Vec { /// /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]); /// ``` - #[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")] + #[stable(feature = "dedup_by", since = "1.16.0")] pub fn dedup_by(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool { unsafe { // Although we have a mutable reference to `self`, we cannot make diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index fea2d111f472e..5b1bc3a3ae4f1 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -643,8 +643,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(deque_extras)] - /// /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); @@ -655,9 +653,7 @@ impl VecDeque { /// assert_eq!(buf.len(), 1); /// assert_eq!(Some(&5), buf.get(0)); /// ``` - #[unstable(feature = "deque_extras", - reason = "matches collection reform specification; waiting on panic semantics", - issue = "27788")] + #[stable(feature = "deque_extras", since = "1.16.0")] pub fn truncate(&mut self, len: usize) { for _ in len..self.len() { self.pop_back(); @@ -1779,8 +1775,6 @@ impl VecDeque { /// # Examples /// /// ``` - /// #![feature(deque_extras)] - /// /// use std::collections::VecDeque; /// /// let mut buf = VecDeque::new(); @@ -1793,9 +1787,7 @@ impl VecDeque { /// assert_eq!(a, b); /// } /// ``` - #[unstable(feature = "deque_extras", - reason = "matches collection reform specification; waiting on panic semantics", - issue = "27788")] + #[stable(feature = "deque_extras", since = "1.16.0")] pub fn resize(&mut self, new_len: usize, value: T) { let len = self.len(); diff --git a/src/libcollectionstest/enum_set.rs b/src/libcollectionstest/enum_set.rs deleted file mode 100644 index 972361326d7bb..0000000000000 --- a/src/libcollectionstest/enum_set.rs +++ /dev/null @@ -1,268 +0,0 @@ -// 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. - -use std::mem; - -use collections::enum_set::{CLike, EnumSet}; - -use self::Foo::*; - -#[derive(Copy, Clone, PartialEq, Debug)] -#[repr(usize)] -enum Foo { - A, - B, - C, -} - -impl CLike for Foo { - fn to_usize(&self) -> usize { - *self as usize - } - - fn from_usize(v: usize) -> Foo { - unsafe { mem::transmute(v) } - } -} - -#[test] -fn test_new() { - let e: EnumSet = EnumSet::new(); - assert!(e.is_empty()); -} - -#[test] -fn test_show() { - let mut e = EnumSet::new(); - assert!(format!("{:?}", e) == "{}"); - e.insert(A); - assert!(format!("{:?}", e) == "{A}"); - e.insert(C); - assert!(format!("{:?}", e) == "{A, C}"); -} - -#[test] -fn test_len() { - let mut e = EnumSet::new(); - assert_eq!(e.len(), 0); - e.insert(A); - e.insert(B); - e.insert(C); - assert_eq!(e.len(), 3); - e.remove(&A); - assert_eq!(e.len(), 2); - e.clear(); - assert_eq!(e.len(), 0); -} - -/////////////////////////////////////////////////////////////////////////// -// intersect - -#[test] -fn test_two_empties_do_not_intersect() { - let e1: EnumSet = EnumSet::new(); - let e2: EnumSet = EnumSet::new(); - assert!(e1.is_disjoint(&e2)); -} - -#[test] -fn test_empty_does_not_intersect_with_full() { - let e1: EnumSet = EnumSet::new(); - - let mut e2: EnumSet = EnumSet::new(); - e2.insert(A); - e2.insert(B); - e2.insert(C); - - assert!(e1.is_disjoint(&e2)); -} - -#[test] -fn test_disjoint_intersects() { - let mut e1: EnumSet = EnumSet::new(); - e1.insert(A); - - let mut e2: EnumSet = EnumSet::new(); - e2.insert(B); - - assert!(e1.is_disjoint(&e2)); -} - -#[test] -fn test_overlapping_intersects() { - let mut e1: EnumSet = EnumSet::new(); - e1.insert(A); - - let mut e2: EnumSet = EnumSet::new(); - e2.insert(A); - e2.insert(B); - - assert!(!e1.is_disjoint(&e2)); -} - -/////////////////////////////////////////////////////////////////////////// -// contains and contains_elem - -#[test] -fn test_superset() { - let mut e1: EnumSet = EnumSet::new(); - e1.insert(A); - - let mut e2: EnumSet = EnumSet::new(); - e2.insert(A); - e2.insert(B); - - let mut e3: EnumSet = EnumSet::new(); - e3.insert(C); - - assert!(e1.is_subset(&e2)); - assert!(e2.is_superset(&e1)); - assert!(!e3.is_superset(&e2)); - assert!(!e2.is_superset(&e3)) -} - -#[test] -fn test_contains() { - let mut e1: EnumSet = EnumSet::new(); - e1.insert(A); - assert!(e1.contains(&A)); - assert!(!e1.contains(&B)); - assert!(!e1.contains(&C)); - - e1.insert(A); - e1.insert(B); - assert!(e1.contains(&A)); - assert!(e1.contains(&B)); - assert!(!e1.contains(&C)); -} - -/////////////////////////////////////////////////////////////////////////// -// iter - -#[test] -fn test_iterator() { - let mut e1: EnumSet = EnumSet::new(); - - let elems: Vec = e1.iter().collect(); - assert!(elems.is_empty()); - - e1.insert(A); - let elems: Vec<_> = e1.iter().collect(); - assert_eq!(elems, [A]); - - e1.insert(C); - let elems: Vec<_> = e1.iter().collect(); - assert_eq!(elems, [A, C]); - - e1.insert(C); - let elems: Vec<_> = e1.iter().collect(); - assert_eq!(elems, [A, C]); - - e1.insert(B); - let elems: Vec<_> = e1.iter().collect(); - assert_eq!(elems, [A, B, C]); -} - -/////////////////////////////////////////////////////////////////////////// -// operators - -#[test] -fn test_operators() { - let mut e1: EnumSet = EnumSet::new(); - e1.insert(A); - e1.insert(C); - - let mut e2: EnumSet = EnumSet::new(); - e2.insert(B); - e2.insert(C); - - let e_union = e1 | e2; - let elems: Vec<_> = e_union.iter().collect(); - assert_eq!(elems, [A, B, C]); - - let e_intersection = e1 & e2; - let elems: Vec<_> = e_intersection.iter().collect(); - assert_eq!(elems, [C]); - - // Another way to express intersection - let e_intersection = e1 - (e1 - e2); - let elems: Vec<_> = e_intersection.iter().collect(); - assert_eq!(elems, [C]); - - let e_subtract = e1 - e2; - let elems: Vec<_> = e_subtract.iter().collect(); - assert_eq!(elems, [A]); - - // Bitwise XOR of two sets, aka symmetric difference - let e_symmetric_diff = e1 ^ e2; - let elems: Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(elems, [A, B]); - - // Another way to express symmetric difference - let e_symmetric_diff = (e1 - e2) | (e2 - e1); - let elems: Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(elems, [A, B]); - - // Yet another way to express symmetric difference - let e_symmetric_diff = (e1 | e2) - (e1 & e2); - let elems: Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(elems, [A, B]); -} - -#[test] -#[should_panic] -fn test_overflow() { - #[allow(dead_code)] - #[derive(Copy, Clone)] - #[repr(usize)] - enum Bar { - V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, - V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, - V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, - V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, - V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, - V50, V51, V52, V53, V54, V55, V56, V57, V58, V59, - V60, V61, V62, V63, V64, V65, V66, V67, V68, V69, - } - - impl CLike for Bar { - fn to_usize(&self) -> usize { - *self as usize - } - - fn from_usize(v: usize) -> Bar { - unsafe { mem::transmute(v) } - } - } - let mut set = EnumSet::new(); - set.insert(Bar::V64); -} - -#[test] -fn test_extend_ref() { - let mut a = EnumSet::new(); - a.insert(A); - - a.extend(&[A, C]); - - assert_eq!(a.len(), 2); - assert!(a.contains(&A)); - assert!(a.contains(&C)); - - let mut b = EnumSet::new(); - b.insert(B); - - a.extend(&b); - - assert_eq!(a.len(), 3); - assert!(a.contains(&A)); - assert!(a.contains(&B)); - assert!(a.contains(&C)); -} diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index bec3965a9589b..b146672893f8d 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -18,17 +18,12 @@ #![feature(collections)] #![feature(collections_bound)] #![feature(const_fn)] -#![feature(dedup_by)] -#![feature(enumset)] #![feature(exact_size_is_empty)] #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(rand)] -#![feature(repeat_str)] #![feature(step_by)] #![feature(str_escape)] -#![feature(str_replacen)] -#![feature(string_split_off)] #![feature(test)] #![feature(unboxed_closures)] #![feature(unicode)] @@ -47,7 +42,6 @@ mod bench; mod binary_heap; mod btree; mod cow_str; -mod enum_set; mod fmt; mod linked_list; mod slice; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index bf5a59c45e4d3..02851c224e2e3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -448,7 +448,6 @@ impl *const T { /// Basic usage: /// /// ``` - /// #![feature(ptr_wrapping_offset)] /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; /// let mut ptr: *const u8 = data.as_ptr(); @@ -463,7 +462,7 @@ impl *const T { /// ptr = ptr.wrapping_offset(step); /// } /// ``` - #[unstable(feature = "ptr_wrapping_offset", issue = "37570")] + #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[inline] pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized { unsafe { @@ -572,7 +571,6 @@ impl *mut T { /// Basic usage: /// /// ``` - /// #![feature(ptr_wrapping_offset)] /// // Iterate using a raw pointer in increments of two elements /// let mut data = [1u8, 2, 3, 4, 5]; /// let mut ptr: *mut u8 = data.as_mut_ptr(); @@ -587,7 +585,7 @@ impl *mut T { /// } /// assert_eq!(&data, &[0, 2, 0, 4, 0]); /// ``` - #[unstable(feature = "ptr_wrapping_offset", issue = "37570")] + #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[inline] pub fn wrapping_offset(self, count: isize) -> *mut T where T: Sized { unsafe { diff --git a/src/libcore/result.rs b/src/libcore/result.rs index f02df88bb2efa..0a2e363965347 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -840,8 +840,6 @@ impl Result { /// `Err` on error. /// /// ``` - /// #![feature(result_unwrap_or_default)] - /// /// let good_year_from_input = "1909"; /// let bad_year_from_input = "190blarg"; /// let good_year = good_year_from_input.parse().unwrap_or_default(); @@ -854,7 +852,7 @@ impl Result { /// [`FromStr`]: ../../std/str/trait.FromStr.html /// ``` #[inline] - #[unstable(feature = "result_unwrap_or_default", issue = "37516")] + #[stable(feature = "result_unwrap_or_default", since = "1.16.0")] pub fn unwrap_or_default(self) -> T { match self { Ok(x) => x, diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index ee47b510ee074..8e5893b5ecbed 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -32,7 +32,6 @@ #![feature(unicode)] #![feature(unique)] #![feature(ordering_chaining)] -#![feature(result_unwrap_or_default)] #![feature(ptr_unaligned)] extern crate core; diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index ba9bf2b86a60f..05cfb6352fbb8 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -11,11 +11,9 @@ //! Implementations of serialization for structures found in libcollections use std::hash::{Hash, BuildHasher}; -use std::mem; use {Decodable, Encodable, Decoder, Encoder}; use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet}; -use collections::enum_set::{EnumSet, CLike}; impl< T: Encodable @@ -128,33 +126,6 @@ impl< } } -impl< - T: Encodable + CLike -> Encodable for EnumSet { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - let mut bits = 0; - for item in self { - bits |= 1 << item.to_usize(); - } - s.emit_usize(bits) - } -} - -impl< - T: Decodable + CLike -> Decodable for EnumSet { - fn decode(d: &mut D) -> Result, D::Error> { - let bits = d.read_usize()?; - let mut set = EnumSet::new(); - for bit in 0..(mem::size_of::()*8) { - if bits & (1 << bit) != 0 { - set.insert(CLike::from_usize(bit)); - } - } - Ok(set) - } -} - impl Encodable for HashMap where K: Encodable + Hash + Eq, V: Encodable, diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 2cfc3924c036e..1cb83fa33da06 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -30,7 +30,6 @@ Core encoding and decoding interfaces. #![feature(box_syntax)] #![feature(collections)] #![feature(core_intrinsics)] -#![feature(enumset)] #![feature(specialization)] #![feature(staged_api)] #![cfg_attr(test, feature(test))] diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f1dc36ae79335..249627c430cb7 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -404,7 +404,6 @@ impl File { /// # Examples /// /// ``` - /// #![feature(set_permissions_atomic)] /// # fn foo() -> std::io::Result<()> { /// use std::fs::File; /// @@ -415,7 +414,7 @@ impl File { /// # Ok(()) /// # } /// ``` - #[unstable(feature = "set_permissions_atomic", issue="37916")] + #[stable(feature = "set_permissions_atomic", since = "1.16.0")] pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> { self.inner.set_permissions(perm.0) } diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index d186a53311dab..751878c687c01 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -148,8 +148,6 @@ impl SocketAddr { /// # Examples /// /// ``` - /// #![feature(sockaddr_checker)] - /// /// use std::net::{IpAddr, Ipv4Addr, SocketAddr}; /// /// fn main() { @@ -158,7 +156,7 @@ impl SocketAddr { /// assert_eq!(socket.is_ipv6(), false); /// } /// ``` - #[unstable(feature = "sockaddr_checker", issue = "36949")] + #[stable(feature = "sockaddr_checker", since = "1.16.0")] pub fn is_ipv4(&self) -> bool { match *self { SocketAddr::V4(_) => true, @@ -172,8 +170,6 @@ impl SocketAddr { /// # Examples /// /// ``` - /// #![feature(sockaddr_checker)] - /// /// use std::net::{IpAddr, Ipv6Addr, SocketAddr}; /// /// fn main() { @@ -183,7 +179,7 @@ impl SocketAddr { /// assert_eq!(socket.is_ipv6(), true); /// } /// ``` - #[unstable(feature = "sockaddr_checker", issue = "36949")] + #[stable(feature = "sockaddr_checker", since = "1.16.0")] pub fn is_ipv6(&self) -> bool { match *self { SocketAddr::V4(_) => false, diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 05e3d38b17eb1..7803cf728f2e9 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -196,8 +196,6 @@ impl IpAddr { /// # Examples /// /// ``` - /// #![feature(ipaddr_checker)] - /// /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// /// fn main() { @@ -206,7 +204,7 @@ impl IpAddr { /// false); /// } /// ``` - #[unstable(feature = "ipaddr_checker", issue = "36949")] + #[stable(feature = "ipaddr_checker", since = "1.16.0")] pub fn is_ipv4(&self) -> bool { match *self { IpAddr::V4(_) => true, @@ -219,8 +217,6 @@ impl IpAddr { /// # Examples /// /// ``` - /// #![feature(ipaddr_checker)] - /// /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// /// fn main() { @@ -229,7 +225,7 @@ impl IpAddr { /// true); /// } /// ``` - #[unstable(feature = "ipaddr_checker", issue = "36949")] + #[stable(feature = "ipaddr_checker", since = "1.16.0")] pub fn is_ipv6(&self) -> bool { match *self { IpAddr::V4(_) => false, diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs index 0a3221aeae6fa..1419a4af42738 100644 --- a/src/libstd/sys/windows/ext/process.rs +++ b/src/libstd/sys/windows/ext/process.rs @@ -99,17 +99,17 @@ impl ExitStatusExt for process::ExitStatus { } /// Windows-specific extensions to the `std::process::Command` builder -#[unstable(feature = "windows_process_extensions", issue = "37827")] +#[stable(feature = "windows_process_extensions", since = "1.16.0")] pub trait CommandExt { /// Sets the [process creation flags][1] to be passed to `CreateProcess`. /// /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`. /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx - #[unstable(feature = "windows_process_extensions", issue = "37827")] + #[stable(feature = "windows_process_extensions", since = "1.16.0")] fn creation_flags(&mut self, flags: u32) -> &mut process::Command; } -#[unstable(feature = "windows_process_extensions", issue = "37827")] +#[stable(feature = "windows_process_extensions", since = "1.16.0")] impl CommandExt for process::Command { fn creation_flags(&mut self, flags: u32) -> &mut process::Command { self.as_inner_mut().creation_flags(flags); diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 2c4e2bbff93a1..af7eaeb3106b2 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -154,14 +154,12 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_checked_ops)] - /// /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1))); /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(std::u64::MAX, 0)), None); /// ``` - #[unstable(feature = "duration_checked_ops", issue = "35774")] + #[stable(feature = "duration_checked_ops", since = "1.16.0")] #[inline] pub fn checked_add(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_add(rhs.secs) { @@ -194,14 +192,12 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_checked_ops)] - /// /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 1).checked_sub(Duration::new(0, 0)), Some(Duration::new(0, 1))); /// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None); /// ``` - #[unstable(feature = "duration_checked_ops", issue = "35774")] + #[stable(feature = "duration_checked_ops", since = "1.16.0")] #[inline] pub fn checked_sub(self, rhs: Duration) -> Option { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { @@ -232,14 +228,12 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_checked_ops)] - /// /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2))); /// assert_eq!(Duration::new(std::u64::MAX - 1, 0).checked_mul(2), None); /// ``` - #[unstable(feature = "duration_checked_ops", issue = "35774")] + #[stable(feature = "duration_checked_ops", since = "1.16.0")] #[inline] pub fn checked_mul(self, rhs: u32) -> Option { // Multiply nanoseconds as u64, because it cannot overflow that way. @@ -269,15 +263,13 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_checked_ops)] - /// /// use std::time::Duration; /// /// assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0))); /// assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000))); /// assert_eq!(Duration::new(2, 0).checked_div(0), None); /// ``` - #[unstable(feature = "duration_checked_ops", issue = "35774")] + #[stable(feature = "duration_checked_ops", since = "1.16.0")] #[inline] pub fn checked_div(self, rhs: u32) -> Option { if rhs != 0 { From ff11f987c669a62058267c5b71f804b03fe9954d Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 26 Jan 2017 10:37:20 +0100 Subject: [PATCH 27/86] drop_in_place is stable now, don't #![feature] it in the nomicon and a test It was stable since Rust 1.8. --- src/doc/nomicon/destructors.md | 6 +++--- src/test/run-pass/extern_fat_drop.rs | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/doc/nomicon/destructors.md b/src/doc/nomicon/destructors.md index c6fa5b079db02..be4730cf8bce6 100644 --- a/src/doc/nomicon/destructors.md +++ b/src/doc/nomicon/destructors.md @@ -26,7 +26,7 @@ this is totally fine. For instance, a custom implementation of `Box` might write `Drop` like this: ```rust -#![feature(alloc, heap_api, drop_in_place, unique)] +#![feature(alloc, heap_api, unique)] extern crate alloc; @@ -57,7 +57,7 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible. However this wouldn't work: ```rust -#![feature(alloc, heap_api, drop_in_place, unique)] +#![feature(alloc, heap_api, unique)] extern crate alloc; @@ -135,7 +135,7 @@ The classic safe solution to overriding recursive drop and allowing moving out of Self during `drop` is to use an Option: ```rust -#![feature(alloc, heap_api, drop_in_place, unique)] +#![feature(alloc, heap_api, unique)] extern crate alloc; diff --git a/src/test/run-pass/extern_fat_drop.rs b/src/test/run-pass/extern_fat_drop.rs index deb7e6bd53986..8ce1f744dee17 100644 --- a/src/test/run-pass/extern_fat_drop.rs +++ b/src/test/run-pass/extern_fat_drop.rs @@ -10,8 +10,6 @@ // aux-build:fat_drop.rs -#![feature(drop_in_place)] - extern crate fat_drop; fn main() { From f02c9e37415de1b838ec08f6cbc54524d5c755f7 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Thu, 26 Jan 2017 11:09:45 +0100 Subject: [PATCH 28/86] Rewrite the first sentence in slice::sort For every method, the first sentence should consisely explain what it does, not how. This sentence usually starts with a verb. It's really weird for `sort` to be explained in terms of another function, namely `sort_by`. There's no need for that because it's obvious how `sort` sorts elements: there is `T: Ord`. If `sort_by_key` does not have to explicitly state how it's implemented, then `sort` doesn't either. --- src/libcollections/slice.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index fc49c9f56438c..11f513ed798e0 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -509,7 +509,7 @@ impl [T] { core_slice::SliceExt::swap(self, a, b) } - /// Reverse the order of elements in a slice, in place. + /// Reverses the order of elements in a slice, in place. /// /// # Example /// @@ -1062,7 +1062,7 @@ impl [T] { core_slice::SliceExt::binary_search_by_key(self, b, f) } - /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. + /// Sorts the slice. /// /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// From e7c3fb90eeda06c6ac2bed523ce8fa358d48505b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 4 Jan 2017 12:56:33 +0100 Subject: [PATCH 29/86] Add a distinct error code and description for "main function has wrong type" --- src/librustc/diagnostics.rs | 24 +++++++++++++++++++ src/librustc/infer/error_reporting.rs | 7 ++++-- .../compile-fail/{E0308-3.rs => E0579.rs} | 2 +- src/test/compile-fail/bad-main.rs | 2 +- src/test/compile-fail/extern-main-fn.rs | 2 +- src/test/compile-fail/main-wrong-type-2.rs | 2 +- src/test/compile-fail/main-wrong-type.rs | 2 +- 7 files changed, 34 insertions(+), 7 deletions(-) rename src/test/compile-fail/{E0308-3.rs => E0579.rs} (92%) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 0d180e6ad76fd..6d94e1d725938 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1694,6 +1694,30 @@ To understand better how closures work in Rust, read: https://doc.rust-lang.org/book/closures.html "##, +E0579: r##" +The `main` function was incorrectly declared. + +Erroneous code example: + +```compile_fail,E0579 +fn main() -> i32 { // error: main function has wrong type + 0 +} +``` + +The `main` function prototype should never take arguments or return type. +Example: + +``` +fn main() { + // your code +} +``` + +If you want to get command-line arguments, use `std::env::args`. To exit with a +specified exit code, use `std::process::exit`. +"##, + } diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 095d2a78a94cd..2bed8148b9f8c 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -629,10 +629,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let mut diag = match trace.cause.code { ObligationCauseCode::IfExpressionWithNoElse => { struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str) - }, + } + ObligationCauseCode::MainFunctionType => { + struct_span_err!(self.tcx.sess, span, E0579, "{}", failure_str) + } _ => { struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str) - }, + } }; self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr); diag diff --git a/src/test/compile-fail/E0308-3.rs b/src/test/compile-fail/E0579.rs similarity index 92% rename from src/test/compile-fail/E0308-3.rs rename to src/test/compile-fail/E0579.rs index d7dca056f3fa6..beb6c792fa18a 100644 --- a/src/test/compile-fail/E0308-3.rs +++ b/src/test/compile-fail/E0579.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() -> i32 { 0 } //~ ERROR E0308 +fn main() -> i32 { 0 } //~ ERROR E0579 diff --git a/src/test/compile-fail/bad-main.rs b/src/test/compile-fail/bad-main.rs index 1253f7569e7e8..6cd033da4bd71 100644 --- a/src/test/compile-fail/bad-main.rs +++ b/src/test/compile-fail/bad-main.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main(x: isize) { } //~ ERROR: main function has wrong type +fn main(x: isize) { } //~ ERROR: main function has wrong type [E0579] diff --git a/src/test/compile-fail/extern-main-fn.rs b/src/test/compile-fail/extern-main-fn.rs index 11f299acefa87..479b3e532c6b3 100644 --- a/src/test/compile-fail/extern-main-fn.rs +++ b/src/test/compile-fail/extern-main-fn.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern fn main() {} //~ ERROR: main function has wrong type +extern fn main() {} //~ ERROR: main function has wrong type [E0579] diff --git a/src/test/compile-fail/main-wrong-type-2.rs b/src/test/compile-fail/main-wrong-type-2.rs index 2878cbc7fc154..da1455403c2e3 100644 --- a/src/test/compile-fail/main-wrong-type-2.rs +++ b/src/test/compile-fail/main-wrong-type-2.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() -> char { -//~^ ERROR: main function has wrong type +//~^ ERROR: main function has wrong type [E0579] ' ' } diff --git a/src/test/compile-fail/main-wrong-type.rs b/src/test/compile-fail/main-wrong-type.rs index 431b855d51773..dc51777503569 100644 --- a/src/test/compile-fail/main-wrong-type.rs +++ b/src/test/compile-fail/main-wrong-type.rs @@ -14,5 +14,5 @@ struct S { } fn main(foo: S) { -//~^ ERROR: main function has wrong type +//~^ ERROR: main function has wrong type [E0579] } From 97b9c8b8d37ec21212d9c54ae510eae0220fbf7e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Jan 2017 11:17:17 +0100 Subject: [PATCH 30/86] Update error code number --- src/librustc/diagnostics.rs | 4 ++-- src/librustc/infer/error_reporting.rs | 2 +- src/test/compile-fail/{E0579.rs => E0580.rs} | 2 +- src/test/compile-fail/bad-main.rs | 2 +- src/test/compile-fail/extern-main-fn.rs | 2 +- src/test/compile-fail/main-wrong-type-2.rs | 2 +- src/test/compile-fail/main-wrong-type.rs | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename src/test/compile-fail/{E0579.rs => E0580.rs} (92%) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 6d94e1d725938..2878ff5e2846e 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1694,12 +1694,12 @@ To understand better how closures work in Rust, read: https://doc.rust-lang.org/book/closures.html "##, -E0579: r##" +E0580: r##" The `main` function was incorrectly declared. Erroneous code example: -```compile_fail,E0579 +```compile_fail,E0580 fn main() -> i32 { // error: main function has wrong type 0 } diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 2bed8148b9f8c..d859a8b44db0c 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -631,7 +631,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str) } ObligationCauseCode::MainFunctionType => { - struct_span_err!(self.tcx.sess, span, E0579, "{}", failure_str) + struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str) } _ => { struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str) diff --git a/src/test/compile-fail/E0579.rs b/src/test/compile-fail/E0580.rs similarity index 92% rename from src/test/compile-fail/E0579.rs rename to src/test/compile-fail/E0580.rs index beb6c792fa18a..a2ef7da78a843 100644 --- a/src/test/compile-fail/E0579.rs +++ b/src/test/compile-fail/E0580.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() -> i32 { 0 } //~ ERROR E0579 +fn main() -> i32 { 0 } //~ ERROR E0580 diff --git a/src/test/compile-fail/bad-main.rs b/src/test/compile-fail/bad-main.rs index 6cd033da4bd71..b73b4a6af6e89 100644 --- a/src/test/compile-fail/bad-main.rs +++ b/src/test/compile-fail/bad-main.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main(x: isize) { } //~ ERROR: main function has wrong type [E0579] +fn main(x: isize) { } //~ ERROR: main function has wrong type [E0580] diff --git a/src/test/compile-fail/extern-main-fn.rs b/src/test/compile-fail/extern-main-fn.rs index 479b3e532c6b3..d9bdb4ecd0477 100644 --- a/src/test/compile-fail/extern-main-fn.rs +++ b/src/test/compile-fail/extern-main-fn.rs @@ -8,4 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern fn main() {} //~ ERROR: main function has wrong type [E0579] +extern fn main() {} //~ ERROR: main function has wrong type [E0580] diff --git a/src/test/compile-fail/main-wrong-type-2.rs b/src/test/compile-fail/main-wrong-type-2.rs index da1455403c2e3..9d74d1a90493b 100644 --- a/src/test/compile-fail/main-wrong-type-2.rs +++ b/src/test/compile-fail/main-wrong-type-2.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() -> char { -//~^ ERROR: main function has wrong type [E0579] +//~^ ERROR: main function has wrong type [E0580] ' ' } diff --git a/src/test/compile-fail/main-wrong-type.rs b/src/test/compile-fail/main-wrong-type.rs index dc51777503569..402cd3a2d31b6 100644 --- a/src/test/compile-fail/main-wrong-type.rs +++ b/src/test/compile-fail/main-wrong-type.rs @@ -14,5 +14,5 @@ struct S { } fn main(foo: S) { -//~^ ERROR: main function has wrong type [E0579] +//~^ ERROR: main function has wrong type [E0580] } From eaf182e5395e4e0ab0b792020daed1f12b99d688 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Jan 2017 23:28:59 +0100 Subject: [PATCH 31/86] Add note for E0117 --- src/librustc_typeck/coherence/orphan.rs | 1 + src/test/compile-fail/E0117.rs | 1 + src/test/compile-fail/E0206.rs | 1 + src/test/compile-fail/coherence-impls-copy.rs | 5 ++++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 2b5a4515cd0d8..c54f467a4c41f 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -263,6 +263,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { .span_label(item.span, &format!("impl doesn't use types inside crate")) .note(&format!("the impl does not reference any types defined in \ this crate")) + .note("define and implement a trait or new type instead") .emit(); return; } diff --git a/src/test/compile-fail/E0117.rs b/src/test/compile-fail/E0117.rs index e9375e673253f..4ba9c3382f35d 100644 --- a/src/test/compile-fail/E0117.rs +++ b/src/test/compile-fail/E0117.rs @@ -11,6 +11,7 @@ impl Drop for u32 {} //~ ERROR E0117 //~^ NOTE impl doesn't use types inside crate //~| NOTE the impl does not reference any types defined in this crate +//~| NOTE define and implement a trait or new type instead fn main() { } diff --git a/src/test/compile-fail/E0206.rs b/src/test/compile-fail/E0206.rs index 888e42ed3a18c..1131e8e1b01ca 100644 --- a/src/test/compile-fail/E0206.rs +++ b/src/test/compile-fail/E0206.rs @@ -16,6 +16,7 @@ impl Copy for Foo { } //~| ERROR only traits defined in the current crate can be implemented for arbitrary types //~| NOTE impl doesn't use types inside crate //~| NOTE the impl does not reference any types defined in this crate +//~| NOTE define and implement a trait or new type instead #[derive(Copy, Clone)] struct Bar; diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs index f686a146042ce..fe121a3bc48ff 100644 --- a/src/test/compile-fail/coherence-impls-copy.rs +++ b/src/test/compile-fail/coherence-impls-copy.rs @@ -37,6 +37,7 @@ impl Copy for (MyType, MyType) {} //~| ERROR only traits defined in the current crate can be implemented for arbitrary types //~| NOTE impl doesn't use types inside crate //~| NOTE the impl does not reference any types defined in this crate +//~| NOTE define and implement a trait or new type instead impl Copy for &'static NotSync {} //~^ ERROR the trait `Copy` may not be implemented for this type @@ -46,8 +47,9 @@ impl Copy for [MyType] {} //~^ ERROR the trait `Copy` may not be implemented for this type //~| NOTE type is not a structure or enumeration //~| ERROR only traits defined in the current crate can be implemented for arbitrary types -//~| NOTE impl doesn't use types inside crate //~| NOTE the impl does not reference any types defined in this crate +//~| NOTE define and implement a trait or new type instead +//~| NOTE impl doesn't use types inside crate impl Copy for &'static [NotSync] {} //~^ ERROR the trait `Copy` may not be implemented for this type @@ -55,6 +57,7 @@ impl Copy for &'static [NotSync] {} //~| ERROR only traits defined in the current crate can be implemented for arbitrary types //~| NOTE impl doesn't use types inside crate //~| NOTE the impl does not reference any types defined in this crate +//~| NOTE define and implement a trait or new type instead fn main() { } From 45c8c5678a3065c5d1f75b2413bd800a792cf3d9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 26 Jan 2017 02:41:06 +0200 Subject: [PATCH 32/86] rustc: rename TyCtxt's `map` field to `hir`. --- src/librustc/cfg/construct.rs | 6 +- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/dep_graph/dep_tracking_map.rs | 2 +- src/librustc/dep_graph/visit.rs | 8 +- src/librustc/hir/itemlikevisit.rs | 2 +- src/librustc/infer/error_reporting.rs | 32 ++--- src/librustc/infer/mod.rs | 10 +- src/librustc/lint/context.rs | 10 +- src/librustc/middle/dataflow.rs | 2 +- src/librustc/middle/dead.rs | 20 +-- src/librustc/middle/effect.rs | 6 +- src/librustc/middle/expr_use_visitor.rs | 4 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/liveness.rs | 22 +-- src/librustc/middle/mem_categorization.rs | 12 +- src/librustc/middle/reachable.rs | 30 ++-- src/librustc/middle/stability.rs | 26 ++-- src/librustc/mir/mod.rs | 6 +- src/librustc/mir/transform.rs | 6 +- src/librustc/traits/error_reporting.rs | 6 +- src/librustc/ty/context.rs | 12 +- src/librustc/ty/error.rs | 4 +- .../ty/inhabitedness/def_id_forest.rs | 2 +- src/librustc/ty/item_path.rs | 6 +- src/librustc/ty/mod.rs | 80 +++++------ src/librustc/util/ppaux.rs | 8 +- src/librustc_borrowck/borrowck/check_loans.rs | 4 +- src/librustc_borrowck/borrowck/fragments.rs | 6 +- .../borrowck/gather_loans/mod.rs | 4 +- src/librustc_borrowck/borrowck/mir/mod.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 40 +++--- src/librustc_const_eval/check_match.rs | 8 +- src/librustc_const_eval/eval.rs | 36 ++--- src/librustc_const_eval/pattern.rs | 2 +- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/pretty.rs | 16 +-- src/librustc_driver/test.rs | 4 +- src/librustc_incremental/assert_dep_graph.rs | 6 +- src/librustc_incremental/calculate_svh/mod.rs | 6 +- .../calculate_svh/svh_visitor.rs | 2 +- .../persist/dirty_clean.rs | 8 +- src/librustc_lint/bad_style.rs | 2 +- src/librustc_lint/builtin.rs | 32 ++--- src/librustc_lint/types.rs | 6 +- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/astencode.rs | 4 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_metadata/encoder.rs | 60 ++++---- src/librustc_metadata/index_builder.rs | 6 +- src/librustc_mir/build/block.rs | 2 +- src/librustc_mir/build/mod.rs | 10 +- src/librustc_mir/build/scope.rs | 2 +- src/librustc_mir/graphviz.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 12 +- src/librustc_mir/hair/cx/mod.rs | 4 +- src/librustc_mir/mir_map.rs | 12 +- src/librustc_mir/pretty.rs | 4 +- src/librustc_mir/transform/copy_prop.rs | 2 +- src/librustc_mir/transform/deaggregator.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 14 +- src/librustc_passes/consts.rs | 14 +- src/librustc_passes/rvalues.rs | 2 +- src/librustc_privacy/lib.rs | 72 +++++----- src/librustc_save_analysis/dump_visitor.rs | 20 +-- src/librustc_save_analysis/external_data.rs | 80 +++++------ src/librustc_save_analysis/lib.rs | 22 +-- src/librustc_trans/assert_module_sources.rs | 2 +- src/librustc_trans/back/symbol_export.rs | 6 +- src/librustc_trans/back/symbol_names.rs | 4 +- src/librustc_trans/base.rs | 10 +- src/librustc_trans/collector.rs | 26 ++-- src/librustc_trans/consts.rs | 6 +- src/librustc_trans/debuginfo/gdb.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/debuginfo/mod.rs | 2 +- src/librustc_trans/declare.rs | 2 +- src/librustc_trans/partitioning.rs | 6 +- src/librustc_trans/symbol_map.rs | 4 +- src/librustc_trans/symbol_names_test.rs | 4 +- src/librustc_trans/trans_item.rs | 16 +-- src/librustc_typeck/astconv.rs | 22 +-- src/librustc_typeck/check/_match.rs | 6 +- src/librustc_typeck/check/callee.rs | 6 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/compare_method.rs | 48 +++---- src/librustc_typeck/check/dropck.rs | 10 +- src/librustc_typeck/check/intrinsic.rs | 4 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 10 +- src/librustc_typeck/check/mod.rs | 70 +++++----- src/librustc_typeck/check/regionck.rs | 4 +- src/librustc_typeck/check/upvar.rs | 10 +- src/librustc_typeck/check/wfcheck.rs | 20 +-- src/librustc_typeck/check/writeback.rs | 12 +- src/librustc_typeck/check_unused.rs | 2 +- src/librustc_typeck/coherence/builtin.rs | 20 +-- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 10 +- src/librustc_typeck/coherence/overlap.rs | 10 +- src/librustc_typeck/coherence/unsafety.rs | 4 +- src/librustc_typeck/collect.rs | 128 +++++++++--------- src/librustc_typeck/impl_wf_check.rs | 6 +- src/librustc_typeck/lib.rs | 8 +- src/librustc_typeck/variance/constraints.rs | 26 ++-- src/librustc_typeck/variance/solve.rs | 4 +- src/librustc_typeck/variance/terms.rs | 8 +- src/librustdoc/clean/mod.rs | 74 +++++----- src/librustdoc/core.rs | 6 +- src/librustdoc/visit_ast.rs | 24 ++-- .../issue-37290/auxiliary/lint.rs | 4 +- 111 files changed, 761 insertions(+), 761 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 6f2b9ca0c4220..595059332895d 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -46,18 +46,18 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Find the function this expression is from. let mut node_id = body.id; loop { - let node = tcx.map.get(node_id); + let node = tcx.hir.get(node_id); if hir::map::blocks::FnLikeNode::from_node(node).is_some() { break; } - let parent = tcx.map.get_parent_node(node_id); + let parent = tcx.hir.get_parent_node(node_id); assert!(node_id != parent); node_id = parent; } let mut cfg_builder = CFGBuilder { tcx: tcx, - tables: tcx.item_tables(tcx.map.local_def_id(node_id)), + tables: tcx.item_tables(tcx.hir.local_def_id(node_id)), graph: graph, fn_exit: fn_exit, loop_scopes: Vec::new() diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index d9fd0b9a1f939..df6db366df5b3 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -29,10 +29,10 @@ pub enum DepNode { // Represents the `Krate` as a whole (the `hir::Krate` value) (as // distinct from the krate module). This is basically a hash of // the entire krate, so if you read from `Krate` (e.g., by calling - // `tcx.map.krate()`), we will have to assume that any change + // `tcx.hir.krate()`), we will have to assume that any change // means that you need to be recompiled. This is because the // `Krate` value gives you access to all other items. To avoid - // this fate, do not call `tcx.map.krate()`; instead, prefer + // this fate, do not call `tcx.hir.krate()`; instead, prefer // wrappers like `tcx.visit_all_items_in_krate()`. If there is no // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain // access to the krate, but you must remember to add suitable diff --git a/src/librustc/dep_graph/dep_tracking_map.rs b/src/librustc/dep_graph/dep_tracking_map.rs index 50dfe9d22f12f..9660758220368 100644 --- a/src/librustc/dep_graph/dep_tracking_map.rs +++ b/src/librustc/dep_graph/dep_tracking_map.rs @@ -117,7 +117,7 @@ impl MemoizationMap for RefCell> { /// /// ``` /// fn type_of_item(..., item: &hir::Item) -> Ty<'tcx> { - /// let item_def_id = ccx.tcx.map.local_def_id(it.id); + /// let item_def_id = ccx.tcx.hir.local_def_id(it.id); /// ccx.tcx.item_types.memoized(item_def_id, || { /// ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id)); // (*) /// compute_type_of_item(ccx, item) diff --git a/src/librustc/dep_graph/visit.rs b/src/librustc/dep_graph/visit.rs index 1990574ca9a83..f0a81fd1cfd33 100644 --- a/src/librustc/dep_graph/visit.rs +++ b/src/librustc/dep_graph/visit.rs @@ -36,7 +36,7 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> where F: FnMut(DefId) -> DepNode, V: ItemLikeVisitor<'tcx> { fn visit_item(&mut self, i: &'tcx hir::Item) { - let item_def_id = self.tcx.map.local_def_id(i.id); + let item_def_id = self.tcx.hir.local_def_id(i.id); let task_id = (self.dep_node_fn)(item_def_id); let _task = self.tcx.dep_graph.in_task(task_id.clone()); debug!("Started task {:?}", task_id); @@ -46,7 +46,7 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> } fn visit_trait_item(&mut self, i: &'tcx hir::TraitItem) { - let trait_item_def_id = self.tcx.map.local_def_id(i.id); + let trait_item_def_id = self.tcx.hir.local_def_id(i.id); let task_id = (self.dep_node_fn)(trait_item_def_id); let _task = self.tcx.dep_graph.in_task(task_id.clone()); debug!("Started task {:?}", task_id); @@ -56,7 +56,7 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> } fn visit_impl_item(&mut self, i: &'tcx hir::ImplItem) { - let impl_item_def_id = self.tcx.map.local_def_id(i.id); + let impl_item_def_id = self.tcx.hir.local_def_id(i.id); let task_id = (self.dep_node_fn)(impl_item_def_id); let _task = self.tcx.dep_graph.in_task(task_id.clone()); debug!("Started task {:?}", task_id); @@ -66,7 +66,7 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx> } } - let krate = tcx.dep_graph.with_ignore(|| tcx.map.krate()); + let krate = tcx.dep_graph.with_ignore(|| tcx.hir.krate()); let mut tracking_visitor = TrackingVisitor { tcx: tcx, dep_node_fn: &mut dep_node_fn, diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index f359ca2016359..0d79017066b01 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -44,7 +44,7 @@ use super::intravisit::Visitor; /// - How: Implement `intravisit::Visitor` and override the /// `visit_nested_map()` methods to return /// `NestedVisitorMap::All`. Walk your crate with -/// `intravisit::walk_crate()` invoked on `tcx.map.krate()`. +/// `intravisit::walk_crate()` invoked on `tcx.hir.krate()`. /// - Pro: Visitor methods for any kind of HIR node, not just item-like things. /// - Pro: Preserves nesting information /// - Con: Does not integrate well into dependency tracking. diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 095d2a78a94cd..0b43f32e3dc29 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -144,14 +144,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix) }; - let span = match scope.span(&self.region_maps, &self.map) { + let span = match scope.span(&self.region_maps, &self.hir) { Some(s) => s, None => { err.note(&unknown_scope()); return; } }; - let tag = match self.map.find(scope.node_id(&self.region_maps)) { + let tag = match self.hir.find(scope.node_id(&self.region_maps)) { Some(ast_map::NodeBlock(_)) => "block", Some(ast_map::NodeExpr(expr)) => match expr.node { hir::ExprCall(..) => "call", @@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let node = fr.scope.node_id(&self.region_maps); let unknown; - let tag = match self.map.find(node) { + let tag = match self.hir.find(node) { Some(ast_map::NodeBlock(_)) | Some(ast_map::NodeExpr(_)) => "body", Some(ast_map::NodeItem(it)) => item_scope_tag(&it), @@ -218,7 +218,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Some(_) => { unknown = format!("unexpected node ({}) for scope {:?}. \ Please report a bug.", - self.map.node_to_string(node), fr.scope); + self.hir.node_to_string(node), fr.scope); &unknown } None => { @@ -227,7 +227,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { &unknown } }; - let (msg, opt_span) = explain_span(self, tag, self.map.span(node)); + let (msg, opt_span) = explain_span(self, tag, self.hir.span(node)); (format!("{} {}", prefix, msg), opt_span) } @@ -467,8 +467,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }, _ => return None }; - let parent = tcx.map.get_parent(scope_id); - let parent_node = tcx.map.find(parent); + let parent = tcx.hir.get_parent(scope_id); + let parent_node = tcx.hir.find(parent); match parent_node { Some(node) => match node { ast_map::NodeItem(item) => match item.node { @@ -1068,8 +1068,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegions]) { let scope_id = same_regions[0].scope_id; - let parent = self.tcx.map.get_parent(scope_id); - let parent_node = self.tcx.map.find(parent); + let parent = self.tcx.hir.get_parent(scope_id); + let parent_node = self.tcx.hir.find(parent); let taken = lifetimes_in_scope(self.tcx, scope_id); let life_giver = LifeGiver::with_taken(&taken[..]); let node_inner = match parent_node { @@ -1083,8 +1083,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } ast_map::NodeImplItem(item) => { - let id = self.tcx.map.get_parent(item.id); - if let Some(ast_map::NodeItem(parent_scope)) = self.tcx.map.find(id) { + let id = self.tcx.hir.get_parent(item.id); + if let Some(ast_map::NodeItem(parent_scope)) = self.tcx.hir.find(id) { if let hir::ItemImpl(_, _, _, None, _, _) = parent_scope.node { // this impl scope implements a trait, do not recomend // using explicit lifetimes (#37363) @@ -1654,7 +1654,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { generics: &hir::Generics, span: Span, body: hir::BodyId) { - let s = hir::print::to_string(&self.tcx.map, |s| { + let s = hir::print::to_string(&self.tcx.hir, |s| { use syntax::abi::Abi; use syntax::print::pprust::PrintState; @@ -1891,8 +1891,8 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, scope_id: ast::NodeId) -> Vec { let mut taken = Vec::new(); - let parent = tcx.map.get_parent(scope_id); - let method_id_opt = match tcx.map.find(parent) { + let parent = tcx.hir.get_parent(scope_id); + let method_id_opt = match tcx.hir.find(parent) { Some(node) => match node { ast_map::NodeItem(item) => match item.node { hir::ItemFn(.., ref gen, _) => { @@ -1915,8 +1915,8 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, None => None }; if let Some(method_id) = method_id_opt { - let parent = tcx.map.get_parent(method_id); - if let Some(node) = tcx.map.find(parent) { + let parent = tcx.hir.get_parent(method_id); + if let Some(node) = tcx.hir.find(parent) { match node { ast_map::NodeItem(item) => match item.node { hir::ItemImpl(_, _, ref gen, ..) => { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4e64dda1a3044..45a58333f781f 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -453,8 +453,8 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId { -> (Option<&'a ty::TypeckTables<'tcx>>, Option>, Option>) { - let item_id = tcx.map.body_owner(self); - (Some(tcx.item_tables(tcx.map.local_def_id(item_id))), + let item_id = tcx.hir.body_owner(self); + (Some(tcx.item_tables(tcx.hir.local_def_id(item_id))), None, Some(ty::ParameterEnvironment::for_item(tcx, item_id))) } @@ -1269,7 +1269,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.types.err, None => { bug!("no type for node {}: {} in fcx", - id, self.tcx.map.node_to_string(id)); + id, self.tcx.hir.node_to_string(id)); } } } @@ -1639,7 +1639,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { -> Option { if let InferTables::InProgress(tables) = self.tables { - if let Some(id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { return tables.borrow().closure_kinds.get(&id).cloned(); } } @@ -1657,7 +1657,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { -> ty::ClosureTy<'tcx> { if let InferTables::InProgress(tables) = self.tables { - if let Some(id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { if let Some(ty) = tables.borrow().closure_tys.get(&id) { return ty.subst(self.tcx, substs.substs); } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 5ac000923e071..3506a9c067ca6 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -768,7 +768,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { /// items in the context of the outer item, so enable /// deep-walking. fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> { - hir_visit::NestedVisitorMap::All(&self.tcx.map) + hir_visit::NestedVisitorMap::All(&self.tcx.hir) } // Output any lints that were previously added to the session. @@ -784,7 +784,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { let old_tables = self.tables; self.tables = self.tcx.body_tables(body); - let body = self.tcx.map.body(body); + let body = self.tcx.hir.body(body); self.visit_body(body); self.tables = old_tables; } @@ -834,7 +834,7 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { // in order for `check_fn` to be able to use them. let old_tables = self.tables; self.tables = self.tcx.body_tables(body_id); - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); run_lints!(self, check_fn, late_passes, fk, decl, body, span, id); hir_visit::walk_fn(self, fk, decl, body_id, span, id); run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id); @@ -1206,7 +1206,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: &AccessLevels) { let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); // We want to own the lint store, so move it out of the session. let lint_store = mem::replace(&mut *tcx.sess.lint_store.borrow_mut(), LintStore::new()); @@ -1236,7 +1236,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, for early_lint in v { span_bug!(early_lint.diagnostic.span.clone(), "unprocessed lint {:?} at {}", - early_lint, tcx.map.node_to_string(*id)); + early_lint, tcx.hir.node_to_string(*id)); } } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index dfcb5cb7b79fe..7d62103e386c4 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -109,7 +109,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> { fn nested(&self, state: &mut pprust::State, nested: pprust::Nested) -> io::Result<()> { - pprust::PpAnn::nested(&self.tcx.map, state, nested) + pprust::PpAnn::nested(&self.tcx.hir, state, nested) } fn pre(&self, ps: &mut pprust::State, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 38fbe650a89bd..fe1dadca05134 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -35,7 +35,7 @@ use syntax_pos; // may need to be marked as live. fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) -> bool { - match tcx.map.find(node_id) { + match tcx.hir.find(node_id) { Some(ast_map::NodeItem(..)) | Some(ast_map::NodeImplItem(..)) | Some(ast_map::NodeForeignItem(..)) | @@ -59,7 +59,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn check_def_id(&mut self, def_id: DefId) { - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { if should_explore(self.tcx, node_id) { self.worklist.push(node_id); } @@ -68,7 +68,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn insert_def_id(&mut self, def_id: DefId) { - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { debug_assert!(!should_explore(self.tcx, node_id)); self.live_symbols.insert(node_id); } @@ -143,7 +143,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } scanned.insert(id); - if let Some(ref node) = self.tcx.map.find(id) { + if let Some(ref node) = self.tcx.hir.find(id) { self.live_symbols.insert(id); self.visit_node(node); } @@ -203,7 +203,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { let old_tables = self.tables; self.tables = self.tcx.body_tables(body); - let body = self.tcx.map.body(body); + let body = self.tcx.hir.body(body); self.visit_body(body); self.tables = old_tables; } @@ -434,7 +434,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { } fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool { - let field_type = self.tcx.item_type(self.tcx.map.local_def_id(field.id)); + let field_type = self.tcx.item_type(self.tcx.hir.local_def_id(field.id)); let is_marker_field = match field_type.ty_to_def_id() { Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)), _ => false @@ -478,10 +478,10 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { // method of a private type is used, but the type itself is never // called directly. if let Some(impl_list) = - self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) { + self.tcx.inherent_impls.borrow().get(&self.tcx.hir.local_def_id(id)) { for &impl_did in impl_list.iter() { for &item_did in &self.tcx.associated_item_def_ids(impl_did)[..] { - if let Some(item_node_id) = self.tcx.map.as_local_node_id(item_did) { + if let Some(item_node_id) = self.tcx.hir.as_local_node_id(item_did) { if self.live_symbols.contains(&item_node_id) { return true; } @@ -514,7 +514,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { /// an error. We could do this also by checking the parents, but /// this is how the code is setup and it seems harmless enough. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.map) + NestedVisitorMap::All(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -596,7 +596,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: &privacy::AccessLevels) { let _task = tcx.dep_graph.in_task(DepNode::DeadCheck); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); let live_symbols = find_live(tcx, access_levels, krate); let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; intravisit::walk_crate(&mut visitor, krate); diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index f90d9143e9d57..ab33c3843aae5 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { let old_tables = self.tables; self.tables = self.tcx.body_tables(body); - let body = self.tcx.map.body(body); + let body = self.tcx.hir.body(body); self.visit_body(body); self.tables = old_tables; } @@ -203,7 +203,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { if let Def::Static(def_id, mutbl) = path.def { if mutbl { self.require_unsafe(expr.span, "use of mutable static"); - } else if match self.tcx.map.get_if_local(def_id) { + } else if match self.tcx.hir.get_if_local(def_id) { Some(hir::map::NodeForeignItem(..)) => true, Some(..) => false, None => self.tcx.sess.cstore.is_foreign_item(def_id), @@ -249,5 +249,5 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { unsafe_context: UnsafeContext::new(SafeContext), }; - tcx.map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 0eacbba3fdd44..738bd0009abae 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1020,7 +1020,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.tcx().with_freevars(closure_expr.id, |freevars| { for freevar in freevars { let def_id = freevar.def.def_id(); - let id_var = self.tcx().map.as_local_node_id(def_id).unwrap(); + let id_var = self.tcx().hir.as_local_node_id(def_id).unwrap(); let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr.id }; let upvar_capture = self.mc.infcx.upvar_capture(upvar_id).unwrap(); @@ -1052,7 +1052,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { -> mc::McResult> { // Create the cmt for the variable being borrowed, from the // caller's perspective - let var_id = self.tcx().map.as_local_node_id(upvar_def.def_id()).unwrap(); + let var_id = self.tcx().hir.as_local_node_id(upvar_def.def_id()).unwrap(); let var_ty = self.mc.infcx.node_ty(var_id)?; self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def) } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index d42b866d47209..05be35df95991 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -110,7 +110,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> { } fn visit_nested_body(&mut self, body_id: hir::BodyId) { - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); self.tcx.infer_ctxt(body_id, Reveal::All).enter(|infcx| { let mut visitor = ExprVisitor { infcx: &infcx diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index e0521f98416bc..7fa3365694c26 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -183,7 +183,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String { impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, @@ -197,7 +197,7 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let _task = tcx.dep_graph.in_task(DepNode::Liveness); - tcx.map.krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor()); + tcx.hir.krate().visit_all_item_likes(&mut IrMaps::new(tcx).as_deep_visitor()); tcx.sess.abort_if_errors(); } @@ -364,7 +364,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, debug!("creating fn_maps: {:?}", &fn_maps as *const IrMaps); - let body = ir.tcx.map.body(body_id); + let body = ir.tcx.hir.body(body_id); for arg in &body.arguments { arg.pat.each_binding(|_bm, arg_id, _x, path1| { @@ -440,7 +440,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) { ir.tcx.with_freevars(expr.id, |freevars| { for fv in freevars { if let Def::Local(def_id) = fv.def { - let rv = ir.tcx.map.as_local_node_id(def_id).unwrap(); + let rv = ir.tcx.hir.as_local_node_id(def_id).unwrap(); let fv_ln = ir.add_live_node(FreeVarNode(fv.span)); call_caps.push(CaptureInfo {ln: fv_ln, var_nid: rv}); @@ -807,7 +807,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // effectively a return---this only occurs in `for` loops, // where the body is really a closure. - debug!("compute: using id for body, {}", self.ir.tcx.map.node_to_pretty_string(body.id)); + debug!("compute: using id for body, {}", self.ir.tcx.hir.node_to_pretty_string(body.id)); let exit_ln = self.s.exit_ln; let entry_ln: LiveNode = self.with_loop_nodes(body.id, exit_ln, exit_ln, |this| { @@ -900,7 +900,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode { - debug!("propagate_through_expr: {}", self.ir.tcx.map.node_to_pretty_string(expr.id)); + debug!("propagate_through_expr: {}", self.ir.tcx.hir.node_to_pretty_string(expr.id)); match expr.node { // Interesting cases with control flow or which gen/kill @@ -919,7 +919,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprClosure(.., blk_id, _) => { debug!("{} is an ExprClosure", - self.ir.tcx.map.node_to_pretty_string(expr.id)); + self.ir.tcx.hir.node_to_pretty_string(expr.id)); /* The next-node for a break is the successor of the entire @@ -1241,7 +1241,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { -> LiveNode { match path.def { Def::Local(def_id) => { - let nid = self.ir.tcx.map.as_local_node_id(def_id).unwrap(); + let nid = self.ir.tcx.hir.as_local_node_id(def_id).unwrap(); let ln = self.live_node(id, path.span); if acc != 0 { self.init_from_succ(ln, succ); @@ -1295,7 +1295,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } debug!("propagate_through_loop: using id for loop body {} {}", - expr.id, self.ir.tcx.map.node_to_pretty_string(body.id)); + expr.id, self.ir.tcx.hir.node_to_pretty_string(body.id)); let cond_ln = match kind { LoopLoop => ln, @@ -1440,7 +1440,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { entry_ln: LiveNode, body: &hir::Body) { - let fn_ty = self.ir.tcx.item_type(self.ir.tcx.map.local_def_id(id)); + let fn_ty = self.ir.tcx.item_type(self.ir.tcx.hir.local_def_id(id)); let fn_ret = match fn_ty.sty { ty::TyClosure(closure_def_id, substs) => self.ir.tcx.closure_type(closure_def_id, substs).sig.output(), @@ -1477,7 +1477,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // if there is no later assignment. If this local is actually // mutable, then check for a reassignment to flag the mutability // as being used. - let nid = self.ir.tcx.map.as_local_node_id(def_id).unwrap(); + let nid = self.ir.tcx.hir.as_local_node_id(def_id).unwrap(); let ln = self.live_node(expr.id, expr.span); let var = self.variable(nid, expr.span); self.warn_about_dead_assign(expr.span, expr.id, ln, var); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 92e69d7d72957..d4438f5ecfa1a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -268,7 +268,7 @@ impl MutabilityCategory { } fn from_local(tcx: TyCtxt, id: ast::NodeId) -> MutabilityCategory { - let ret = match tcx.map.get(id) { + let ret = match tcx.hir.get(id) { ast_map::NodeLocal(p) => match p.node { PatKind::Binding(bind_mode, ..) => { if bind_mode == hir::BindByValue(hir::MutMutable) { @@ -279,7 +279,7 @@ impl MutabilityCategory { } _ => span_bug!(p.span, "expected identifier pattern") }, - _ => span_bug!(tcx.map.span(id), "expected identifier pattern") + _ => span_bug!(tcx.hir.span(id), "expected identifier pattern") }; debug!("MutabilityCategory::{}(tcx, id={:?}) => {:?}", "from_local", id, ret); @@ -539,7 +539,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Upvar(def_id, _, fn_node_id) => { - let var_id = self.tcx().map.as_local_node_id(def_id).unwrap(); + let var_id = self.tcx().hir.as_local_node_id(def_id).unwrap(); let ty = self.node_ty(fn_node_id)?; match ty.sty { ty::TyClosure(closure_id, _) => { @@ -576,7 +576,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Local(def_id) => { - let vid = self.tcx().map.as_local_node_id(def_id).unwrap(); + let vid = self.tcx().hir.as_local_node_id(def_id).unwrap(); Ok(Rc::new(cmt_ { id: id, span: span, @@ -698,7 +698,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // Look up the node ID of the closure body so we can construct // a free region within it let fn_body_id = { - let fn_expr = match self.tcx().map.find(upvar_id.closure_expr_id) { + let fn_expr = match self.tcx().hir.find(upvar_id.closure_expr_id) { Some(ast_map::NodeExpr(e)) => e, _ => bug!() }; @@ -1313,7 +1313,7 @@ impl<'tcx> cmt_<'tcx> { "non-lvalue".to_string() } Categorization::Local(vid) => { - if tcx.map.is_argument(vid) { + if tcx.hir.is_argument(vid) { "argument".to_string() } else { "local variable".to_string() diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 385dd3d9bf764..9b00fc3f220ec 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -63,8 +63,8 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, generics_require_inlining(&sig.generics) { return true } - if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_src) { - match tcx.map.find(impl_node_id) { + if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) { + match tcx.hir.find(impl_node_id) { Some(ast_map::NodeItem(item)) => item_might_be_inlined(&item), Some(..) | None => @@ -97,7 +97,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { let old_tables = self.tables; self.tables = self.tcx.body_tables(body); - let body = self.tcx.map.body(body); + let body = self.tcx.hir.body(body); self.visit_body(body); self.tables = old_tables; } @@ -117,7 +117,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { if let Some(def) = def { let def_id = def.def_id(); - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { if self.def_id_represents_local_inlined_item(def_id) { self.worklist.push(node_id); } else { @@ -147,12 +147,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // Returns true if the given def ID represents a local item that is // eligible for inlining and false otherwise. fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool { - let node_id = match self.tcx.map.as_local_node_id(def_id) { + let node_id = match self.tcx.hir.as_local_node_id(def_id) { Some(node_id) => node_id, None => { return false; } }; - match self.tcx.map.find(node_id) { + match self.tcx.hir.find(node_id) { Some(ast_map::NodeItem(item)) => { match item.node { hir::ItemFn(..) => item_might_be_inlined(&item), @@ -176,13 +176,13 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { true } else { let impl_did = self.tcx - .map + .hir .get_parent_did(node_id); // Check the impl. If the generics on the self // type of the impl require inlining, this method // does too. - let impl_node_id = self.tcx.map.as_local_node_id(impl_did).unwrap(); - match self.tcx.map.expect_item(impl_node_id).node { + let impl_node_id = self.tcx.hir.as_local_node_id(impl_did).unwrap(); + match self.tcx.hir.expect_item(impl_node_id).node { hir::ItemImpl(_, _, ref generics, ..) => { generics_require_inlining(generics) } @@ -210,7 +210,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { continue } - if let Some(ref item) = self.tcx.map.find(search_item) { + if let Some(ref item) = self.tcx.hir.find(search_item) { self.propagate_node(item, search_item); } } @@ -287,7 +287,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { self.visit_nested_body(body); } hir::ImplItemKind::Method(ref sig, body) => { - let did = self.tcx.map.get_parent_did(search_item); + let did = self.tcx.hir.get_parent_did(search_item); if method_might_be_inlined(self.tcx, sig, impl_item, did) { self.visit_nested_body(body) } @@ -303,7 +303,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { ast_map::NodeTy(_) => {} _ => { bug!("found unexpected thingy in worklist: {}", - self.tcx.map.node_to_string(search_item)) + self.tcx.hir.node_to_string(search_item)) } } } @@ -343,7 +343,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, for default_method in self.tcx.provided_trait_methods(trait_def_id) { let node_id = self.tcx - .map + .hir .as_local_node_id(default_method.def_id) .unwrap(); self.worklist.push(node_id); @@ -386,7 +386,7 @@ pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } for item in tcx.lang_items.items().iter() { if let Some(did) = *item { - if let Some(node_id) = tcx.map.as_local_node_id(did) { + if let Some(node_id) = tcx.hir.as_local_node_id(did) { reachable_context.worklist.push(node_id); } } @@ -397,7 +397,7 @@ pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: access_levels, worklist: &mut reachable_context.worklist, }; - tcx.map.krate().visit_all_item_likes(&mut collect_private_impl_items); + tcx.hir.krate().visit_all_item_likes(&mut collect_private_impl_items); } // Step 2: Mark all symbols that the symbols on the worklist touch. diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index e6c9d2c36d013..487e13b47fec2 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } } - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); self.index.stab_map.insert(def_id, Some(stab)); let orig_parent_stab = replace(&mut self.parent_stab, Some(stab)); @@ -188,7 +188,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { debug!("annotate: not found, parent = {:?}", self.parent_stab); if let Some(stab) = self.parent_stab { if stab.level.is_unstable() { - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); self.index.stab_map.insert(def_id, Some(stab)); } } @@ -211,7 +211,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } // `Deprecation` is just two pointers, no need to intern it - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); let depr_entry = Some(DeprecationEntry::local(depr, def_id)); self.index.depr_map.insert(def_id, depr_entry.clone()); @@ -219,7 +219,7 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { visit_children(self); self.parent_depr = orig_parent_depr; } else if let parent_depr @ Some(_) = self.parent_depr.clone() { - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); self.index.depr_map.insert(def_id, parent_depr); visit_children(self); } else { @@ -234,7 +234,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { /// nested items in the context of the outer item, so enable /// deep-walking. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.map) + NestedVisitorMap::All(&self.tcx.hir) } fn visit_item(&mut self, i: &'tcx Item) { @@ -313,7 +313,7 @@ struct MissingStabilityAnnotations<'a, 'tcx: 'a> { impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> { fn check_missing_stability(&self, id: NodeId, span: Span) { - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); let is_error = !self.tcx.sess.opts.test && !self.tcx.stability.borrow().stab_map.contains_key(&def_id) && self.access_levels.is_reachable(id); @@ -325,7 +325,7 @@ impl<'a, 'tcx: 'a> MissingStabilityAnnotations<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, i: &'tcx Item) { @@ -348,7 +348,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { - let impl_def_id = self.tcx.map.local_def_id(self.tcx.map.get_parent(ii.id)); + let impl_def_id = self.tcx.hir.local_def_id(self.tcx.hir.get_parent(ii.id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.id, ii.span); } @@ -384,7 +384,7 @@ impl<'a, 'tcx> Index<'tcx> { self.active_features = active_lib_features.iter().map(|&(ref s, _)| s.clone()).collect(); let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); let mut annotator = Annotator { tcx: tcx, index: self, @@ -484,7 +484,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let skip = if id == ast::DUMMY_NODE_ID { true } else { - let parent_def_id = self.map.local_def_id(self.map.get_parent(id)); + let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id)); self.lookup_deprecation_entry(parent_def_id).map_or(false, |parent_depr| { parent_depr.same_origin(&depr_entry) }) @@ -555,7 +555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { /// nested items in the context of the outer item, so enable /// deep-walking. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -578,7 +578,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { hir::ItemImpl(.., Some(ref t), _, ref impl_item_refs) => { if let Def::Trait(trait_did) = t.path.def { for impl_item_ref in impl_item_refs { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); let trait_item_def_id = self.tcx.associated_items(trait_did) .find(|item| item.name == impl_item.name).map(|item| item.def_id); if let Some(def_id) = trait_item_def_id { @@ -658,7 +658,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api { let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); let mut missing = MissingStabilityAnnotations { tcx: tcx, access_levels: access_levels, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5bae0e347f7c4..6e9091cf31728 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1163,14 +1163,14 @@ impl<'tcx> Debug for Rvalue<'tcx> { } AggregateKind::Closure(def_id, _) => ty::tls::with(|tcx| { - if let Some(node_id) = tcx.map.as_local_node_id(def_id) { - let name = format!("[closure@{:?}]", tcx.map.span(node_id)); + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + let name = format!("[closure@{:?}]", tcx.hir.span(node_id)); let mut struct_fmt = fmt.debug_struct(&name); tcx.with_freevars(node_id, |freevars| { for (freevar, lv) in freevars.iter().zip(lvs) { let def_id = freevar.def.def_id(); - let var_id = tcx.map.as_local_node_id(def_id).unwrap(); + let var_id = tcx.hir.as_local_node_id(def_id).unwrap(); let var_name = tcx.local_var_name_str(var_id); struct_fmt.field(&var_name, lv); } diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs index 3c5a91f4ff04c..652fef76f288a 100644 --- a/src/librustc/mir/transform.rs +++ b/src/librustc/mir/transform.rs @@ -40,13 +40,13 @@ impl<'a, 'tcx> MirSource { use hir::*; // Handle constants in enum discriminants, types, and repeat expressions. - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); let def_key = tcx.def_key(def_id); if def_key.disambiguated_data.data == DefPathData::Initializer { return MirSource::Const(id); } - match tcx.map.get(id) { + match tcx.hir.get(id) { map::NodeItem(&Item { node: ItemConst(..), .. }) | map::NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) | map::NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => { @@ -124,7 +124,7 @@ impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T { let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut(); tcx.dep_graph.write(DepNode::Mir(def_id)); - let id = tcx.map.as_local_node_id(def_id).unwrap(); + let id = tcx.hir.as_local_node_id(def_id).unwrap(); let src = MirSource::from_node(tcx, id); for hook in &mut *hooks { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5cc9875e8018b..1658efb03235a 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -441,7 +441,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { E0276, "impl has stricter requirements than trait"); - if let Some(trait_item_span) = self.tcx.map.span_if_local(trait_item_def_id) { + if let Some(trait_item_span) = self.tcx.hir.span_if_local(trait_item_def_id) { err.span_label(trait_item_span, &format!("definition of `{}` from trait", item_name)); } @@ -594,7 +594,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::Predicate::ClosureKind(closure_def_id, kind) => { let found_kind = self.closure_kind(closure_def_id).unwrap(); - let closure_span = self.tcx.map.span_if_local(closure_def_id).unwrap(); + let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap(); let mut err = struct_span_err!( self.tcx.sess, closure_span, E0525, "expected a closure that implements the `{}` trait, \ @@ -653,7 +653,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { -> DiagnosticBuilder<'tcx> { assert!(type_def_id.is_local()); - let span = self.map.span_if_local(type_def_id).unwrap(); + let span = self.hir.span_if_local(type_def_id).unwrap(); let mut err = struct_span_err!(self.sess, span, E0072, "recursive type `{}` has infinite size", self.item_path_str(type_def_id)); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c32e40c6cef22..7f26fdfba5693 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -265,7 +265,7 @@ impl<'tcx> TypeckTables<'tcx> { Some(ty) => ty, None => { bug!("node_id_to_type: no type for node `{}`", - tls::with(|tcx| tcx.map.node_to_string(id))) + tls::with(|tcx| tcx.hir.node_to_string(id))) } } } @@ -428,7 +428,7 @@ pub struct GlobalCtxt<'tcx> { /// additional acyclicity requirements). pub super_predicates: RefCell>>, - pub map: ast_map::Map<'tcx>, + pub hir: ast_map::Map<'tcx>, /// Maps from the def-id of a function/method or const/static /// to its MIR. Mutation is done at an item granularity to @@ -628,7 +628,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("retrace_path(path={:?}, krate={:?})", path_data, self.crate_name(krate)); if krate == LOCAL_CRATE { - self.map + self.hir .definitions() .def_path_table() .retrace_path(path_data) @@ -730,7 +730,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { arena: &'tcx DroplessArena, resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, - map: ast_map::Map<'tcx>, + hir: ast_map::Map<'tcx>, region_maps: RegionMaps, lang_items: middle::lang_items::LanguageItems, stability: stability::Index<'tcx>, @@ -741,7 +741,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let data_layout = TargetDataLayout::parse(s); let interners = CtxtInterners::new(arena); let common_types = CommonTypes::new(&interners); - let dep_graph = map.dep_graph.clone(); + let dep_graph = hir.dep_graph.clone(); let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone()); tls::enter_global(GlobalCtxt { specializes_cache: RefCell::new(traits::SpecializesCache::new()), @@ -765,7 +765,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())), super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())), fulfilled_predicates: RefCell::new(fulfilled_predicates), - map: map, + hir: hir, mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())), freevars: RefCell::new(resolutions.freevars), maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e95ce97e13577..91087a3dcecd0 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -283,7 +283,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { expected.ty, found.ty)); - match self.map.span_if_local(expected.def_id) { + match self.hir.span_if_local(expected.def_id) { Some(span) => { db.span_note(span, "a default was defined here..."); } @@ -297,7 +297,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { expected.origin_span, "...that was applied to an unconstrained type variable here"); - match self.map.span_if_local(found.def_id) { + match self.hir.span_if_local(found.def_id) { Some(span) => { db.span_note(span, "a second default was defined here..."); } diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index 16bc65603f135..6801e82fe7476 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -43,7 +43,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest { /// crate. #[inline] pub fn full(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> DefIdForest { - let crate_id = tcx.map.local_def_id(CRATE_NODE_ID); + let crate_id = tcx.hir.local_def_id(CRATE_NODE_ID); DefIdForest::from_id(crate_id) } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0e4c14029e9b9..d488cd1c42711 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -52,7 +52,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a string identifying this local node-id. pub fn node_path_str(self, id: ast::NodeId) -> String { - self.item_path_str(self.map.local_def_id(id)) + self.item_path_str(self.hir.local_def_id(id)) } /// Returns a string identifying this def-id. This string is @@ -286,8 +286,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // only occur very early in the compiler pipeline. let parent_def_id = self.parent_def_id(impl_def_id).unwrap(); self.push_item_path(buffer, parent_def_id); - let node_id = self.map.as_local_node_id(impl_def_id).unwrap(); - let item = self.map.expect_item(node_id); + let node_id = self.hir.as_local_node_id(impl_def_id).unwrap(); + let item = self.hir.expect_item(node_id); let span_str = self.sess.codemap().span_to_string(item.span); buffer.push(&format!("", span_str)); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 697ab6ee491d4..7a8788f053dd0 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -261,7 +261,7 @@ impl Visibility { def => Visibility::Restricted(def.def_id()), }, hir::Inherited => { - Visibility::Restricted(tcx.map.local_def_id(tcx.map.get_module_parent(id))) + Visibility::Restricted(tcx.hir.local_def_id(tcx.hir.get_module_parent(id))) } } } @@ -1198,14 +1198,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { /// Construct a parameter environment given an item, impl item, or trait item pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId) -> ParameterEnvironment<'tcx> { - match tcx.map.find(id) { + match tcx.hir.find(id) { Some(ast_map::NodeImplItem(ref impl_item)) => { match impl_item.node { 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); - let impl_def_id = tcx.map.local_def_id(impl_id); + let impl_id = tcx.hir.get_parent(id); + let impl_def_id = tcx.hir.local_def_id(impl_id); tcx.construct_parameter_environment(impl_item.span, impl_def_id, tcx.region_maps.item_extent(id)) @@ -1213,7 +1213,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { hir::ImplItemKind::Method(_, ref body) => { tcx.construct_parameter_environment( impl_item.span, - tcx.map.local_def_id(id), + tcx.hir.local_def_id(id), tcx.region_maps.call_site_extent(id, body.node_id)) } } @@ -1223,8 +1223,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { hir::TraitItemKind::Type(..) | hir::TraitItemKind::Const(..) => { // 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); - let trait_def_id = tcx.map.local_def_id(trait_id); + let trait_id = tcx.hir.get_parent(id); + let trait_def_id = tcx.hir.local_def_id(trait_id); tcx.construct_parameter_environment(trait_item.span, trait_def_id, tcx.region_maps.item_extent(id)) @@ -1242,7 +1242,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { }; tcx.construct_parameter_environment( trait_item.span, - tcx.map.local_def_id(id), + tcx.hir.local_def_id(id), extent) } } @@ -1251,7 +1251,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { match item.node { hir::ItemFn(.., body_id) => { // We assume this is a function. - let fn_def_id = tcx.map.local_def_id(id); + let fn_def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment( item.span, @@ -1265,13 +1265,13 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { hir::ItemImpl(..) | hir::ItemConst(..) | hir::ItemStatic(..) => { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, tcx.region_maps.item_extent(id)) } hir::ItemTrait(..) => { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, tcx.region_maps.item_extent(id)) @@ -1287,7 +1287,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { Some(ast_map::NodeExpr(expr)) => { // This is a convenience to allow closures to work. if let hir::ExprClosure(.., body, _) = expr.node { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); let base_def_id = tcx.closure_base_def_id(def_id); tcx.construct_parameter_environment( expr.span, @@ -1298,7 +1298,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } } Some(ast_map::NodeForeignItem(item)) => { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, ROOT_CODE_EXTENT) @@ -1306,7 +1306,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { _ => { bug!("ParameterEnvironment::from_item(): \ `{}` is not an item", - tcx.map.node_to_string(id)) + tcx.hir.node_to_string(id)) } } } @@ -1918,7 +1918,7 @@ impl BorrowKind { impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> { - self.item_tables(self.map.body_owner_def_id(body)) + self.item_tables(self.hir.body_owner_def_id(body)) } pub fn item_tables(self, def_id: DefId) -> &'gcx TypeckTables<'gcx> { @@ -1944,7 +1944,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn expr_span(self, id: NodeId) -> Span { - match self.map.find(id) { + match self.hir.find(id) { Some(ast_map::NodeExpr(e)) => { e.span } @@ -1958,7 +1958,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn local_var_name_str(self, id: NodeId) -> InternedString { - match self.map.find(id) { + match self.hir.find(id) { Some(ast_map::NodeLocal(pat)) => { match pat.node { hir::PatKind::Binding(_, _, ref path1, _) => path1.node.as_str(), @@ -2031,8 +2031,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity { - if let Some(id) = self.map.as_local_node_id(id) { - match self.map.expect_item(id).node { + if let Some(id) = self.hir.as_local_node_id(id) { + match self.hir.expect_item(id).node { hir::ItemImpl(_, polarity, ..) => polarity, ref item => bug!("trait_impl_polarity: {:?} not an impl", item) } @@ -2077,10 +2077,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // those tasks that just need to scan the names of items // and so forth. - let id = self.map.as_local_node_id(def_id).unwrap(); - let parent_id = self.map.get_parent(id); - let parent_def_id = self.map.local_def_id(parent_id); - let parent_item = self.map.expect_item(parent_id); + let id = self.hir.as_local_node_id(def_id).unwrap(); + let parent_id = self.hir.get_parent(id); + let parent_def_id = self.hir.local_def_id(parent_id); + let parent_item = self.hir.expect_item(parent_id); match parent_item.node { hir::ItemImpl(.., ref impl_trait_ref, _, ref impl_item_refs) => { for impl_item_ref in impl_item_refs { @@ -2115,7 +2115,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { parent_def_id: DefId, trait_item_ref: &hir::TraitItemRef) -> AssociatedItem { - let def_id = self.map.local_def_id(trait_item_ref.id.node_id); + let def_id = self.hir.local_def_id(trait_item_ref.id.node_id); let (kind, has_self) = match trait_item_ref.kind { hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false), hir::AssociatedItemKind::Method { has_self } => { @@ -2140,7 +2140,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { from_trait_impl: bool, impl_item_ref: &hir::ImplItemRef) -> AssociatedItem { - let def_id = self.map.local_def_id(impl_item_ref.id.node_id); + let def_id = self.hir.local_def_id(impl_item_ref.id.node_id); let (kind, has_self) = match impl_item_ref.kind { hir::AssociatedItemKind::Const => (ty::AssociatedKind::Const, false), hir::AssociatedItemKind::Method { has_self } => { @@ -2170,19 +2170,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { return Rc::new(self.sess.cstore.associated_item_def_ids(def_id)); } - let id = self.map.as_local_node_id(def_id).unwrap(); - let item = self.map.expect_item(id); + let id = self.hir.as_local_node_id(def_id).unwrap(); + let item = self.hir.expect_item(id); let vec: Vec<_> = match item.node { hir::ItemTrait(.., ref trait_item_refs) => { trait_item_refs.iter() .map(|trait_item_ref| trait_item_ref.id) - .map(|id| self.map.local_def_id(id.node_id)) + .map(|id| self.hir.local_def_id(id.node_id)) .collect() } hir::ItemImpl(.., ref impl_item_refs) => { impl_item_refs.iter() .map(|impl_item_ref| impl_item_ref.id) - .map(|id| self.map.local_def_id(id.node_id)) + .map(|id| self.hir.local_def_id(id.node_id)) .collect() } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") @@ -2227,7 +2227,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn def_key(self, id: DefId) -> ast_map::DefKey { if id.is_local() { - self.map.def_key(id) + self.hir.def_key(id) } else { self.sess.cstore.def_key(id) } @@ -2240,27 +2240,27 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // be a non-local `DefPath`. pub fn def_path(self, id: DefId) -> ast_map::DefPath { if id.is_local() { - self.map.def_path(id) + self.hir.def_path(id) } else { self.sess.cstore.def_path(id) } } pub fn def_span(self, def_id: DefId) -> Span { - if let Some(id) = self.map.as_local_node_id(def_id) { - self.map.span(id) + if let Some(id) = self.hir.as_local_node_id(def_id) { + self.hir.span(id) } else { self.sess.cstore.def_span(&self.sess, def_id) } } pub fn vis_is_accessible_from(self, vis: Visibility, block: NodeId) -> bool { - vis.is_accessible_from(self.map.local_def_id(self.map.get_module_parent(block)), self) + vis.is_accessible_from(self.hir.local_def_id(self.hir.get_module_parent(block)), self) } pub fn item_name(self, id: DefId) -> ast::Name { - if let Some(id) = self.map.as_local_node_id(id) { - self.map.name(id) + if let Some(id) = self.hir.as_local_node_id(id) { + self.hir.name(id) } else if id.index == CRATE_DEF_INDEX { self.sess.cstore.original_crate_name(id.krate) } else { @@ -2372,8 +2372,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Get the attributes of a definition. pub fn get_attrs(self, did: DefId) -> Cow<'gcx, [ast::Attribute]> { - if let Some(id) = self.map.as_local_node_id(did) { - Cow::Borrowed(self.map.attrs(id)) + if let Some(id) = self.hir.as_local_node_id(did) { + Cow::Borrowed(self.hir.attrs(id)) } else { Cow::Owned(self.sess.cstore.item_attrs(did)) } @@ -2656,8 +2656,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// with the name of the crate containing the impl. pub fn span_of_impl(self, impl_did: DefId) -> Result { if impl_did.is_local() { - let node_id = self.map.as_local_node_id(impl_did).unwrap(); - Ok(self.map.span(node_id)) + let node_id = self.hir.as_local_node_id(impl_did).unwrap(); + Ok(self.hir.span(node_id)) } else { Err(self.sess.cstore.crate_name(impl_did.krate)) } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 38b38e5b49764..e90e1a94be951 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -285,7 +285,7 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter, ty::BrEnv => { let name = Symbol::intern("'r"); let _ = write!(f, "{}", name); - ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), + ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID), name, ty::Issue32330::WontChange) } @@ -833,13 +833,13 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { let upvar_tys = substs.upvar_tys(did, tcx); write!(f, "[closure")?; - if let Some(node_id) = tcx.map.as_local_node_id(did) { - write!(f, "@{:?}", tcx.map.span(node_id))?; + if let Some(node_id) = tcx.hir.as_local_node_id(did) { + write!(f, "@{:?}", tcx.hir.span(node_id))?; let mut sep = " "; tcx.with_freevars(node_id, |freevars| { for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { let def_id = freevar.def.def_id(); - let node_id = tcx.map.as_local_node_id(def_id).unwrap(); + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); write!(f, "{}{}:{}", sep, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 0605644d497db..e3dec97472a48 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -460,7 +460,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // 3. Where does old loan expire. let previous_end_span = - self.tcx().map.span(old_loan.kill_scope.node_id(&self.tcx().region_maps)) + self.tcx().hir.span(old_loan.kill_scope.node_id(&self.tcx().region_maps)) .end_point(); let mut err = match (new_loan.kind, old_loan.kind) { @@ -704,7 +704,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { borrow_kind: ty::BorrowKind) -> UseError<'tcx> { debug!("analyze_restrictions_on_use(expr_id={}, use_path={:?})", - self.tcx().map.node_to_string(expr_id), + self.tcx().hir.node_to_string(expr_id), use_path); let mut ret = UseOk; diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index b0a1b3498545f..285f3ab9047c8 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -132,7 +132,7 @@ pub fn build_unfragmented_map(this: &mut borrowck::BorrowckCtxt, } let mut fraginfo_map = this.tcx.fragment_infos.borrow_mut(); - let fn_did = this.tcx.map.local_def_id(id); + let fn_did = this.tcx.hir.local_def_id(id); let prev = fraginfo_map.insert(fn_did, fragment_infos); assert!(prev.is_none()); } @@ -202,7 +202,7 @@ pub fn instrument_move_fragments<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::NodeId) { - let span_err = tcx.map.attrs(id).iter() + let span_err = tcx.hir.attrs(id).iter() .any(|a| a.check_name("rustc_move_fragments")); let print = tcx.sess.opts.debugging_opts.print_move_fragments; @@ -496,7 +496,7 @@ fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>, }, ref ty => { - let span = origin_id.map_or(DUMMY_SP, |id| tcx.map.span(id)); + let span = origin_id.map_or(DUMMY_SP, |id| tcx.hir.span(id)); span_bug!(span, "type {:?} ({:?}) is not fragmentable", parent_ty, ty); diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 7101d843b4ce3..7f7f73d9a9678 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -53,7 +53,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_error_collector: move_error::MoveErrorCollector::new(), }; - let body = glcx.bccx.tcx.map.body(body); + let body = glcx.bccx.tcx.hir.body(body); euv::ExprUseVisitor::new(&mut glcx, &infcx).consume_body(body); glcx.report_potential_errors(); @@ -553,6 +553,6 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, body: hir::Bo body_id: body }; - let body = sicx.bccx.tcx.map.body(body); + let body = sicx.bccx.tcx.hir.body(body); sicx.visit_body(body); } diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index c7bd5b7ed0461..372eb1d5d64f0 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -57,7 +57,7 @@ pub fn borrowck_mir(bcx: &mut BorrowckCtxt, id: ast::NodeId, attributes: &[ast::Attribute]) { let tcx = bcx.tcx; - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); debug!("borrowck_mir({}) UNIMPLEMENTED", tcx.item_path_str(def_id)); let mir = &tcx.item_mir(def_id); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index c0e038d183dad..3464f1fa89a27 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -64,7 +64,7 @@ pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, @@ -167,7 +167,7 @@ fn borrowck_fn<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, attributes: &[ast::Attribute]) { debug!("borrowck_fn(id={})", id); - let body = this.tcx.map.body(body_id); + let body = this.tcx.hir.body(body_id); if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) { this.with_temp_region_map(id, |this| { @@ -201,9 +201,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, { // Check the body of fn items. let tcx = this.tcx; - let body = tcx.map.body(body_id); + let body = tcx.hir.body(body_id); let id_range = { - let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.map); + let mut visitor = intravisit::IdRangeComputingVisitor::new(&tcx.hir); visitor.visit_body(body); visitor.result() }; @@ -398,7 +398,7 @@ pub enum LoanPathElem<'tcx> { pub fn closure_to_block(closure_id: ast::NodeId, tcx: TyCtxt) -> ast::NodeId { - match tcx.map.get(closure_id) { + match tcx.hir.get(closure_id) { hir_map::NodeExpr(expr) => match expr.node { hir::ExprClosure(.., body_id, _) => { body_id.node_id @@ -685,10 +685,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { move_data::MoveExpr | move_data::MovePat => - (self.tcx.map.span(the_move.id), ""), + (self.tcx.hir.span(the_move.id), ""), move_data::Captured => - (match self.tcx.map.expect_expr(the_move.id).node { + (match self.tcx.hir.expect_expr(the_move.id).node { hir::ExprClosure(.., fn_decl_span) => fn_decl_span, ref r => bug!("Captured({}) maps to non-closure: {:?}", the_move.id, r), @@ -882,10 +882,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { // happen for nested closures, so we know the enclosing // closure incorrectly accepts an `Fn` while it needs to // be `FnMut`. - span_help!(&mut err, self.tcx.map.span(id), + span_help!(&mut err, self.tcx.hir.span(id), "consider changing this to accept closures that implement `FnMut`"); } else { - span_help!(&mut err, self.tcx.map.span(id), + span_help!(&mut err, self.tcx.hir.span(id), "consider changing this closure to take self by mutable reference"); } err @@ -948,7 +948,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { fn region_end_span(&self, region: &'tcx ty::Region) -> Option { match *region { ty::ReScope(scope) => { - match scope.span(&self.tcx.region_maps, &self.tcx.map) { + match scope.span(&self.tcx.region_maps, &self.tcx.hir) { Some(s) => { Some(s.end_point()) } @@ -1097,7 +1097,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { _ => bug!() }; if kind == ty::ClosureKind::Fn { - db.span_help(self.tcx.map.span(upvar_id.closure_expr_id), + db.span_help(self.tcx.hir.span(upvar_id.closure_expr_id), "consider changing this closure to take \ self by mutable reference"); } @@ -1105,10 +1105,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { _ => { if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat { if let Categorization::Local(local_id) = inner_cmt.cat { - let parent = self.tcx.map.get_parent_node(local_id); + let parent = self.tcx.hir.get_parent_node(local_id); - if let Some(fn_like) = FnLikeNode::from_node(self.tcx.map.get(parent)) { - if let Some(i) = self.tcx.map.body(fn_like.body()).arguments.iter() + if let Some(fn_like) = FnLikeNode::from_node(self.tcx.hir.get(parent)) { + if let Some(i) = self.tcx.hir.body(fn_like.body()).arguments.iter() .position(|arg| arg.pat.id == local_id) { let arg_ty = &fn_like.decl().inputs[i]; if let hir::TyRptr( @@ -1141,7 +1141,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } } else if let Categorization::Local(local_id) = err.cmt.cat { - let span = self.tcx.map.span(local_id); + let span = self.tcx.hir.span(local_id); if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) { if snippet.starts_with("ref mut ") || snippet.starts_with("&mut ") { db.span_label(*error_span, &format!("cannot reborrow mutably")); @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { fn statement_scope_span(tcx: TyCtxt, region: &ty::Region) -> Option { match *region { ty::ReScope(scope) => { - match tcx.map.find(scope.node_id(&tcx.region_maps)) { + match tcx.hir.find(scope.node_id(&tcx.region_maps)) { Some(hir_map::NodeStmt(stmt)) => Some(stmt.span), _ => None } @@ -1302,11 +1302,11 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.kind { LpVar(id) => { - write!(f, "$({})", ty::tls::with(|tcx| tcx.map.node_to_string(id))) + write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_string(id))) } LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => { - let s = ty::tls::with(|tcx| tcx.map.node_to_string(var_id)); + let s = ty::tls::with(|tcx| tcx.hir.node_to_string(var_id)); write!(f, "$({} captured by id={})", s, closure_expr_id) } @@ -1334,11 +1334,11 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.kind { LpVar(id) => { - write!(f, "$({})", ty::tls::with(|tcx| tcx.map.node_to_user_string(id))) + write!(f, "$({})", ty::tls::with(|tcx| tcx.hir.node_to_user_string(id))) } LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => { - let s = ty::tls::with(|tcx| tcx.map.node_to_user_string(var_id)); + let s = ty::tls::with(|tcx| tcx.hir.node_to_user_string(var_id)); write!(f, "$({} captured by closure)", s) } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index a6452a3f0310a..0b1f2465a4d59 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -42,7 +42,7 @@ struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, @@ -53,7 +53,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { tcx: self.tcx, tables: self.tcx.body_tables(b), param_env: &ty::ParameterEnvironment::for_item(self.tcx, id) - }.visit_body(self.tcx.map.body(b)); + }.visit_body(self.tcx.hir.body(b)); } } @@ -152,7 +152,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { } } - let module = self.tcx.map.local_def_id(self.tcx.map.get_module_parent(scrut.id)); + let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id)); MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| { let mut have_errors = false; @@ -195,7 +195,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { "local binding" }; - let module = self.tcx.map.local_def_id(self.tcx.map.get_module_parent(pat.id)); + let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(pat.id)); MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| { let mut patcx = PatternContext::new(self.tcx, self.tables); let pattern = patcx.lower_pattern(pat); diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 2325c37bc4050..e8055602087e5 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -53,15 +53,15 @@ macro_rules! math { fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, variant_def: DefId) -> Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>)> { - if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) { - let enum_node_id = tcx.map.get_parent(variant_node_id); - if let Some(ast_map::NodeItem(it)) = tcx.map.find(enum_node_id) { + if let Some(variant_node_id) = tcx.hir.as_local_node_id(variant_def) { + let enum_node_id = tcx.hir.get_parent(variant_node_id); + if let Some(ast_map::NodeItem(it)) = tcx.hir.find(enum_node_id) { if let hir::ItemEnum(ref edef, _) = it.node { for variant in &edef.variants { if variant.node.data.id() == variant_node_id { return variant.node.disr_expr.map(|e| { - let def_id = tcx.map.body_owner_def_id(e); - (&tcx.map.body(e).value, + let def_id = tcx.hir.body_owner_def_id(e); + (&tcx.hir.body(e).value, tcx.tables.borrow().get(&def_id).cloned()) }); } @@ -83,8 +83,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>, Option>)> { - if let Some(node_id) = tcx.map.as_local_node_id(def_id) { - match tcx.map.find(node_id) { + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + match tcx.hir.find(node_id) { None => None, Some(ast_map::NodeItem(&hir::Item { node: hir::ItemConst(ref ty, body), .. @@ -92,7 +92,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(ast_map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Const(ref ty, body), .. })) => { - Some((&tcx.map.body(body).value, + Some((&tcx.hir.body(body).value, tcx.tables.borrow().get(&def_id).cloned(), tcx.ast_ty_to_prim_ty(ty))) } @@ -102,10 +102,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // If we have a trait item and the substitutions for it, // `resolve_trait_associated_const` will select an impl // or the default. - let trait_id = tcx.map.get_parent(node_id); - let trait_id = tcx.map.local_def_id(trait_id); + let trait_id = tcx.hir.get_parent(node_id); + let trait_id = tcx.hir.local_def_id(trait_id); let default_value = default.map(|body| { - (&tcx.map.body(body).value, + (&tcx.hir.body(body).value, tcx.tables.borrow().get(&def_id).cloned(), tcx.ast_ty_to_prim_ty(ty)) }); @@ -156,10 +156,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn lookup_const_fn_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<(&'tcx hir::Body, Option<&'a ty::TypeckTables<'tcx>>)> { - if let Some(node_id) = tcx.map.as_local_node_id(def_id) { - FnLikeNode::from_node(tcx.map.get(node_id)).and_then(|fn_like| { + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + FnLikeNode::from_node(tcx.hir.get(node_id)).and_then(|fn_like| { if fn_like.constness() == hir::Constness::Const { - Some((tcx.map.body(fn_like.body()), + Some((tcx.hir.body(fn_like.body()), tcx.tables.borrow().get(&def_id).cloned())) } else { None @@ -232,7 +232,7 @@ pub struct ConstContext<'a, 'tcx: 'a> { impl<'a, 'tcx> ConstContext<'a, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: hir::BodyId) -> Self { - let def_id = tcx.map.body_owner_def_id(body); + let def_id = tcx.hir.body_owner_def_id(body); ConstContext { tcx: tcx, tables: tcx.tables.borrow().get(&def_id).cloned(), @@ -808,7 +808,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, _ => bug!() } } else { - let n = &tcx.map.body(count).value; + let n = &tcx.hir.body(count).value; match ConstContext::new(tcx, count).eval(n, len_hint)? { Integral(Usize(i)) => i.as_u64(tcx.sess.target.uint_type), Integral(_) => signal!(e, RepeatCountNotNatural), @@ -1203,7 +1203,7 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Result { let hint = UncheckedExprHint(tcx.types.usize); - let count_expr = &tcx.map.body(count).value; + let count_expr = &tcx.hir.body(count).value; match ConstContext::new(tcx, count).eval(count_expr, hint) { Ok(Integral(Usize(count))) => { let val = count.as_u64(tcx.sess.target.uint_type); @@ -1227,7 +1227,7 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node { if let Def::Local(..) = path.def { diag.note(&format!("`{}` is a variable", - tcx.map.node_to_pretty_string(count_expr.id))); + tcx.hir.node_to_pretty_string(count_expr.id))); } } diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 24c795befa3c8..a3b80ebddcf00 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -360,7 +360,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } PatKind::Binding(bm, def_id, ref ident, ref sub) => { - let id = self.tcx.map.as_local_node_id(def_id).unwrap(); + let id = self.tcx.hir.as_local_node_id(def_id).unwrap(); let var_ty = self.tables.node_id_to_type(pat.id); let region = match var_ty.sty { ty::TyRef(r, _) => Some(r), diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 83dec4b0b77ab..1991fbb58edf1 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -181,7 +181,7 @@ pub fn compile_input(sess: &Session, outdir, output, opt_crate, - tcx.map.krate(), + tcx.hir.krate(), &analysis, tcx, &crate_name); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index c5e0e8fb45f64..1885f76f1e4cd 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -502,7 +502,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { } fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> { - Some(&self.tcx.map) + Some(&self.tcx.hir) } fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { @@ -521,7 +521,7 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { if let pprust_hir::Nested::Body(id) = nested { self.tables.set(self.tcx.body_tables(id)); } - pprust_hir::PpAnn::nested(&self.tcx.map, state, nested)?; + pprust_hir::PpAnn::nested(&self.tcx.hir, state, nested)?; self.tables.set(old_tables); Ok(()) } @@ -739,13 +739,13 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, let cfg = match code { blocks::Code::Expr(expr) => cfg::CFG::new(tcx, expr), blocks::Code::FnLike(fn_like) => { - let body = tcx.map.body(fn_like.body()); + let body = tcx.hir.body(fn_like.body()); cfg::CFG::new(tcx, &body.value) }, }; let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges; let lcfg = LabelledCFG { - ast_map: &tcx.map, + ast_map: &tcx.hir, cfg: &cfg, name: format!("node_{}", code.id()), labelled_edges: labelled_edges, @@ -1005,7 +1005,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, match ppm { PpmMir | PpmMirCFG => { if let Some(nodeid) = nodeid { - let def_id = tcx.map.local_def_id(nodeid); + let def_id = tcx.hir.local_def_id(nodeid); match ppm { PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out), PpmMirCFG => write_mir_graphviz(tcx, iter::once(def_id), &mut out), @@ -1030,11 +1030,11 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, let nodeid = nodeid.expect("`pretty flowgraph=..` needs NodeId (int) or unique path \ suffix (b::c::d)"); - let node = tcx.map.find(nodeid).unwrap_or_else(|| { + let node = tcx.hir.find(nodeid).unwrap_or_else(|| { tcx.sess.fatal(&format!("--pretty flowgraph couldn't find id: {}", nodeid)) }); - match blocks::Code::from_node(&tcx.map, nodeid) { + match blocks::Code::from_node(&tcx.hir, nodeid) { Some(code) => { let variants = gather_flowgraph_variants(tcx.sess); @@ -1047,7 +1047,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, got {:?}", node); - tcx.sess.span_fatal(tcx.map.span(nodeid), &message) + tcx.sess.span_fatal(tcx.hir.span(nodeid), &message) } } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 4ce5f96f171ed..0ac95d12eeef3 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -197,7 +197,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now pub fn lookup_item(&self, names: &[String]) -> ast::NodeId { - return match search_mod(self, &self.infcx.tcx.map.krate().module, 0, names) { + return match search_mod(self, &self.infcx.tcx.hir.krate().module, 0, names) { Some(id) => id, None => { panic!("no item found: `{}`", names.join("::")); @@ -211,7 +211,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { -> Option { assert!(idx < names.len()); for item in &m.item_ids { - let item = this.infcx.tcx.map.expect_item(item.id); + let item = this.infcx.tcx.hir.expect_item(item.id); if item.name.to_string() == names[idx] { return search(this, item, idx + 1, names); } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index b5fe158f158ca..287ee7dd13e4e 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -79,8 +79,8 @@ pub fn assert_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut visitor = IfThisChanged { tcx: tcx, if_this_changed: vec![], then_this_would_need: vec![] }; - visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.map.krate().attrs); - tcx.map.krate().visit_all_item_likes(&mut visitor); + visitor.process_attrs(ast::CRATE_NODE_ID, &tcx.hir.krate().attrs); + tcx.hir.krate().visit_all_item_likes(&mut visitor); (visitor.if_this_changed, visitor.then_this_would_need) }; @@ -120,7 +120,7 @@ impl<'a, 'tcx> IfThisChanged<'a, 'tcx> { } fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) { - let def_id = self.tcx.map.local_def_id(node_id); + let def_id = self.tcx.hir.local_def_id(node_id); for attr in attrs { if attr.check_name(ATTR_IF_THIS_CHANGED) { let dep_node_interned = self.argument(attr); diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 49609fbc7984f..b9e6426dc01d8 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -102,7 +102,7 @@ impl<'a> ::std::ops::Index<&'a DepNode> for IncrementalHashesMap { pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> IncrementalHashesMap { let _ignore = tcx.dep_graph.in_ignore(); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); let hash_spans = tcx.sess.opts.debuginfo != NoDebugInfo; let mut visitor = HashItemsVisitor { tcx: tcx, @@ -141,7 +141,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { fn calculate_node_id(&mut self, id: ast::NodeId, walk_op: W) where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>) { - let def_id = self.tcx.map.local_def_id(id); + let def_id = self.tcx.hir.local_def_id(id); self.calculate_def_id(def_id, walk_op) } @@ -178,7 +178,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> { } fn compute_crate_hash(&mut self) { - let krate = self.tcx.map.krate(); + let krate = self.tcx.hir.krate(); let mut crate_state = IchHasher::new(); diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 3427a42526181..69237f406760d 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -561,7 +561,7 @@ macro_rules! hash_span { impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> visit::NestedVisitorMap<'this, 'tcx> { if self.hash_bodies { - visit::NestedVisitorMap::OnlyBodies(&self.tcx.map) + visit::NestedVisitorMap::OnlyBodies(&self.tcx.hir) } else { visit::NestedVisitorMap::None } diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 4cefc16efe5ab..6e66dac6470f0 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -72,7 +72,7 @@ pub fn check_dirty_clean_annotations<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .collect(); let query = tcx.dep_graph.query(); debug!("query-nodes: {:?}", query.nodes()); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); krate.visit_all_item_likes(&mut DirtyCleanVisitor { tcx: tcx, query: &query, @@ -171,7 +171,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> { impl<'a, 'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); for attr in self.tcx.get_attrs(def_id).iter() { if attr.check_name(ATTR_DIRTY) { if check_config(self.tcx, attr) { @@ -200,7 +200,7 @@ pub fn check_dirty_clean_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } tcx.dep_graph.with_ignore(||{ - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); krate.visit_all_item_likes(&mut DirtyCleanMetadataVisitor { tcx: tcx, prev_metadata_hashes: prev_metadata_hashes, @@ -217,7 +217,7 @@ pub struct DirtyCleanMetadataVisitor<'a, 'tcx:'a, 'm> { impl<'a, 'tcx, 'm> ItemLikeVisitor<'tcx> for DirtyCleanMetadataVisitor<'a, 'tcx, 'm> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); for attr in self.tcx.get_attrs(def_id).iter() { if attr.check_name(ATTR_DIRTY_METADATA) { diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 2baef47c214c2..d4ab31da8a31e 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -28,7 +28,7 @@ pub enum MethodLateContext { } pub fn method_context(cx: &LateContext, id: ast::NodeId, span: Span) -> MethodLateContext { - let def_id = cx.tcx.map.local_def_id(id); + let def_id = cx.tcx.hir.local_def_id(id); match cx.tcx.associated_items.borrow().get(&def_id) { None => span_bug!(span, "missing method descriptor?!"), Some(item) => { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 8d86e7e2e8b9e..2892d61b8bd6f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -117,7 +117,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => { - let def_id = cx.tcx.map.local_def_id(it.id); + let def_id = cx.tcx.hir.local_def_id(it.id); self.check_heap_type(cx, it.span, cx.tcx.item_type(def_id)) } _ => () @@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { hir::ItemStruct(ref struct_def, _) | hir::ItemUnion(ref struct_def, _) => { for struct_field in struct_def.fields() { - let def_id = cx.tcx.map.local_def_id(struct_field.id); + let def_id = cx.tcx.hir.local_def_id(struct_field.id); self.check_heap_type(cx, struct_field.span, cx.tcx.item_type(def_id)); } @@ -390,8 +390,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { // If the trait is private, add the impl items to private_traits so they don't get // reported for missing docs. let real_trait = trait_ref.path.def.def_id(); - if let Some(node_id) = cx.tcx.map.as_local_node_id(real_trait) { - match cx.tcx.map.find(node_id) { + if let Some(node_id) = cx.tcx.hir.as_local_node_id(real_trait) { + match cx.tcx.hir.find(node_id) { Some(hir_map::NodeItem(item)) => { if item.vis == hir::Visibility::Inherited { for impl_item_ref in impl_item_refs { @@ -504,21 +504,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { if ast_generics.is_parameterized() { return; } - let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); + let def = cx.tcx.lookup_adt_def(cx.tcx.hir.local_def_id(item.id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } hir::ItemUnion(_, ref ast_generics) => { if ast_generics.is_parameterized() { return; } - let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); + let def = cx.tcx.lookup_adt_def(cx.tcx.hir.local_def_id(item.id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } hir::ItemEnum(_, ref ast_generics) => { if ast_generics.is_parameterized() { return; } - let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); + let def = cx.tcx.lookup_adt_def(cx.tcx.hir.local_def_id(item.id)); (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) } _ => return, @@ -586,7 +586,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { let mut impls = NodeSet(); debug_def.for_each_impl(cx.tcx, |d| { if let Some(ty_def) = cx.tcx.item_type(d).ty_to_def_id() { - if let Some(node_id) = cx.tcx.map.as_local_node_id(ty_def) { + if let Some(node_id) = cx.tcx.hir.as_local_node_id(ty_def) { impls.insert(node_id); } } @@ -680,7 +680,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { let method = match fn_kind { FnKind::ItemFn(..) => None, FnKind::Method(..) => { - Some(cx.tcx.associated_item(cx.tcx.map.local_def_id(id))) + Some(cx.tcx.associated_item(cx.tcx.hir.local_def_id(id))) } // closures can't recur, so they don't matter. FnKind::Closure(_) => return, @@ -745,7 +745,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { false }; if self_recursive { - self_call_spans.push(cx.tcx.map.span(node_id)); + self_call_spans.push(cx.tcx.hir.span(node_id)); // this is a self call, so we shouldn't explore past // this node in the CFG. continue; @@ -788,14 +788,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { // represents a call to the function `fn_id`/method `method`. fn expr_refers_to_this_fn(cx: &LateContext, fn_id: ast::NodeId, id: ast::NodeId) -> bool { - match cx.tcx.map.get(id) { + match cx.tcx.hir.get(id) { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { let def = if let hir::ExprPath(ref qpath) = callee.node { cx.tables.qpath_def(qpath, callee.id) } else { return false; }; - def.def_id() == cx.tcx.map.local_def_id(fn_id) + def.def_id() == cx.tcx.hir.local_def_id(fn_id) } _ => false, } @@ -830,7 +830,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { } // Check for calls to methods via explicit paths (e.g. `T::method()`). - match cx.tcx.map.get(id) { + match cx.tcx.hir.get(id) { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { let def = if let hir::ExprPath(ref qpath) = callee.node { cx.tables.qpath_def(qpath, callee.id) @@ -871,7 +871,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { ty::TraitContainer(trait_def_id) => { let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, callee_substs); let trait_ref = ty::Binder(trait_ref); - let span = tcx.map.span(expr_id); + let span = tcx.hir.span(expr_id); let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, expr_id), trait_ref.to_poly_trait_predicate()); @@ -879,7 +879,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { // unwrap() is ok here b/c `method` is the method // defined in this crate whose body we are // checking, so it's always local - let node_id = tcx.map.as_local_node_id(method.def_id).unwrap(); + let node_id = tcx.hir.as_local_node_id(method.def_id).unwrap(); let param_env = ty::ParameterEnvironment::for_item(tcx, node_id); tcx.infer_ctxt(param_env, Reveal::NotSpecializable).enter(|infcx| { @@ -1151,7 +1151,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields { if let hir::ItemUnion(ref vdata, _) = item.node { let param_env = &ty::ParameterEnvironment::for_item(ctx.tcx, item.id); for field in vdata.fields() { - let field_ty = ctx.tcx.item_type(ctx.tcx.map.local_def_id(field.id)); + let field_ty = ctx.tcx.item_type(ctx.tcx.hir.local_def_id(field.id)); if ctx.tcx.type_needs_drop_given_env(field_ty, param_env) { ctx.span_lint(UNIONS_WITH_DROP_FIELDS, field.span, diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 2a77e9a4a7c8b..532e602226450 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -631,7 +631,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) { - let def_id = self.cx.tcx.map.local_def_id(id); + let def_id = self.cx.tcx.hir.local_def_id(id); let sig = self.cx.tcx.item_type(def_id).fn_sig(); let sig = self.cx.tcx.erase_late_bound_regions(&sig); @@ -648,7 +648,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } fn check_foreign_static(&mut self, id: ast::NodeId, span: Span) { - let def_id = self.cx.tcx.map.local_def_id(id); + let def_id = self.cx.tcx.hir.local_def_id(id); let ty = self.cx.tcx.item_type(def_id); self.check_type_for_ffi_and_report_errors(span, ty); } @@ -696,7 +696,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { if let hir::ItemEnum(ref enum_definition, ref gens) = it.node { if gens.ty_params.is_empty() { // sizes only make sense for non-generic types - let t = cx.tcx.item_type(cx.tcx.map.local_def_id(it.id)); + let t = cx.tcx.item_type(cx.tcx.hir.local_def_id(it.id)); let layout = cx.tcx.infer_ctxt((), Reveal::All).enter(|infcx| { let ty = cx.tcx.erase_regions(&t); ty.layout(&infcx).unwrap_or_else(|e| { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 48d9f5e72c26d..a85b47c8ada7a 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -64,7 +64,7 @@ impl UnusedMut { for (_, v) in &mutables { if !v.iter().any(|e| used_mutables.contains(e)) { cx.span_lint(UNUSED_MUT, - cx.tcx.map.span(v[0]), + cx.tcx.hir.span(v[0]), "variable does not need to be mutable"); } } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ef7bb80312eb5..459132eb9c613 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -28,7 +28,7 @@ pub struct Ast<'tcx> { impl<'a, 'tcx> EncodeContext<'a, 'tcx> { pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy> { - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); let lazy_body = self.lazy(body); let tables = self.tcx.body_tables(body_id); @@ -67,7 +67,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedBodyEncodingVisitor<'a, 'b, 'tcx> { } fn visit_nested_body(&mut self, body: hir::BodyId) { - let body = self.ecx.tcx.map.body(body); + let body = self.ecx.tcx.hir.body(body); body.encode(self.ecx).unwrap(); self.count += 1; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index f6107bc135915..d100cb53a8b01 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -428,7 +428,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { def_id: DefId) -> Option<&'tcx hir::Body> { - if let Some(cached) = tcx.map.get_inlined_body(def_id) { + if let Some(cached) = tcx.hir.get_inlined_body(def_id) { return Some(cached); } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 4abdee345c298..101531b52afb8 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -776,7 +776,7 @@ impl<'a, 'tcx> CrateMetadata { tcx.tables.borrow_mut().insert(def_id, tcx.alloc_tables(tables)); let body = ast.body.decode((self, tcx)); - tcx.map.intern_inlined_body(def_id, body) + tcx.hir.intern_inlined_body(def_id, body) }) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7de768b7b9049..2f71776ecf758 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -267,8 +267,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { struct_ctor: None, }; - let enum_id = tcx.map.as_local_node_id(enum_did).unwrap(); - let enum_vis = &tcx.map.expect_item(enum_id).vis; + let enum_id = tcx.hir.as_local_node_id(enum_did).unwrap(); + let enum_vis = &tcx.hir.expect_item(enum_id).vis; Entry { kind: EntryKind::Variant(self.lazy(&data)), @@ -299,7 +299,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { &hir::Visibility)>) -> Entry<'tcx> { let tcx = self.tcx; - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); let data = ModData { reexports: match self.reexports.get(&id) { @@ -314,7 +314,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { span: self.lazy(&md.inner), attributes: self.encode_attributes(attrs), children: self.lazy_seq(md.item_ids.iter().map(|item_id| { - tcx.map.local_def_id(item_id.id).index + tcx.hir.local_def_id(item_id.id).index })), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), @@ -361,8 +361,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let field = &variant.fields[field_index]; let def_id = field.did; - let variant_id = tcx.map.as_local_node_id(variant.did).unwrap(); - let variant_data = tcx.map.expect_variant_data(variant_id); + let variant_id = tcx.hir.as_local_node_id(variant.did).unwrap(); + let variant_data = tcx.hir.expect_variant_data(variant_id); Entry { kind: EntryKind::Field, @@ -394,8 +394,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { struct_ctor: Some(def_id.index), }; - let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap(); - let struct_vis = &tcx.map.expect_item(struct_id).vis; + let struct_id = tcx.hir.as_local_node_id(adt_def_id).unwrap(); + let struct_vis = &tcx.hir.expect_item(struct_id).vis; Entry { kind: EntryKind::Struct(self.lazy(&data)), @@ -430,8 +430,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> { let tcx = self.tcx; - let node_id = tcx.map.as_local_node_id(def_id).unwrap(); - let ast_item = tcx.map.expect_trait_item(node_id); + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let ast_item = tcx.hir.expect_trait_item(node_id); let trait_item = tcx.associated_item(def_id); let container = match trait_item.defaultness { @@ -508,8 +508,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { - let node_id = self.tcx.map.as_local_node_id(def_id).unwrap(); - let ast_item = self.tcx.map.expect_impl_item(node_id); + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let ast_item = self.tcx.hir.expect_impl_item(node_id); let impl_item = self.tcx.associated_item(def_id); let container = match impl_item.defaultness { @@ -576,7 +576,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId) -> LazySeq { let _ignore = self.tcx.dep_graph.in_ignore(); - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); self.lazy_seq(body.arguments.iter().map(|arg| { match arg.pat.node { PatKind::Binding(_, _, name, _) => name.node, @@ -646,7 +646,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // for methods, write all the stuff get_trait_method // needs to know let struct_ctor = if !struct_def.is_struct() { - Some(tcx.map.local_def_id(struct_def.id()).index) + Some(tcx.hir.local_def_id(struct_def.id()).index) } else { None }; @@ -725,7 +725,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemForeignMod(ref fm) => { self.lazy_seq(fm.items .iter() - .map(|foreign_item| tcx.map.local_def_id(foreign_item.id).index)) + .map(|foreign_item| tcx.hir.local_def_id(foreign_item.id).index)) } hir::ItemEnum(..) => { let def = self.tcx.lookup_adt_def(def_id); @@ -855,7 +855,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { /// so it's easier to do that here then to wait until we would encounter /// normally in the visitor walk. fn encode_addl_info_for_item(&mut self, item: &hir::Item) { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); match item.node { hir::ItemStatic(..) | hir::ItemConst(..) | @@ -883,7 +883,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { // If the struct has a constructor, encode it. if !struct_def.is_struct() { - let ctor_def_id = self.tcx.map.local_def_id(struct_def.id()); + let ctor_def_id = self.tcx.hir.local_def_id(struct_def.id()); self.record(ctor_def_id, EncodeContext::encode_struct_ctor, (def_id, ctor_def_id)); @@ -957,7 +957,7 @@ struct EncodeVisitor<'a, 'b: 'a, 'tcx: 'b> { impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.index.tcx.map) + NestedVisitorMap::OnlyBodies(&self.index.tcx.hir) } fn visit_expr(&mut self, ex: &'tcx hir::Expr) { intravisit::walk_expr(self, ex); @@ -965,7 +965,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item) { intravisit::walk_item(self, item); - let def_id = self.index.tcx.map.local_def_id(item.id); + let def_id = self.index.tcx.hir.local_def_id(item.id); match item.node { hir::ItemExternCrate(_) | hir::ItemUse(..) => (), // ignore these @@ -975,7 +975,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - let def_id = self.index.tcx.map.local_def_id(ni.id); + let def_id = self.index.tcx.hir.local_def_id(ni.id); self.index.record(def_id, EncodeContext::encode_info_for_foreign_item, (def_id, ni)); @@ -985,7 +985,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { self.index.encode_info_for_ty(ty); } fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) { - let def_id = self.index.tcx.map.local_def_id(macro_def.id); + let def_id = self.index.tcx.hir.local_def_id(macro_def.id); self.index.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def); } } @@ -993,7 +993,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_ty(&mut self, ty: &hir::Ty) { if let hir::TyImplTrait(_) = ty.node { - let def_id = self.tcx.map.local_def_id(ty.id); + let def_id = self.tcx.hir.local_def_id(ty.id); self.record(def_id, EncodeContext::encode_info_for_anon_ty, def_id); } } @@ -1001,7 +1001,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_info_for_expr(&mut self, expr: &hir::Expr) { match expr.node { hir::ExprClosure(..) => { - let def_id = self.tcx.map.local_def_id(expr.id); + let def_id = self.tcx.hir.local_def_id(expr.id); self.record(def_id, EncodeContext::encode_info_for_closure, def_id); } _ => {} @@ -1061,7 +1061,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_info_for_items(&mut self) -> Index { - let krate = self.tcx.map.krate(); + let krate = self.tcx.hir.krate(); let mut index = IndexBuilder::new(self); index.record(DefId::local(CRATE_DEF_INDEX), EncodeContext::encode_info_for_mod, @@ -1145,7 +1145,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } fn encode_def_path_table(&mut self) -> Lazy { - let definitions = self.tcx.map.definitions(); + let definitions = self.tcx.hir.definitions(); self.lazy(definitions.def_path_table()) } } @@ -1158,7 +1158,7 @@ struct ImplVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { if let hir::ItemImpl(..) = item.node { - let impl_id = self.tcx.map.local_def_id(item.id); + let impl_id = self.tcx.hir.local_def_id(item.id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { self.impls .entry(trait_ref.def_id) @@ -1182,7 +1182,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { tcx: self.tcx, impls: FxHashMap(), }; - self.tcx.map.krate().visit_all_item_likes(&mut visitor); + self.tcx.hir.krate().visit_all_item_likes(&mut visitor); let all_impls: Vec<_> = visitor.impls .into_iter() @@ -1206,7 +1206,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_exported_symbols(&mut self) -> LazySeq { let exported_symbols = self.exported_symbols; let tcx = self.tcx; - self.lazy_seq(exported_symbols.iter().map(|&id| tcx.map.local_def_id(id).index)) + self.lazy_seq(exported_symbols.iter().map(|&id| tcx.hir.local_def_id(id).index)) } fn encode_dylib_dependency_formats(&mut self) -> LazySeq> { @@ -1283,10 +1283,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { plugin_registrar_fn: tcx.sess .plugin_registrar_fn .get() - .map(|id| tcx.map.local_def_id(id).index), + .map(|id| tcx.hir.local_def_id(id).index), macro_derive_registrar: if is_proc_macro { let id = tcx.sess.derive_registrar_fn.get().unwrap(); - Some(tcx.map.local_def_id(id).index) + Some(tcx.hir.local_def_id(id).index) } else { None }, diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index 1a74a92545477..2359c747d888d 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -90,7 +90,7 @@ impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self { IndexBuilder { - items: Index::new(ecx.tcx.map.num_local_def_ids()), + items: Index::new(ecx.tcx.hir.num_local_def_ids()), ecx: ecx, } } @@ -186,7 +186,7 @@ macro_rules! read_hir { ($t:ty) => { impl<'tcx> DepGraphRead for &'tcx $t { fn read(&self, tcx: TyCtxt) { - tcx.map.read(self.id); + tcx.hir.read(self.id); } } } @@ -220,6 +220,6 @@ pub struct FromId(pub ast::NodeId, pub T); impl DepGraphRead for FromId { fn read(&self, tcx: TyCtxt) { - tcx.map.read(self.0); + tcx.hir.read(self.0); } } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 2c7b47c766999..73d3875ba2384 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -58,7 +58,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let_extent_stack.push(remainder_scope); // Declare the bindings, which may create a visibility scope. - let remainder_span = remainder_scope.span(&tcx.region_maps, &tcx.map); + let remainder_span = remainder_scope.span(&tcx.region_maps, &tcx.hir); let remainder_span = remainder_span.unwrap_or(span); let scope = this.declare_bindings(None, remainder_span, &pattern); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 7347841a5f1ef..ecdc58ba55d6c 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -133,7 +133,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let arguments: Vec<_> = arguments.collect(); let tcx = hir.tcx(); - let span = tcx.map.span(fn_id); + let span = tcx.hir.span(fn_id); let mut builder = Builder::new(hir, span, arguments.len(), return_ty); let call_site_extent = @@ -168,7 +168,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, // Gather the upvars of a closure, if any. let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| { freevars.iter().map(|fv| { - let var_id = tcx.map.as_local_node_id(fv.def.def_id()).unwrap(); + let var_id = tcx.hir.as_local_node_id(fv.def.def_id()).unwrap(); let by_ref = hir.tables().upvar_capture(ty::UpvarId { var_id: var_id, closure_expr_id: fn_id @@ -180,7 +180,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, debug_name: keywords::Invalid.name(), by_ref: by_ref }; - if let Some(hir::map::NodeLocal(pat)) = tcx.map.find(var_id) { + if let Some(hir::map::NodeLocal(pat)) = tcx.hir.find(var_id) { if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node { decl.debug_name = ident.node; } @@ -198,9 +198,9 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, body_id: hir::BodyId) -> Mir<'tcx> { let tcx = hir.tcx(); - let ast_expr = &tcx.map.body(body_id).value; + let ast_expr = &tcx.hir.body(body_id).value; let ty = hir.tables().expr_ty_adjusted(ast_expr); - let span = tcx.map.span(tcx.map.body_owner(body_id)); + let span = tcx.hir.span(tcx.hir.body_owner(body_id)); let mut builder = Builder::new(hir, span, 0, ty); let extent = tcx.region_maps.temporary_scope(ast_expr.id) diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 59a11782e0856..c702a142fab34 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { scope.needs_cleanup = true; } let tcx = self.hir.tcx(); - let extent_span = extent.span(&tcx.region_maps, &tcx.map).unwrap(); + let extent_span = extent.span(&tcx.region_maps, &tcx.hir).unwrap(); // Attribute scope exit drops to scope's closing brace let scope_end = Span { lo: extent_span.hi, .. extent_span}; scope.drops.push(DropData { diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs index dd4dd4699d858..91600b947c610 100644 --- a/src/librustc_mir/graphviz.rs +++ b/src/librustc_mir/graphviz.rs @@ -26,7 +26,7 @@ pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, where W: Write, I: Iterator { for def_id in iter { - let nodeid = tcx.map.as_local_node_id(def_id).unwrap(); + let nodeid = tcx.hir.as_local_node_id(def_id).unwrap(); let mir = &tcx.item_mir(def_id); writeln!(w, "digraph Mir_{} {{", nodeid)?; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index cdf7cae3020c8..c4c6ec6b8f400 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -574,7 +574,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Now comes the rote stuff: hir::ExprRepeat(ref v, count) => { let tcx = cx.tcx.global_tcx(); - let c = &cx.tcx.map.body(count).value; + let c = &cx.tcx.hir.body(count).value; let count = match ConstContext::new(tcx, count).eval(c, EvalHint::ExprTypeChecked) { Ok(ConstVal::Integral(ConstInt::Usize(u))) => u, Ok(other) => bug!("constant evaluation of repeat count yielded {:?}", other), @@ -765,19 +765,19 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, match def { Def::Local(def_id) => { - let node_id = cx.tcx.map.as_local_node_id(def_id).unwrap(); + let node_id = cx.tcx.hir.as_local_node_id(def_id).unwrap(); ExprKind::VarRef { id: node_id } } Def::Upvar(def_id, index, closure_expr_id) => { - let id_var = cx.tcx.map.as_local_node_id(def_id).unwrap(); + let id_var = cx.tcx.hir.as_local_node_id(def_id).unwrap(); debug!("convert_var(upvar({:?}, {:?}, {:?}))", id_var, index, closure_expr_id); let var_ty = cx.tables().node_id_to_type(id_var); - let body_id = match cx.tcx.map.find(closure_expr_id) { + let body_id = match cx.tcx.hir.find(closure_expr_id) { Some(map::NodeExpr(expr)) => { match expr.node { hir::ExprClosure(.., body, _) => body.node_id, @@ -803,7 +803,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }); let region = cx.tcx.mk_region(region); - let self_expr = match cx.tcx.closure_kind(cx.tcx.map.local_def_id(closure_expr_id)) { + let self_expr = match cx.tcx.closure_kind(cx.tcx.hir.local_def_id(closure_expr_id)) { ty::ClosureKind::Fn => { let ref_closure_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { @@ -1013,7 +1013,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, freevar: &hir::Freevar, freevar_ty: Ty<'tcx>) -> ExprRef<'tcx> { - let id_var = cx.tcx.map.as_local_node_id(freevar.def.def_id()).unwrap(); + let id_var = cx.tcx.hir.as_local_node_id(freevar.def.def_id()).unwrap(); let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr.id, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 533d804a23651..5b3297cb694e8 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -45,13 +45,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { MirSource::Const(_) | MirSource::Static(..) => hir::Constness::Const, MirSource::Fn(id) => { - let fn_like = FnLikeNode::from_node(infcx.tcx.map.get(id)); + let fn_like = FnLikeNode::from_node(infcx.tcx.hir.get(id)); fn_like.map_or(hir::Constness::NotConst, |f| f.constness()) } MirSource::Promoted(..) => bug!(), }; - let attrs = infcx.tcx.map.attrs(src.item_id()); + let attrs = infcx.tcx.hir.attrs(src.item_id()); // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 453c3e43b6b86..c71255dcc7c61 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -84,7 +84,7 @@ fn build<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, -> (Mir<'tcx>, MirSource) { let tcx = infcx.tcx.global_tcx(); - let item_id = tcx.map.body_owner(body_id); + let item_id = tcx.hir.body_owner(body_id); let src = MirSource::from_node(tcx, item_id); let cx = Cx::new(infcx, src); if let MirSource::Fn(id) = src { @@ -92,14 +92,14 @@ fn build<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, // types/lifetimes replaced) let fn_sig = cx.tables().liberated_fn_sigs[&id].clone(); - let ty = tcx.item_type(tcx.map.local_def_id(id)); + let ty = tcx.item_type(tcx.hir.local_def_id(id)); let (abi, implicit_argument) = if let ty::TyClosure(..) = ty.sty { (Abi::Rust, Some((closure_self_ty(tcx, id, body_id), None))) } else { (ty.fn_abi(), None) }; - let body = tcx.map.body(body_id); + let body = tcx.hir.body(body_id); let explicit_arguments = body.arguments .iter() @@ -138,11 +138,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BuildMir<'a, 'tcx> { pretty::dump_mir(tcx, "mir_map", &0, src, &mir); let mir = tcx.alloc_mir(mir); - let def_id = tcx.map.local_def_id(src.item_id()); + let def_id = tcx.hir.local_def_id(src.item_id()); assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none()); }); - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); self.visit_body(body); } } @@ -162,7 +162,7 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }); let region = tcx.mk_region(region); - match tcx.closure_kind(tcx.map.local_def_id(closure_expr_id)) { + match tcx.closure_kind(tcx.hir.local_def_id(closure_expr_id)) { ty::ClosureKind::Fn => tcx.mk_ref(region, ty::TypeAndMut { ty: closure_ty, diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index e7188d536980f..bfe3e143e7c50 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -48,7 +48,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(ref filters) => filters, }; let node_id = src.item_id(); - let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id)); + let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id)); let is_matched = filters.split("&") .any(|filter| { @@ -102,7 +102,7 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, writeln!(w, "")?; } - let id = tcx.map.as_local_node_id(def_id).unwrap(); + let id = tcx.hir.as_local_node_id(def_id).unwrap(); let src = MirSource::from_node(tcx, id); write_mir_fn(tcx, src, mir, w)?; diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 3cbf8573ba97f..2194c20c2f442 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -57,7 +57,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { return } MirSource::Fn(function_node_id) => { - if qualify_consts::is_const_fn(tcx, tcx.map.local_def_id(function_node_id)) { + if qualify_consts::is_const_fn(tcx, tcx.hir.local_def_id(function_node_id)) { // Don't run on const functions, as, again, trans might not be able to evaluate // the optimized IR. return diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index 771f05f7bccfe..3a93bef36c5f7 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -21,7 +21,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator { fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, source: MirSource, mir: &mut Mir<'tcx>) { let node_id = source.item_id(); - let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id)); + let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id)); debug!("running on: {:?}", node_path); // we only run when mir_opt_level > 2 if tcx.sess.opts.debugging_opts.mir_opt_level <= 2 { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index fea27ee5c5483..af9f7fb578138 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -115,8 +115,8 @@ impl fmt::Display for Mode { } pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool { - if let Some(node_id) = tcx.map.as_local_node_id(def_id) { - if let Some(fn_like) = FnLikeNode::from_node(tcx.map.get(node_id)) { + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) { fn_like.constness() == hir::Constness::Const } else { false @@ -267,15 +267,15 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { self.tcx .lookup_trait_def(drop_trait_id) .for_each_relevant_impl(self.tcx, self.mir.return_ty, |impl_did| { - self.tcx.map + self.tcx.hir .as_local_node_id(impl_did) - .and_then(|impl_node_id| self.tcx.map.find(impl_node_id)) + .and_then(|impl_node_id| self.tcx.hir.find(impl_node_id)) .map(|node| { if let hir_map::NodeItem(item) = node { if let hir::ItemImpl(.., ref impl_item_refs) = item.node { span = impl_item_refs.first() .map(|iiref| { - self.tcx.map.impl_item(iiref.id) + self.tcx.hir.impl_item(iiref.id) .span }); } @@ -953,7 +953,7 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let param_env = if def_id.is_local() { - let node_id = tcx.map.as_local_node_id(def_id).unwrap(); + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); ty::ParameterEnvironment::for_item(tcx, node_id) } else { // These should only be monomorphic constants. @@ -978,7 +978,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants { fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { let id = src.item_id(); - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); let mode = match src { MirSource::Fn(_) => { if is_const_fn(tcx, def_id) { diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index fa148da2e3996..b6241c618df2f 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -98,8 +98,8 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { fn handle_const_fn_call(&mut self, def_id: DefId, ret_ty: Ty<'gcx>) { self.add_type(ret_ty); - self.promotable &= if let Some(fn_id) = self.tcx.map.as_local_node_id(def_id) { - FnLikeNode::from_node(self.tcx.map.get(fn_id)).map_or(false, |fn_like| { + self.promotable &= if let Some(fn_id) = self.tcx.hir.as_local_node_id(def_id) { + FnLikeNode::from_node(self.tcx.hir.get(fn_id)).map_or(false, |fn_like| { fn_like.constness() == hir::Constness::Const }) } else { @@ -122,7 +122,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { } } - let item_id = self.tcx.map.body_owner(body_id); + let item_id = self.tcx.hir.body_owner(body_id); let outer_in_fn = self.in_fn; self.in_fn = match MirSource::from_node(self.tcx, item_id) { @@ -131,9 +131,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { }; let outer_tables = self.tables; - self.tables = self.tcx.item_tables(self.tcx.map.local_def_id(item_id)); + self.tables = self.tcx.item_tables(self.tcx.hir.local_def_id(item_id)); - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); if !self.in_fn { self.check_const_eval(&body.value); } @@ -329,8 +329,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node Def::Fn(..) | Def::Method(..) => {} Def::AssociatedConst(_) => v.add_type(node_ty), Def::Const(did) => { - v.promotable &= if let Some(node_id) = v.tcx.map.as_local_node_id(did) { - match v.tcx.map.expect_item(node_id).node { + v.promotable &= if let Some(node_id) = v.tcx.hir.as_local_node_id(did) { + match v.tcx.hir.expect_item(node_id).node { hir::ItemConst(_, body) => { v.visit_nested_body(body); v.tcx.rvalue_promotable_to_static.borrow()[&body.node_id] diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index 78b591a48cca5..9de5ff541a52c 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RvalueContext<'a, 'tcx> { } fn visit_nested_body(&mut self, body_id: hir::BodyId) { - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); self.tcx.infer_ctxt(body_id, Reveal::NotSpecializable).enter(|infcx| { let mut delegate = RvalueContextDelegate { tcx: infcx.tcx, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 445da5a8c3f4e..7357d6f38b651 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { ty::TyProjection(ref proj) => proj.trait_ref.def_id, _ => return Some(AccessLevel::Public) }; - if let Some(node_id) = self.tcx.map.as_local_node_id(ty_def_id) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(ty_def_id) { self.get(node_id) } else { Some(AccessLevel::Public) @@ -84,7 +84,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { fn impl_trait_level(&self, impl_def_id: DefId) -> Option { if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) { - if let Some(node_id) = self.tcx.map.as_local_node_id(trait_ref.def_id) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(trait_ref.def_id) { return self.get(node_id); } } @@ -111,7 +111,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { fn reach<'b>(&'b mut self, item_id: ast::NodeId) -> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { ReachEverythingInTheInterfaceVisitor { - item_def_id: self.tcx.map.local_def_id(item_id), + item_def_id: self.tcx.hir.local_def_id(item_id), ev: self, } } @@ -121,18 +121,18 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.map) + NestedVisitorMap::All(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { let inherited_item_level = match item.node { // Impls inherit level from their types and traits hir::ItemImpl(..) => { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); cmp::min(self.item_ty_level(def_id), self.impl_trait_level(def_id)) } hir::ItemDefaultImpl(..) => { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); self.impl_trait_level(def_id) } // Foreign mods inherit level from parents @@ -306,7 +306,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { if self.prev_level.is_some() { if let Some(exports) = self.export_map.get(&id) { for export in exports { - if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) { self.update(node_id, Some(AccessLevel::Exported)); } } @@ -366,7 +366,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b }; if let Some(def_id) = ty_def_id { - if let Some(node_id) = self.ev.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(def_id) { self.ev.update(node_id, Some(AccessLevel::Reachable)); } } @@ -375,8 +375,8 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b } fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool { - if let Some(node_id) = self.ev.tcx.map.as_local_node_id(trait_ref.def_id) { - let item = self.ev.tcx.map.expect_item(node_id); + if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(trait_ref.def_id) { + let item = self.ev.tcx.hir.expect_item(node_id); self.ev.update(item.id, Some(AccessLevel::Reachable)); } @@ -397,9 +397,9 @@ struct PrivacyVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { fn item_is_accessible(&self, did: DefId) -> bool { - match self.tcx.map.as_local_node_id(did) { + match self.tcx.hir.as_local_node_id(did) { Some(node_id) => - ty::Visibility::from_hir(&self.tcx.map.expect_item(node_id).vis, node_id, self.tcx), + ty::Visibility::from_hir(&self.tcx.hir.expect_item(node_id).vis, node_id, self.tcx), None => self.tcx.sess.cstore.visibility(did), }.is_accessible_from(self.curitem, self.tcx) } @@ -433,19 +433,19 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.map) + NestedVisitorMap::All(&self.tcx.hir) } fn visit_nested_body(&mut self, body: hir::BodyId) { let old_tables = self.tables; self.tables = self.tcx.body_tables(body); - let body = self.tcx.map.body(body); + let body = self.tcx.hir.body(body); self.visit_body(body); self.tables = old_tables; } fn visit_item(&mut self, item: &'tcx hir::Item) { - let orig_curitem = replace(&mut self.curitem, self.tcx.map.local_def_id(item.id)); + let orig_curitem = replace(&mut self.curitem, self.tcx.hir.local_def_id(item.id)); intravisit::walk_item(self, item); self.curitem = orig_curitem; } @@ -492,8 +492,8 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { error.span_label(expr.span, &format!("cannot construct with a private field")); - if let Some(node_id) = self.tcx.map.as_local_node_id(adt_def.did) { - let node = self.tcx.map.find(node_id); + if let Some(node_id) = self.tcx.hir.as_local_node_id(adt_def.did) { + let node = self.tcx.hir.find(node_id); if let Some(hir::map::NodeStructCtor(vdata)) = node { for i in private_indexes { error.span_label(vdata.fields()[i].span, @@ -590,10 +590,10 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // A path can only be private if: // it's in this crate... - if let Some(node_id) = self.tcx.map.as_local_node_id(did) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(did) { // .. and it corresponds to a private type in the AST (this returns // None for type parameters) - match self.tcx.map.find(node_id) { + match self.tcx.hir.find(node_id) { Some(hir::map::NodeItem(ref item)) => item.vis != hir::Public, Some(_) | None => false, } @@ -653,7 +653,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { /// We want to visit items in the context of their containing /// module and so forth, so supply a crate for doing a deep walk. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.tcx.map) + NestedVisitorMap::All(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -709,7 +709,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { |tr| { let did = tr.path.def.def_id(); - if let Some(node_id) = self.tcx.map.as_local_node_id(did) { + if let Some(node_id) = self.tcx.hir.as_local_node_id(did) { self.trait_is_public(node_id) } else { true // external traits must be public @@ -728,7 +728,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { trait_ref.is_some() || impl_item_refs.iter() .any(|impl_item_ref| { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); match impl_item.node { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { @@ -752,7 +752,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // should only walk into public items so that we // don't erroneously report errors for private // types in private items. - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); match impl_item.node { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) @@ -785,7 +785,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // Those in 3. are warned with this call. for impl_item_ref in impl_item_refs { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); if let hir::ImplItemKind::Type(ref ty) = impl_item.node { self.visit_ty(ty); } @@ -798,7 +798,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { let mut found_pub_static = false; for impl_item_ref in impl_item_refs { if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); match impl_item_ref.kind { hir::AssociatedItemKind::Const => { found_pub_static = true; @@ -962,8 +962,8 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' if let Some(def_id) = ty_def_id { // Non-local means public (private items can't leave their crate, modulo bugs) - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { - let item = self.tcx.map.expect_item(node_id); + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + let item = self.tcx.hir.expect_item(node_id); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); if !vis.is_at_least(self.min_visibility, self.tcx) { @@ -997,8 +997,8 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool { // Non-local means public (private items can't leave their crate, modulo bugs) - if let Some(node_id) = self.tcx.map.as_local_node_id(trait_ref.def_id) { - let item = self.tcx.map.expect_item(node_id); + if let Some(node_id) = self.tcx.hir.as_local_node_id(trait_ref.def_id) { + let item = self.tcx.hir.expect_item(node_id); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); if !vis.is_at_least(self.min_visibility, self.tcx) { @@ -1045,7 +1045,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { has_old_errors = true; break; } - let parent = self.tcx.map.get_parent_node(id); + let parent = self.tcx.hir.get_parent_node(id); if parent == id { break; } @@ -1059,8 +1059,8 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { SearchInterfaceForPrivateItemsVisitor { tcx: self.tcx, - item_def_id: self.tcx.map.local_def_id(item_id), - span: self.tcx.map.span(item_id), + item_def_id: self.tcx.hir.local_def_id(item_id), + span: self.tcx.hir.span(item_id), min_visibility: ty::Visibility::Public, required_visibility: required_visibility, has_old_errors: has_old_errors, @@ -1070,7 +1070,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.tcx.map) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -1148,7 +1148,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> self.check(item.id, ty_vis).generics().predicates(); for impl_item_ref in impl_item_refs { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); let impl_item_vis = ty::Visibility::from_hir(&impl_item.vis, item.id, tcx); self.check(impl_item.id, min(impl_item_vis, ty_vis)) @@ -1166,7 +1166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> .item_type().impl_trait_ref().min_visibility; self.check(item.id, vis).generics().predicates(); for impl_item_ref in impl_item_refs { - let impl_item = self.tcx.map.impl_item(impl_item_ref.id); + let impl_item = self.tcx.hir.impl_item(impl_item_ref.id); self.check(impl_item.id, vis).generics().predicates().item_type(); // Recurse for e.g. `impl Trait` (see `visit_ty`). @@ -1205,7 +1205,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> AccessLevels { let _task = tcx.dep_graph.in_task(DepNode::Privacy); - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); // Use the parent map to check the privacy of everything let mut visitor = PrivacyVisitor { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index e5c41d08e1f67..74521fe465bcd 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -112,7 +112,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>) { let old_tables = self.save_ctxt.tables; - let item_def_id = self.tcx.map.local_def_id(item_id); + let item_def_id = self.tcx.hir.local_def_id(item_id); self.save_ctxt.tables = self.tcx.item_tables(item_def_id); f(self); self.save_ctxt.tables = old_tables; @@ -399,7 +399,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { // with the right name. if !self.span.filter_generated(Some(method_data.span), span) { let container = - self.tcx.associated_item(self.tcx.map.local_def_id(id)).container; + self.tcx.associated_item(self.tcx.hir.local_def_id(id)).container; let mut trait_id; let mut decl_id = None; match container { @@ -418,7 +418,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } } None => { - if let Some(NodeItem(item)) = self.tcx.map.get_if_local(id) { + if let Some(NodeItem(item)) = self.tcx.hir.get_if_local(id) { if let hir::ItemImpl(_, _, _, _, ref ty, _) = item.node { trait_id = self.lookup_def_id(ty.id); } @@ -693,7 +693,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { type_value: enum_data.qualname.clone(), value: val, scope: enum_data.scope, - parent: Some(make_def_id(item.id, &self.tcx.map)), + parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, }.lower(self.tcx)); @@ -719,7 +719,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { type_value: enum_data.qualname.clone(), value: val, scope: enum_data.scope, - parent: Some(make_def_id(item.id, &self.tcx.map)), + parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, }.lower(self.tcx)); @@ -775,7 +775,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } self.process_generic_params(type_parameters, item.span, "", item.id); for impl_item in impl_items { - let map = &self.tcx.map; + let map = &self.tcx.hir; self.process_impl_item(impl_item, make_def_id(item.id, map)); } } @@ -848,7 +848,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { // walk generics and methods self.process_generic_params(generics, item.span, &qualname, item.id); for method in methods { - let map = &self.tcx.map; + let map = &self.tcx.hir; self.process_trait_item(method, make_def_id(item.id, map)) } } @@ -1383,7 +1383,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, visit::walk_expr(self, ex); } ast::ExprKind::Struct(ref path, ref fields, ref base) => { - let hir_expr = self.save_ctxt.tcx.map.expect_expr(ex.id); + let hir_expr = self.save_ctxt.tcx.hir.expect_expr(ex.id); let adt = match self.save_ctxt.tables.expr_ty_opt(&hir_expr) { Some(ty) => ty.ty_adt_def().unwrap(), None => { @@ -1408,7 +1408,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, ast::ExprKind::TupField(ref sub_ex, idx) => { self.visit_expr(&sub_ex); - let hir_node = match self.save_ctxt.tcx.map.find(sub_ex.id) { + let hir_node = match self.save_ctxt.tcx.hir.find(sub_ex.id) { Some(Node::NodeExpr(expr)) => expr, _ => { debug!("Missing or weird node for sub-expression {} in {:?}", @@ -1510,7 +1510,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, for &(id, ref p, immut, ref_kind) in &collector.collected_paths { match self.save_ctxt.get_path_def(id) { Def::Local(def_id) => { - let id = self.tcx.map.as_local_node_id(def_id).unwrap(); + let id = self.tcx.hir.as_local_node_id(def_id).unwrap(); let mut value = if immut == ast::Mutability::Immutable { self.span.snippet(p.span).to_string() } else { diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index 18ae3a7fa9ea8..fccb56e88b3de 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -105,13 +105,13 @@ impl Lower for data::EnumData { fn lower(self, tcx: TyCtxt) -> EnumData { EnumData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, value: self.value, qualname: self.qualname, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), - variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + scope: make_def_id(self.scope, &tcx.hir), + variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), @@ -135,12 +135,12 @@ impl Lower for data::ExternCrateData { fn lower(self, tcx: TyCtxt) -> ExternCrateData { ExternCrateData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, crate_num: self.crate_num, location: self.location, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), } } } @@ -159,7 +159,7 @@ impl Lower for data::FunctionCallData { fn lower(self, tcx: TyCtxt) -> FunctionCallData { FunctionCallData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } } @@ -186,12 +186,12 @@ impl Lower for data::FunctionData { fn lower(self, tcx: TyCtxt) -> FunctionData { FunctionData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, qualname: self.qualname, declaration: self.declaration, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), value: self.value, visibility: self.visibility, parent: self.parent, @@ -215,7 +215,7 @@ impl Lower for data::FunctionRefData { fn lower(self, tcx: TyCtxt) -> FunctionRefData { FunctionRefData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } } @@ -234,9 +234,9 @@ impl Lower for data::ImplData { fn lower(self, tcx: TyCtxt) -> ImplData { ImplData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), trait_ref: self.trait_ref, self_ref: self.self_ref, } @@ -257,7 +257,7 @@ impl Lower for data::InheritanceData { InheritanceData { span: SpanData::from_span(self.span, tcx.sess.codemap()), base_id: self.base_id, - deriv_id: make_def_id(self.deriv_id, &tcx.map) + deriv_id: make_def_id(self.deriv_id, &tcx.hir) } } } @@ -305,7 +305,7 @@ impl Lower for data::MacroUseData { name: self.name, qualname: self.qualname, callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), } } } @@ -325,7 +325,7 @@ impl Lower for data::MethodCallData { fn lower(self, tcx: TyCtxt) -> MethodCallData { MethodCallData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, decl_id: self.decl_id, } @@ -355,8 +355,8 @@ impl Lower for data::MethodData { MethodData { span: SpanData::from_span(self.span, tcx.sess.codemap()), name: self.name, - scope: make_def_id(self.scope, &tcx.map), - id: make_def_id(self.id, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), + id: make_def_id(self.id, &tcx.hir), qualname: self.qualname, value: self.value, decl_id: self.decl_id, @@ -388,13 +388,13 @@ impl Lower for data::ModData { fn lower(self, tcx: TyCtxt) -> ModData { ModData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, qualname: self.qualname, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), filename: self.filename, - items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), @@ -417,7 +417,7 @@ impl Lower for data::ModRefData { fn lower(self, tcx: TyCtxt) -> ModRefData { ModRefData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, qualname: self.qualname, } @@ -446,12 +446,12 @@ impl Lower for data::StructData { StructData { span: SpanData::from_span(self.span, tcx.sess.codemap()), name: self.name, - id: make_def_id(self.id, &tcx.map), - ctor_id: make_def_id(self.ctor_id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), + ctor_id: make_def_id(self.ctor_id, &tcx.hir), qualname: self.qualname, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), value: self.value, - fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), @@ -480,11 +480,11 @@ impl Lower for data::StructVariantData { StructVariantData { span: SpanData::from_span(self.span, tcx.sess.codemap()), name: self.name, - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), qualname: self.qualname, type_value: self.type_value, value: self.value, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), @@ -513,11 +513,11 @@ impl Lower for data::TraitData { TraitData { span: SpanData::from_span(self.span, tcx.sess.codemap()), name: self.name, - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), qualname: self.qualname, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), value: self.value, - items: self.items.into_iter().map(|id| make_def_id(id, &tcx.map)).collect(), + items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(), visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), @@ -545,12 +545,12 @@ impl Lower for data::TupleVariantData { fn lower(self, tcx: TyCtxt) -> TupleVariantData { TupleVariantData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, qualname: self.qualname, type_value: self.type_value, value: self.value, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), @@ -577,7 +577,7 @@ impl Lower for data::TypeDefData { fn lower(self, tcx: TyCtxt) -> TypeDefData { TypeDefData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), name: self.name, span: SpanData::from_span(self.span, tcx.sess.codemap()), qualname: self.qualname, @@ -605,7 +605,7 @@ impl Lower for data::TypeRefData { fn lower(self, tcx: TyCtxt) -> TypeRefData { TypeRefData { span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, qualname: self.qualname, } @@ -627,11 +627,11 @@ impl Lower for data::UseData { fn lower(self, tcx: TyCtxt) -> UseData { UseData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), span: SpanData::from_span(self.span, tcx.sess.codemap()), name: self.name, mod_id: self.mod_id, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), visibility: self.visibility, } } @@ -651,10 +651,10 @@ impl Lower for data::UseGlobData { fn lower(self, tcx: TyCtxt) -> UseGlobData { UseGlobData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), span: SpanData::from_span(self.span, tcx.sess.codemap()), names: self.names, - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), visibility: self.visibility, } } @@ -682,12 +682,12 @@ impl Lower for data::VariableData { fn lower(self, tcx: TyCtxt) -> VariableData { VariableData { - id: make_def_id(self.id, &tcx.map), + id: make_def_id(self.id, &tcx.hir), kind: self.kind, name: self.name, qualname: self.qualname, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), value: self.value, type_value: self.type_value, parent: self.parent, @@ -715,7 +715,7 @@ impl Lower for data::VariableRefData { VariableRefData { name: self.name, span: SpanData::from_span(self.span, tcx.sess.codemap()), - scope: make_def_id(self.scope, &tcx.map), + scope: make_def_id(self.scope, &tcx.hir), ref_id: self.ref_id, } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index ded59cfccf134..8d0cdd1678c73 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -285,7 +285,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); filter!(self.span_utils, sub_span, field.span, None); - let def_id = self.tcx.map.local_def_id(field.id); + let def_id = self.tcx.hir.local_def_id(field.id); let typ = self.tcx.item_type(def_id).to_string(); let span = field.span; @@ -307,7 +307,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname: qualname, span: sub_span.unwrap(), scope: scope, - parent: Some(make_def_id(scope, &self.tcx.map)), + parent: Some(make_def_id(scope, &self.tcx.hir)), value: "".to_owned(), type_value: typ, visibility: From::from(&field.vis), @@ -326,13 +326,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. let (qualname, parent_scope, decl_id, vis, docs) = - match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) { - Some(impl_id) => match self.tcx.map.get_if_local(impl_id) { + match self.tcx.impl_of_method(self.tcx.hir.local_def_id(id)) { + Some(impl_id) => match self.tcx.hir.get_if_local(impl_id) { Some(Node::NodeItem(item)) => { match item.node { hir::ItemImpl(.., ref ty, _) => { let mut result = String::from("<"); - result.push_str(&self.tcx.map.node_to_pretty_string(ty.id)); + result.push_str(&self.tcx.hir.node_to_pretty_string(ty.id)); let trait_id = self.tcx.trait_id_of_impl(impl_id); let mut decl_id = None; @@ -365,9 +365,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { r); } }, - None => match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) { + None => match self.tcx.trait_of_item(self.tcx.hir.local_def_id(id)) { Some(def_id) => { - match self.tcx.map.get_if_local(def_id) { + match self.tcx.hir.get_if_local(def_id) { Some(Node::NodeItem(item)) => { (format!("::{}", self.tcx.item_path_str(def_id)), Some(def_id), None, @@ -442,14 +442,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { - let hir_node = self.tcx.map.expect_expr(expr.id); + let hir_node = self.tcx.hir.expect_expr(expr.id); let ty = self.tables.expr_ty_adjusted_opt(&hir_node); if ty.is_none() || ty.unwrap().sty == ty::TyError { return None; } match expr.node { ast::ExprKind::Field(ref sub_ex, ident) => { - let hir_node = match self.tcx.map.find(sub_ex.id) { + let hir_node = match self.tcx.hir.find(sub_ex.id) { Some(Node::NodeExpr(expr)) => expr, _ => { debug!("Missing or weird node for sub-expression {} in {:?}", @@ -523,7 +523,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } pub fn get_path_def(&self, id: NodeId) -> Def { - match self.tcx.map.get(id) { + match self.tcx.hir.get(id) { Node::NodeTraitRef(tr) => tr.path.def, Node::NodeItem(&hir::Item { node: hir::ItemUse(ref path, _), .. }) | @@ -733,7 +733,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { #[inline] pub fn enclosing_scope(&self, id: NodeId) -> NodeId { - self.tcx.map.get_enclosing_scope(id).unwrap_or(CRATE_NODE_ID) + self.tcx.hir.get_enclosing_scope(id).unwrap_or(CRATE_NODE_ID) } } diff --git a/src/librustc_trans/assert_module_sources.rs b/src/librustc_trans/assert_module_sources.rs index 898e65ce391e6..7a41f8341099b 100644 --- a/src/librustc_trans/assert_module_sources.rs +++ b/src/librustc_trans/assert_module_sources.rs @@ -50,7 +50,7 @@ pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let ams = AssertModuleSource { tcx: tcx, modules: modules }; - for attr in &tcx.map.krate().attrs { + for attr in &tcx.hir.krate().attrs { ams.check_attr(attr); } } diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 5f16291892387..81be2d02f125b 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -48,7 +48,7 @@ impl ExportedSymbols { .exported_symbols() .iter() .map(|&node_id| { - scx.tcx().map.local_def_id(node_id) + scx.tcx().hir.local_def_id(node_id) }) .map(|def_id| { let name = symbol_for_def_id(scx, def_id, symbol_map); @@ -64,7 +64,7 @@ impl ExportedSymbols { if let Some(id) = scx.sess().derive_registrar_fn.get() { let svh = &scx.link_meta().crate_hash; - let def_id = scx.tcx().map.local_def_id(id); + let def_id = scx.tcx().hir.local_def_id(id); let idx = def_id.index; let registrar = scx.sess().generate_derive_registrar_symbol(svh, idx); local_crate.push((registrar, SymbolExportLevel::C)); @@ -181,7 +181,7 @@ fn symbol_for_def_id<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, -> String { // Just try to look things up in the symbol map. If nothing's there, we // recompute. - if let Some(node_id) = scx.tcx().map.as_local_node_id(def_id) { + if let Some(node_id) = scx.tcx().hir.as_local_node_id(def_id) { if let Some(sym) = symbol_map.get(TransItem::Static(node_id)) { return sym.to_owned(); } diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 8f8c48a06b2c0..20338e4f6afb0 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -175,7 +175,7 @@ impl<'a, 'tcx> Instance<'tcx> { debug!("symbol_name(def_id={:?}, substs={:?})", def_id, substs); - let node_id = scx.tcx().map.as_local_node_id(def_id); + let node_id = scx.tcx().hir.as_local_node_id(def_id); if let Some(id) = node_id { if scx.sess().plugin_registrar_fn.get() == Some(id) { @@ -193,7 +193,7 @@ impl<'a, 'tcx> Instance<'tcx> { // FIXME(eddyb) Precompute a custom symbol name based on attributes. let attrs = scx.tcx().get_attrs(def_id); let is_foreign = if let Some(id) = node_id { - match scx.tcx().map.get(id) { + match scx.tcx().hir.get(id) { hir_map::NodeForeignItem(_) => true, _ => false } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index d006dccbccc58..32fe3effcc9f8 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -710,7 +710,7 @@ pub fn set_link_section(ccx: &CrateContext, pub fn maybe_create_entry_wrapper(ccx: &CrateContext) { let (main_def_id, span) = match *ccx.sess().entry_fn.borrow() { Some((id, span)) => { - (ccx.tcx().map.local_def_id(id), span) + (ccx.tcx().hir.local_def_id(id), span) } None => return, }; @@ -1075,9 +1075,9 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: NodeSet) -> NodeSet { // // As a result, if this id is an FFI item (foreign item) then we only // let it through if it's included statically. - match tcx.map.get(id) { + match tcx.hir.get(id) { hir_map::NodeForeignItem(..) => { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); tcx.sess.cstore.is_statically_included_foreign_item(def_id) } @@ -1088,7 +1088,7 @@ pub fn find_exported_symbols(tcx: TyCtxt, reachable: NodeSet) -> NodeSet { node: hir::ItemFn(..), .. }) | hir_map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => { - let def_id = tcx.map.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); let generics = tcx.item_generics(def_id); let attributes = tcx.get_attrs(def_id); (generics.parent_types == 0 && generics.types.is_empty()) && @@ -1112,7 +1112,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // entire contents of the krate. So if you push any subtasks of // `TransCrate`, you need to be careful to register "reads" of the // particular items that will be processed. - let krate = tcx.map.krate(); + let krate = tcx.hir.krate(); let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis; let exported_symbols = find_exported_symbols(tcx, reachable); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 5e409a2aa5520..d30766dc5392a 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -309,7 +309,7 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, output: &mut roots, }; - scx.tcx().map.krate().visit_all_item_likes(&mut visitor); + scx.tcx().hir.krate().visit_all_item_likes(&mut visitor); } roots @@ -336,7 +336,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, recursion_depth_reset = None; } TransItem::Static(node_id) => { - let def_id = scx.tcx().map.local_def_id(node_id); + let def_id = scx.tcx().hir.local_def_id(node_id); // Sanity check whether this ended up being collected accidentally debug_assert!(should_trans_locally(scx.tcx(), def_id)); @@ -406,8 +406,8 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if recursion_depth > tcx.sess.recursion_limit.get() { let error = format!("reached the recursion limit while instantiating `{}`", instance); - if let Some(node_id) = tcx.map.as_local_node_id(instance.def) { - tcx.sess.span_fatal(tcx.map.span(node_id), &error); + if let Some(node_id) = tcx.hir.as_local_node_id(instance.def) { + tcx.sess.span_fatal(tcx.hir.span(node_id), &error); } else { tcx.sess.fatal(&error); } @@ -438,8 +438,8 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let instance_name = instance.to_string(); let msg = format!("reached the type-length limit while instantiating `{:.64}...`", instance_name); - let mut diag = if let Some(node_id) = tcx.map.as_local_node_id(instance.def) { - tcx.sess.struct_span_fatal(tcx.map.span(node_id), &msg) + let mut diag = if let Some(node_id) = tcx.hir.as_local_node_id(instance.def) { + tcx.sess.struct_span_fatal(tcx.hir.span(node_id), &msg) } else { tcx.sess.struct_fatal(&msg) }; @@ -619,7 +619,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // Some constructors also have type TyFnDef but they are // always instantiated inline and don't result in a // translation item. Same for FFI functions. - if let Some(hir_map::NodeForeignItem(_)) = tcx.map.get_if_local(def_id) { + if let Some(hir_map::NodeForeignItem(_)) = tcx.hir.get_if_local(def_id) { return false; } @@ -1152,7 +1152,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemUnion(_, ref generics) => { if !generics.is_parameterized() { if self.mode == TransItemCollectionMode::Eager { - let def_id = self.scx.tcx().map.local_def_id(item.id); + let def_id = self.scx.tcx().hir.local_def_id(item.id); debug!("RootCollector: ADT drop-glue for {}", def_id_to_string(self.scx.tcx(), def_id)); @@ -1165,7 +1165,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemStatic(..) => { debug!("RootCollector: ItemStatic({})", def_id_to_string(self.scx.tcx(), - self.scx.tcx().map.local_def_id(item.id))); + self.scx.tcx().hir.local_def_id(item.id))); self.output.push(TransItem::Static(item.id)); } hir::ItemConst(..) => { @@ -1174,7 +1174,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { } hir::ItemFn(.., ref generics, _) => { if !generics.is_type_parameterized() { - let def_id = self.scx.tcx().map.local_def_id(item.id); + let def_id = self.scx.tcx().hir.local_def_id(item.id); debug!("RootCollector: ItemFn({})", def_id_to_string(self.scx.tcx(), def_id)); @@ -1197,7 +1197,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { ref generics, .. }, _) => { - let hir_map = &self.scx.tcx().map; + let hir_map = &self.scx.tcx().hir; let parent_node_id = hir_map.get_parent_node(ii.id); let is_impl_generic = match hir_map.expect_item(parent_node_id) { &hir::Item { @@ -1212,7 +1212,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { }; if !generics.is_type_parameterized() && !is_impl_generic { - let def_id = self.scx.tcx().map.local_def_id(ii.id); + let def_id = self.scx.tcx().hir.local_def_id(ii.id); debug!("RootCollector: MethodImplItem({})", def_id_to_string(self.scx.tcx(), def_id)); @@ -1240,7 +1240,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, ' return } - let impl_def_id = tcx.map.local_def_id(item.id); + let impl_def_id = tcx.hir.local_def_id(item.id); debug!("create_trans_items_for_default_impls(item={})", def_id_to_string(tcx, impl_def_id)); diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index a9c1edfdc66cc..b68de7b46c82e 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -85,10 +85,10 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { } let ty = ccx.tcx().item_type(def_id); - let g = if let Some(id) = ccx.tcx().map.as_local_node_id(def_id) { + let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) { let llty = type_of::type_of(ccx, ty); - let (g, attrs) = match ccx.tcx().map.get(id) { + let (g, attrs) = match ccx.tcx().hir.get(id) { hir_map::NodeItem(&hir::Item { ref attrs, span, node: hir::ItemStatic(..), .. }) => { @@ -219,7 +219,7 @@ pub fn trans_static(ccx: &CrateContext, attrs: &[ast::Attribute]) -> Result { unsafe { - let def_id = ccx.tcx().map.local_def_id(id); + let def_id = ccx.tcx().hir.local_def_id(id); let g = get_static(ccx, def_id); let v = ::mir::trans_static_initializer(ccx, def_id)?; diff --git a/src/librustc_trans/debuginfo/gdb.rs b/src/librustc_trans/debuginfo/gdb.rs index e8728a3999308..4567ec8b452df 100644 --- a/src/librustc_trans/debuginfo/gdb.rs +++ b/src/librustc_trans/debuginfo/gdb.rs @@ -79,7 +79,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) pub fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(&ccx.tcx().map.krate_attrs(), + attr::contains_name(&ccx.tcx().hir.krate_attrs(), "omit_gdb_pretty_printer_section"); !omit_gdb_pretty_printer_section && diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 1473e55b2643c..0de3c13dc21a9 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1738,7 +1738,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, let tcx = cx.tcx(); - let node_def_id = tcx.map.local_def_id(node_id); + let node_def_id = tcx.hir.local_def_id(node_id); let (var_scope, span) = get_namespace_and_span_for_item(cx, node_def_id); let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 9117f49cf3ea5..f05d48566daae 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -251,7 +251,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let scope_line = span_start(cx, span).line; - let local_id = cx.tcx().map.as_local_node_id(instance.def); + let local_id = cx.tcx().hir.as_local_node_id(instance.def); let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id)); let function_name = CString::new(name).unwrap(); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index 9bf023fc18936..bf7a02eb0f196 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -76,7 +76,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: // compiler-rt, then we want to implicitly compile everything with hidden // visibility as we're going to link this object all over the place but // don't want the symbols to get exported. - if attr::contains_name(ccx.tcx().map.krate_attrs(), "compiler_builtins") { + if attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") { unsafe { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index d1d167306c1fd..706f131ed627f 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -186,7 +186,7 @@ impl<'tcx> CodegenUnit<'tcx> { symbol_name.hash(&mut state); let exported = match item { TransItem::Fn(ref instance) => { - let node_id = scx.tcx().map.as_local_node_id(instance.def); + let node_id = scx.tcx().hir.as_local_node_id(instance.def); node_id.map(|node_id| exported_symbols.contains(&node_id)) .unwrap_or(false) } @@ -241,7 +241,7 @@ impl<'tcx> CodegenUnit<'tcx> { fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option { match trans_item { TransItem::Fn(instance) => { - tcx.map.as_local_node_id(instance.def) + tcx.hir.as_local_node_id(instance.def) } TransItem::Static(node_id) => Some(node_id), TransItem::DropGlue(_) => None, @@ -482,7 +482,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't Some(instance.def) } TransItem::DropGlue(dg) => characteristic_def_id_of_type(dg.ty()), - TransItem::Static(node_id) => Some(tcx.map.local_def_id(node_id)), + TransItem::Static(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs index c3e0ac1fee515..880c65937e308 100644 --- a/src/librustc_trans/symbol_map.rs +++ b/src/librustc_trans/symbol_map.rs @@ -97,12 +97,12 @@ impl<'tcx> SymbolMap<'tcx> { trans_item: TransItem<'tcx>) -> Option { match trans_item { TransItem::Fn(Instance { def, .. }) => { - tcx.map.as_local_node_id(def) + tcx.hir.as_local_node_id(def) } TransItem::Static(node_id) => Some(node_id), TransItem::DropGlue(_) => None, }.map(|node_id| { - tcx.map.span(node_id) + tcx.hir.span(node_id) }) } diff --git a/src/librustc_trans/symbol_names_test.rs b/src/librustc_trans/symbol_names_test.rs index 9ed5a5d148cd6..02e1290b57783 100644 --- a/src/librustc_trans/symbol_names_test.rs +++ b/src/librustc_trans/symbol_names_test.rs @@ -36,7 +36,7 @@ pub fn report_symbol_names(scx: &SharedCrateContext) { let _ignore = tcx.dep_graph.in_ignore(); let mut visitor = SymbolNamesTest { scx: scx }; // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like - tcx.map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); } struct SymbolNamesTest<'a, 'tcx:'a> { @@ -47,7 +47,7 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { fn process_attrs(&mut self, node_id: ast::NodeId) { let tcx = self.scx.tcx(); - let def_id = tcx.map.local_def_id(node_id); + let def_id = tcx.hir.local_def_id(node_id); for attr in tcx.get_attrs(def_id).iter() { if attr.check_name(SYMBOL_NAME) { // for now, can only use on monomorphic names diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 816c344254371..43ea1e56a5a4d 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -77,9 +77,9 @@ impl<'a, 'tcx> TransItem<'tcx> { match *self { TransItem::Static(node_id) => { - let def_id = ccx.tcx().map.local_def_id(node_id); + let def_id = ccx.tcx().hir.local_def_id(node_id); let _task = ccx.tcx().dep_graph.in_task(DepNode::TransCrateItem(def_id)); // (*) - let item = ccx.tcx().map.expect_item(node_id); + let item = ccx.tcx().hir.expect_item(node_id); if let hir::ItemStatic(_, m, _) = item.node { match consts::trans_static(&ccx, m, item.id, &item.attrs) { Ok(_) => { /* Cool, everything's alright. */ }, @@ -145,12 +145,12 @@ impl<'a, 'tcx> TransItem<'tcx> { node_id: ast::NodeId, linkage: llvm::Linkage, symbol_name: &str) { - let def_id = ccx.tcx().map.local_def_id(node_id); + let def_id = ccx.tcx().hir.local_def_id(node_id); let ty = ccx.tcx().item_type(def_id); let llty = type_of::type_of(ccx, ty); let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| { - ccx.sess().span_fatal(ccx.tcx().map.span(node_id), + ccx.sess().span_fatal(ccx.tcx().hir.span(node_id), &format!("symbol `{}` is already defined", symbol_name)) }); @@ -222,7 +222,7 @@ impl<'a, 'tcx> TransItem<'tcx> { match *self { TransItem::Fn(instance) => instance.symbol_name(scx), TransItem::Static(node_id) => { - let def_id = scx.tcx().map.local_def_id(node_id); + let def_id = scx.tcx().hir.local_def_id(node_id); Instance::mono(scx, def_id).symbol_name(scx) } TransItem::DropGlue(dg) => { @@ -274,7 +274,7 @@ impl<'a, 'tcx> TransItem<'tcx> { pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { let def_id = match *self { TransItem::Fn(ref instance) => instance.def, - TransItem::Static(node_id) => tcx.map.local_def_id(node_id), + TransItem::Static(node_id) => tcx.hir.local_def_id(node_id), TransItem::DropGlue(..) => return None, }; @@ -283,7 +283,7 @@ impl<'a, 'tcx> TransItem<'tcx> { if let Some(linkage) = base::llvm_linkage_by_name(&name.as_str()) { Some(linkage) } else { - let span = tcx.map.span_if_local(def_id); + let span = tcx.hir.span_if_local(def_id); if let Some(span) = span { tcx.sess.span_fatal(span, "invalid linkage specified") } else { @@ -296,7 +296,7 @@ impl<'a, 'tcx> TransItem<'tcx> { } pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { - let hir_map = &tcx.map; + let hir_map = &tcx.hir; return match *self { TransItem::DropGlue(dg) => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 838dbef8ecf1b..1af8b59cdfa7d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -186,7 +186,7 @@ pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, .get(&id) .cloned() .unwrap_or(ty::Issue32330::WontChange); - ty::ReLateBound(debruijn, ty::BrNamed(tcx.map.local_def_id(id), + ty::ReLateBound(debruijn, ty::BrNamed(tcx.hir.local_def_id(id), lifetime.name, issue_32330)) } @@ -208,7 +208,7 @@ pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, .unwrap_or(ty::Issue32330::WontChange); ty::ReFree(ty::FreeRegion { scope: scope.to_code_extent(&tcx.region_maps), - bound_region: ty::BrNamed(tcx.map.local_def_id(id), + bound_region: ty::BrNamed(tcx.hir.local_def_id(id), lifetime.name, issue_32330) }) @@ -245,8 +245,8 @@ fn report_elision_failure( } = info; let help_name = if let Some(body) = parent { - let arg = &tcx.map.body(body).arguments[index]; - format!("`{}`", tcx.map.node_to_pretty_string(arg.pat.id)) + let arg = &tcx.hir.body(body).arguments[index]; + format!("`{}`", tcx.hir.node_to_pretty_string(arg.pat.id)) } else { format!("argument {}", index + 1) }; @@ -684,7 +684,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } _ => { span_fatal!(self.tcx().sess, path.span, E0245, "`{}` is not a trait", - self.tcx().map.node_to_pretty_string(trait_ref.ref_id)); + self.tcx().hir.node_to_pretty_string(trait_ref.ref_id)); } } } @@ -1152,7 +1152,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| { item.kind == ty::AssociatedKind::Type && item.name == assoc_name }) - .and_then(|item| self.tcx().map.span_if_local(item.def_id)); + .and_then(|item| self.tcx().hir.span_if_local(item.def_id)); if let Some(span) = bound_span { err.span_label(span, &format!("ambiguous `{}` from `{}`", @@ -1223,7 +1223,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } (&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => { - let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap(); + let trait_node_id = tcx.hir.as_local_node_id(trait_did).unwrap(); match self.find_bound_for_assoc_item(trait_node_id, keywords::SelfType.name(), assoc_name, @@ -1233,7 +1233,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } (&ty::TyParam(_), Def::TyParam(param_did)) => { - let param_node_id = tcx.map.as_local_node_id(param_did).unwrap(); + let param_node_id = tcx.hir.as_local_node_id(param_did).unwrap(); let param_name = tcx.type_parameter_def(param_node_id).name; match self.find_bound_for_assoc_item(param_node_id, param_name, @@ -1379,7 +1379,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { assert_eq!(opt_self_ty, None); tcx.prohibit_type_params(&path.segments); - let node_id = tcx.map.as_local_node_id(did).unwrap(); + let node_id = tcx.hir.as_local_node_id(did).unwrap(); let param = tcx.ty_param_defs.borrow().get(&node_id) .map(ty::ParamTy::for_def); if let Some(p) = param { @@ -1544,10 +1544,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { use collect::{compute_bounds, SizedByDefault}; // Create the anonymized type. - let def_id = tcx.map.local_def_id(ast_ty.id); + let def_id = tcx.hir.local_def_id(ast_ty.id); if let Some(anon_scope) = rscope.anon_type_scope() { let substs = anon_scope.fresh_substs(self, ast_ty.span); - let ty = tcx.mk_anon(tcx.map.local_def_id(ast_ty.id), substs); + let ty = tcx.mk_anon(tcx.hir.local_def_id(ast_ty.id), substs); // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`. let bounds = compute_bounds(self, ty, bounds, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 3b3c0257c4a41..932e7ae1dd426 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -139,7 +139,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // if there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be - let var_id = tcx.map.as_local_node_id(def_id).unwrap(); + let var_id = tcx.hir.as_local_node_id(def_id).unwrap(); if var_id != pat.id { let vt = self.local_ty(pat.span, var_id); self.demand_eqtype(pat.span, vt, typ); @@ -561,7 +561,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span_err!(tcx.sess, pat.span, E0533, "expected unit struct/variant or constant, found {} `{}`", def.kind_name(), - hir::print::to_string(&tcx.map, |s| s.print_qpath(qpath, false))); + hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false))); }; // Resolve the path and check the definition for errors. @@ -603,7 +603,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let report_unexpected_def = |def: Def| { let msg = format!("expected tuple struct/variant, found {} `{}`", def.kind_name(), - hir::print::to_string(&tcx.map, |s| s.print_qpath(qpath, false))); + hir::print::to_string(&tcx.hir, |s| s.print_qpath(qpath, false))); struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg) .span_label(pat.span, &format!("not a tuple variant or struct")).emit(); on_error(); diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 0b9cf38fa0733..3a980c8e7642b 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -194,7 +194,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let (fn_sig, def_span) = match callee_ty.sty { ty::TyFnDef(def_id, .., &ty::BareFnTy {ref sig, ..}) => { - (sig, self.tcx.map.span_if_local(def_id)) + (sig, self.tcx.hir.span_if_local(def_id)) } ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => (sig, None), ref t => { @@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let &ty::TyAdt(adt_def, ..) = t { if adt_def.is_enum() { if let hir::ExprCall(ref expr, _) = call_expr.node { - unit_variant = Some(self.tcx.map.node_to_pretty_string(expr.id)) + unit_variant = Some(self.tcx.hir.node_to_pretty_string(expr.id)) } } } @@ -225,7 +225,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Err }; if def != Def::Err { - if let Some(span) = self.tcx.map.span_if_local(def.def_id()) { + if let Some(span) = self.tcx.hir.span_if_local(def.def_id()) { err.span_note(span, "defined here"); } } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 0551887e2e8a0..2e6592b550179 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -39,7 +39,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(ty) => self.deduce_expectations_from_expected_type(ty), None => (None, None), }; - let body = self.tcx.map.body(body_id); + let body = self.tcx.hir.body(body_id); self.check_closure(expr, expected_kind, decl, body, expected_sig) } @@ -54,7 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { opt_kind, expected_sig); - let expr_def_id = self.tcx.map.local_def_id(expr.id); + let expr_def_id = self.tcx.hir.local_def_id(expr.id); let mut fn_ty = AstConv::ty_of_closure(self, hir::Unsafety::Normal, decl, diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 3960dc9edbd27..d110c16cf3313 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -170,7 +170,7 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Create a parameter environment that represents the implementation's // method. - let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap(); + let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id); // Create mapping from impl to skolemized. @@ -437,8 +437,8 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a trait_sig: ty::FnSig<'tcx>) -> (Span, Option) { let tcx = infcx.tcx; - let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap(); - let (impl_m_output, impl_m_iter) = match tcx.map.expect_impl_item(impl_m_node_id).node { + let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); + let (impl_m_output, impl_m_iter) = match tcx.hir.expect_impl_item(impl_m_node_id).node { ImplItemKind::Method(ref impl_m_sig, _) => { (&impl_m_sig.decl.output, impl_m_sig.decl.inputs.iter()) } @@ -447,8 +447,8 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a match *terr { TypeError::Mutability => { - if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) { - let trait_m_iter = match tcx.map.expect_trait_item(trait_m_node_id).node { + if let Some(trait_m_node_id) = tcx.hir.as_local_node_id(trait_m.def_id) { + let trait_m_iter = match tcx.hir.expect_trait_item(trait_m_node_id).node { TraitItemKind::Method(ref trait_m_sig, _) => { trait_m_sig.decl.inputs.iter() } @@ -466,15 +466,15 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a }).map(|(ref impl_arg, ref trait_arg)| { (impl_arg.span, Some(trait_arg.span)) }) - .unwrap_or_else(|| (cause.span, tcx.map.span_if_local(trait_m.def_id))) + .unwrap_or_else(|| (cause.span, tcx.hir.span_if_local(trait_m.def_id))) } else { - (cause.span, tcx.map.span_if_local(trait_m.def_id)) + (cause.span, tcx.hir.span_if_local(trait_m.def_id)) } } TypeError::Sorts(ExpectedFound { .. }) => { - if let Some(trait_m_node_id) = tcx.map.as_local_node_id(trait_m.def_id) { + if let Some(trait_m_node_id) = tcx.hir.as_local_node_id(trait_m.def_id) { let (trait_m_output, trait_m_iter) = - match tcx.map.expect_trait_item(trait_m_node_id).node { + match tcx.hir.expect_trait_item(trait_m_node_id).node { TraitItemKind::Method(ref trait_m_sig, _) => { (&trait_m_sig.decl.output, trait_m_sig.decl.inputs.iter()) } @@ -499,14 +499,14 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a .is_err() { (impl_m_output.span(), Some(trait_m_output.span())) } else { - (cause.span, tcx.map.span_if_local(trait_m.def_id)) + (cause.span, tcx.hir.span_if_local(trait_m.def_id)) } }) } else { - (cause.span, tcx.map.span_if_local(trait_m.def_id)) + (cause.span, tcx.hir.span_if_local(trait_m.def_id)) } } - _ => (cause.span, tcx.map.span_if_local(trait_m.def_id)), + _ => (cause.span, tcx.hir.span_if_local(trait_m.def_id)), } } @@ -554,7 +554,7 @@ fn compare_self_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_m.name, self_descr); err.span_label(impl_m_span, &format!("`{}` used in impl", self_descr)); - if let Some(span) = tcx.map.span_if_local(trait_m.def_id) { + if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { err.span_label(span, &format!("trait declared without `{}`", self_descr)); } err.emit(); @@ -572,7 +572,7 @@ fn compare_self_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, self_descr); err.span_label(impl_m_span, &format!("expected `{}` in impl", self_descr)); - if let Some(span) = tcx.map.span_if_local(trait_m.def_id) { + if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { err.span_label(span, &format!("`{}` used in trait", self_descr)); } err.emit(); @@ -595,8 +595,8 @@ fn compare_number_of_generics<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let num_impl_m_type_params = impl_m_generics.types.len(); let num_trait_m_type_params = trait_m_generics.types.len(); if num_impl_m_type_params != num_trait_m_type_params { - let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap(); - let span = match tcx.map.expect_impl_item(impl_m_node_id).node { + let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); + let span = match tcx.hir.expect_impl_item(impl_m_node_id).node { ImplItemKind::Method(ref impl_m_sig, _) => { if impl_m_sig.generics.is_parameterized() { impl_m_sig.generics.span @@ -671,9 +671,9 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let trait_number_args = trait_m_fty.sig.inputs().skip_binder().len(); let impl_number_args = impl_m_fty.sig.inputs().skip_binder().len(); if trait_number_args != impl_number_args { - let trait_m_node_id = tcx.map.as_local_node_id(trait_m.def_id); + let trait_m_node_id = tcx.hir.as_local_node_id(trait_m.def_id); let trait_span = if let Some(trait_id) = trait_m_node_id { - match tcx.map.expect_trait_item(trait_id).node { + match tcx.hir.expect_trait_item(trait_id).node { TraitItemKind::Method(ref trait_m_sig, _) => { if let Some(arg) = trait_m_sig.decl.inputs.get(if trait_number_args > 0 { trait_number_args - 1 @@ -690,8 +690,8 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } else { trait_item_span }; - let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap(); - let impl_span = match tcx.map.expect_impl_item(impl_m_node_id).node { + let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); + let impl_span = match tcx.hir.expect_impl_item(impl_m_node_id).node { ImplItemKind::Method(ref impl_m_sig, _) => { if let Some(arg) = impl_m_sig.decl.inputs.get(if impl_number_args > 0 { impl_number_args - 1 @@ -759,7 +759,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Create a parameter environment that represents the implementation's // method. - let impl_c_node_id = tcx.map.as_local_node_id(impl_c.def_id).unwrap(); + let impl_c_node_id = tcx.hir.as_local_node_id(impl_c.def_id).unwrap(); let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_c_node_id); // Create mapping from impl to skolemized. @@ -810,7 +810,7 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_ty); // Locate the Span containing just the type of the offending impl - match tcx.map.expect_impl_item(impl_c_node_id).node { + match tcx.hir.expect_impl_item(impl_c_node_id).node { ImplItemKind::Const(ref ty, _) => cause.span = ty.span, _ => bug!("{:?} is not a impl const", impl_c), } @@ -823,8 +823,8 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, trait_c.name); // Add a label to the Span containing just the type of the item - let trait_c_node_id = tcx.map.as_local_node_id(trait_c.def_id).unwrap(); - let trait_c_span = match tcx.map.expect_trait_item(trait_c_node_id).node { + let trait_c_node_id = tcx.hir.as_local_node_id(trait_c.def_id).unwrap(); + let trait_c_span = match tcx.hir.expect_trait_item(trait_c_node_id).node { TraitItemKind::Const(ref ty, _) => ty.span, _ => bug!("{:?} is not a trait const", trait_c), }; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 9cd54bd94c817..91b772a748c72 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -75,8 +75,8 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( -> Result<(), ()> { let tcx = ccx.tcx; - let drop_impl_node_id = tcx.map.as_local_node_id(drop_impl_did).unwrap(); - let self_type_node_id = tcx.map.as_local_node_id(self_type_did).unwrap(); + let drop_impl_node_id = tcx.hir.as_local_node_id(drop_impl_did).unwrap(); + let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap(); // check that the impl type can be made to match the trait type. @@ -100,7 +100,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( assert!(obligations.is_empty()); } Err(_) => { - let item_span = tcx.map.span(self_type_node_id); + let item_span = tcx.hir.span(self_type_node_id); struct_span_err!(tcx.sess, drop_impl_span, E0366, "Implementations of Drop cannot be specialized") .span_note(item_span, @@ -171,7 +171,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( let tcx = ccx.tcx; - let self_type_node_id = tcx.map.as_local_node_id(self_type_did).unwrap(); + let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap(); let drop_impl_span = tcx.def_span(drop_impl_did); @@ -203,7 +203,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // repeated `contains` calls. if !assumptions_in_impl_context.contains(&predicate) { - let item_span = tcx.map.span(self_type_node_id); + let item_span = tcx.hir.span(self_type_node_id); struct_span_err!(tcx.sess, drop_impl_span, E0367, "The requirement `{}` is added only by the Drop impl.", predicate) .span_note(item_span, diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 4f41bbe9924b0..7ead7ada893d7 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -34,7 +34,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, inputs: Vec>, output: Ty<'tcx>) { let tcx = ccx.tcx; - let def_id = tcx.map.local_def_id(it.id); + let def_id = tcx.hir.local_def_id(it.id); let substs = Substs::for_item(tcx, def_id, |_, _| tcx.mk_region(ty::ReErased), @@ -324,7 +324,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, }; let tcx = ccx.tcx; - let def_id = tcx.map.local_def_id(it.id); + let def_id = tcx.hir.local_def_id(it.id); let i_n_tps = tcx.item_generics(def_id).types.len(); let name = it.name.as_str(); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index aa8f3bef92ed2..e2d7d31a8a890 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -803,7 +803,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { for step in steps.iter() { let closure_id = match step.self_ty.sty { ty::TyClosure(def_id, _) => { - if let Some(id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { id } else { continue; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b1705425e6eb0..f6345e6e262db 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -99,8 +99,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { item_name ) }).unwrap(); - let note_span = self.tcx.map.span_if_local(item.def_id).or_else(|| { - self.tcx.map.span_if_local(impl_did) + let note_span = self.tcx.hir.span_if_local(item.def_id).or_else(|| { + self.tcx.hir.span_if_local(impl_did) }); let impl_ty = self.impl_self_ty(span, impl_did).ty; @@ -285,7 +285,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let msg = if let Some(callee) = rcvr_expr { format!("{}; use overloaded call notation instead (e.g., `{}()`)", msg, - self.tcx.map.node_to_pretty_string(callee.id)) + self.tcx.hir.node_to_pretty_string(callee.id)) } else { msg }; @@ -488,8 +488,8 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { } } - ccx.tcx.map.krate().visit_all_item_likes(&mut Visitor { - map: &ccx.tcx.map, + ccx.tcx.hir.krate().visit_all_item_likes(&mut Visitor { + map: &ccx.tcx.hir, traits: &mut traits, }); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7a9df90c1a613..7b87ec5dd5d2f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -538,7 +538,7 @@ struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map) + NestedVisitorMap::OnlyBodies(&self.ccx.tcx.hir) } fn visit_item(&mut self, i: &'tcx hir::Item) { @@ -634,7 +634,7 @@ pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult { // bodies have been fully inferred. for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() { // Use the same DepNode as for the body of the original function/item. - let def_id = ccx.tcx.map.local_def_id(item_id); + let def_id = ccx.tcx.hir.local_def_id(item_id); let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckTables(def_id)); let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id); @@ -677,9 +677,9 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, body_id: hir::BodyId, fn_id: ast::NodeId, span: Span) { - let body = ccx.tcx.map.body(body_id); + let body = ccx.tcx.hir.body(body_id); - let raw_fty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(fn_id)); + let raw_fty = ccx.tcx.item_type(ccx.tcx.hir.local_def_id(fn_id)); let fn_ty = match raw_fty.sty { ty::TyFnDef(.., f) => f, _ => span_bug!(body.value.span, "check_bare_fn: function type expected") @@ -835,7 +835,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); check_representable(ccx.tcx, span, def_id); if ccx.tcx.lookup_simd(def_id) { @@ -844,13 +844,13 @@ fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { } fn check_union(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { - check_representable(ccx.tcx, span, ccx.tcx.map.local_def_id(id)); + check_representable(ccx.tcx, span, ccx.tcx.hir.local_def_id(id)); } pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { debug!("check_item_type(it.id={}, it.name={})", it.id, - ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(it.id))); + ccx.tcx.item_path_str(ccx.tcx.hir.local_def_id(it.id))); let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. @@ -865,7 +865,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { hir::ItemFn(..) => {} // entirely within check_item_body hir::ItemImpl(.., ref impl_item_refs) => { debug!("ItemImpl {} with id {}", it.name, it.id); - let impl_def_id = ccx.tcx.map.local_def_id(it.id); + let impl_def_id = ccx.tcx.hir.local_def_id(it.id); if let Some(impl_trait_ref) = ccx.tcx.impl_trait_ref(impl_def_id) { check_impl_items_against_trait(ccx, it.span, @@ -877,7 +877,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } hir::ItemTrait(..) => { - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); check_on_unimplemented(ccx, def_id, it); } hir::ItemStruct(..) => { @@ -887,7 +887,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { check_union(ccx, it.id, it.span); } hir::ItemTy(_, ref generics) => { - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); let pty_ty = ccx.tcx.item_type(def_id); check_bounds_are_used(ccx, generics, pty_ty); } @@ -904,7 +904,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } else { for item in &m.items { - let generics = ccx.tcx.item_generics(ccx.tcx.map.local_def_id(item.id)); + let generics = ccx.tcx.item_generics(ccx.tcx.hir.local_def_id(item.id)); if !generics.types.is_empty() { let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044, "foreign items may not have type parameters"); @@ -1038,12 +1038,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id); let mut overridden_associated_type = None; - let impl_items = || impl_item_refs.iter().map(|iiref| ccx.tcx.map.impl_item(iiref.id)); + let impl_items = || impl_item_refs.iter().map(|iiref| ccx.tcx.hir.impl_item(iiref.id)); // Check existing impl methods to see if they are both present in trait // and compatible with trait signature for impl_item in impl_items() { - let ty_impl_item = tcx.associated_item(tcx.map.local_def_id(impl_item.id)); + let ty_impl_item = tcx.associated_item(tcx.hir.local_def_id(impl_item.id)); let ty_trait_item = tcx.associated_items(impl_trait_ref.def_id) .find(|ac| ac.name == ty_impl_item.name); @@ -1067,14 +1067,14 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, err.span_label(impl_item.span, &format!("does not match trait")); // We can only get the spans from local trait definition // Same for E0324 and E0325 - if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id) { + if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) { err.span_label(trait_span, &format!("item in trait")); } err.emit() } } hir::ImplItemKind::Method(_, body_id) => { - let trait_span = tcx.map.span_if_local(ty_trait_item.def_id); + let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssociatedKind::Method { let err_count = tcx.sess.err_count(); compare_impl_method(ccx, @@ -1103,7 +1103,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty_impl_item.name, impl_trait_ref); err.span_label(impl_item.span, &format!("does not match trait")); - if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id) { + if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) { err.span_label(trait_span, &format!("item in trait")); } err.emit() @@ -1121,7 +1121,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty_impl_item.name, impl_trait_ref); err.span_label(impl_item.span, &format!("does not match trait")); - if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id) { + if let Some(trait_span) = tcx.hir.span_if_local(ty_trait_item.def_id) { err.span_label(trait_span, &format!("item in trait")); } err.emit() @@ -1176,7 +1176,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, .map(|trait_item| trait_item.name.to_string()) .collect::>().join("`, `"))); for trait_item in missing_items { - if let Some(span) = tcx.map.span_if_local(trait_item.def_id) { + if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) { err.span_label(span, &format!("`{}` from trait", trait_item.name)); } else { err.note(&format!("`{}` from trait: `{}`", @@ -1204,7 +1204,7 @@ fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, body: hir::BodyId, expected_type: Ty<'tcx>, id: ast::NodeId) { - let body = ccx.tcx.map.body(body); + let body = ccx.tcx.hir.body(body); ccx.inherited(id).enter(|inh| { let fcx = FnCtxt::new(&inh, None, body.value.id); fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized); @@ -1231,7 +1231,7 @@ fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>, body: hir::BodyId, id: ast::NodeId) { - let decl_ty = ccx.tcx.item_type(ccx.tcx.map.local_def_id(id)); + let decl_ty = ccx.tcx.item_type(ccx.tcx.hir.local_def_id(id)); check_const_with_type(ccx, body, decl_ty, id); } @@ -1294,7 +1294,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, sp: Span, vs: &'tcx [hir::Variant], id: ast::NodeId) { - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); if hint != attr::ReprAny && vs.is_empty() { @@ -1319,7 +1319,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } } - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); let variants = &ccx.tcx.lookup_adt_def(def_id).variants; let mut disr_vals: Vec = Vec::new(); @@ -1328,14 +1328,14 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, // Check for duplicate discriminant values if let Some(i) = disr_vals.iter().position(|&x| x == current_disr_val) { - let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap(); - let variant_i = ccx.tcx.map.expect_variant(variant_i_node_id); + let variant_i_node_id = ccx.tcx.hir.as_local_node_id(variants[i].did).unwrap(); + let variant_i = ccx.tcx.hir.expect_variant(variant_i_node_id); let i_span = match variant_i.node.disr_expr { - Some(expr) => ccx.tcx.map.span(expr.node_id), - None => ccx.tcx.map.span(variant_i_node_id) + Some(expr) => ccx.tcx.hir.span(expr.node_id), + None => ccx.tcx.hir.span(variant_i_node_id) }; let span = match v.node.disr_expr { - Some(expr) => ccx.tcx.map.span(expr.node_id), + Some(expr) => ccx.tcx.hir.span(expr.node_id), None => v.span }; struct_span_err!(ccx.tcx.sess, span, E0081, @@ -1610,7 +1610,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(&t) => t, None => { span_bug!(span, "no type for local variable {}", - self.tcx.map.node_to_string(nid)); + self.tcx.hir.node_to_string(nid)); } } } @@ -1841,7 +1841,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None if self.err_count_since_creation() != 0 => self.tcx.types.err, None => { bug!("no type for node {}: {} in fcx {}", - id, self.tcx.map.node_to_string(id), + id, self.tcx.hir.node_to_string(id), self.tag()); } } @@ -2159,7 +2159,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { TypeVariableOrigin::MiscVariable(syntax_pos::DUMMY_SP)), origin_span: syntax_pos::DUMMY_SP, // what do I put here? - def_id: self.tcx.map.local_def_id(ast::CRATE_NODE_ID) + def_id: self.tcx.hir.local_def_id(ast::CRATE_NODE_ID) }); // This is to ensure that we elimnate any non-determinism from the error @@ -2435,7 +2435,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); self.check_argument_types(sp, &fty.sig.0.inputs()[1..], &expected_arg_tys[..], args_no_rcvr, fty.sig.0.variadic, tuple_arguments, - self.tcx.map.span_if_local(def_id)); + self.tcx.hir.span_if_local(def_id)); fty.sig.0.output() } _ => { @@ -3021,7 +3021,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::TyRawPtr(..) => { err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \ `(*{0}).{1}`", - self.tcx.map.node_to_pretty_string(base.id), + self.tcx.hir.node_to_pretty_string(base.id), field.node)); } _ => {} @@ -3436,12 +3436,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.diverges.set(self.diverges.get() | old_diverges); self.has_errors.set(self.has_errors.get() | old_has_errors); - debug!("type of {} is...", self.tcx.map.node_to_string(expr.id)); + debug!("type of {} is...", self.tcx.hir.node_to_string(expr.id)); debug!("... {:?}, expected is {:?}", ty, expected); // Add adjustments to !-expressions if ty.is_never() { - if let Some(hir::map::NodeExpr(node_expr)) = self.tcx.map.find(expr.id) { + if let Some(hir::map::NodeExpr(node_expr)) = self.tcx.hir.find(expr.id) { let adj_ty = self.next_diverging_ty_var( TypeVariableOrigin::AdjustmentType(node_expr.span)); self.write_adjustment(expr.id, adjustment::Adjustment { @@ -4370,7 +4370,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match def { Def::Local(def_id) | Def::Upvar(def_id, ..) => { - let nid = self.tcx.map.as_local_node_id(def_id).unwrap(); + let nid = self.tcx.hir.as_local_node_id(def_id).unwrap(); let ty = self.local_ty(span, nid); let ty = self.normalize_associated_types_in(span, &ty); self.write_ty(node_id, ty); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index bd63eb6ad25ef..9a5d402ef0adf 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -148,7 +148,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if self.err_count_since_creation() == 0 { // regionck assumes typeck succeeded - rcx.visit_fn_body(fn_id, body, self.tcx.map.span(fn_id)); + rcx.visit_fn_body(fn_id, body, self.tcx.hir.span(fn_id)); } rcx.free_region_map.relate_free_regions_from_predicates( @@ -482,7 +482,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { fn visit_fn(&mut self, _fk: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl, b: hir::BodyId, span: Span, id: ast::NodeId) { - let body = self.tcx.map.body(b); + let body = self.tcx.hir.body(b); self.visit_fn_body(id, body, span) } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 95da5a97f6750..d511d57c3780d 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for SeedBorrowKind<'a, 'gcx, 'tcx> { fn visit_expr(&mut self, expr: &'gcx hir::Expr) { match expr.node { hir::ExprClosure(cc, _, body_id, _) => { - let body = self.fcx.tcx.map.body(body_id); + let body = self.fcx.tcx.hir.body(body_id); self.visit_body(body); self.check_closure(expr, cc); } @@ -114,7 +114,7 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> { self.fcx.tcx.with_freevars(expr.id, |freevars| { for freevar in freevars { let def_id = freevar.def.def_id(); - let var_node_id = self.fcx.tcx.map.as_local_node_id(def_id).unwrap(); + let var_node_id = self.fcx.tcx.hir.as_local_node_id(def_id).unwrap(); let upvar_id = ty::UpvarId { var_id: var_node_id, closure_expr_id: expr.id }; debug!("seed upvar_id {:?}", upvar_id); @@ -208,7 +208,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { // If we are also inferred the closure kind here, update the // main table and process any deferred resolutions. - let closure_def_id = self.fcx.tcx.map.local_def_id(id); + let closure_def_id = self.fcx.tcx.hir.local_def_id(id); if let Some(&kind) = self.temp_closure_kinds.get(&id) { self.fcx.tables.borrow_mut().closure_kinds.insert(id, kind); debug!("closure_kind({:?}) = {:?}", closure_def_id, kind); @@ -232,7 +232,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { tcx.with_freevars(closure_id, |freevars| { freevars.iter().map(|freevar| { let def_id = freevar.def.def_id(); - let var_id = tcx.map.as_local_node_id(def_id).unwrap(); + let var_id = tcx.hir.as_local_node_id(def_id).unwrap(); let freevar_ty = self.fcx.node_ty(var_id); let upvar_id = ty::UpvarId { var_id: var_id, @@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for AdjustBorrowKind<'a, 'gcx, 'tcx> { { intravisit::walk_fn(self, fn_kind, decl, body, span, id); - let body = self.fcx.tcx.map.body(body); + let body = self.fcx.tcx.hir.body(body); self.visit_body(body); self.analyze_closure(id, span, body); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 4c124cdd60c0f..cef6a75e58dc9 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -90,7 +90,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let ccx = self.ccx; debug!("check_item_well_formed(it.id={}, it.name={})", item.id, - ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(item.id))); + ccx.tcx.item_path_str(ccx.tcx.hir.local_def_id(item.id))); match item.node { /// Right now we check that every default trait implementation @@ -117,7 +117,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), ..) => { // FIXME(#27579) what amount of WF checking do we need for neg impls? - let trait_ref = ccx.tcx.impl_trait_ref(ccx.tcx.map.local_def_id(item.id)).unwrap(); + let trait_ref = ccx.tcx.impl_trait_ref(ccx.tcx.hir.local_def_id(item.id)).unwrap(); if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) { error_192(ccx, item.span); } @@ -168,7 +168,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { let free_substs = &fcx.parameter_environment.free_substs; let free_id_outlive = fcx.parameter_environment.free_id_outlive; - let item = fcx.tcx.associated_item(fcx.tcx.map.local_def_id(item_id)); + let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); let (mut implied_bounds, self_ty) = match item.container { ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()), @@ -251,7 +251,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } let free_substs = &fcx.parameter_environment.free_substs; - let def_id = fcx.tcx.map.local_def_id(item.id); + let def_id = fcx.tcx.hir.local_def_id(item.id); let predicates = fcx.instantiate_bounds(item.span, def_id, free_substs); this.check_where_clauses(fcx, item.span, &predicates); @@ -321,7 +321,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } fn check_trait(&mut self, item: &hir::Item) { - let trait_def_id = self.tcx().map.local_def_id(item.id); + let trait_def_id = self.tcx().hir.local_def_id(item.id); if self.tcx().trait_has_default_impl(trait_def_id) { self.check_auto_trait(trait_def_id, item.span); @@ -341,7 +341,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { { self.for_item(item).with_fcx(|fcx, this| { let free_substs = &fcx.parameter_environment.free_substs; - let def_id = fcx.tcx.map.local_def_id(item.id); + let def_id = fcx.tcx.hir.local_def_id(item.id); let ty = fcx.tcx.item_type(def_id); let item_ty = fcx.instantiate_type_scheme(item.span, free_substs, &ty); let bare_fn_ty = match item_ty.sty { @@ -367,7 +367,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { debug!("check_item_type: {:?}", item); self.for_item(item).with_fcx(|fcx, this| { - let ty = fcx.tcx.item_type(fcx.tcx.map.local_def_id(item.id)); + let ty = fcx.tcx.item_type(fcx.tcx.hir.local_def_id(item.id)); let item_ty = fcx.instantiate_type_scheme(item.span, &fcx.parameter_environment .free_substs, @@ -388,7 +388,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { self.for_item(item).with_fcx(|fcx, this| { let free_substs = &fcx.parameter_environment.free_substs; - let item_def_id = fcx.tcx.map.local_def_id(item.id); + let item_def_id = fcx.tcx.hir.local_def_id(item.id); match *ast_trait_ref { Some(ref ast_trait_ref) => { @@ -514,7 +514,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { item: &hir::Item, ast_generics: &hir::Generics) { - let item_def_id = self.tcx().map.local_def_id(item.id); + let item_def_id = self.tcx().hir.local_def_id(item.id); let ty = self.tcx().item_type(item_def_id); if self.tcx().has_error_field(ty) { return; @@ -644,7 +644,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let fields = struct_def.fields().iter() .map(|field| { - let field_ty = self.tcx.item_type(self.tcx.map.local_def_id(field.id)); + let field_ty = self.tcx.item_type(self.tcx.hir.local_def_id(field.id)); let field_ty = self.instantiate_type_scheme(field.span, &self.parameter_environment .free_substs, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 172c1dfe35eae..b95126af56aa7 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -36,8 +36,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) { assert_eq!(self.writeback_errors.get(), false); - let item_id = self.tcx.map.body_owner(body.id()); - let item_def_id = self.tcx.map.local_def_id(item_id); + let item_id = self.tcx.hir.body_owner(body.id()); + let item_def_id = self.tcx.hir.local_def_id(item_id); let mut wbcx = WritebackCx::new(self); for arg in &body.arguments { @@ -209,7 +209,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { MethodCall::expr(e.id)); if let hir::ExprClosure(_, _, body, _) = e.node { - let body = self.fcx.tcx.map.body(body); + let body = self.fcx.tcx.hir.body(body); for arg in &body.arguments { self.visit_node_id(ResolvingExpr(e.span), arg.id); } @@ -281,12 +281,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { for (&id, closure_ty) in self.fcx.tables.borrow().closure_tys.iter() { let closure_ty = self.resolve(closure_ty, ResolvingClosure(id)); - let def_id = self.tcx().map.local_def_id(id); + let def_id = self.tcx().hir.local_def_id(id); self.tcx().closure_tys.borrow_mut().insert(def_id, closure_ty); } for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() { - let def_id = self.tcx().map.local_def_id(id); + let def_id = self.tcx().hir.local_def_id(id); self.tcx().closure_kinds.borrow_mut().insert(def_id, closure_kind); } } @@ -517,7 +517,7 @@ impl<'a, 'gcx, 'tcx> ResolveReason { ResolvingFnSig(id) | ResolvingFieldTypes(id) | ResolvingTyNode(id) => { - tcx.map.span(id) + tcx.hir.span(id) } ResolvingAnonTy(did) => { tcx.def_span(did) diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index cd9453770a6ab..bdda538db160e 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -60,5 +60,5 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck); let mut visitor = UnusedTraitImportVisitor { tcx: tcx }; - tcx.map.krate().visit_all_item_likes(&mut visitor); + tcx.hir.krate().visit_all_item_likes(&mut visitor); } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 57df0fb2cee93..086484c643ad1 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -69,8 +69,8 @@ fn visit_implementation_of_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } _ => { // Destructors only work on nominal types. - if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) { - match tcx.map.find(impl_node_id) { + if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_did) { + match tcx.hir.find(impl_node_id) { Some(hir_map::NodeItem(item)) => { let span = match item.node { ItemImpl(.., ref ty, _) => ty.span, @@ -101,7 +101,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did: DefId) { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); - let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) { + let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) { n } else { debug!("visit_implementation_of_copy(): impl not in this \ @@ -113,7 +113,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type); - let span = tcx.map.span(impl_node_id); + let span = tcx.hir.span(impl_node_id); let param_env = ParameterEnvironment::for_item(tcx, impl_node_id); let self_type = self_type.subst(tcx, ¶m_env.free_substs); assert!(!self_type.has_escaping_regions()); @@ -124,7 +124,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match param_env.can_type_implement_copy(tcx, self_type, span) { Ok(()) => {} Err(CopyImplementationError::InfrigingField(field)) => { - let item = tcx.map.expect_item(impl_node_id); + let item = tcx.hir.expect_item(impl_node_id); let span = if let ItemImpl(.., Some(ref tr), _, _) = item.node { tr.path.span } else { @@ -141,7 +141,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .emit() } Err(CopyImplementationError::NotAnAdt) => { - let item = tcx.map.expect_item(impl_node_id); + let item = tcx.hir.expect_item(impl_node_id); let span = if let ItemImpl(.., ref ty, _) = item.node { ty.span } else { @@ -180,7 +180,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }; - let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) { + let impl_node_id = if let Some(n) = tcx.hir.as_local_node_id(impl_did) { n } else { debug!("visit_implementation_of_coerce_unsized(): impl not \ @@ -195,7 +195,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, source, target); - let span = tcx.map.span(impl_node_id); + let span = tcx.hir.span(impl_node_id); let param_env = ParameterEnvironment::for_item(tcx, impl_node_id); let source = source.subst(tcx, ¶m_env.free_substs); let target = target.subst(tcx, ¶m_env.free_substs); @@ -281,11 +281,11 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, being coerced, none found"); return; } else if diff_fields.len() > 1 { - let item = tcx.map.expect_item(impl_node_id); + let item = tcx.hir.expect_item(impl_node_id); let span = if let ItemImpl(.., Some(ref t), _, _) = item.node { t.path.span } else { - tcx.map.span(impl_node_id) + tcx.hir.span(impl_node_id) }; let mut err = struct_span_err!(tcx.sess, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 6cf752dd69fca..5af9ea29fafa7 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fn check_implementation(&self, item: &Item) { let tcx = self.tcx; - let impl_did = tcx.map.local_def_id(item.id); + let impl_did = tcx.hir.local_def_id(item.id); let self_type = tcx.item_type(impl_did); // If there are no traits, then this implementation must have a diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 2b5a4515cd0d8..c3417ab08d7fa 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -76,13 +76,13 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { /// to prevent inundating the user with a bunch of similar error /// reports. fn visit_item(&mut self, item: &hir::Item) { - let def_id = self.tcx.map.local_def_id(item.id); + let def_id = self.tcx.hir.local_def_id(item.id); match item.node { hir::ItemImpl(.., None, ref ty, _) => { // For inherent impls, self type must be a nominal type // defined in this crate. debug!("coherence2::orphan check: inherent impl {}", - self.tcx.map.node_to_string(item.id)); + self.tcx.hir.node_to_string(item.id)); let self_ty = self.tcx.item_type(def_id); match self_ty.sty { ty::TyAdt(def, _) => { @@ -249,7 +249,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { hir::ItemImpl(.., Some(_), _, _) => { // "Trait" impl debug!("coherence2::orphan check: trait impl {}", - self.tcx.map.node_to_string(item.id)); + self.tcx.hir.node_to_string(item.id)); let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); let trait_def_id = trait_ref.def_id; match traits::orphan_check(self.tcx, def_id) { @@ -374,7 +374,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { hir::ItemDefaultImpl(_, ref item_trait_ref) => { // "Trait" impl debug!("coherence2::orphan check: default trait impl {}", - self.tcx.map.node_to_string(item.id)); + self.tcx.hir.node_to_string(item.id)); let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); if trait_ref.def_id.krate != LOCAL_CRATE { struct_span_err!(self.tcx.sess, @@ -384,7 +384,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { the crate they're defined in; define a new trait instead") .span_label(item_trait_ref.path.span, &format!("`{}` trait not defined in this crate", - self.tcx.map.node_to_pretty_string(item_trait_ref.ref_id))) + self.tcx.hir.node_to_pretty_string(item_trait_ref.ref_id))) .emit(); return; } diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 7890ae20ec26c..56c17dc2f6efd 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -66,7 +66,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { for &item2 in &impl_items2[..] { if (name, namespace) == name_and_namespace(item2) { let msg = format!("duplicate definitions with name `{}`", name); - let node_id = self.tcx.map.as_local_node_id(item1).unwrap(); + let node_id = self.tcx.hir.as_local_node_id(item1).unwrap(); self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS, node_id, self.tcx.span_of_impl(item1).unwrap(), @@ -104,7 +104,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> { hir::ItemStruct(..) | hir::ItemTrait(..) | hir::ItemUnion(..) => { - let type_def_id = self.tcx.map.local_def_id(item.id); + let type_def_id = self.tcx.hir.local_def_id(item.id); self.check_for_overlapping_inherent_impls(type_def_id); } @@ -112,7 +112,7 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> { // look for another default impl; note that due to the // general orphan/coherence rules, it must always be // in this crate. - let impl_def_id = self.tcx.map.local_def_id(item.id); + let impl_def_id = self.tcx.hir.local_def_id(item.id); let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id); @@ -124,14 +124,14 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OverlapChecker<'cx, 'tcx> { `{}`:", trait_ref); err.span_note(self.tcx - .span_of_impl(self.tcx.map.local_def_id(prev_id)) + .span_of_impl(self.tcx.hir.local_def_id(prev_id)) .unwrap(), "redundant implementation is here:"); err.emit(); } } hir::ItemImpl(.., Some(_), _, _) => { - let impl_def_id = self.tcx.map.local_def_id(item.id); + let impl_def_id = self.tcx.hir.local_def_id(item.id); let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index c4c7c699f65f6..8c98e2952ebe9 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -17,7 +17,7 @@ use rustc::hir::{self, Unsafety}; pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut unsafety = UnsafetyChecker { tcx: tcx }; - tcx.map.krate().visit_all_item_likes(&mut unsafety); + tcx.hir.krate().visit_all_item_likes(&mut unsafety); } struct UnsafetyChecker<'cx, 'tcx: 'cx> { @@ -30,7 +30,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { impl_generics: Option<&hir::Generics>, unsafety: hir::Unsafety, polarity: hir::ImplPolarity) { - match self.tcx.impl_trait_ref(self.tcx.map.local_def_id(item.id)) { + match self.tcx.impl_trait_ref(self.tcx.hir.local_def_id(item.id)) { None => { // Inherent impl. match unsafety { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d403ac4343531..841b4516a18f3 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -169,9 +169,9 @@ impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { fn with_collect_item_sig(&self, id: ast::NodeId, op: OP) where OP: FnOnce() { - let def_id = self.ccx.tcx.map.local_def_id(id); + let def_id = self.ccx.tcx.hir.local_def_id(id); self.ccx.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), || { - self.ccx.tcx.map.read(id); + self.ccx.tcx.hir.read(id); op(); }); } @@ -179,7 +179,7 @@ impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.ccx.tcx.map) + NestedVisitorMap::OnlyBodies(&self.ccx.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { @@ -189,7 +189,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprClosure(..) = expr.node { - let def_id = self.ccx.tcx.map.local_def_id(expr.id); + let def_id = self.ccx.tcx.hir.local_def_id(expr.id); generics_of_def_id(self.ccx, def_id); type_of_def_id(self.ccx, def_id); } @@ -198,7 +198,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty) { if let hir::TyImplTrait(..) = ty.node { - let def_id = self.ccx.tcx.map.local_def_id(ty.id); + let def_id = self.ccx.tcx.hir.local_def_id(ty.id); generics_of_def_id(self.ccx, def_id); } intravisit::walk_ty(self, ty); @@ -341,8 +341,8 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { { let tcx = self.tcx; - if let Some(trait_id) = tcx.map.as_local_node_id(def_id) { - let item = match tcx.map.get(trait_id) { + if let Some(trait_id) = tcx.hir.as_local_node_id(def_id) { + let item = match tcx.hir.get(trait_id) { hir_map::NodeItem(item) => item, _ => bug!("get_trait_def({:?}): not an item", trait_id) }; @@ -611,7 +611,7 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match path.def { Def::SelfTy(Some(def_id), None) | Def::TyParam(def_id) => { - def_id == tcx.map.local_def_id(param_id) + def_id == tcx.hir.local_def_id(param_id) } _ => false } @@ -629,7 +629,7 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty); ccx.tcx.item_types.borrow_mut().insert(ty_f.did, tt); - let def_id = ccx.tcx.map.local_def_id(field.id); + let def_id = ccx.tcx.hir.local_def_id(field.id); ccx.tcx.item_types.borrow_mut().insert(def_id, tt); ccx.tcx.generics.borrow_mut().insert(def_id, struct_generics); ccx.tcx.predicates.borrow_mut().insert(def_id, struct_predicates.clone()); @@ -642,7 +642,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, untransformed_rcvr_ty: Ty<'tcx>, body: Option, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,) { - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); let ty_generics = generics_of_def_id(ccx, def_id); let ty_generic_predicates = @@ -662,7 +662,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, sig, self_value_ty, body, anon_scope); let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), - ccx.tcx.map.span(id), def_id); + ccx.tcx.hir.span(id), def_id); let fty = ccx.tcx.mk_fn_def(def_id, substs, fty); ccx.tcx.item_types.borrow_mut().insert(def_id, fty); ccx.tcx.predicates.borrow_mut().insert(def_id, ty_generic_predicates); @@ -677,7 +677,7 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, parent: Some(container.id()), predicates: vec![] }; - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); ccx.tcx.predicates.borrow_mut().insert(def_id, predicates); ccx.tcx.item_types.borrow_mut().insert(def_id, ty); } @@ -691,7 +691,7 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, parent: Some(container.id()), predicates: vec![] }; - let def_id = ccx.tcx.map.local_def_id(id); + let def_id = ccx.tcx.hir.local_def_id(id); ccx.tcx.predicates.borrow_mut().insert(def_id, predicates); if let Some(ty) = ty { @@ -741,7 +741,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { let tcx = ccx.tcx; debug!("convert: item {} with id {}", it.name, it.id); - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); match it.node { // These don't define types. hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => { @@ -756,7 +756,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { let generics = generics_of_def_id(ccx, def_id); let predicates = predicates_of_item(ccx, it); convert_enum_variant_types(ccx, - tcx.lookup_adt_def(ccx.tcx.map.local_def_id(it.id)), + tcx.lookup_adt_def(ccx.tcx.hir.local_def_id(it.id)), ty, generics, predicates, @@ -771,7 +771,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { tcx.record_trait_has_default_impl(trait_ref.def_id); - tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), + tcx.impl_trait_refs.borrow_mut().insert(ccx.tcx.hir.local_def_id(it.id), Some(trait_ref)); } hir::ItemImpl(.., @@ -851,12 +851,12 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { // we can lookup details about the trait because items are visited // before trait-items - let trait_def_id = tcx.map.get_parent_did(trait_item.id); + let trait_def_id = tcx.hir.get_parent_did(trait_item.id); let trait_predicates = tcx.item_predicates(trait_def_id); match trait_item.node { hir::TraitItemKind::Const(ref ty, _) => { - let const_def_id = ccx.tcx.map.local_def_id(trait_item.id); + let const_def_id = ccx.tcx.hir.local_def_id(trait_item.id); generics_of_def_id(ccx, const_def_id); let ty = ccx.icx(&trait_predicates) .to_ty(&ExplicitRscope, &ty); @@ -866,7 +866,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { } hir::TraitItemKind::Type(_, ref opt_ty) => { - let type_def_id = ccx.tcx.map.local_def_id(trait_item.id); + let type_def_id = ccx.tcx.hir.local_def_id(trait_item.id); generics_of_def_id(ccx, type_def_id); let typ = opt_ty.as_ref().map({ @@ -893,14 +893,14 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { // we can lookup details about the impl because items are visited // before impl-items - let impl_def_id = tcx.map.get_parent_did(impl_item.id); + let impl_def_id = tcx.hir.get_parent_did(impl_item.id); let impl_predicates = tcx.item_predicates(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); let impl_self_ty = tcx.item_type(impl_def_id); match impl_item.node { hir::ImplItemKind::Const(ref ty, _) => { - let const_def_id = ccx.tcx.map.local_def_id(impl_item.id); + let const_def_id = ccx.tcx.hir.local_def_id(impl_item.id); generics_of_def_id(ccx, const_def_id); let ty = ccx.icx(&impl_predicates) .to_ty(&ExplicitRscope, &ty); @@ -910,7 +910,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { } hir::ImplItemKind::Type(ref ty) => { - let type_def_id = ccx.tcx.map.local_def_id(impl_item.id); + let type_def_id = ccx.tcx.hir.local_def_id(impl_item.id); generics_of_def_id(ccx, type_def_id); if impl_trait_ref.is_none() { @@ -937,13 +937,13 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty: Ty<'tcx>, predicates: ty::GenericPredicates<'tcx>) { let tcx = ccx.tcx; - let def_id = tcx.map.local_def_id(ctor_id); + let def_id = tcx.hir.local_def_id(ctor_id); generics_of_def_id(ccx, def_id); let ctor_ty = match variant.ctor_kind { CtorKind::Fictive | CtorKind::Const => ty, CtorKind::Fn => { let inputs = variant.fields.iter().map(|field| tcx.item_type(field.did)); - let substs = mk_item_substs(&ccx.icx(&predicates), ccx.tcx.map.span(ctor_id), def_id); + let substs = mk_item_substs(&ccx.icx(&predicates), ccx.tcx.hir.span(ctor_id), def_id); tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: abi::Abi::Rust, @@ -952,7 +952,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } }; tcx.item_types.borrow_mut().insert(def_id, ctor_ty); - tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates); + tcx.predicates.borrow_mut().insert(tcx.hir.local_def_id(ctor_id), predicates); } fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -986,9 +986,9 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def: &hir::VariantData) -> ty::VariantDef { let mut seen_fields: FxHashMap = FxHashMap(); - let node_id = ccx.tcx.map.as_local_node_id(did).unwrap(); + let node_id = ccx.tcx.hir.as_local_node_id(did).unwrap(); let fields = def.fields().iter().map(|f| { - let fid = ccx.tcx.map.local_def_id(f.id); + let fid = ccx.tcx.hir.local_def_id(f.id); let dup_span = seen_fields.get(&f.name).cloned(); if let Some(prev_span) = dup_span { struct_span_err!(ccx.tcx.sess, f.span, E0124, @@ -1021,9 +1021,9 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def: &hir::VariantData) -> &'tcx ty::AdtDef { - let did = ccx.tcx.map.local_def_id(it.id); + let did = ccx.tcx.hir.local_def_id(it.id); // Use separate constructor id for unit/tuple structs and reuse did for braced structs. - let ctor_id = if !def.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) } else { None }; + let ctor_id = if !def.is_struct() { Some(ccx.tcx.hir.local_def_id(def.id())) } else { None }; let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name, ConstInt::Infer(0), def)]; let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants); @@ -1041,7 +1041,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def: &hir::VariantData) -> &'tcx ty::AdtDef { - let did = ccx.tcx.map.local_def_id(it.id); + let did = ccx.tcx.hir.local_def_id(it.id); let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)]; let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants); @@ -1051,8 +1051,8 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, body: hir::BodyId) -> Option { - let e = &ccx.tcx.map.body(body).value; - debug!("disr expr, checking {}", ccx.tcx.map.node_to_pretty_string(e.id)); + let e = &ccx.tcx.hir.body(body).value; + debug!("disr expr, checking {}", ccx.tcx.hir.node_to_pretty_string(e.id)); let ty_hint = repr_ty.to_ty(ccx.tcx); let print_err = |cv: ConstVal| { @@ -1106,7 +1106,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, -> &'tcx ty::AdtDef { let tcx = ccx.tcx; - let did = tcx.map.local_def_id(it.id); + let did = tcx.hir.local_def_id(it.id); let repr_hints = tcx.lookup_repr_hints(did); let repr_type = tcx.enum_repr_type(repr_hints.get(0)); let initial = repr_type.initial_discriminant(tcx); @@ -1128,7 +1128,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }.unwrap_or(wrapped_disr); prev_disr = Some(disr); - let did = tcx.map.local_def_id(v.node.data.id()); + let did = tcx.hir.local_def_id(v.node.data.id()); convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data) }).collect(); @@ -1152,7 +1152,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id); - let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) { + let trait_node_id = if let Some(n) = tcx.hir.as_local_node_id(trait_def_id) { n } else { // If this trait comes from an external crate, then all of the @@ -1165,7 +1165,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned(); let superpredicates = superpredicates.unwrap_or_else(|| { - let item = match ccx.tcx.map.get(trait_node_id) { + let item = match ccx.tcx.hir.get(trait_node_id) { hir_map::NodeItem(item) => item, _ => bug!("trait_node_id {} is not an item", trait_node_id) }; @@ -1213,7 +1213,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, predicates: superbounds }; debug!("superpredicates for trait {:?} = {:?}", - tcx.map.local_def_id(item.id), + tcx.hir.local_def_id(item.id), superpredicates); tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone()); @@ -1233,7 +1233,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, } fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef { - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); let tcx = ccx.tcx; tcx.trait_defs.memoize(def_id, || { @@ -1262,7 +1262,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'t fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) { let tcx = ccx.tcx; - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); generics_of_def_id(ccx, def_id); trait_def_of_item(ccx, it); @@ -1319,7 +1319,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> Vec> { trait_item_refs.iter().flat_map(|trait_item_ref| { - let trait_item = ccx.tcx.map.trait_item(trait_item_ref.id); + let trait_item = ccx.tcx.hir.trait_item(trait_item_ref.id); let bounds = match trait_item.node { hir::TraitItemKind::Type(ref bounds, _) => bounds, _ => { @@ -1346,7 +1346,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId) -> &'tcx ty::Generics<'tcx> { let tcx = ccx.tcx; - let node_id = if let Some(id) = tcx.map.as_local_node_id(def_id) { + let node_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) { id } else { return tcx.item_generics(def_id); @@ -1355,14 +1355,14 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, use rustc::hir::map::*; use rustc::hir::*; - let node = tcx.map.get(node_id); + let node = tcx.hir.get(node_id); let parent_def_id = match node { NodeImplItem(_) | NodeTraitItem(_) | NodeVariant(_) | NodeStructCtor(_) => { - let parent_id = tcx.map.get_parent(node_id); - Some(tcx.map.local_def_id(parent_id)) + let parent_id = tcx.hir.get_parent(node_id); + Some(tcx.hir.local_def_id(parent_id)) } NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => { Some(tcx.closure_base_def_id(def_id)) @@ -1370,14 +1370,14 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => { let mut parent_id = node_id; loop { - match tcx.map.get(parent_id) { + match tcx.hir.get(parent_id) { NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break, _ => { - parent_id = tcx.map.get_parent_node(parent_id); + parent_id = tcx.hir.get_parent_node(parent_id); } } } - Some(tcx.map.local_def_id(parent_id)) + Some(tcx.hir.local_def_id(parent_id)) } _ => None }; @@ -1421,13 +1421,13 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // the node id for the Self type parameter. let param_id = item.id; - let parent = ccx.tcx.map.get_parent(param_id); + let parent = ccx.tcx.hir.get_parent(param_id); let def = ty::TypeParameterDef { index: 0, name: keywords::SelfType.name(), - def_id: tcx.map.local_def_id(param_id), - default_def_id: tcx.map.local_def_id(parent), + def_id: tcx.hir.local_def_id(param_id), + default_def_id: tcx.hir.local_def_id(parent), default: None, object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault, pure_wrt_drop: false, @@ -1470,7 +1470,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty::RegionParameterDef { name: l.lifetime.name, index: own_start + i as u32, - def_id: tcx.map.local_def_id(l.lifetime.id), + def_id: tcx.hir.local_def_id(l.lifetime.id), bounds: l.bounds.iter().map(|l| { ast_region_to_region(tcx, l) }).collect(), @@ -1512,7 +1512,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, d => format!("{:?}", d), } }).collect::>().join(","); - tcx.sess.span_err(tcx.map.span(node_id), &object_lifetime_default_reprs); + tcx.sess.span_err(tcx.hir.span(node_id), &object_lifetime_default_reprs); } tcx.alloc_generics(ty::Generics { @@ -1529,7 +1529,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: DefId) -> Ty<'tcx> { - let node_id = if let Some(id) = ccx.tcx.map.as_local_node_id(def_id) { + let node_id = if let Some(id) = ccx.tcx.hir.as_local_node_id(def_id) { id } else { return ccx.tcx.item_type(def_id); @@ -1541,7 +1541,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Alway bring in generics, as computing the type needs them. generics_of_def_id(ccx, def_id); - let ty = match ccx.tcx.map.get(node_id) { + let ty = match ccx.tcx.hir.get(node_id) { NodeItem(item) => { match item.node { ItemStatic(ref t, ..) | ItemConst(ref t, _) => { @@ -1586,12 +1586,12 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } NodeForeignItem(foreign_item) => { - let abi = ccx.tcx.map.get_foreign_abi(node_id); + let abi = ccx.tcx.hir.get_foreign_abi(node_id); match foreign_item.node { ForeignItemFn(ref fn_decl, _, ref generics) => { compute_type_of_foreign_fn_decl( - ccx, ccx.tcx.map.local_def_id(foreign_item.id), + ccx, ccx.tcx.hir.local_def_id(foreign_item.id), fn_decl, generics, abi) } ForeignItemStatic(ref t, _) => { @@ -1621,7 +1621,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> ty::GenericPredicates<'tcx> { - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); let no_generics = hir::Generics::empty(); let generics = match it.node { @@ -1648,7 +1648,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // map, and I regard each time that I use it as a personal and // moral failing, but at the moment it seems like the only // convenient way to extract the ABI. - ndm - let def_id = ccx.tcx.map.local_def_id(it.id); + let def_id = ccx.tcx.hir.local_def_id(it.id); type_of_def_id(ccx, def_id); generics_of_def_id(ccx, def_id); @@ -1868,7 +1868,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, compute_object_lifetime_default(ccx, param.id, ¶m.bounds, &ast_generics.where_clause); - let parent = tcx.map.get_parent(param.id); + let parent = tcx.hir.get_parent(param.id); if !allow_defaults && default.is_some() { if !tcx.sess.features.borrow().default_type_parameter_fallback { @@ -1884,8 +1884,8 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let def = ty::TypeParameterDef { index: index, name: param.name, - def_id: ccx.tcx.map.local_def_id(param.id), - default_def_id: ccx.tcx.map.local_def_id(parent), + def_id: ccx.tcx.hir.local_def_id(param.id), + default_def_id: ccx.tcx.hir.local_def_id(parent), default: default, object_lifetime_default: object_lifetime_default, pure_wrt_drop: param.pure_wrt_drop, @@ -2083,7 +2083,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( ccx.tcx.sess.struct_span_err(ast_ty.span, &format!("use of SIMD type `{}` in FFI is highly experimental and \ may result in invalid code", - ccx.tcx.map.node_to_pretty_string(ast_ty.id))) + ccx.tcx.hir.node_to_pretty_string(ast_ty.id))) .help("add #![feature(simd_ffi)] to the crate attributes to enable") .emit(); } @@ -2096,8 +2096,8 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( } } - let id = ccx.tcx.map.as_local_node_id(def_id).unwrap(); - let substs = mk_item_substs(&ccx.icx(ast_generics), ccx.tcx.map.span(id), def_id); + let id = ccx.tcx.hir.as_local_node_id(def_id).unwrap(); + let substs = mk_item_substs(&ccx.icx(ast_generics), ccx.tcx.hir.span(id), def_id); ccx.tcx.mk_fn_def(def_id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy { abi: abi, unsafety: hir::Unsafety::Unsafe, diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index ce495e6fb4cd8..3a19b3579d559 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { hir::ItemImpl(.., ref generics, _, _, ref impl_item_refs) => { - let impl_def_id = self.ccx.tcx.map.local_def_id(item.id); + let impl_def_id = self.ccx.tcx.hir.local_def_id(item.id); enforce_impl_params_are_constrained(self.ccx, generics, impl_def_id, @@ -117,7 +117,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Disallow unconstrained lifetimes, but only if they appear in assoc types. let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() - .map(|item_ref| ccx.tcx.map.local_def_id(item_ref.id.node_id)) + .map(|item_ref| ccx.tcx.hir.local_def_id(item_ref.id.node_id)) .filter(|&def_id| { let item = ccx.tcx.associated_item(def_id); item.kind == ty::AssociatedKind::Type && item.defaultness.has_value() @@ -181,7 +181,7 @@ fn enforce_impl_items_are_distinct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let mut seen_type_items = FxHashMap(); let mut seen_value_items = FxHashMap(); for impl_item_ref in impl_item_refs { - let impl_item = tcx.map.impl_item(impl_item_ref.id); + let impl_item = tcx.hir.impl_item(impl_item_ref.id); let seen_items = match impl_item.node { hir::ImplItemKind::Type(_) => &mut seen_type_items, _ => &mut seen_value_items, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 6d30a85b58291..0e7daa03404c5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -196,11 +196,11 @@ fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::NodeId, main_span: Span) { let tcx = ccx.tcx; - let main_def_id = tcx.map.local_def_id(main_id); + let main_def_id = tcx.hir.local_def_id(main_id); let main_t = tcx.item_type(main_def_id); match main_t.sty { ty::TyFnDef(..) => { - match tcx.map.find(main_id) { + match tcx.hir.find(main_id) { Some(hir_map::NodeItem(it)) => { match it.node { hir::ItemFn(.., ref generics, _) => { @@ -244,11 +244,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt, start_id: ast::NodeId, start_span: Span) { let tcx = ccx.tcx; - let start_def_id = ccx.tcx.map.local_def_id(start_id); + let start_def_id = ccx.tcx.hir.local_def_id(start_id); let start_t = tcx.item_type(start_def_id); match start_t.sty { ty::TyFnDef(..) => { - match tcx.map.find(start_id) { + match tcx.hir.find(start_id) { Some(hir_map::NodeItem(it)) => { match it.node { hir::ItemFn(..,ref ps,_) diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 507079a4f874c..55033330a4490 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -74,9 +74,9 @@ pub fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>) impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { let tcx = self.terms_cx.tcx; - let did = tcx.map.local_def_id(item.id); + let did = tcx.hir.local_def_id(item.id); - debug!("visit_item item={}", tcx.map.node_to_string(item.id)); + debug!("visit_item item={}", tcx.hir.node_to_string(item.id)); match item.node { hir::ItemEnum(..) | @@ -145,14 +145,14 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { Some(&index) => index, None => { bug!("no inferred index entry for {}", - self.tcx().map.node_to_string(param_id)); + self.tcx().hir.node_to_string(param_id)); } } } fn find_binding_for_lifetime(&self, param_id: ast::NodeId) -> ast::NodeId { let tcx = self.terms_cx.tcx; - assert!(is_lifetime(&tcx.map, param_id)); + assert!(is_lifetime(&tcx.hir, param_id)); match tcx.named_region_map.defs.get(¶m_id) { Some(&rl::DefEarlyBoundRegion(_, lifetime_decl_id)) => lifetime_decl_id, Some(_) => bug!("should not encounter non early-bound cases"), @@ -177,17 +177,17 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let tcx = this.terms_cx.tcx; let decl_id = this.find_binding_for_lifetime(param_id); // Currently only called on lifetimes; double-checking that. - assert!(is_lifetime(&tcx.map, param_id)); - let parent_id = tcx.map.get_parent(decl_id); - let parent = tcx.map + assert!(is_lifetime(&tcx.hir, param_id)); + let parent_id = tcx.hir.get_parent(decl_id); + let parent = tcx.hir .find(parent_id) - .unwrap_or_else(|| bug!("tcx.map missing entry for id: {}", parent_id)); + .unwrap_or_else(|| bug!("tcx.hir missing entry for id: {}", parent_id)); let is_inferred; macro_rules! cannot_happen { () => { { bug!("invalid parent: {} for {}", - tcx.map.node_to_string(parent_id), - tcx.map.node_to_string(param_id)); + tcx.hir.node_to_string(parent_id), + tcx.hir.node_to_string(param_id)); } } } match parent { @@ -224,7 +224,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { -> VarianceTermPtr<'a> { assert_eq!(param_def_id.krate, item_def_id.krate); - if let Some(param_node_id) = self.tcx().map.as_local_node_id(param_def_id) { + if let Some(param_node_id) = self.tcx().hir.as_local_node_id(param_def_id) { // Parameter on an item defined within current crate: // variance not yet inferred, so return a symbolic // variance. @@ -400,7 +400,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { i -= generics.regions.len(); } let def_id = generics.types[i].def_id; - let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); + let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap(); match self.terms_cx.inferred_map.get(&node_id) { Some(&index) => { self.add_constraint(index, variance); @@ -487,7 +487,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { assert_eq!(generics.parent, None); let i = data.index as usize - generics.has_self as usize; let def_id = generics.regions[i].def_id; - let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); + let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap(); if self.is_to_be_inferred(node_id) { let index = self.inferred_index(node_id); self.add_constraint(index, variance); diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs index a5c53b4c6291c..bdf1d0590bcc7 100644 --- a/src/librustc_typeck/variance/solve.rs +++ b/src/librustc_typeck/variance/solve.rs @@ -125,13 +125,13 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { debug!("item_id={} item_variances={:?}", item_id, item_variances); - let item_def_id = tcx.map.local_def_id(item_id); + let item_def_id = tcx.hir.local_def_id(item_id); // For unit testing: check for a special "rustc_variance" // attribute and report an error with various results if found. if tcx.has_attr(item_def_id, "rustc_variance") { span_err!(tcx.sess, - tcx.map.span(item_id), + tcx.hir.span(item_id), E0208, "{:?}", item_variances); diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index d4d3edbcb126e..0e09d34cc9bd3 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -132,7 +132,7 @@ fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId, Vec)> { all.into_iter() // iterating over (Option, Variance) .filter(|&(ref d,_)| d.is_some()) .map(|(d, v)| (d.unwrap(), v)) // (DefId, Variance) - .filter_map(|(d, v)| tcx.map.as_local_node_id(d).map(|n| (n, v))) // (NodeId, Variance) + .filter_map(|(d, v)| tcx.hir.as_local_node_id(d).map(|n| (n, v))) // (NodeId, Variance) .collect() } @@ -177,7 +177,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { // "invalid item id" from "item id with no // parameters". if self.num_inferred() == inferreds_on_entry { - let item_def_id = self.tcx.map.local_def_id(item_id); + let item_def_id = self.tcx.hir.local_def_id(item_id); let newly_added = self.tcx .item_variance_map .borrow_mut() @@ -207,7 +207,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { param_id={}, \ inf_index={:?}, \ initial_variance={:?})", - self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)), + self.tcx.item_path_str(self.tcx.hir.local_def_id(item_id)), item_id, index, param_id, @@ -230,7 +230,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { debug!("add_inferreds for item {}", - self.tcx.map.node_to_string(item.id)); + self.tcx.hir.node_to_string(item.id)); match item.node { hir::ItemEnum(_, ref generics) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a77485477b159..eedca0ffb6327 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -223,17 +223,17 @@ impl Clean for CrateNum { None }; let primitives = if root.is_local() { - cx.tcx.map.krate().module.item_ids.iter().filter_map(|&id| { - let item = cx.tcx.map.expect_item(id.id); + cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| { + let item = cx.tcx.hir.expect_item(id.id); match item.node { hir::ItemMod(_) => { - as_primitive(Def::Mod(cx.tcx.map.local_def_id(id.id))) + as_primitive(Def::Mod(cx.tcx.hir.local_def_id(id.id))) } hir::ItemUse(ref path, hir::UseKind::Single) if item.vis == hir::Visibility::Public => { as_primitive(path.def).map(|(_, prim, attrs)| { // Pretend the primitive is local. - (cx.tcx.map.local_def_id(id.id), prim, attrs) + (cx.tcx.hir.local_def_id(id.id), prim, attrs) }) } _ => None @@ -454,7 +454,7 @@ impl Clean for doctree::Module { visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), inner: ModuleItem(Module { is_crate: self.is_crate, items: items @@ -576,7 +576,7 @@ impl Clean for hir::TyParam { fn clean(&self, cx: &DocContext) -> TyParam { TyParam { name: self.name.clean(cx), - did: cx.tcx.map.local_def_id(self.id), + did: cx.tcx.hir.local_def_id(self.id), bounds: self.bounds.clean(cx), default: self.default.clean(cx), } @@ -1067,7 +1067,7 @@ impl Clean for doctree::Function { visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), inner: FunctionItem(Function { decl: (&self.decl, self.body).clean(cx), generics: self.generics.clean(cx), @@ -1122,7 +1122,7 @@ impl<'a> Clean for (&'a [P], &'a [Spanned]) { impl<'a> Clean for (&'a [P], hir::BodyId) { fn clean(&self, cx: &DocContext) -> Arguments { - let body = cx.tcx.map.body(self.1); + let body = cx.tcx.hir.body(self.1); Arguments { values: self.0.iter().enumerate().map(|(i, ty)| { @@ -1151,7 +1151,7 @@ impl<'a, A: Copy> Clean for (&'a hir::FnDecl, A) impl<'a, 'tcx> Clean for (DefId, &'a ty::PolyFnSig<'tcx>) { fn clean(&self, cx: &DocContext) -> FnDecl { let (did, sig) = *self; - let mut names = if cx.tcx.map.as_local_node_id(did).is_some() { + let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() { vec![].into_iter() } else { cx.tcx.sess.cstore.fn_arg_names(did).into_iter() @@ -1231,7 +1231,7 @@ impl Clean for doctree::Trait { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -1286,10 +1286,10 @@ impl Clean for hir::TraitItem { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.span.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: None, - stability: get_stability(cx, cx.tcx.map.local_def_id(self.id)), - deprecation: get_deprecation(cx, cx.tcx.map.local_def_id(self.id)), + stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)), + deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)), inner: inner } } @@ -1318,10 +1318,10 @@ impl Clean for hir::ImplItem { name: Some(self.name.clean(cx)), source: self.span.clean(cx), attrs: self.attrs.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), - stability: get_stability(cx, cx.tcx.map.local_def_id(self.id)), - deprecation: get_deprecation(cx, cx.tcx.map.local_def_id(self.id)), + stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)), + deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)), inner: inner } } @@ -1703,9 +1703,9 @@ impl Clean for hir::Ty { let mut alias = None; if let Def::TyAlias(def_id) = path.def { // Substitute private type aliases - if let Some(node_id) = cx.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) { if !cx.access_levels.borrow().is_exported(def_id) { - alias = Some(&cx.tcx.map.expect_item(node_id).node); + alias = Some(&cx.tcx.hir.expect_item(node_id).node); } } }; @@ -1715,7 +1715,7 @@ impl Clean for hir::Ty { let mut ty_substs = FxHashMap(); let mut lt_substs = FxHashMap(); for (i, ty_param) in generics.ty_params.iter().enumerate() { - let ty_param_def = Def::TyParam(cx.tcx.map.local_def_id(ty_param.id)); + let ty_param_def = Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id)); if let Some(ty) = provided_params.types().get(i).cloned() .cloned() { ty_substs.insert(ty_param_def, ty.unwrap().clean(cx)); @@ -1823,7 +1823,7 @@ impl<'tcx> Clean for ty::Ty<'tcx> { type_params: Vec::new(), where_predicates: Vec::new() }, - decl: (cx.tcx.map.local_def_id(ast::CRATE_NODE_ID), &fty.sig).clean(cx), + decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), &fty.sig).clean(cx), abi: fty.abi, }), ty::TyAdt(def, substs) => { @@ -1919,9 +1919,9 @@ impl Clean for hir::StructField { attrs: self.attrs.clean(cx), source: self.span.clean(cx), visibility: self.vis.clean(cx), - stability: get_stability(cx, cx.tcx.map.local_def_id(self.id)), - deprecation: get_deprecation(cx, cx.tcx.map.local_def_id(self.id)), - def_id: cx.tcx.map.local_def_id(self.id), + stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)), + deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)), + def_id: cx.tcx.hir.local_def_id(self.id), inner: StructFieldItem(self.ty.clean(cx)), } } @@ -1982,7 +1982,7 @@ impl Clean for doctree::Struct { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2002,7 +2002,7 @@ impl Clean for doctree::Union { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2049,7 +2049,7 @@ impl Clean for doctree::Enum { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2076,7 +2076,7 @@ impl Clean for doctree::Variant { visibility: None, stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), - def_id: cx.tcx.map.local_def_id(self.def.id()), + def_id: cx.tcx.hir.local_def_id(self.def.id()), inner: VariantItem(Variant { kind: self.def.clean(cx), }), @@ -2306,7 +2306,7 @@ impl Clean for doctree::Typedef { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id.clone()), + def_id: cx.tcx.hir.local_def_id(self.id.clone()), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2358,7 +2358,7 @@ impl Clean for doctree::Static { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2383,7 +2383,7 @@ impl Clean for doctree::Constant { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2459,7 +2459,7 @@ impl Clean> for doctree::Impl { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), stability: self.stab.clean(cx), deprecation: self.depr.clean(cx), @@ -2542,7 +2542,7 @@ impl Clean for doctree::DefaultImpl { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: Some(Public), stability: None, deprecation: None, @@ -2598,7 +2598,7 @@ impl Clean> for doctree::Import { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), - def_id: cx.tcx.map.local_def_id(ast::CRATE_NODE_ID), + def_id: cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), visibility: self.vis.clean(cx), stability: None, deprecation: None, @@ -2657,10 +2657,10 @@ impl Clean for hir::ForeignItem { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.span.clean(cx), - def_id: cx.tcx.map.local_def_id(self.id), + def_id: cx.tcx.hir.local_def_id(self.id), visibility: self.vis.clean(cx), - stability: get_stability(cx, cx.tcx.map.local_def_id(self.id)), - deprecation: get_deprecation(cx, cx.tcx.map.local_def_id(self.id)), + stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)), + deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)), inner: inner, } } @@ -2721,7 +2721,7 @@ fn name_from_pat(p: &hir::Pat) -> String { } fn print_const_expr(cx: &DocContext, body: hir::BodyId) -> String { - cx.tcx.map.node_to_pretty_string(body.node_id) + cx.tcx.hir.node_to_pretty_string(body.node_id) } /// Given a type Path, resolve it to a Type using the TyCtxt diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 514eb6ea843de..5393e395bbe43 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths, // to the map from defid -> nodeid let access_levels = AccessLevels { map: access_levels.map.into_iter() - .map(|(k, v)| (tcx.map.local_def_id(k), v)) + .map(|(k, v)| (tcx.hir.local_def_id(k), v)) .collect() }; @@ -204,11 +204,11 @@ pub fn run_core(search_paths: SearchPaths, export_map: export_map, hir_ty_to_ty: hir_ty_to_ty, }; - debug!("crate: {:?}", tcx.map.krate()); + debug!("crate: {:?}", tcx.hir.krate()); let krate = { let mut v = RustdocVisitor::new(&ctxt); - v.visit(tcx.map.krate()); + v.visit(tcx.hir.krate()); v.clean(&ctxt) }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index b0afc3d63f479..394eb4779898c 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -65,12 +65,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } fn stability(&self, id: ast::NodeId) -> Option { - self.cx.tcx.map.opt_local_def_id(id) + self.cx.tcx.hir.opt_local_def_id(id) .and_then(|def_id| self.cx.tcx.lookup_stability(def_id)).cloned() } fn deprecation(&self, id: ast::NodeId) -> Option { - self.cx.tcx.map.opt_local_def_id(id) + self.cx.tcx.hir.opt_local_def_id(id) .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id)) } @@ -193,7 +193,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let orig_inside_public_path = self.inside_public_path; self.inside_public_path &= vis == hir::Public; for i in &m.item_ids { - let item = self.cx.tcx.map.expect_item(i.id); + let item = self.cx.tcx.hir.expect_item(i.id); self.visit_item(item, None, &mut om); } self.inside_public_path = orig_inside_public_path; @@ -246,9 +246,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { please_inline: bool) -> bool { fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool { - while let Some(id) = cx.tcx.map.get_enclosing_scope(node) { + while let Some(id) = cx.tcx.hir.get_enclosing_scope(node) { node = id; - if cx.tcx.map.attrs(node).lists("doc").has_word("hidden") { + if cx.tcx.hir.attrs(node).lists("doc").has_word("hidden") { return true; } if node == ast::CRATE_NODE_ID { @@ -264,7 +264,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } let def_did = def.def_id(); - let use_attrs = tcx.map.attrs(id); + let use_attrs = tcx.hir.attrs(id); // Don't inline doc(hidden) imports so they can be stripped at a later stage. let is_no_inline = use_attrs.lists("doc").has_word("no_inline") || use_attrs.lists("doc").has_word("hidden"); @@ -292,7 +292,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false } - let def_node_id = match tcx.map.as_local_node_id(def_did) { + let def_node_id = match tcx.hir.as_local_node_id(def_did) { Some(n) => n, None => return false }; @@ -306,14 +306,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if !self.view_item_stack.insert(def_node_id) { return false } - let ret = match tcx.map.get(def_node_id) { + let ret = match tcx.hir.get(def_node_id) { hir_map::NodeItem(it) => { let prev = mem::replace(&mut self.inlining, true); if glob { match it.node { hir::ItemMod(ref m) => { for i in &m.item_ids { - let i = self.cx.tcx.map.expect_item(i.id); + let i = self.cx.tcx.hir.expect_item(i.id); self.visit_item(i, None, om); } } @@ -460,7 +460,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }, hir::ItemTrait(unsafety, ref gen, ref b, ref item_ids) => { let items = item_ids.iter() - .map(|ti| self.cx.tcx.map.trait_item(ti.id).clone()) + .map(|ti| self.cx.tcx.hir.trait_item(ti.id).clone()) .collect(); let t = Trait { unsafety: unsafety, @@ -483,7 +483,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // regardless of where they're located. if !self.inlining { let items = item_ids.iter() - .map(|ii| self.cx.tcx.map.impl_item(ii.id).clone()) + .map(|ii| self.cx.tcx.hir.impl_item(ii.id).clone()) .collect(); let i = Impl { unsafety: unsafety, @@ -524,7 +524,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let matchers = def.body.chunks(4).map(|arm| arm[0].get_span()).collect(); Macro { - def_id: self.cx.tcx.map.local_def_id(def.id), + def_id: self.cx.tcx.hir.local_def_id(def.id), attrs: def.attrs.clone(), name: def.name, whence: def.span, diff --git a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs b/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs index e1b1b441894b7..778c49d144c02 100644 --- a/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs +++ b/src/test/run-pass-fulldeps/issue-37290/auxiliary/lint.rs @@ -53,8 +53,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if let Some(other) = self.map.insert(extent, node) { cx.span_lint(REGION_HIERARCHY, span, &format!( "different fns {:?}, {:?} with the same root extent {:?}", - cx.tcx.map.local_def_id(other), - cx.tcx.map.local_def_id(node), + cx.tcx.hir.local_def_id(other), + cx.tcx.hir.local_def_id(node), extent)); } } From 1ff3641623ce5f83cba30c2d2f039dbd49c4b4b8 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 26 Jan 2017 03:21:50 +0200 Subject: [PATCH 33/86] rustc: don't call the HIR AST. --- src/librustc/cfg/graphviz.rs | 14 +- src/librustc/hir/intravisit.rs | 12 +- src/librustc/hir/map/collector.rs | 54 +++---- src/librustc/hir/map/mod.rs | 152 ++++++++++---------- src/librustc/infer/error_reporting.rs | 44 +++--- src/librustc/middle/dead.rs | 20 +-- src/librustc/middle/entry.rs | 14 +- src/librustc/middle/lang_items.rs | 14 +- src/librustc/middle/mem_categorization.rs | 6 +- src/librustc/middle/reachable.rs | 30 ++-- src/librustc/middle/region.rs | 46 +++--- src/librustc/ty/context.rs | 6 +- src/librustc/ty/mod.rs | 22 +-- src/librustc/ty/util.rs | 4 +- src/librustc_borrowck/borrowck/move_data.rs | 2 +- src/librustc_const_eval/eval.rs | 10 +- src/librustc_driver/driver.rs | 6 +- src/librustc_driver/lib.rs | 2 +- src/librustc_driver/pretty.rs | 136 ++++++++---------- src/librustc_driver/test.rs | 12 +- src/librustc_passes/loops.rs | 18 +-- src/librustc_passes/static_recursion.rs | 84 +++++------ 22 files changed, 345 insertions(+), 363 deletions(-) diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs index c651baae28224..944b77dbf01fd 100644 --- a/src/librustc/cfg/graphviz.rs +++ b/src/librustc/cfg/graphviz.rs @@ -17,14 +17,14 @@ use graphviz::IntoCow; use syntax::ast; -use hir::map as ast_map; +use hir::map as hir_map; use cfg; pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode); pub type Edge<'a> = &'a cfg::CFGEdge; -pub struct LabelledCFG<'a, 'ast: 'a> { - pub ast_map: &'a ast_map::Map<'ast>, +pub struct LabelledCFG<'a, 'hir: 'a> { + pub hir_map: &'a hir_map::Map<'hir>, pub cfg: &'a cfg::CFG, pub name: String, /// `labelled_edges` controls whether we emit labels on the edges @@ -52,7 +52,7 @@ fn replace_newline_with_backslash_l(s: String) -> String { } } -impl<'a, 'ast> dot::Labeller<'a> for LabelledCFG<'a, 'ast> { +impl<'a, 'hir> dot::Labeller<'a> for LabelledCFG<'a, 'hir> { type Node = Node<'a>; type Edge = Edge<'a>; fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[..]).unwrap() } @@ -69,7 +69,7 @@ impl<'a, 'ast> dot::Labeller<'a> for LabelledCFG<'a, 'ast> { } else if n.data.id() == ast::DUMMY_NODE_ID { dot::LabelText::LabelStr("(dummy_node)".into_cow()) } else { - let s = self.ast_map.node_to_string(n.data.id()); + let s = self.hir_map.node_to_string(n.data.id()); // left-aligns the lines let s = replace_newline_with_backslash_l(s); dot::LabelText::EscStr(s.into_cow()) @@ -88,7 +88,7 @@ impl<'a, 'ast> dot::Labeller<'a> for LabelledCFG<'a, 'ast> { } else { put_one = true; } - let s = self.ast_map.node_to_string(node_id); + let s = self.hir_map.node_to_string(node_id); // left-aligns the lines let s = replace_newline_with_backslash_l(s); label.push_str(&format!("exiting scope_{} {}", @@ -120,7 +120,7 @@ impl<'a> dot::GraphWalk<'a> for &'a cfg::CFG { } } -impl<'a, 'ast> dot::GraphWalk<'a> for LabelledCFG<'a, 'ast> +impl<'a, 'hir> dot::GraphWalk<'a> for LabelledCFG<'a, 'hir> { type Node = Node<'a>; type Edge = Edge<'a>; diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index cc6d61c21c696..d4095c6875c1d 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1085,13 +1085,13 @@ impl IdRange { } -pub struct IdRangeComputingVisitor<'a, 'ast: 'a> { +pub struct IdRangeComputingVisitor<'a, 'hir: 'a> { result: IdRange, - map: &'a map::Map<'ast>, + map: &'a map::Map<'hir>, } -impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> { - pub fn new(map: &'a map::Map<'ast>) -> IdRangeComputingVisitor<'a, 'ast> { +impl<'a, 'hir> IdRangeComputingVisitor<'a, 'hir> { + pub fn new(map: &'a map::Map<'hir>) -> IdRangeComputingVisitor<'a, 'hir> { IdRangeComputingVisitor { result: IdRange::max(), map: map } } @@ -1100,8 +1100,8 @@ impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> { } } -impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { +impl<'a, 'hir> Visitor<'hir> for IdRangeComputingVisitor<'a, 'hir> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { NestedVisitorMap::OnlyBodies(&self.map) } diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index bd0ff695d093a..904f74b8787fd 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -16,17 +16,17 @@ use syntax::ast::{NodeId, CRATE_NODE_ID}; use syntax_pos::Span; /// A Visitor that walks over the HIR and collects Nodes into a HIR map -pub struct NodeCollector<'ast> { +pub struct NodeCollector<'hir> { /// The crate - pub krate: &'ast Crate, + pub krate: &'hir Crate, /// The node map - pub(super) map: Vec>, + pub(super) map: Vec>, /// The parent of this node pub parent_node: NodeId, } -impl<'ast> NodeCollector<'ast> { - pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { +impl<'hir> NodeCollector<'hir> { + pub fn root(krate: &'hir Crate) -> NodeCollector<'hir> { let mut collector = NodeCollector { krate: krate, map: vec![], @@ -37,8 +37,8 @@ impl<'ast> NodeCollector<'ast> { collector } - fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { - debug!("ast_map: {:?} => {:?}", id, entry); + fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'hir>) { + debug!("hir_map: {:?} => {:?}", id, entry); let len = self.map.len(); if id.as_usize() >= len { self.map.extend(repeat(NotPresent).take(id.as_usize() - len + 1)); @@ -46,7 +46,7 @@ impl<'ast> NodeCollector<'ast> { self.map[id.as_usize()] = entry; } - fn insert(&mut self, id: NodeId, node: Node<'ast>) { + fn insert(&mut self, id: NodeId, node: Node<'hir>) { let entry = MapEntry::from_node(self.parent_node, node); self.insert_entry(id, entry); } @@ -59,12 +59,12 @@ impl<'ast> NodeCollector<'ast> { } } -impl<'ast> Visitor<'ast> for NodeCollector<'ast> { +impl<'hir> Visitor<'hir> for NodeCollector<'hir> { /// Because we want to track parent items and so forth, enable /// deep walking so that we walk nested items in the context of /// their outer items. - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { panic!("visit_nested_xxx must be manually implemented in this visitor") } @@ -85,7 +85,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.visit_body(self.krate.body(id)); } - fn visit_item(&mut self, i: &'ast Item) { + fn visit_item(&mut self, i: &'hir Item) { debug!("visit_item: {:?}", i); self.insert(i.id, NodeItem(i)); @@ -104,7 +104,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) { self.insert(foreign_item.id, NodeForeignItem(foreign_item)); self.with_parent(foreign_item.id, |this| { @@ -112,7 +112,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_generics(&mut self, generics: &'ast Generics) { + fn visit_generics(&mut self, generics: &'hir Generics) { for ty_param in generics.ty_params.iter() { self.insert(ty_param.id, NodeTyParam(ty_param)); } @@ -120,7 +120,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { intravisit::walk_generics(self, generics); } - fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + fn visit_trait_item(&mut self, ti: &'hir TraitItem) { self.insert(ti.id, NodeTraitItem(ti)); self.with_parent(ti.id, |this| { @@ -128,7 +128,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + fn visit_impl_item(&mut self, ii: &'hir ImplItem) { self.insert(ii.id, NodeImplItem(ii)); self.with_parent(ii.id, |this| { @@ -136,7 +136,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_pat(&mut self, pat: &'ast Pat) { + fn visit_pat(&mut self, pat: &'hir Pat) { let node = if let PatKind::Binding(..) = pat.node { NodeLocal(pat) } else { @@ -149,7 +149,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_expr(&mut self, expr: &'ast Expr) { + fn visit_expr(&mut self, expr: &'hir Expr) { self.insert(expr.id, NodeExpr(expr)); self.with_parent(expr.id, |this| { @@ -157,7 +157,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_stmt(&mut self, stmt: &'ast Stmt) { + fn visit_stmt(&mut self, stmt: &'hir Stmt) { let id = stmt.node.id(); self.insert(id, NodeStmt(stmt)); @@ -166,7 +166,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_ty(&mut self, ty: &'ast Ty) { + fn visit_ty(&mut self, ty: &'hir Ty) { self.insert(ty.id, NodeTy(ty)); self.with_parent(ty.id, |this| { @@ -174,7 +174,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_trait_ref(&mut self, tr: &'ast TraitRef) { + fn visit_trait_ref(&mut self, tr: &'hir TraitRef) { self.insert(tr.ref_id, NodeTraitRef(tr)); self.with_parent(tr.ref_id, |this| { @@ -182,24 +182,24 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, + fn visit_fn(&mut self, fk: intravisit::FnKind<'hir>, fd: &'hir FnDecl, b: BodyId, s: Span, id: NodeId) { assert_eq!(self.parent_node, id); intravisit::walk_fn(self, fk, fd, b, s, id); } - fn visit_block(&mut self, block: &'ast Block) { + fn visit_block(&mut self, block: &'hir Block) { self.insert(block.id, NodeBlock(block)); self.with_parent(block.id, |this| { intravisit::walk_block(this, block); }); } - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { + fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { self.insert(lifetime.id, NodeLifetime(lifetime)); } - fn visit_vis(&mut self, visibility: &'ast Visibility) { + fn visit_vis(&mut self, visibility: &'hir Visibility) { match *visibility { Visibility::Public | Visibility::Crate | @@ -213,11 +213,11 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + fn visit_macro_def(&mut self, macro_def: &'hir MacroDef) { self.insert_entry(macro_def.id, NotPresent); } - fn visit_variant(&mut self, v: &'ast Variant, g: &'ast Generics, item_id: NodeId) { + fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) { let id = v.node.data.id(); self.insert(id, NodeVariant(v)); self.with_parent(id, |this| { @@ -225,7 +225,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { }); } - fn visit_struct_field(&mut self, field: &'ast StructField) { + fn visit_struct_field(&mut self, field: &'hir StructField) { self.insert(field.id, NodeField(field)); self.with_parent(field.id, |this| { intravisit::walk_struct_field(this, field); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7c0621279fd6f..9f31b5b456b9f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -38,67 +38,67 @@ mod def_collector; pub mod definitions; #[derive(Copy, Clone, Debug)] -pub enum Node<'ast> { - NodeItem(&'ast Item), - NodeForeignItem(&'ast ForeignItem), - NodeTraitItem(&'ast TraitItem), - NodeImplItem(&'ast ImplItem), - NodeVariant(&'ast Variant), - NodeField(&'ast StructField), - NodeExpr(&'ast Expr), - NodeStmt(&'ast Stmt), - NodeTy(&'ast Ty), - NodeTraitRef(&'ast TraitRef), - NodeLocal(&'ast Pat), - NodePat(&'ast Pat), - NodeBlock(&'ast Block), +pub enum Node<'hir> { + NodeItem(&'hir Item), + NodeForeignItem(&'hir ForeignItem), + NodeTraitItem(&'hir TraitItem), + NodeImplItem(&'hir ImplItem), + NodeVariant(&'hir Variant), + NodeField(&'hir StructField), + NodeExpr(&'hir Expr), + NodeStmt(&'hir Stmt), + NodeTy(&'hir Ty), + NodeTraitRef(&'hir TraitRef), + NodeLocal(&'hir Pat), + NodePat(&'hir Pat), + NodeBlock(&'hir Block), /// NodeStructCtor represents a tuple struct. - NodeStructCtor(&'ast VariantData), + NodeStructCtor(&'hir VariantData), - NodeLifetime(&'ast Lifetime), - NodeTyParam(&'ast TyParam), - NodeVisibility(&'ast Visibility), + NodeLifetime(&'hir Lifetime), + NodeTyParam(&'hir TyParam), + NodeVisibility(&'hir Visibility), } /// Represents an entry and its parent NodeID. /// The odd layout is to bring down the total size. #[derive(Copy, Debug)] -enum MapEntry<'ast> { +enum MapEntry<'hir> { /// Placeholder for holes in the map. NotPresent, /// All the node types, with a parent ID. - EntryItem(NodeId, &'ast Item), - EntryForeignItem(NodeId, &'ast ForeignItem), - EntryTraitItem(NodeId, &'ast TraitItem), - EntryImplItem(NodeId, &'ast ImplItem), - EntryVariant(NodeId, &'ast Variant), - EntryField(NodeId, &'ast StructField), - EntryExpr(NodeId, &'ast Expr), - EntryStmt(NodeId, &'ast Stmt), - EntryTy(NodeId, &'ast Ty), - EntryTraitRef(NodeId, &'ast TraitRef), - EntryLocal(NodeId, &'ast Pat), - EntryPat(NodeId, &'ast Pat), - EntryBlock(NodeId, &'ast Block), - EntryStructCtor(NodeId, &'ast VariantData), - EntryLifetime(NodeId, &'ast Lifetime), - EntryTyParam(NodeId, &'ast TyParam), - EntryVisibility(NodeId, &'ast Visibility), + EntryItem(NodeId, &'hir Item), + EntryForeignItem(NodeId, &'hir ForeignItem), + EntryTraitItem(NodeId, &'hir TraitItem), + EntryImplItem(NodeId, &'hir ImplItem), + EntryVariant(NodeId, &'hir Variant), + EntryField(NodeId, &'hir StructField), + EntryExpr(NodeId, &'hir Expr), + EntryStmt(NodeId, &'hir Stmt), + EntryTy(NodeId, &'hir Ty), + EntryTraitRef(NodeId, &'hir TraitRef), + EntryLocal(NodeId, &'hir Pat), + EntryPat(NodeId, &'hir Pat), + EntryBlock(NodeId, &'hir Block), + EntryStructCtor(NodeId, &'hir VariantData), + EntryLifetime(NodeId, &'hir Lifetime), + EntryTyParam(NodeId, &'hir TyParam), + EntryVisibility(NodeId, &'hir Visibility), /// Roots for node trees. RootCrate, } -impl<'ast> Clone for MapEntry<'ast> { - fn clone(&self) -> MapEntry<'ast> { +impl<'hir> Clone for MapEntry<'hir> { + fn clone(&self) -> MapEntry<'hir> { *self } } -impl<'ast> MapEntry<'ast> { - fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { +impl<'hir> MapEntry<'hir> { + fn from_node(p: NodeId, node: Node<'hir>) -> MapEntry<'hir> { match node { NodeItem(n) => EntryItem(p, n), NodeForeignItem(n) => EntryForeignItem(p, n), @@ -145,7 +145,7 @@ impl<'ast> MapEntry<'ast> { }) } - fn to_node(self) -> Option> { + fn to_node(self) -> Option> { Some(match self { EntryItem(_, n) => NodeItem(n), EntryForeignItem(_, n) => NodeForeignItem(n), @@ -225,7 +225,7 @@ impl Forest { } } - pub fn krate<'ast>(&'ast self) -> &'ast Crate { + pub fn krate<'hir>(&'hir self) -> &'hir Crate { self.dep_graph.read(DepNode::Krate); &self.krate } @@ -234,9 +234,9 @@ impl Forest { /// Represents a mapping from Node IDs to AST elements and their parent /// Node IDs #[derive(Clone)] -pub struct Map<'ast> { +pub struct Map<'hir> { /// The backing storage for all the AST nodes. - pub forest: &'ast Forest, + pub forest: &'hir Forest, /// Same as the dep_graph in forest, just available with one fewer /// deref. This is a gratuitious micro-optimization. @@ -251,15 +251,15 @@ pub struct Map<'ast> { /// /// Also, indexing is pretty quick when you've got a vector and /// plain old integers. - map: Vec>, + map: Vec>, definitions: Definitions, /// Bodies inlined from other crates are cached here. - inlined_bodies: RefCell>, + inlined_bodies: RefCell>, } -impl<'ast> Map<'ast> { +impl<'hir> Map<'hir> { /// Registers a read in the dependency graph of the AST node with /// the given `id`. This needs to be called each time a public /// function returns the HIR for a node -- in other words, when it @@ -388,15 +388,15 @@ impl<'ast> Map<'ast> { self.map.len() } - fn find_entry(&self, id: NodeId) -> Option> { + fn find_entry(&self, id: NodeId) -> Option> { self.map.get(id.as_usize()).cloned() } - pub fn krate(&self) -> &'ast Crate { + pub fn krate(&self) -> &'hir Crate { self.forest.krate() } - pub fn trait_item(&self, id: TraitItemId) -> &'ast TraitItem { + pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem { self.read(id.node_id); // NB: intentionally bypass `self.forest.krate()` so that we @@ -404,7 +404,7 @@ impl<'ast> Map<'ast> { self.forest.krate.trait_item(id) } - pub fn impl_item(&self, id: ImplItemId) -> &'ast ImplItem { + pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem { self.read(id.node_id); // NB: intentionally bypass `self.forest.krate()` so that we @@ -412,7 +412,7 @@ impl<'ast> Map<'ast> { self.forest.krate.impl_item(id) } - pub fn body(&self, id: BodyId) -> &'ast Body { + pub fn body(&self, id: BodyId) -> &'hir Body { self.read(id.node_id); // NB: intentionally bypass `self.forest.krate()` so that we @@ -440,7 +440,7 @@ impl<'ast> Map<'ast> { /// Get the attributes on the krate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. - pub fn krate_attrs(&self) -> &'ast [ast::Attribute] { + pub fn krate_attrs(&self) -> &'hir [ast::Attribute] { let crate_root_def_id = DefId::local(CRATE_DEF_INDEX); self.dep_graph.read(DepNode::Hir(crate_root_def_id)); &self.forest.krate.attrs @@ -448,20 +448,20 @@ impl<'ast> Map<'ast> { /// Retrieve the Node corresponding to `id`, panicking if it cannot /// be found. - pub fn get(&self, id: NodeId) -> Node<'ast> { + pub fn get(&self, id: NodeId) -> Node<'hir> { match self.find(id) { Some(node) => node, // read recorded by `find` None => bug!("couldn't find node id {} in the AST map", id) } } - pub fn get_if_local(&self, id: DefId) -> Option> { + pub fn get_if_local(&self, id: DefId) -> Option> { self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` } /// Retrieve the Node corresponding to `id`, returning None if /// cannot be found. - pub fn find(&self, id: NodeId) -> Option> { + pub fn find(&self, id: NodeId) -> Option> { let result = self.find_entry(id).and_then(|x| x.to_node()); if result.is_some() { self.read(id); @@ -508,7 +508,7 @@ impl<'ast> Map<'ast> { /// is not an error, since items in the crate module have the crate root as /// parent. fn walk_parent_nodes(&self, start_id: NodeId, found: F) -> Result - where F: Fn(&Node<'ast>) -> bool + where F: Fn(&Node<'hir>) -> bool { let mut id = start_id; loop { @@ -611,28 +611,28 @@ impl<'ast> Map<'ast> { } } - pub fn expect_item(&self, id: NodeId) -> &'ast Item { + pub fn expect_item(&self, id: NodeId) -> &'hir Item { match self.find(id) { // read recorded by `find` Some(NodeItem(item)) => item, _ => bug!("expected item, found {}", self.node_to_string(id)) } } - pub fn expect_impl_item(&self, id: NodeId) -> &'ast ImplItem { + pub fn expect_impl_item(&self, id: NodeId) -> &'hir ImplItem { match self.find(id) { Some(NodeImplItem(item)) => item, _ => bug!("expected impl item, found {}", self.node_to_string(id)) } } - pub fn expect_trait_item(&self, id: NodeId) -> &'ast TraitItem { + pub fn expect_trait_item(&self, id: NodeId) -> &'hir TraitItem { match self.find(id) { Some(NodeTraitItem(item)) => item, _ => bug!("expected trait item, found {}", self.node_to_string(id)) } } - pub fn expect_variant_data(&self, id: NodeId) -> &'ast VariantData { + pub fn expect_variant_data(&self, id: NodeId) -> &'hir VariantData { match self.find(id) { Some(NodeItem(i)) => { match i.node { @@ -653,35 +653,35 @@ impl<'ast> Map<'ast> { } } - pub fn expect_variant(&self, id: NodeId) -> &'ast Variant { + pub fn expect_variant(&self, id: NodeId) -> &'hir Variant { match self.find(id) { Some(NodeVariant(variant)) => variant, _ => bug!("expected variant, found {}", self.node_to_string(id)), } } - pub fn expect_foreign_item(&self, id: NodeId) -> &'ast ForeignItem { + pub fn expect_foreign_item(&self, id: NodeId) -> &'hir ForeignItem { match self.find(id) { Some(NodeForeignItem(item)) => item, _ => bug!("expected foreign item, found {}", self.node_to_string(id)) } } - pub fn expect_expr(&self, id: NodeId) -> &'ast Expr { + pub fn expect_expr(&self, id: NodeId) -> &'hir Expr { match self.find(id) { // read recorded by find Some(NodeExpr(expr)) => expr, _ => bug!("expected expr, found {}", self.node_to_string(id)) } } - pub fn get_inlined_body(&self, def_id: DefId) -> Option<&'ast Body> { + pub fn get_inlined_body(&self, def_id: DefId) -> Option<&'hir Body> { self.inlined_bodies.borrow().get(&def_id).map(|&body| { self.dep_graph.read(DepNode::MetaData(def_id)); body }) } - pub fn intern_inlined_body(&self, def_id: DefId, body: Body) -> &'ast Body { + pub fn intern_inlined_body(&self, def_id: DefId, body: Body) -> &'hir Body { let body = self.forest.inlined_bodies.alloc(body); self.inlined_bodies.borrow_mut().insert(def_id, body); body @@ -706,7 +706,7 @@ impl<'ast> Map<'ast> { /// Given a node ID, get a list of attributes associated with the AST /// corresponding to the Node ID - pub fn attrs(&self, id: NodeId) -> &'ast [ast::Attribute] { + pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { self.read(id); // reveals attributes on the node let attrs = match self.find(id) { Some(NodeItem(i)) => Some(&i.attrs[..]), @@ -735,7 +735,7 @@ impl<'ast> Map<'ast> { /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and /// any other such items it can find in the map. pub fn nodes_matching_suffix<'a>(&'a self, parts: &'a [String]) - -> NodesMatchingSuffix<'a, 'ast> { + -> NodesMatchingSuffix<'a, 'hir> { NodesMatchingSuffix { map: self, item_name: parts.last().unwrap(), @@ -790,14 +790,14 @@ impl<'ast> Map<'ast> { } } -pub struct NodesMatchingSuffix<'a, 'ast:'a> { - map: &'a Map<'ast>, +pub struct NodesMatchingSuffix<'a, 'hir:'a> { + map: &'a Map<'hir>, item_name: &'a String, in_which: &'a [String], idx: NodeId, } -impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { +impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> { /// Returns true only if some suffix of the module path for parent /// matches `self.in_which`. /// @@ -853,7 +853,7 @@ impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { } } -impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> { +impl<'a, 'hir> Iterator for NodesMatchingSuffix<'a, 'hir> { type Item = NodeId; fn next(&mut self) -> Option { @@ -892,9 +892,9 @@ impl Named for StructField { fn name(&self) -> Name { self.name } } impl Named for TraitItem { fn name(&self) -> Name { self.name } } impl Named for ImplItem { fn name(&self) -> Name { self.name } } -pub fn map_crate<'ast>(forest: &'ast mut Forest, +pub fn map_crate<'hir>(forest: &'hir mut Forest, definitions: Definitions) - -> Map<'ast> { + -> Map<'hir> { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); let map = collector.map; @@ -926,7 +926,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest, /// Identical to the `PpAnn` implementation for `hir::Crate`, /// except it avoids creating a dependency on the whole crate. -impl<'ast> print::PpAnn for Map<'ast> { +impl<'hir> print::PpAnn for Map<'hir> { fn nested(&self, state: &mut print::State, nested: print::Nested) -> io::Result<()> { match nested { Nested::Item(id) => state.print_item(self.expect_item(id.id)), @@ -966,7 +966,7 @@ impl<'a> print::State<'a> { NodeTyParam(_) => bug!("cannot print TyParam"), NodeField(_) => bug!("cannot print StructField"), // these cases do not carry enough information in the - // ast_map to reconstruct their full structure for pretty + // hir_map to reconstruct their full structure for pretty // printing. NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), } diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 0b43f32e3dc29..73b5fda275819 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -73,7 +73,7 @@ use super::region_inference::SameRegions; use std::collections::HashSet; -use hir::map as ast_map; +use hir::map as hir_map; use hir; use lint; @@ -152,8 +152,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } }; let tag = match self.hir.find(scope.node_id(&self.region_maps)) { - Some(ast_map::NodeBlock(_)) => "block", - Some(ast_map::NodeExpr(expr)) => match expr.node { + Some(hir_map::NodeBlock(_)) => "block", + Some(hir_map::NodeExpr(expr)) => match expr.node { hir::ExprCall(..) => "call", hir::ExprMethodCall(..) => "method call", hir::ExprMatch(.., hir::MatchSource::IfLetDesugar { .. }) => "if let", @@ -162,10 +162,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { hir::ExprMatch(..) => "match", _ => "expression", }, - Some(ast_map::NodeStmt(_)) => "statement", - Some(ast_map::NodeItem(it)) => item_scope_tag(&it), - Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), - Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it), + Some(hir_map::NodeStmt(_)) => "statement", + Some(hir_map::NodeItem(it)) => item_scope_tag(&it), + Some(hir_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), + Some(hir_map::NodeImplItem(it)) => impl_item_scope_tag(&it), Some(_) | None => { err.span_note(span, &unknown_scope()); return; @@ -207,11 +207,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let node = fr.scope.node_id(&self.region_maps); let unknown; let tag = match self.hir.find(node) { - Some(ast_map::NodeBlock(_)) | - Some(ast_map::NodeExpr(_)) => "body", - Some(ast_map::NodeItem(it)) => item_scope_tag(&it), - Some(ast_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), - Some(ast_map::NodeImplItem(it)) => impl_item_scope_tag(&it), + Some(hir_map::NodeBlock(_)) | + Some(hir_map::NodeExpr(_)) => "body", + Some(hir_map::NodeItem(it)) => item_scope_tag(&it), + Some(hir_map::NodeTraitItem(it)) => trait_item_scope_tag(&it), + Some(hir_map::NodeImplItem(it)) => impl_item_scope_tag(&it), // this really should not happen, but it does: // FIXME(#27942) @@ -471,14 +471,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let parent_node = tcx.hir.find(parent); match parent_node { Some(node) => match node { - ast_map::NodeItem(item) => match item.node { + hir_map::NodeItem(item) => match item.node { hir::ItemFn(..) => { Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id)) }, _ => None }, - ast_map::NodeImplItem(..) | - ast_map::NodeTraitItem(..) => { + hir_map::NodeImplItem(..) | + hir_map::NodeTraitItem(..) => { Some(FreeRegionsFromSameFn::new(fr1, fr2, scope_id)) }, _ => None @@ -1074,7 +1074,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let life_giver = LifeGiver::with_taken(&taken[..]); let node_inner = match parent_node { Some(ref node) => match *node { - ast_map::NodeItem(ref item) => { + hir_map::NodeItem(ref item) => { match item.node { hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, body) => { Some((fn_decl, gen, unsafety, constness, item.name, item.span, body)) @@ -1082,9 +1082,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => None, } } - ast_map::NodeImplItem(item) => { + hir_map::NodeImplItem(item) => { let id = self.tcx.hir.get_parent(item.id); - if let Some(ast_map::NodeItem(parent_scope)) = self.tcx.hir.find(id) { + if let Some(hir_map::NodeItem(parent_scope)) = self.tcx.hir.find(id) { if let hir::ItemImpl(_, _, _, None, _, _) = parent_scope.node { // this impl scope implements a trait, do not recomend // using explicit lifetimes (#37363) @@ -1103,7 +1103,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { None } }, - ast_map::NodeTraitItem(item) => { + hir_map::NodeTraitItem(item) => { match item.node { hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { Some((&sig.decl, @@ -1894,14 +1894,14 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, let parent = tcx.hir.get_parent(scope_id); let method_id_opt = match tcx.hir.find(parent) { Some(node) => match node { - ast_map::NodeItem(item) => match item.node { + hir_map::NodeItem(item) => match item.node { hir::ItemFn(.., ref gen, _) => { taken.extend_from_slice(&gen.lifetimes); None }, _ => None }, - ast_map::NodeImplItem(ii) => { + hir_map::NodeImplItem(ii) => { match ii.node { hir::ImplItemKind::Method(ref sig, _) => { taken.extend_from_slice(&sig.generics.lifetimes); @@ -1918,7 +1918,7 @@ fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, let parent = tcx.hir.get_parent(method_id); if let Some(node) = tcx.hir.find(parent) { match node { - ast_map::NodeItem(item) => match item.node { + hir_map::NodeItem(item) => match item.node { hir::ItemImpl(_, _, ref gen, ..) => { taken.extend_from_slice(&gen.lifetimes); } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index fe1dadca05134..ae349667f9dc6 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -13,7 +13,7 @@ // from live codes are live, and everything else is dead. use dep_graph::DepNode; -use hir::map as ast_map; +use hir::map as hir_map; use hir::{self, PatKind}; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::itemlikevisit::ItemLikeVisitor; @@ -36,10 +36,10 @@ use syntax_pos; fn should_explore<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) -> bool { match tcx.hir.find(node_id) { - Some(ast_map::NodeItem(..)) | - Some(ast_map::NodeImplItem(..)) | - Some(ast_map::NodeForeignItem(..)) | - Some(ast_map::NodeTraitItem(..)) => + Some(hir_map::NodeItem(..)) | + Some(hir_map::NodeImplItem(..)) | + Some(hir_map::NodeForeignItem(..)) | + Some(hir_map::NodeTraitItem(..)) => true, _ => false @@ -150,13 +150,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn visit_node(&mut self, node: &ast_map::Node<'tcx>) { + fn visit_node(&mut self, node: &hir_map::Node<'tcx>) { let had_extern_repr = self.struct_has_extern_repr; self.struct_has_extern_repr = false; let had_inherited_pub_visibility = self.inherited_pub_visibility; self.inherited_pub_visibility = false; match *node { - ast_map::NodeItem(item) => { + hir_map::NodeItem(item) => { match item.node { hir::ItemStruct(..) | hir::ItemUnion(..) => { self.struct_has_extern_repr = item.attrs.iter().any(|attr| { @@ -179,13 +179,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { _ => () } } - ast_map::NodeTraitItem(trait_item) => { + hir_map::NodeTraitItem(trait_item) => { intravisit::walk_trait_item(self, trait_item); } - ast_map::NodeImplItem(impl_item) => { + hir_map::NodeImplItem(impl_item) => { intravisit::walk_impl_item(self, impl_item); } - ast_map::NodeForeignItem(foreign_item) => { + hir_map::NodeForeignItem(foreign_item) => { intravisit::walk_foreign_item(self, &foreign_item); } _ => () diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index f2e46d4cbc96b..ff7adfb327ad4 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -10,7 +10,7 @@ use dep_graph::DepNode; -use hir::map as ast_map; +use hir::map as hir_map; use hir::def_id::{CRATE_DEF_INDEX}; use session::{config, Session}; use syntax::ast::NodeId; @@ -23,7 +23,7 @@ use hir::itemlikevisit::ItemLikeVisitor; struct EntryContext<'a, 'tcx: 'a> { session: &'a Session, - map: &'a ast_map::Map<'tcx>, + map: &'a hir_map::Map<'tcx>, // The top-level function called 'main' main_fn: Option<(NodeId, Span)>, @@ -56,8 +56,8 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { } } -pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) { - let _task = ast_map.dep_graph.in_task(DepNode::EntryPoint); +pub fn find_entry_point(session: &Session, hir_map: &hir_map::Map) { + let _task = hir_map.dep_graph.in_task(DepNode::EntryPoint); let any_exe = session.crate_types.borrow().iter().any(|ty| { *ty == config::CrateTypeExecutable @@ -68,21 +68,21 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) { } // If the user wants no main function at all, then stop here. - if attr::contains_name(&ast_map.krate().attrs, "no_main") { + if attr::contains_name(&hir_map.krate().attrs, "no_main") { session.entry_type.set(Some(config::EntryNone)); return } let mut ctxt = EntryContext { session: session, - map: ast_map, + map: hir_map, main_fn: None, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new(), }; - ast_map.krate().visit_all_item_likes(&mut ctxt); + hir_map.krate().visit_all_item_likes(&mut ctxt); configure_main(&mut ctxt); } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index cd7859af8ee7b..b9f1611f62baf 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -117,7 +117,7 @@ impl LanguageItems { struct LanguageItemCollector<'a, 'tcx: 'a> { items: LanguageItems, - ast_map: &'a hir_map::Map<'tcx>, + hir_map: &'a hir_map::Map<'tcx>, session: &'a Session, @@ -130,9 +130,9 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { let item_index = self.item_refs.get(&*value.as_str()).cloned(); if let Some(item_index) = item_index { - self.collect_item(item_index, self.ast_map.local_def_id(item.id)) + self.collect_item(item_index, self.hir_map.local_def_id(item.id)) } else { - let span = self.ast_map.span(item.id); + let span = self.hir_map.span(item.id); span_err!(self.session, span, E0522, "definition of an unknown language item: `{}`.", value); @@ -150,7 +150,7 @@ impl<'a, 'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'a, 'tcx> { } impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { - pub fn new(session: &'a Session, ast_map: &'a hir_map::Map<'tcx>) + pub fn new(session: &'a Session, hir_map: &'a hir_map::Map<'tcx>) -> LanguageItemCollector<'a, 'tcx> { let mut item_refs = FxHashMap(); @@ -158,7 +158,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { LanguageItemCollector { session: session, - ast_map: ast_map, + hir_map: hir_map, items: LanguageItems::new(), item_refs: item_refs, } @@ -171,7 +171,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { Some(original_def_id) if original_def_id != item_def_id => { let cstore = &self.session.cstore; let name = LanguageItems::item_name(item_index); - let mut err = match self.ast_map.span_if_local(item_def_id) { + let mut err = match self.hir_map.span_if_local(item_def_id) { Some(span) => struct_span_err!( self.session, span, @@ -183,7 +183,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { cstore.crate_name(item_def_id.krate), name)), }; - if let Some(span) = self.ast_map.span_if_local(original_def_id) { + if let Some(span) = self.hir_map.span_if_local(original_def_id) { span_note!(&mut err, span, "first defined here."); } else { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d4438f5ecfa1a..126d43aa6900e 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -71,7 +71,7 @@ pub use self::Note::*; use self::Aliasability::*; use hir::def_id::DefId; -use hir::map as ast_map; +use hir::map as hir_map; use infer::InferCtxt; use hir::def::{Def, CtorKind}; use ty::adjustment; @@ -269,7 +269,7 @@ impl MutabilityCategory { fn from_local(tcx: TyCtxt, id: ast::NodeId) -> MutabilityCategory { let ret = match tcx.hir.get(id) { - ast_map::NodeLocal(p) => match p.node { + hir_map::NodeLocal(p) => match p.node { PatKind::Binding(bind_mode, ..) => { if bind_mode == hir::BindByValue(hir::MutMutable) { McDeclared @@ -699,7 +699,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // a free region within it let fn_body_id = { let fn_expr = match self.tcx().hir.find(upvar_id.closure_expr_id) { - Some(ast_map::NodeExpr(e)) => e, + Some(hir_map::NodeExpr(e)) => e, _ => bug!() }; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 9b00fc3f220ec..4ec43e368a60d 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -16,7 +16,7 @@ // reachable as well. use dep_graph::DepNode; -use hir::map as ast_map; +use hir::map as hir_map; use hir::def::Def; use hir::def_id::DefId; use ty::{self, TyCtxt}; @@ -65,7 +65,7 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) { match tcx.hir.find(impl_node_id) { - Some(ast_map::NodeItem(item)) => + Some(hir_map::NodeItem(item)) => item_might_be_inlined(&item), Some(..) | None => span_bug!(impl_item.span, "impl did is not an item") @@ -153,13 +153,13 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { }; match self.tcx.hir.find(node_id) { - Some(ast_map::NodeItem(item)) => { + Some(hir_map::NodeItem(item)) => { match item.node { hir::ItemFn(..) => item_might_be_inlined(&item), _ => false, } } - Some(ast_map::NodeTraitItem(trait_method)) => { + Some(hir_map::NodeTraitItem(trait_method)) => { match trait_method.node { hir::TraitItemKind::Const(_, ref default) => default.is_some(), hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true, @@ -167,7 +167,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::TraitItemKind::Type(..) => false, } } - Some(ast_map::NodeImplItem(impl_item)) => { + Some(hir_map::NodeImplItem(impl_item)) => { match impl_item.node { hir::ImplItemKind::Const(..) => true, hir::ImplItemKind::Method(ref sig, _) => { @@ -216,12 +216,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } - fn propagate_node(&mut self, node: &ast_map::Node<'tcx>, + fn propagate_node(&mut self, node: &hir_map::Node<'tcx>, search_item: ast::NodeId) { if !self.any_library { // If we are building an executable, only explicitly extern // types need to be exported. - if let ast_map::NodeItem(item) = *node { + if let hir_map::NodeItem(item) = *node { let reachable = if let hir::ItemFn(.., abi, _, _) = item.node { abi != Abi::Rust } else { @@ -242,7 +242,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } match *node { - ast_map::NodeItem(item) => { + hir_map::NodeItem(item) => { match item.node { hir::ItemFn(.., body) => { if item_might_be_inlined(&item) { @@ -268,7 +268,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::ItemUnion(..) | hir::ItemDefaultImpl(..) => {} } } - ast_map::NodeTraitItem(trait_method) => { + hir_map::NodeTraitItem(trait_method) => { match trait_method.node { hir::TraitItemKind::Const(_, None) | hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => { @@ -281,7 +281,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { hir::TraitItemKind::Type(..) => {} } } - ast_map::NodeImplItem(impl_item) => { + hir_map::NodeImplItem(impl_item) => { match impl_item.node { hir::ImplItemKind::Const(_, body) => { self.visit_nested_body(body); @@ -296,11 +296,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } // Nothing to recurse on for these - ast_map::NodeForeignItem(_) | - ast_map::NodeVariant(_) | - ast_map::NodeStructCtor(_) | - ast_map::NodeField(_) | - ast_map::NodeTy(_) => {} + hir_map::NodeForeignItem(_) | + hir_map::NodeVariant(_) | + hir_map::NodeStructCtor(_) | + hir_map::NodeField(_) | + hir_map::NodeTy(_) => {} _ => { bug!("found unexpected thingy in worklist: {}", self.tcx.hir.node_to_string(search_item)) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index faf4a448b7a84..7337c03795b6d 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,7 +17,7 @@ //! `middle/infer/region_inference/README.md` use dep_graph::DepNode; -use hir::map as ast_map; +use hir::map as hir_map; use session::Session; use util::nodemap::{FxHashMap, NodeMap, NodeSet}; use ty; @@ -217,9 +217,9 @@ impl CodeExtent { /// Returns the span of this CodeExtent. Note that in general the /// returned span may not correspond to the span of any node id in /// the AST. - pub fn span(&self, region_maps: &RegionMaps, ast_map: &ast_map::Map) -> Option { - match ast_map.find(self.node_id(region_maps)) { - Some(ast_map::NodeBlock(ref blk)) => { + pub fn span(&self, region_maps: &RegionMaps, hir_map: &hir_map::Map) -> Option { + match hir_map.find(self.node_id(region_maps)) { + Some(hir_map::NodeBlock(ref blk)) => { match region_maps.code_extent_data(*self) { CodeExtentData::CallSiteScope { .. } | CodeExtentData::ParameterScope { .. } | @@ -240,9 +240,9 @@ impl CodeExtent { } } } - Some(ast_map::NodeExpr(ref expr)) => Some(expr.span), - Some(ast_map::NodeStmt(ref stmt)) => Some(stmt.span), - Some(ast_map::NodeItem(ref item)) => Some(item.span), + Some(hir_map::NodeExpr(ref expr)) => Some(expr.span), + Some(hir_map::NodeStmt(ref stmt)) => Some(stmt.span), + Some(hir_map::NodeItem(ref item)) => Some(item.span), Some(_) | None => None, } } @@ -302,7 +302,7 @@ pub struct Context { parent: CodeExtent } -struct RegionResolutionVisitor<'ast: 'a, 'a> { +struct RegionResolutionVisitor<'hir: 'a, 'a> { sess: &'a Session, // Generated maps: @@ -310,7 +310,7 @@ struct RegionResolutionVisitor<'ast: 'a, 'a> { cx: Context, - map: &'a ast_map::Map<'ast>, + map: &'a hir_map::Map<'hir>, /// `terminating_scopes` is a set containing the ids of each /// statement, or conditional/repeating expression. These scopes @@ -1137,7 +1137,7 @@ fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, visitor.terminating_scopes = outer_ts; } -impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> { +impl<'hir, 'a> RegionResolutionVisitor<'hir, 'a> { /// Records the current parent (if any) as the parent of `child_scope`. fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent { self.region_maps.intern_code_extent(child_scope, self.cx.parent) @@ -1173,49 +1173,49 @@ impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> { } } -impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { +impl<'hir, 'a> Visitor<'hir> for RegionResolutionVisitor<'hir, 'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { NestedVisitorMap::OnlyBodies(&self.map) } - fn visit_block(&mut self, b: &'ast Block) { + fn visit_block(&mut self, b: &'hir Block) { resolve_block(self, b); } - fn visit_item(&mut self, i: &'ast Item) { + fn visit_item(&mut self, i: &'hir Item) { resolve_item_like(self, i.id, |this| intravisit::walk_item(this, i)); } - fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { + fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { resolve_item_like(self, ii.id, |this| intravisit::walk_impl_item(this, ii)); } - fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { resolve_item_like(self, ti.id, |this| intravisit::walk_trait_item(this, ti)); } - fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl, + fn visit_fn(&mut self, fk: FnKind<'hir>, fd: &'hir FnDecl, b: hir::BodyId, s: Span, n: NodeId) { resolve_fn(self, fk, fd, b, s, n); } - fn visit_arm(&mut self, a: &'ast Arm) { + fn visit_arm(&mut self, a: &'hir Arm) { resolve_arm(self, a); } - fn visit_pat(&mut self, p: &'ast Pat) { + fn visit_pat(&mut self, p: &'hir Pat) { resolve_pat(self, p); } - fn visit_stmt(&mut self, s: &'ast Stmt) { + fn visit_stmt(&mut self, s: &'hir Stmt) { resolve_stmt(self, s); } - fn visit_expr(&mut self, ex: &'ast Expr) { + fn visit_expr(&mut self, ex: &'hir Expr) { resolve_expr(self, ex); } - fn visit_local(&mut self, l: &'ast Local) { + fn visit_local(&mut self, l: &'hir Local) { resolve_local(self, l); } } -pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps { +pub fn resolve_crate(sess: &Session, map: &hir_map::Map) -> RegionMaps { let _task = map.dep_graph.in_task(DepNode::RegionResolveCrate); let krate = map.krate(); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7f26fdfba5693..c78ba3b8a9bbf 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -16,7 +16,7 @@ use middle; use hir::TraitMap; use hir::def::Def; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use hir::map as ast_map; +use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; use middle::region::RegionMaps; @@ -428,7 +428,7 @@ pub struct GlobalCtxt<'tcx> { /// additional acyclicity requirements). pub super_predicates: RefCell>>, - pub hir: ast_map::Map<'tcx>, + pub hir: hir_map::Map<'tcx>, /// Maps from the def-id of a function/method or const/static /// to its MIR. Mutation is done at an item granularity to @@ -730,7 +730,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { arena: &'tcx DroplessArena, resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, - hir: ast_map::Map<'tcx>, + hir: hir_map::Map<'tcx>, region_maps: RegionMaps, lang_items: middle::lang_items::LanguageItems, stability: stability::Index<'tcx>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7a8788f053dd0..5681e8c776623 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -17,7 +17,7 @@ pub use self::LvaluePreference::*; pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; -use hir::{map as ast_map, FreevarMap, TraitMap}; +use hir::{map as hir_map, FreevarMap, TraitMap}; use middle; use hir::def::{Def, CtorKind, ExportMap}; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -1199,7 +1199,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId) -> ParameterEnvironment<'tcx> { match tcx.hir.find(id) { - Some(ast_map::NodeImplItem(ref impl_item)) => { + Some(hir_map::NodeImplItem(ref impl_item)) => { match impl_item.node { hir::ImplItemKind::Type(_) | hir::ImplItemKind::Const(..) => { // associated types don't have their own entry (for some reason), @@ -1218,7 +1218,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } } } - Some(ast_map::NodeTraitItem(trait_item)) => { + Some(hir_map::NodeTraitItem(trait_item)) => { match trait_item.node { hir::TraitItemKind::Type(..) | hir::TraitItemKind::Const(..) => { // associated types don't have their own entry (for some reason), @@ -1247,7 +1247,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } } } - Some(ast_map::NodeItem(item)) => { + Some(hir_map::NodeItem(item)) => { match item.node { hir::ItemFn(.., body_id) => { // We assume this is a function. @@ -1284,7 +1284,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { } } } - Some(ast_map::NodeExpr(expr)) => { + Some(hir_map::NodeExpr(expr)) => { // This is a convenience to allow closures to work. if let hir::ExprClosure(.., body, _) = expr.node { let def_id = tcx.hir.local_def_id(id); @@ -1297,7 +1297,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { tcx.empty_parameter_environment() } } - Some(ast_map::NodeForeignItem(item)) => { + Some(hir_map::NodeForeignItem(item)) => { let def_id = tcx.hir.local_def_id(id); tcx.construct_parameter_environment(item.span, def_id, @@ -1945,7 +1945,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn expr_span(self, id: NodeId) -> Span { match self.hir.find(id) { - Some(ast_map::NodeExpr(e)) => { + Some(hir_map::NodeExpr(e)) => { e.span } Some(f) => { @@ -1959,7 +1959,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn local_var_name_str(self, id: NodeId) -> InternedString { match self.hir.find(id) { - Some(ast_map::NodeLocal(pat)) => { + Some(hir_map::NodeLocal(pat)) => { match pat.node { hir::PatKind::Binding(_, _, ref path1, _) => path1.node.as_str(), _ => { @@ -2225,7 +2225,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn def_key(self, id: DefId) -> ast_map::DefKey { + pub fn def_key(self, id: DefId) -> hir_map::DefKey { if id.is_local() { self.hir.def_key(id) } else { @@ -2238,7 +2238,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// /// Note that if `id` is not local to this crate, the result will // be a non-local `DefPath`. - pub fn def_path(self, id: DefId) -> ast_map::DefPath { + pub fn def_path(self, id: DefId) -> hir_map::DefPath { if id.is_local() { self.hir.def_path(id) } else { @@ -2266,7 +2266,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } else { let def_key = self.sess.cstore.def_key(id); // The name of a StructCtor is that of its struct parent. - if let ast_map::DefPathData::StructCtor = def_key.disambiguated_data.data { + if let hir_map::DefPathData::StructCtor = def_key.disambiguated_data.data { self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 65bec9ecdaf95..c05375c47b03a 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -13,7 +13,7 @@ use hir::def_id::DefId; use hir::map::DefPathData; use infer::InferCtxt; -use hir::map as ast_map; +use hir::map as hir_map; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; use ty::{Disr, ParameterEnvironment}; @@ -429,7 +429,7 @@ impl<'a, 'gcx, 'tcx, W> TypeIdHasher<'a, 'gcx, 'tcx, W> self.def_path(&path) } - pub fn def_path(&mut self, def_path: &ast_map::DefPath) { + pub fn def_path(&mut self, def_path: &hir_map::DefPath) { def_path.deterministic_hash_to(self.tcx, &mut self.state); } } diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index a02aba7208c7f..2047a58f8ed85 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -490,7 +490,7 @@ impl<'a, 'tcx> MoveData<'tcx> { /// Adds a new record for a match of `base_lp`, downcast to /// variant `lp`, that occurs at location `pattern_id`. (One /// should be able to recover the span info from the - /// `pattern_id` and the ast_map, I think.) + /// `pattern_id` and the hir_map, I think.) pub fn add_variant_match(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, lp: Rc>, pattern_id: ast::NodeId, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index e8055602087e5..a9dcb1ed89613 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -15,7 +15,7 @@ use rustc::middle::const_val::ConstVal; use self::ErrKind::*; use self::EvalHint::*; -use rustc::hir::map as ast_map; +use rustc::hir::map as hir_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::traits; use rustc::hir::def::Def; @@ -55,7 +55,7 @@ fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Option<(&'tcx Expr, Option<&'a ty::TypeckTables<'tcx>>)> { if let Some(variant_node_id) = tcx.hir.as_local_node_id(variant_def) { let enum_node_id = tcx.hir.get_parent(variant_node_id); - if let Some(ast_map::NodeItem(it)) = tcx.hir.find(enum_node_id) { + if let Some(hir_map::NodeItem(it)) = tcx.hir.find(enum_node_id) { if let hir::ItemEnum(ref edef, _) = it.node { for variant in &edef.variants { if variant.node.data.id() == variant_node_id { @@ -86,17 +86,17 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { match tcx.hir.find(node_id) { None => None, - Some(ast_map::NodeItem(&hir::Item { + Some(hir_map::NodeItem(&hir::Item { node: hir::ItemConst(ref ty, body), .. })) | - Some(ast_map::NodeImplItem(&hir::ImplItem { + Some(hir_map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Const(ref ty, body), .. })) => { Some((&tcx.hir.body(body).value, tcx.tables.borrow().get(&def_id).cloned(), tcx.ast_ty_to_prim_ty(ty))) } - Some(ast_map::NodeTraitItem(ti)) => match ti.node { + Some(hir_map::NodeTraitItem(ti)) => match ti.node { hir::TraitItemKind::Const(ref ty, default) => { if let Some(substs) = substs { // If we have a trait item and the substitutions for it, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1991fbb58edf1..a7188f6da1ff9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -340,7 +340,7 @@ pub struct CompileState<'a, 'tcx: 'a> { pub arenas: Option<&'tcx GlobalArenas<'tcx>>, pub expanded_crate: Option<&'a ast::Crate>, pub hir_crate: Option<&'a hir::Crate>, - pub ast_map: Option<&'a hir_map::Map<'tcx>>, + pub hir_map: Option<&'a hir_map::Map<'tcx>>, pub resolutions: Option<&'a Resolutions>, pub analysis: Option<&'a ty::CrateAnalysis<'tcx>>, pub tcx: Option>, @@ -366,7 +366,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { output_filenames: None, expanded_crate: None, hir_crate: None, - ast_map: None, + hir_map: None, resolutions: None, analysis: None, tcx: None, @@ -427,7 +427,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { arena: Some(arena), arenas: Some(arenas), cstore: Some(cstore), - ast_map: Some(hir_map), + hir_map: Some(hir_map), analysis: Some(analysis), resolutions: Some(resolutions), expanded_crate: Some(krate), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ad2aefbb79539..7fd4fa44ca45d 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -454,7 +454,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { }; control.after_hir_lowering.callback = box move |state| { pretty::print_after_hir_lowering(state.session, - state.ast_map.unwrap(), + state.hir_map.unwrap(), state.analysis.unwrap(), state.resolutions.unwrap(), state.input, diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 1885f76f1e4cd..21fe13997b787 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -167,7 +167,7 @@ impl PpSourceMode { /// Constructs a `PrinterSupport` object and passes it to `f`. fn call_with_pp_support<'tcx, A, B, F>(&self, sess: &'tcx Session, - ast_map: Option<&hir_map::Map<'tcx>>, + hir_map: Option<&hir_map::Map<'tcx>>, payload: B, f: F) -> A @@ -177,7 +177,7 @@ impl PpSourceMode { PpmNormal | PpmEveryBodyLoops | PpmExpanded => { let annotation = NoAnn { sess: sess, - ast_map: ast_map.map(|m| m.clone()), + hir_map: hir_map.map(|m| m.clone()), }; f(&annotation, payload) } @@ -185,14 +185,13 @@ impl PpSourceMode { PpmIdentified | PpmExpandedIdentified => { let annotation = IdentifiedAnnotation { sess: sess, - ast_map: ast_map.map(|m| m.clone()), + hir_map: hir_map.map(|m| m.clone()), }; f(&annotation, payload) } PpmExpandedHygiene => { let annotation = HygieneAnnotation { sess: sess, - ast_map: ast_map.map(|m| m.clone()), }; f(&annotation, payload) } @@ -201,7 +200,7 @@ impl PpSourceMode { } fn call_with_pp_support_hir<'tcx, A, B, F>(&self, sess: &'tcx Session, - ast_map: &hir_map::Map<'tcx>, + hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis<'tcx>, resolutions: &Resolutions, arena: &'tcx DroplessArena, @@ -216,21 +215,21 @@ impl PpSourceMode { PpmNormal => { let annotation = NoAnn { sess: sess, - ast_map: Some(ast_map.clone()), + hir_map: Some(hir_map.clone()), }; - f(&annotation, payload, ast_map.forest.krate()) + f(&annotation, payload, hir_map.forest.krate()) } PpmIdentified => { let annotation = IdentifiedAnnotation { sess: sess, - ast_map: Some(ast_map.clone()), + hir_map: Some(hir_map.clone()), }; - f(&annotation, payload, ast_map.forest.krate()) + f(&annotation, payload, hir_map.forest.krate()) } PpmTyped => { abort_on_err(driver::phase_3_run_analysis_passes(sess, - ast_map.clone(), + hir_map.clone(), analysis.clone(), resolutions.clone(), arena, @@ -243,7 +242,7 @@ impl PpSourceMode { tables: Cell::new(&empty_tables) }; let _ignore = tcx.dep_graph.in_ignore(); - f(&annotation, payload, ast_map.forest.krate()) + f(&annotation, payload, hir_map.forest.krate()) }), sess) } @@ -252,15 +251,11 @@ impl PpSourceMode { } } -trait PrinterSupport<'ast>: pprust::PpAnn { +trait PrinterSupport: pprust::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. fn sess<'a>(&'a self) -> &'a Session; - /// Provides a uniform interface for re-extracting a reference to an - /// `hir_map::Map` from a value that now owns it. - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>; - /// Produces the pretty-print annotation object. /// /// (Rust does not yet support upcasting from a trait object to @@ -268,14 +263,14 @@ trait PrinterSupport<'ast>: pprust::PpAnn { fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn; } -trait HirPrinterSupport<'ast>: pprust_hir::PpAnn { +trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// Provides a uniform interface for re-extracting a reference to a /// `Session` from a value that now owns it. fn sess<'a>(&'a self) -> &'a Session; /// Provides a uniform interface for re-extracting a reference to an /// `hir_map::Map` from a value that now owns it. - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>>; + fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>>; /// Produces the pretty-print annotation object. /// @@ -285,7 +280,7 @@ trait HirPrinterSupport<'ast>: pprust_hir::PpAnn { /// Computes an user-readable representation of a path, if possible. fn node_path(&self, id: ast::NodeId) -> Option { - self.ast_map().and_then(|map| map.def_path_from_id(id)).map(|path| { + self.hir_map().and_then(|map| map.def_path_from_id(id)).map(|path| { path.data .into_iter() .map(|elem| elem.data.to_string()) @@ -295,32 +290,28 @@ trait HirPrinterSupport<'ast>: pprust_hir::PpAnn { } } -struct NoAnn<'ast> { - sess: &'ast Session, - ast_map: Option>, +struct NoAnn<'hir> { + sess: &'hir Session, + hir_map: Option>, } -impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> { +impl<'hir> PrinterSupport for NoAnn<'hir> { fn sess<'a>(&'a self) -> &'a Session { self.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> { - self.ast_map.as_ref() - } - fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self } } -impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> { +impl<'hir> HirPrinterSupport<'hir> for NoAnn<'hir> { fn sess<'a>(&'a self) -> &'a Session { self.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> { - self.ast_map.as_ref() + fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { + self.hir_map.as_ref() } fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { @@ -328,11 +319,11 @@ impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> { } } -impl<'ast> pprust::PpAnn for NoAnn<'ast> {} -impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> { +impl<'hir> pprust::PpAnn for NoAnn<'hir> {} +impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { fn nested(&self, state: &mut pprust_hir::State, nested: pprust_hir::Nested) -> io::Result<()> { - if let Some(ref map) = self.ast_map { + if let Some(ref map) = self.hir_map { pprust_hir::PpAnn::nested(map, state, nested) } else { Ok(()) @@ -340,26 +331,22 @@ impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> { } } -struct IdentifiedAnnotation<'ast> { - sess: &'ast Session, - ast_map: Option>, +struct IdentifiedAnnotation<'hir> { + sess: &'hir Session, + hir_map: Option>, } -impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> { +impl<'hir> PrinterSupport for IdentifiedAnnotation<'hir> { fn sess<'a>(&'a self) -> &'a Session { self.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> { - self.ast_map.as_ref() - } - fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self } } -impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { +impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { fn pre(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeExpr(_) => s.popen(), @@ -396,13 +383,13 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> { } } -impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> { +impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { fn sess<'a>(&'a self) -> &'a Session { self.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> { - self.ast_map.as_ref() + fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'hir>> { + self.hir_map.as_ref() } fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { @@ -410,10 +397,10 @@ impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> { } } -impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> { +impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { fn nested(&self, state: &mut pprust_hir::State, nested: pprust_hir::Nested) -> io::Result<()> { - if let Some(ref map) = self.ast_map { + if let Some(ref map) = self.hir_map { pprust_hir::PpAnn::nested(map, state, nested) } else { Ok(()) @@ -453,26 +440,21 @@ impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> { } } -struct HygieneAnnotation<'ast> { - sess: &'ast Session, - ast_map: Option>, +struct HygieneAnnotation<'a> { + sess: &'a Session } -impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> { - fn sess<'a>(&'a self) -> &'a Session { +impl<'a> PrinterSupport for HygieneAnnotation<'a> { + fn sess(&self) -> &Session { self.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> { - self.ast_map.as_ref() - } - - fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { + fn pp_ann(&self) -> &pprust::PpAnn { self } } -impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> { +impl<'a> pprust::PpAnn for HygieneAnnotation<'a> { fn post(&self, s: &mut pprust::State, node: pprust::AnnNode) -> io::Result<()> { match node { pprust::NodeIdent(&ast::Ident { name, ctxt }) => { @@ -501,7 +483,7 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { &self.tcx.sess } - fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> { + fn hir_map<'a>(&'a self) -> Option<&'a hir_map::Map<'tcx>> { Some(&self.tcx.hir) } @@ -579,12 +561,12 @@ impl FromStr for UserIdentifiedItem { } } -enum NodesMatchingUII<'a, 'ast: 'a> { +enum NodesMatchingUII<'a, 'hir: 'a> { NodesMatchingDirect(option::IntoIter), - NodesMatchingSuffix(hir_map::NodesMatchingSuffix<'a, 'ast>), + NodesMatchingSuffix(hir_map::NodesMatchingSuffix<'a, 'hir>), } -impl<'a, 'ast> Iterator for NodesMatchingUII<'a, 'ast> { +impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> { type Item = ast::NodeId; fn next(&mut self) -> Option { @@ -603,9 +585,9 @@ impl UserIdentifiedItem { } } - fn all_matching_node_ids<'a, 'ast>(&'a self, - map: &'a hir_map::Map<'ast>) - -> NodesMatchingUII<'a, 'ast> { + fn all_matching_node_ids<'a, 'hir>(&'a self, + map: &'a hir_map::Map<'hir>) + -> NodesMatchingUII<'a, 'hir> { match *self { ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()), ItemViaPath(ref parts) => NodesMatchingSuffix(map.nodes_matching_suffix(&parts[..])), @@ -745,7 +727,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec, }; let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges; let lcfg = LabelledCFG { - ast_map: &tcx.hir, + hir_map: &tcx.hir, cfg: &cfg, name: format!("node_{}", code.id()), labelled_edges: labelled_edges, @@ -855,7 +837,7 @@ pub fn print_after_parsing(sess: &Session, } pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, - ast_map: &hir_map::Map<'tcx>, + hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis<'tcx>, resolutions: &Resolutions, input: &Input, @@ -871,7 +853,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, if ppm.needs_analysis() { print_with_analysis(sess, - ast_map, + hir_map, analysis, resolutions, crate_name, @@ -892,7 +874,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, (PpmSource(s), _) => { // Silently ignores an identified node. let out: &mut Write = &mut out; - s.call_with_pp_support(sess, Some(ast_map), box out, |annotation, out| { + s.call_with_pp_support(sess, Some(hir_map), box out, |annotation, out| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); pprust::print_crate(sess.codemap(), @@ -909,7 +891,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, (PpmHir(s), None) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(sess, - ast_map, + hir_map, analysis, resolutions, arena, @@ -933,7 +915,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, (PpmHir(s), Some(uii)) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(sess, - ast_map, + hir_map, analysis, resolutions, arena, @@ -943,7 +925,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, |annotation, (out, uii), _| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - let ast_map = annotation.ast_map().expect("--unpretty missing HIR map"); + let hir_map = annotation.hir_map().expect("--unpretty missing HIR map"); let mut pp_state = pprust_hir::State::new_from_input(sess.codemap(), &sess.parse_sess, src_name.to_string(), @@ -951,8 +933,8 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, box out, annotation.pp_ann(), true); - for node_id in uii.all_matching_node_ids(ast_map) { - let node = ast_map.get(node_id); + for node_id in uii.all_matching_node_ids(hir_map) { + let node = hir_map.get(node_id); pp_state.print_node(node)?; pp::space(&mut pp_state.s)?; let path = annotation.node_path(node_id) @@ -975,7 +957,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, - ast_map: &hir_map::Map<'tcx>, + hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis<'tcx>, resolutions: &Resolutions, crate_name: &str, @@ -986,7 +968,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, ofile: Option<&Path>) { let nodeid = if let Some(uii) = uii { debug!("pretty printing for {:?}", uii); - Some(uii.to_one_node_id("--unpretty", sess, &ast_map)) + Some(uii.to_one_node_id("--unpretty", sess, &hir_map)) } else { debug!("pretty printing for whole crate"); None @@ -995,7 +977,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, let mut out = Vec::new(); abort_on_err(driver::phase_3_run_analysis_passes(sess, - ast_map.clone(), + hir_map.clone(), analysis.clone(), resolutions.clone(), arena, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 0ac95d12eeef3..59f6889ba4d94 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -131,19 +131,19 @@ fn test_env(source_string: &str, let arena = DroplessArena::new(); let arenas = ty::GlobalArenas::new(); - let ast_map = hir_map::map_crate(&mut hir_forest, defs); + let hir_map = hir_map::map_crate(&mut hir_forest, defs); // run just enough stuff to build a tcx: - let lang_items = lang_items::collect_language_items(&sess, &ast_map); - let named_region_map = resolve_lifetime::krate(&sess, &ast_map); - let region_map = region::resolve_crate(&sess, &ast_map); - let index = stability::Index::new(&ast_map); + let lang_items = lang_items::collect_language_items(&sess, &hir_map); + let named_region_map = resolve_lifetime::krate(&sess, &hir_map); + let region_map = region::resolve_crate(&sess, &hir_map); + let index = stability::Index::new(&hir_map); TyCtxt::create_and_enter(&sess, &arenas, &arena, resolutions, named_region_map.unwrap(), - ast_map, + hir_map, region_map, lang_items, index, diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index df9fe00e9a88e..a5bd69fff0138 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -43,9 +43,9 @@ enum Context { } #[derive(Copy, Clone)] -struct CheckLoopVisitor<'a, 'ast: 'a> { +struct CheckLoopVisitor<'a, 'hir: 'a> { sess: &'a Session, - hir_map: &'a Map<'ast>, + hir_map: &'a Map<'hir>, cx: Context, } @@ -59,20 +59,20 @@ pub fn check_crate(sess: &Session, map: &Map) { }.as_deep_visitor()); } -impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { +impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { NestedVisitorMap::OnlyBodies(&self.hir_map) } - fn visit_item(&mut self, i: &'ast hir::Item) { + fn visit_item(&mut self, i: &'hir hir::Item) { self.with_context(Normal, |v| intravisit::walk_item(v, i)); } - fn visit_impl_item(&mut self, i: &'ast hir::ImplItem) { + fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) { self.with_context(Normal, |v| intravisit::walk_impl_item(v, i)); } - fn visit_expr(&mut self, e: &'ast hir::Expr) { + fn visit_expr(&mut self, e: &'hir hir::Expr) { match e.node { hir::ExprWhile(ref e, ref b, _) => { self.with_context(Loop(LoopKind::WhileLoop), |v| { @@ -125,9 +125,9 @@ impl<'a, 'ast> Visitor<'ast> for CheckLoopVisitor<'a, 'ast> { } } -impl<'a, 'ast> CheckLoopVisitor<'a, 'ast> { +impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { fn with_context(&mut self, cx: Context, f: F) - where F: FnOnce(&mut CheckLoopVisitor<'a, 'ast>) + where F: FnOnce(&mut CheckLoopVisitor<'a, 'hir>) { let old_cx = self.cx; self.cx = cx; diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index ba4fc57276b2c..1ef8a5b0080f3 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -12,7 +12,7 @@ // recursively. use rustc::dep_graph::DepNode; -use rustc::hir::map as ast_map; +use rustc::hir::map as hir_map; use rustc::session::{CompileResult, Session}; use rustc::hir::def::{Def, CtorKind}; use rustc::util::nodemap::{NodeMap, NodeSet}; @@ -23,9 +23,9 @@ use syntax_pos::Span; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -struct CheckCrateVisitor<'a, 'ast: 'a> { +struct CheckCrateVisitor<'a, 'hir: 'a> { sess: &'a Session, - ast_map: &'a ast_map::Map<'ast>, + hir_map: &'a hir_map::Map<'hir>, // `discriminant_map` is a cache that associates the `NodeId`s of local // variant definitions with the discriminant expression that applies to // each one. If the variant uses the default values (starting from `0`), @@ -34,12 +34,12 @@ struct CheckCrateVisitor<'a, 'ast: 'a> { detected_recursive_ids: NodeSet, } -impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { +impl<'a, 'hir: 'a> Visitor<'hir> for CheckCrateVisitor<'a, 'hir> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { NestedVisitorMap::None } - fn visit_item(&mut self, it: &'ast hir::Item) { + fn visit_item(&mut self, it: &'hir hir::Item) { match it.node { hir::ItemStatic(..) | hir::ItemConst(..) => { @@ -64,7 +64,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { intravisit::walk_item(self, it) } - fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { match ti.node { hir::TraitItemKind::Const(_, ref default) => { if let Some(_) = *default { @@ -77,7 +77,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { intravisit::walk_trait_item(self, ti) } - fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { + fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { match ii.node { hir::ImplItemKind::Const(..) => { let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ii.span); @@ -89,36 +89,36 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { } } -pub fn check_crate<'ast>(sess: &Session, ast_map: &ast_map::Map<'ast>) -> CompileResult { - let _task = ast_map.dep_graph.in_task(DepNode::CheckStaticRecursion); +pub fn check_crate<'hir>(sess: &Session, hir_map: &hir_map::Map<'hir>) -> CompileResult { + let _task = hir_map.dep_graph.in_task(DepNode::CheckStaticRecursion); let mut visitor = CheckCrateVisitor { sess: sess, - ast_map: ast_map, + hir_map: hir_map, discriminant_map: NodeMap(), detected_recursive_ids: NodeSet(), }; sess.track_errors(|| { // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like - ast_map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + hir_map.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); }) } -struct CheckItemRecursionVisitor<'a, 'b: 'a, 'ast: 'b> { +struct CheckItemRecursionVisitor<'a, 'b: 'a, 'hir: 'b> { root_span: &'b Span, sess: &'b Session, - ast_map: &'b ast_map::Map<'ast>, + hir_map: &'b hir_map::Map<'hir>, discriminant_map: &'a mut NodeMap>, idstack: Vec, detected_recursive_ids: &'a mut NodeSet, } -impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> { - fn new(v: &'a mut CheckCrateVisitor<'b, 'ast>, span: &'b Span) -> Self { +impl<'a, 'b: 'a, 'hir: 'b> CheckItemRecursionVisitor<'a, 'b, 'hir> { + fn new(v: &'a mut CheckCrateVisitor<'b, 'hir>, span: &'b Span) -> Self { CheckItemRecursionVisitor { root_span: span, sess: v.sess, - ast_map: v.ast_map, + hir_map: v.hir_map, discriminant_map: &mut v.discriminant_map, idstack: Vec::new(), detected_recursive_ids: &mut v.detected_recursive_ids, @@ -133,7 +133,7 @@ impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> { } self.detected_recursive_ids.insert(id); let any_static = self.idstack.iter().any(|&x| { - if let ast_map::NodeItem(item) = self.ast_map.get(x) { + if let hir_map::NodeItem(item) = self.hir_map.get(x) { if let hir::ItemStatic(..) = item.node { true } else { @@ -170,7 +170,7 @@ impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> { // So for every variant, we need to track whether there is an expression // somewhere in the enum definition that controls its discriminant. We do // this by starting from the end and searching backward. - fn populate_enum_discriminants(&mut self, enum_definition: &'ast hir::EnumDef) { + fn populate_enum_discriminants(&mut self, enum_definition: &'hir hir::EnumDef) { // Get the map, and return if we already processed this enum or if it // has no variants. match enum_definition.variants.first() { @@ -204,17 +204,17 @@ impl<'a, 'b: 'a, 'ast: 'b> CheckItemRecursionVisitor<'a, 'b, 'ast> { } } -impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, 'ast> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> { - NestedVisitorMap::OnlyBodies(&self.ast_map) +impl<'a, 'b: 'a, 'hir: 'b> Visitor<'hir> for CheckItemRecursionVisitor<'a, 'b, 'hir> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> { + NestedVisitorMap::OnlyBodies(&self.hir_map) } - fn visit_item(&mut self, it: &'ast hir::Item) { + fn visit_item(&mut self, it: &'hir hir::Item) { self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span); } fn visit_enum_def(&mut self, - enum_definition: &'ast hir::EnumDef, - generics: &'ast hir::Generics, + enum_definition: &'hir hir::EnumDef, + generics: &'hir hir::Generics, item_id: ast::NodeId, _: Span) { self.populate_enum_discriminants(enum_definition); @@ -222,8 +222,8 @@ impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, ' } fn visit_variant(&mut self, - variant: &'ast hir::Variant, - _: &'ast hir::Generics, + variant: &'hir hir::Variant, + _: &'hir hir::Generics, _: ast::NodeId) { let variant_id = variant.node.data.id(); let maybe_expr = *self.discriminant_map.get(&variant_id).unwrap_or_else(|| { @@ -234,34 +234,34 @@ impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, ' // If `maybe_expr` is `None`, that's because no discriminant is // specified that affects this variant. Thus, no risk of recursion. if let Some(expr) = maybe_expr { - let expr = &self.ast_map.body(expr).value; + let expr = &self.hir_map.body(expr).value; self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span); } } - fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { + fn visit_trait_item(&mut self, ti: &'hir hir::TraitItem) { self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti), ti.span); } - fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { + fn visit_impl_item(&mut self, ii: &'hir hir::ImplItem) { self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii), ii.span); } - fn visit_path(&mut self, path: &'ast hir::Path, _: ast::NodeId) { + fn visit_path(&mut self, path: &'hir hir::Path, _: ast::NodeId) { match path.def { Def::Static(def_id, _) | Def::AssociatedConst(def_id) | Def::Const(def_id) => { - if let Some(node_id) = self.ast_map.as_local_node_id(def_id) { - match self.ast_map.get(node_id) { - ast_map::NodeItem(item) => self.visit_item(item), - ast_map::NodeTraitItem(item) => self.visit_trait_item(item), - ast_map::NodeImplItem(item) => self.visit_impl_item(item), - ast_map::NodeForeignItem(_) => {} + if let Some(node_id) = self.hir_map.as_local_node_id(def_id) { + match self.hir_map.get(node_id) { + hir_map::NodeItem(item) => self.visit_item(item), + hir_map::NodeTraitItem(item) => self.visit_trait_item(item), + hir_map::NodeImplItem(item) => self.visit_impl_item(item), + hir_map::NodeForeignItem(_) => {} _ => { span_bug!(path.span, "expected item, found {}", - self.ast_map.node_to_string(node_id)); + self.hir_map.node_to_string(node_id)); } } } @@ -271,10 +271,10 @@ impl<'a, 'b: 'a, 'ast: 'b> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'b, ' // the whole enum definition to see what expression that // might be (if any). Def::VariantCtor(variant_id, CtorKind::Const) => { - if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) { - let variant = self.ast_map.expect_variant(variant_id); - let enum_id = self.ast_map.get_parent(variant_id); - let enum_item = self.ast_map.expect_item(enum_id); + if let Some(variant_id) = self.hir_map.as_local_node_id(variant_id) { + let variant = self.hir_map.expect_variant(variant_id); + let enum_id = self.hir_map.get_parent(variant_id); + let enum_item = self.hir_map.expect_item(enum_id); if let hir::ItemEnum(ref enum_def, ref generics) = enum_item.node { self.populate_enum_discriminants(enum_def); self.visit_variant(variant, generics, enum_id); From bd4d5ec758cac866af2ca8fc09b27ce0d0112786 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 26 Jan 2017 17:41:37 +0300 Subject: [PATCH 34/86] Better comments for FIXMEs --- src/libsyntax/parse/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9e3c1dcef8a6e..0261bda2252aa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1357,10 +1357,10 @@ impl<'a> Parser<'a> { self.expect_and()?; self.parse_borrowed_pointee()? } else if self.check_keyword(keywords::For) { - // FIXME plus priority + // FIXME `+` has incorrect priority in trait object types starting with `for` (#39317). self.parse_for_in_type()? } else if self.eat_keyword(keywords::Impl) { - // FIXME plus priority + // FIXME figure out priority of `+` in `impl Trait1 + Trait2` (#34511). self.parse_impl_trait_type()? } else if self.token_is_bare_fn_keyword() { // BARE FUNCTION From 7095a48bf6c1257f7674059ec678ce5bbe10d195 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Jan 2017 09:04:07 -0800 Subject: [PATCH 35/86] travis: Turn off core dumps on OSX I've seen these take up quite a bit of log space and I have the sneaking suspicion that they're just making our test suite take longer (sometimes timing out on 32-bit OSX now). In any case the backtraces haven't proven too useful, unfortunately. --- .travis.yml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index bbe0cdfb6f8f0..5e7c89fc100d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,17 +43,9 @@ matrix: SRC=. os: osx osx_image: xcode8.2 - before_script: &osx_before_script > - ulimit -c unlimited install: &osx_install_sccache > curl -L https://api.pub.build.mozilla.org/tooltool/sha512/d0025b286468cc5ada83b23d3fafbc936b9f190eaa7d4a981715b18e8e3bf720a7bcee7bfe758cfdeb8268857f6098fd52dcdd8818232692a30ce91039936596 | tar xJf - -C /usr/local/bin --strip-components=1 - after_failure: &osx_after_failure > - echo 'bt all' > cmds; - for file in $(ls /cores); do - echo core file $file; - lldb -c /cores/$file `which ld` -b -s cmds; - done - env: > SCRIPT="./x.py test && ./x.py dist" @@ -62,18 +54,14 @@ matrix: DEPLOY=1 os: osx osx_image: xcode8.2 - before_script: *osx_before_script install: *osx_install_sccache - after_failure: *osx_after_failure - env: > RUST_CHECK_TARGET=check RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin --disable-rustbuild SRC=. os: osx osx_image: xcode8.2 - before_script: *osx_before_script install: *osx_install_sccache - after_failure: *osx_after_failure - env: > RUST_CHECK_TARGET=dist RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended" @@ -81,9 +69,7 @@ matrix: DEPLOY=1 os: osx osx_image: xcode8.2 - before_script: *osx_before_script install: *osx_install_sccache - after_failure: *osx_after_failure env: global: From fc490ad679328d657265352a71ed1f0e59a125bb Mon Sep 17 00:00:00 2001 From: king6cong Date: Fri, 27 Jan 2017 02:05:33 +0800 Subject: [PATCH 36/86] doc comment typo fix --- src/librustc/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 697ab6ee491d4..d8d2b08de0bb6 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -514,7 +514,7 @@ pub enum BorrowKind { /// Data must be immutable but not aliasable. This kind of borrow /// cannot currently be expressed by the user and is used only in - /// implicit closure bindings. It is needed when you the closure + /// implicit closure bindings. It is needed when the closure /// is borrowing or mutating a mutable referent, e.g.: /// /// let x: &mut isize = ...; From 36ad34d343c364f9d9570d5bea4d253882577f4e Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 25 Jan 2017 14:40:47 +1300 Subject: [PATCH 37/86] save-analysis: get tables directly, accomodating them being missing Fixes an ICE when running with save-analsysis after an error --- src/librustc_save_analysis/dump_visitor.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 74521fe465bcd..f128167bbf621 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -111,11 +111,16 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { fn nest_tables(&mut self, item_id: NodeId, f: F) where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>) { - let old_tables = self.save_ctxt.tables; let item_def_id = self.tcx.hir.local_def_id(item_id); - self.save_ctxt.tables = self.tcx.item_tables(item_def_id); - f(self); - self.save_ctxt.tables = old_tables; + match self.tcx.tables.borrow().get(&item_def_id) { + Some(tables) => { + let old_tables = self.save_ctxt.tables; + self.save_ctxt.tables = tables; + f(self); + self.save_ctxt.tables = old_tables; + } + None => f(self), + } } pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) { From 8ad06af1311e7112d6f21709ba344d43867b547c Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Wed, 25 Jan 2017 21:16:38 -0800 Subject: [PATCH 38/86] Avoid ICE when pretty-printing non-local MIR item. This comes up when using `-Zunstable-options --unpretty=mir`. Previously, rustc would ICE due to an unwrap later in this function (after `as_local_node_id`). Instead, we should just ignore items from other crates when pretty-printing MIR. --- src/librustc_mir/pretty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index e7188d536980f..6602d26f17fc5 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -92,7 +92,7 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, where I: Iterator, 'tcx: 'a { let mut first = true; - for def_id in iter { + for def_id in iter.filter(DefId::is_local) { let mir = &tcx.item_mir(def_id); if first { From e1280d81af3101d918fcd1ff9ca040b59e7d907b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 16 Jan 2017 23:42:11 -0800 Subject: [PATCH 39/86] Point to immutable arg/fields when trying to use as &mut Point to immutable borrow arguments and fields when trying to use them as mutable borrows. Add label to primary span on "cannot borrow as mutable" errors. Present the following output when trying to access an immutable borrow's field as mutable: ``` error[E0389]: cannot borrow data mutably in a `&` reference --> $DIR/issue-38147-1.rs:27:9 | 26 | fn f(&self) { | ----- use `&mut self` here to make mutable 27 | f.s.push('x'); | ^^^ assignment into an immutable reference ``` And the following when trying to access an immutable struct field as mutable: ``` error: cannot borrow immutable borrowed content `*self.s` as mutable --> $DIR/issue-38147-3.rs:17:9 | 12 | s: &'a String | ------------- use `&'a mut String` here to make mutable ...| 16 | fn f(&self) { | ----- use `&mut self` here to make mutable 17 | self.s.push('x'); | ^^^^^^ cannot borrow as mutable ``` --- src/librustc/hir/map/blocks.rs | 2 +- src/librustc/middle/mem_categorization.rs | 57 +++++++ src/librustc/ty/mod.rs | 2 + src/librustc/ty/sty.rs | 2 +- .../borrowck/gather_loans/mod.rs | 6 +- src/librustc_borrowck/borrowck/mod.rs | 140 ++++++++++++------ src/test/ui/did_you_mean/issue-38147-1.rs | 31 ++++ src/test/ui/did_you_mean/issue-38147-1.stderr | 10 ++ src/test/ui/did_you_mean/issue-38147-2.rs | 21 +++ src/test/ui/did_you_mean/issue-38147-2.stderr | 11 ++ src/test/ui/did_you_mean/issue-38147-3.rs | 21 +++ src/test/ui/did_you_mean/issue-38147-3.stderr | 13 ++ src/test/ui/did_you_mean/issue-38147-4.rs | 19 +++ src/test/ui/did_you_mean/issue-38147-4.stderr | 10 ++ ...ck-borrow-overloaded-auto-deref-mut.stderr | 8 +- ...orrowck-borrow-overloaded-deref-mut.stderr | 4 +- ...borrowck-call-is-borrow-issue-12224.stderr | 6 +- ...owck-call-method-from-mut-aliasable.stderr | 2 +- .../ui/span/borrowck-fn-in-const-b.stderr | 2 +- .../ui/span/borrowck-object-mutability.stderr | 4 +- src/test/ui/span/mut-arg-hint.stderr | 6 +- 21 files changed, 310 insertions(+), 67 deletions(-) create mode 100644 src/test/ui/did_you_mean/issue-38147-1.rs create mode 100644 src/test/ui/did_you_mean/issue-38147-1.stderr create mode 100644 src/test/ui/did_you_mean/issue-38147-2.rs create mode 100644 src/test/ui/did_you_mean/issue-38147-2.stderr create mode 100644 src/test/ui/did_you_mean/issue-38147-3.rs create mode 100644 src/test/ui/did_you_mean/issue-38147-3.stderr create mode 100644 src/test/ui/did_you_mean/issue-38147-4.rs create mode 100644 src/test/ui/did_you_mean/issue-38147-4.stderr diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 91e88e2c73ff8..ff2f1dc1ba28a 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -38,7 +38,7 @@ use syntax_pos::Span; /// - The default implementation for a trait method. /// /// To construct one, use the `Code::from_node` function. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct FnLikeNode<'a> { node: map::Node<'a> } /// MaybeFnLike wraps a method that indicates if an object diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 126d43aa6900e..85902af68538f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -193,6 +193,63 @@ pub struct cmt_<'tcx> { pub type cmt<'tcx> = Rc>; +impl<'tcx> cmt_<'tcx> { + pub fn get_field(&self, name: ast::Name) -> Option { + match self.cat { + Categorization::Deref(ref cmt, ..) | + Categorization::Interior(ref cmt, _) | + Categorization::Downcast(ref cmt, _) => { + if let Categorization::Local(_) = cmt.cat { + if let ty::TyAdt(def, _) = self.ty.sty { + return def.struct_variant().find_field_named(name).map(|x| x.did); + } + None + } else { + cmt.get_field(name) + } + } + _ => None + } + } + + pub fn get_field_name(&self) -> Option { + match self.cat { + Categorization::Interior(_, ref ik) => { + if let InteriorKind::InteriorField(FieldName::NamedField(name)) = *ik { + Some(name) + } else { + None + } + } + Categorization::Deref(ref cmt, ..) | + Categorization::Downcast(ref cmt, _) => { + cmt.get_field_name() + } + _ => None, + } + } + + pub fn get_arg_if_immutable(&self, map: &hir_map::Map) -> Option { + match self.cat { + Categorization::Deref(ref cmt, ..) | + Categorization::Interior(ref cmt, _) | + Categorization::Downcast(ref cmt, _) => { + if let Categorization::Local(nid) = cmt.cat { + if let ty::TyAdt(_, _) = self.ty.sty { + if let ty::TyRef(_, ty::TypeAndMut{mutbl: MutImmutable, ..}) = cmt.ty.sty { + return Some(nid); + } + } + None + } else { + cmt.get_arg_if_immutable(map) + } + } + _ => None + } + } +} + pub trait ast_node { fn id(&self) -> ast::NodeId; fn span(&self) -> Span; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 5681e8c776623..36fc5149b40d8 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1325,6 +1325,7 @@ bitflags! { } } +#[derive(Debug)] pub struct VariantDef { /// The variant's DefId. If this is a tuple-like struct, /// this is the DefId of the struct's ctor. @@ -1335,6 +1336,7 @@ pub struct VariantDef { pub ctor_kind: CtorKind, } +#[derive(Debug)] pub struct FieldDef { pub did: DefId, pub name: Name, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b02bb7c6e4dd8..d6164e69ffd3a 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -134,7 +134,7 @@ pub enum TypeVariants<'tcx> { TyRawPtr(TypeAndMut<'tcx>), /// A reference; a pointer with an associated lifetime. Written as - /// `&a mut T` or `&'a T`. + /// `&'a mut T` or `&'a T`. TyRef(&'tcx Region, TypeAndMut<'tcx>), /// The anonymous type of a function declaration/definition. Each diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 7f7f73d9a9678..1783ca74a2592 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -195,7 +195,8 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx.report_aliasability_violation( borrow_span, loan_cause, - mc::AliasableReason::UnaliasableImmutable); + mc::AliasableReason::UnaliasableImmutable, + cmt); Err(()) } (mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) | @@ -203,7 +204,8 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx.report_aliasability_violation( borrow_span, loan_cause, - alias_cause); + alias_cause, + cmt); Err(()) } (..) => { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 3464f1fa89a27..4386a5bd1591d 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -540,7 +540,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option>> { // Errors // Errors that can occur -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum bckerr_code<'tcx> { err_mutbl, /// superscope, subscope, loan cause @@ -550,7 +550,7 @@ pub enum bckerr_code<'tcx> { // Combination of an error code and the categorization of the expression // that caused it -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct BckError<'tcx> { span: Span, cause: AliasableViolationKind, @@ -601,12 +601,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { _ => { } } - // General fallback. - let span = err.span.clone(); - let mut db = self.struct_span_err( - err.span, - &self.bckerr_to_string(&err)); - self.note_and_explain_bckerr(&mut db, err, span); + let mut db = self.bckerr_to_diag(&err); + self.note_and_explain_bckerr(&mut db, err); db.emit(); } @@ -771,8 +767,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.sess.span_err_with_code(s, msg, code); } - pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { - match err.code { + pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> { + let span = err.span.clone(); + let mut immutable_field = None; + + let msg = &match err.code { err_mutbl => { let descr = match err.cmt.note { mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => { @@ -783,6 +782,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { format!("{} {}", err.cmt.mutbl.to_user_str(), self.cmt_to_string(&err.cmt)) + } Some(lp) => { format!("{} {} `{}`", @@ -807,6 +807,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { BorrowViolation(euv::AutoUnsafe) | BorrowViolation(euv::ForLoop) | BorrowViolation(euv::MatchDiscriminant) => { + // Check for this field's definition to see if it is an immutable reference + // and suggest making it mutable if that is the case. + immutable_field = err.cmt.get_field_name() + .and_then(|name| err.cmt.get_field(name)) + .and_then(|did| self.tcx.hir.as_local_node_id(did)) + .and_then(|nid| { + if let hir_map::Node::NodeField(ref field) = self.tcx.hir.get(nid) { + return self.suggest_mut_for_immutable(&field.ty) + .map(|msg| (self.tcx.hir.span(nid), msg)); + } + None + }); + format!("cannot borrow {} as mutable", descr) } BorrowViolation(euv::ClosureInvocation) => { @@ -830,13 +843,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { its contents can be safely reborrowed", descr) } + }; + + let mut db = self.struct_span_err(span, msg); + if let Some((span, msg)) = immutable_field { + db.span_label(span, &msg); } + db } pub fn report_aliasability_violation(&self, span: Span, kind: AliasableViolationKind, - cause: mc::AliasableReason) { + cause: mc::AliasableReason, + cmt: mc::cmt<'tcx>) { let mut is_closure = false; let prefix = match kind { MutabilityViolation => { @@ -903,6 +923,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.sess, span, E0389, "{} in a `&` reference", prefix); e.span_label(span, &"assignment into an immutable reference"); + if let Some(nid) = cmt.get_arg_if_immutable(&self.tcx.hir) { + self.immutable_argument_should_be_mut(nid, &mut e); + } e } }; @@ -913,6 +936,55 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { err.emit(); } + /// Given a type, if it is an immutable reference, return a suggestion to make it mutable + fn suggest_mut_for_immutable(&self, pty: &hir::Ty) -> Option { + // Check wether the argument is an immutable reference + if let hir::TyRptr(opt_lifetime, hir::MutTy { + mutbl: hir::Mutability::MutImmutable, + ref ty + }) = pty.node { + // Account for existing lifetimes when generating the message + if let Some(lifetime) = opt_lifetime { + if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(ty.span) { + if let Ok(lifetime_snippet) = self.tcx.sess.codemap() + .span_to_snippet(lifetime.span) { + return Some(format!("use `&{} mut {}` here to make mutable", + lifetime_snippet, + snippet)); + } + } + } else if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(pty.span) { + if snippet.starts_with("&") { + return Some(format!("use `{}` here to make mutable", + snippet.replace("&", "&mut "))); + } + } else { + bug!("couldn't find a snippet for span: {:?}", pty.span); + } + } + None + } + + fn immutable_argument_should_be_mut(&self, nid: ast::NodeId, db: &mut DiagnosticBuilder) { + let parent = self.tcx.hir.get_parent_node(nid); + let parent_node = self.tcx.hir.get(parent); + + // The parent node is like a fn + if let Some(fn_like) = FnLikeNode::from_node(parent_node) { + // `nid`'s parent's `Body` + let fn_body = self.tcx.hir.body(fn_like.body()); + // Get the position of `nid` in the arguments list + let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.id == nid); + if let Some(i) = arg_pos { + // The argument's `Ty` + let arg_ty = &fn_like.decl().inputs[i]; + if let Some(msg) = self.suggest_mut_for_immutable(&arg_ty) { + db.span_label(arg_ty.span, &msg); + } + } + } + } + fn report_out_of_scope_escaping_closure_capture(&self, err: &BckError<'tcx>, capture_span: Span) @@ -961,8 +1033,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>, - error_span: Span) { + pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>) { + let error_span = err.span.clone(); match err.code { err_mutbl => self.note_and_explain_mutbl_error(db, &err, &error_span), err_out_of_scope(super_scope, sub_scope, cause) => { @@ -1103,41 +1175,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } _ => { - if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat { - if let Categorization::Local(local_id) = inner_cmt.cat { - let parent = self.tcx.hir.get_parent_node(local_id); - - if let Some(fn_like) = FnLikeNode::from_node(self.tcx.hir.get(parent)) { - if let Some(i) = self.tcx.hir.body(fn_like.body()).arguments.iter() - .position(|arg| arg.pat.id == local_id) { - let arg_ty = &fn_like.decl().inputs[i]; - if let hir::TyRptr( - opt_lifetime, - hir::MutTy{mutbl: hir::Mutability::MutImmutable, ref ty}) = - arg_ty.node { - if let Some(lifetime) = opt_lifetime { - if let Ok(snippet) = self.tcx.sess.codemap() - .span_to_snippet(ty.span) { - if let Ok(lifetime_snippet) = self.tcx.sess.codemap() - .span_to_snippet(lifetime.span) { - db.span_label(arg_ty.span, - &format!("use `&{} mut {}` \ - here to make mutable", - lifetime_snippet, - snippet)); - } - } - } - else if let Ok(snippet) = self.tcx.sess.codemap() - .span_to_snippet(arg_ty.span) { - if snippet.starts_with("&") { - db.span_label(arg_ty.span, - &format!("use `{}` here to make mutable", - snippet.replace("&", "&mut "))); - } - } - } - } + if let Categorization::Deref(..) = err.cmt.cat { + db.span_label(*error_span, &"cannot borrow as mutable"); + if let Some(local_id) = err.cmt.get_arg_if_immutable(&self.tcx.hir) { + self.immutable_argument_should_be_mut(local_id, db); + } else if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat { + if let Categorization::Local(local_id) = inner_cmt.cat { + self.immutable_argument_should_be_mut(local_id, db); } } } else if let Categorization::Local(local_id) = err.cmt.cat { diff --git a/src/test/ui/did_you_mean/issue-38147-1.rs b/src/test/ui/did_you_mean/issue-38147-1.rs new file mode 100644 index 0000000000000..136921dd0a569 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-1.rs @@ -0,0 +1,31 @@ +// Copyright 2017 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. + +struct Pass<'a> { + s: &'a mut String +} + +impl<'a> Pass<'a> { + fn f(&mut self) { + self.s.push('x'); + } +} + +struct Foo<'a> { + s: &'a mut String +} + +impl<'a> Foo<'a> { + fn f(&self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr new file mode 100644 index 0000000000000..e9f2b1dad806d --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-1.stderr @@ -0,0 +1,10 @@ +error[E0389]: cannot borrow data mutably in a `&` reference + --> $DIR/issue-38147-1.rs:27:9 + | +26 | fn f(&self) { + | ----- use `&mut self` here to make mutable +27 | self.s.push('x'); + | ^^^^^^ assignment into an immutable reference + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-2.rs b/src/test/ui/did_you_mean/issue-38147-2.rs new file mode 100644 index 0000000000000..a5d533edf75ec --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-2.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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. + +struct Bar<'a> { + s: &'a String +} + +impl<'a> Bar<'a> { + fn f(&mut self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr new file mode 100644 index 0000000000000..fdaf0cd44d9d4 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-2.stderr @@ -0,0 +1,11 @@ +error: cannot borrow immutable borrowed content `*self.s` as mutable + --> $DIR/issue-38147-2.rs:17:9 + | +12 | s: &'a String + | ------------- use `&'a mut String` here to make mutable +... +17 | self.s.push('x'); + | ^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-3.rs b/src/test/ui/did_you_mean/issue-38147-3.rs new file mode 100644 index 0000000000000..5e8f2d3eaefaa --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-3.rs @@ -0,0 +1,21 @@ +// Copyright 2017 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. + +struct Qux<'a> { + s: &'a String +} + +impl<'a> Qux<'a> { + fn f(&self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr new file mode 100644 index 0000000000000..d2280fa561bde --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-3.stderr @@ -0,0 +1,13 @@ +error: cannot borrow immutable borrowed content `*self.s` as mutable + --> $DIR/issue-38147-3.rs:17:9 + | +12 | s: &'a String + | ------------- use `&'a mut String` here to make mutable +... +16 | fn f(&self) { + | ----- use `&mut self` here to make mutable +17 | self.s.push('x'); + | ^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-4.rs b/src/test/ui/did_you_mean/issue-38147-4.rs new file mode 100644 index 0000000000000..4eb20ceeed48e --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-4.rs @@ -0,0 +1,19 @@ +// Copyright 2017 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. + +struct Foo<'a> { + s: &'a mut String +} + +fn f(x: usize, f: &Foo) { + f.s.push('x'); +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr new file mode 100644 index 0000000000000..9a8853f4fbbdb --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-4.stderr @@ -0,0 +1,10 @@ +error[E0389]: cannot borrow data mutably in a `&` reference + --> $DIR/issue-38147-4.rs:16:5 + | +15 | fn f(x: usize, f: &Foo) { + | ---- use `&mut Foo` here to make mutable +16 | f.s.push('x'); + | ^^^ assignment into an immutable reference + +error: aborting due to previous error + diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr index 1109351bff839..b83a6aaebf323 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 74 | fn deref_extend_mut_field1(x: &Own) -> &mut isize { | ----------- use `&mut Own` here to make mutable 75 | &mut x.y //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:88:19 @@ -38,7 +38,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 101 | fn assign_field2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 102 | x.y = 3; //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:111:5 @@ -64,7 +64,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 130 | fn deref_extend_mut_method1(x: &Own) -> &mut isize { | ----------- use `&mut Own` here to make mutable 131 | x.y_mut() //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable argument `x` as mutable --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:139:6 @@ -80,7 +80,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 142 | fn assign_method2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 143 | *x.y_mut() = 3; //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to 10 previous errors diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr index a5b7045916141..af954a4d7924f 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 50 | fn deref_extend_mut1<'a>(x: &'a Own) -> &'a mut isize { | -------------- use `&'a mut Own` here to make mutable 51 | &mut **x //~ ERROR cannot borrow - | ^^ + | ^^ cannot borrow as mutable error: cannot borrow immutable argument `x` as mutable --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:59:6 @@ -28,7 +28,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 62 | fn assign2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 63 | **x = 3; //~ ERROR cannot borrow - | ^^ + | ^^ cannot borrow as mutable error: aborting due to 4 previous errors diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 16bb60013674f..f2f0e027f0161 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -17,13 +17,15 @@ error: cannot borrow immutable borrowed content `*f` as mutable 35 | fn test2(f: &F) where F: FnMut() { | -- use `&mut F` here to make mutable 36 | (*f)(); //~ ERROR: cannot borrow immutable borrowed content `*f` as mutable - | ^^^^ + | ^^^^ cannot borrow as mutable error: cannot borrow immutable `Box` content `*f.f` as mutable --> $DIR/borrowck-call-is-borrow-issue-12224.rs:44:5 | +43 | fn test4(f: &Test) { + | ----- use `&mut Test` here to make mutable 44 | f.f.call_mut(()) //~ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable - | ^^^ + | ^^^ cannot borrow as mutable error[E0504]: cannot move `f` into closure because it is borrowed --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13 diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr index a1af1ca7408a2..2349bfaf75e6f 100644 --- a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr +++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr @@ -5,7 +5,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable | ---- use `&mut Foo` here to make mutable 26 | x.f(); 27 | x.h(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-fn-in-const-b.stderr b/src/test/ui/span/borrowck-fn-in-const-b.stderr index 41f549c708a29..251a9e4aa5755 100644 --- a/src/test/ui/span/borrowck-fn-in-const-b.stderr +++ b/src/test/ui/span/borrowck-fn-in-const-b.stderr @@ -4,7 +4,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 16 | fn broken(x: &Vec) { | ------------ use `&mut Vec` here to make mutable 17 | x.push(format!("this is broken")); - | ^ + | ^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr index 32e4da18056ff..4ef1cb9c239e4 100644 --- a/src/test/ui/span/borrowck-object-mutability.stderr +++ b/src/test/ui/span/borrowck-object-mutability.stderr @@ -5,13 +5,13 @@ error: cannot borrow immutable borrowed content `*x` as mutable | ---- use `&mut Foo` here to make mutable 18 | x.borrowed(); 19 | x.borrowed_mut(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable `Box` content `*x` as mutable --> $DIR/borrowck-object-mutability.rs:29:5 | 29 | x.borrowed_mut(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to 2 previous errors diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr index 58f66c1358437..e4ed062214715 100644 --- a/src/test/ui/span/mut-arg-hint.stderr +++ b/src/test/ui/span/mut-arg-hint.stderr @@ -4,7 +4,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 17 | pub fn foo<'a>(mut a: &'a String) { | ---------- use `&'a mut String` here to make mutable 18 | a.push_str("foo"); - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable borrowed content `*a` as mutable --> $DIR/mut-arg-hint.rs:13:9 @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 12 | fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable 13 | a.push_str("bar"); - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable borrowed content `*a` as mutable --> $DIR/mut-arg-hint.rs:25:9 @@ -20,7 +20,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 24 | pub fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable 25 | a.push_str("foo"); - | ^ + | ^ cannot borrow as mutable error: aborting due to 3 previous errors From a2735c02493d816835a19249dd258e0c678530d0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 9 Oct 2016 10:30:11 -0700 Subject: [PATCH 40/86] rustc: Remove all "consider using an explicit lifetime parameter" suggestions These give so many incorrect suggestions that having them is detrimental to the user experience. The compiler should not be suggesting changes to the code that are wrong - it is infuriating: not only is the compiler telling you that _you don't understand_ borrowing, _the compiler itself_ appears to not understand borrowing. It does not inspire confidence. --- src/librustc/infer/error_reporting.rs | 718 +----------------- src/test/compile-fail/issue-13058.rs | 1 - ...me-inference-give-expl-lifetime-param-2.rs | 36 - ...me-inference-give-expl-lifetime-param-3.rs | 32 - ...time-inference-give-expl-lifetime-param.rs | 57 -- .../consider-using-explicit-lifetime.rs | 28 - .../consider-using-explicit-lifetime.stderr | 25 - 7 files changed, 4 insertions(+), 893 deletions(-) delete mode 100644 src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs delete mode 100644 src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs delete mode 100644 src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs delete mode 100644 src/test/ui/lifetimes/consider-using-explicit-lifetime.rs delete mode 100644 src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 23106d2bdc7d3..2489a6a6c7a63 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -55,8 +55,6 @@ //! ported to this system, and which relies on string concatenation at the //! time of error detection. -use self::FreshOrKept::*; - use super::InferCtxt; use super::TypeTrace; use super::SubregionOrigin; @@ -71,13 +69,10 @@ use super::region_inference::ProcessedErrors; use super::region_inference::ProcessedErrorOrigin; use super::region_inference::SameRegions; -use std::collections::HashSet; - use hir::map as hir_map; use hir; use lint; -use hir::def::Def; use hir::def_id::DefId; use infer; use middle::region; @@ -86,13 +81,9 @@ use ty::{self, TyCtxt, TypeFoldable}; use ty::{Region, ReFree}; use ty::error::TypeError; -use std::cell::{Cell, RefCell}; -use std::char::from_u32; use std::fmt; use syntax::ast; -use syntax::ptr::P; -use syntax::symbol::Symbol; -use syntax_pos::{self, Pos, Span}; +use syntax_pos::{Pos, Span}; use errors::DiagnosticBuilder; impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { @@ -292,7 +283,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ProcessedErrors(ref origins, ref same_regions) => { if !same_regions.is_empty() { - self.report_processed_errors(origins, same_regions); + self.report_processed_errors(origins); } } } @@ -1050,9 +1041,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn report_processed_errors(&self, - origins: &[ProcessedErrorOrigin<'tcx>], - same_regions: &[SameRegions]) { - for (i, origin) in origins.iter().enumerate() { + origins: &[ProcessedErrorOrigin<'tcx>]) { + for origin in origins.iter() { let mut err = match *origin { ProcessedErrorOrigin::VariableFailure(ref var_origin) => self.report_inference_failure(var_origin.clone()), @@ -1060,78 +1050,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_concrete_failure(sr_origin.clone(), sub, sup), }; - // attach the suggestion to the last such error - if i == origins.len() - 1 { - self.give_suggestion(&mut err, same_regions); - } - err.emit(); } } - fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegions]) { - let scope_id = same_regions[0].scope_id; - let parent = self.tcx.hir.get_parent(scope_id); - let parent_node = self.tcx.hir.find(parent); - let taken = lifetimes_in_scope(self.tcx, scope_id); - let life_giver = LifeGiver::with_taken(&taken[..]); - let node_inner = match parent_node { - Some(ref node) => match *node { - hir_map::NodeItem(ref item) => { - match item.node { - hir::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, body) => { - Some((fn_decl, gen, unsafety, constness, item.name, item.span, body)) - } - _ => None, - } - } - hir_map::NodeImplItem(item) => { - let id = self.tcx.hir.get_parent(item.id); - if let Some(hir_map::NodeItem(parent_scope)) = self.tcx.hir.find(id) { - if let hir::ItemImpl(_, _, _, None, _, _) = parent_scope.node { - // this impl scope implements a trait, do not recomend - // using explicit lifetimes (#37363) - return; - } - } - if let hir::ImplItemKind::Method(ref sig, body) = item.node { - Some((&sig.decl, - &sig.generics, - sig.unsafety, - sig.constness, - item.name, - item.span, - body)) - } else { - None - } - }, - hir_map::NodeTraitItem(item) => { - match item.node { - hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { - Some((&sig.decl, - &sig.generics, - sig.unsafety, - sig.constness, - item.name, - item.span, - body)) - } - _ => None, - } - } - _ => None, - }, - None => None, - }; - let (fn_decl, generics, unsafety, constness, name, span, body) - = node_inner.expect("expect item fn"); - let rebuilder = Rebuilder::new(self.tcx, fn_decl, generics, same_regions, &life_giver); - let (fn_decl, generics) = rebuilder.rebuild(); - self.give_expl_lifetime_param( - err, &fn_decl, unsafety, constness, name, &generics, span, body); - } - pub fn issue_32330_warnings(&self, span: Span, issue32330s: &[ty::Issue32330]) { for issue32330 in issue32330s { match *issue32330 { @@ -1154,530 +1076,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } -struct RebuildPathInfo<'a> { - path: &'a hir::Path, - // indexes to insert lifetime on path.lifetimes - indexes: Vec, - // number of lifetimes we expect to see on the type referred by `path` - // (e.g., expected=1 for struct Foo<'a>) - expected: u32, - anon_nums: &'a HashSet, - region_names: &'a HashSet -} - -struct Rebuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'tcx>, - fn_decl: &'a hir::FnDecl, - generics: &'a hir::Generics, - same_regions: &'a [SameRegions], - life_giver: &'a LifeGiver, - cur_anon: Cell, - inserted_anons: RefCell>, -} - -enum FreshOrKept { - Fresh, - Kept -} - -impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { - fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, - fn_decl: &'a hir::FnDecl, - generics: &'a hir::Generics, - same_regions: &'a [SameRegions], - life_giver: &'a LifeGiver) - -> Rebuilder<'a, 'gcx, 'tcx> { - Rebuilder { - tcx: tcx, - fn_decl: fn_decl, - generics: generics, - same_regions: same_regions, - life_giver: life_giver, - cur_anon: Cell::new(0), - inserted_anons: RefCell::new(HashSet::new()), - } - } - - fn rebuild(&self) -> (hir::FnDecl, hir::Generics) { - let mut inputs = self.fn_decl.inputs.clone(); - let mut output = self.fn_decl.output.clone(); - let mut ty_params = self.generics.ty_params.clone(); - let where_clause = self.generics.where_clause.clone(); - let mut kept_lifetimes = HashSet::new(); - for sr in self.same_regions { - self.cur_anon.set(0); - self.offset_cur_anon(); - let (anon_nums, region_names) = - self.extract_anon_nums_and_names(sr); - let (lifetime, fresh_or_kept) = self.pick_lifetime(®ion_names); - match fresh_or_kept { - Kept => { kept_lifetimes.insert(lifetime.name); } - _ => () - } - inputs = self.rebuild_args_ty(&inputs[..], lifetime, - &anon_nums, ®ion_names); - output = self.rebuild_output(&output, lifetime, &anon_nums, ®ion_names); - ty_params = self.rebuild_ty_params(ty_params, lifetime, - ®ion_names); - } - let fresh_lifetimes = self.life_giver.get_generated_lifetimes(); - let all_region_names = self.extract_all_region_names(); - let generics = self.rebuild_generics(self.generics, - &fresh_lifetimes, - &kept_lifetimes, - &all_region_names, - ty_params, - where_clause); - let new_fn_decl = hir::FnDecl { - inputs: inputs, - output: output, - variadic: self.fn_decl.variadic - }; - (new_fn_decl, generics) - } - - fn pick_lifetime(&self, - region_names: &HashSet) - -> (hir::Lifetime, FreshOrKept) { - if !region_names.is_empty() { - // It's not necessary to convert the set of region names to a - // vector of string and then sort them. However, it makes the - // choice of lifetime name deterministic and thus easier to test. - let mut names = Vec::new(); - for rn in region_names { - let lt_name = rn.to_string(); - names.push(lt_name); - } - names.sort(); - let name = Symbol::intern(&names[0]); - return (name_to_dummy_lifetime(name), Kept); - } - return (self.life_giver.give_lifetime(), Fresh); - } - - fn extract_anon_nums_and_names(&self, same_regions: &SameRegions) - -> (HashSet, HashSet) { - let mut anon_nums = HashSet::new(); - let mut region_names = HashSet::new(); - for br in &same_regions.regions { - match *br { - ty::BrAnon(i) => { - anon_nums.insert(i); - } - ty::BrNamed(_, name, _) => { - region_names.insert(name); - } - _ => () - } - } - (anon_nums, region_names) - } - - fn extract_all_region_names(&self) -> HashSet { - let mut all_region_names = HashSet::new(); - for sr in self.same_regions { - for br in &sr.regions { - match *br { - ty::BrNamed(_, name, _) => { - all_region_names.insert(name); - } - _ => () - } - } - } - all_region_names - } - - fn inc_cur_anon(&self, n: u32) { - let anon = self.cur_anon.get(); - self.cur_anon.set(anon+n); - } - - fn offset_cur_anon(&self) { - let mut anon = self.cur_anon.get(); - while self.inserted_anons.borrow().contains(&anon) { - anon += 1; - } - self.cur_anon.set(anon); - } - - fn inc_and_offset_cur_anon(&self, n: u32) { - self.inc_cur_anon(n); - self.offset_cur_anon(); - } - - fn track_anon(&self, anon: u32) { - self.inserted_anons.borrow_mut().insert(anon); - } - - fn rebuild_ty_params(&self, - ty_params: hir::HirVec, - lifetime: hir::Lifetime, - region_names: &HashSet) - -> hir::HirVec { - ty_params.into_iter().map(|ty_param| { - let bounds = self.rebuild_ty_param_bounds(ty_param.bounds, - lifetime, - region_names); - hir::TyParam { - name: ty_param.name, - id: ty_param.id, - bounds: bounds, - default: ty_param.default, - span: ty_param.span, - pure_wrt_drop: ty_param.pure_wrt_drop, - } - }).collect() - } - - fn rebuild_ty_param_bounds(&self, - ty_param_bounds: hir::TyParamBounds, - lifetime: hir::Lifetime, - region_names: &HashSet) - -> hir::TyParamBounds { - ty_param_bounds.iter().map(|tpb| { - match tpb { - &hir::RegionTyParamBound(lt) => { - // FIXME -- it's unclear whether I'm supposed to - // substitute lifetime here. I suspect we need to - // be passing down a map. - hir::RegionTyParamBound(lt) - } - &hir::TraitTyParamBound(ref poly_tr, modifier) => { - let tr = &poly_tr.trait_ref; - let last_seg = tr.path.segments.last().unwrap(); - let mut insert = Vec::new(); - let lifetimes = last_seg.parameters.lifetimes(); - for (i, lt) in lifetimes.iter().enumerate() { - if region_names.contains(<.name) { - insert.push(i as u32); - } - } - let rebuild_info = RebuildPathInfo { - path: &tr.path, - indexes: insert, - expected: lifetimes.len() as u32, - anon_nums: &HashSet::new(), - region_names: region_names - }; - let new_path = self.rebuild_path(rebuild_info, lifetime); - hir::TraitTyParamBound(hir::PolyTraitRef { - bound_lifetimes: poly_tr.bound_lifetimes.clone(), - trait_ref: hir::TraitRef { - path: new_path, - ref_id: tr.ref_id, - }, - span: poly_tr.span, - }, modifier) - } - } - }).collect() - } - - fn rebuild_generics(&self, - generics: &hir::Generics, - add: &Vec, - keep: &HashSet, - remove: &HashSet, - ty_params: hir::HirVec, - where_clause: hir::WhereClause) - -> hir::Generics { - let mut lifetimes = Vec::new(); - for lt in add { - lifetimes.push(hir::LifetimeDef { - lifetime: *lt, - bounds: hir::HirVec::new(), - pure_wrt_drop: false, - }); - } - for lt in &generics.lifetimes { - if keep.contains(<.lifetime.name) || - !remove.contains(<.lifetime.name) { - lifetimes.push((*lt).clone()); - } - } - hir::Generics { - lifetimes: lifetimes.into(), - ty_params: ty_params, - where_clause: where_clause, - span: generics.span, - } - } - - fn rebuild_args_ty(&self, - inputs: &[P], - lifetime: hir::Lifetime, - anon_nums: &HashSet, - region_names: &HashSet) - -> hir::HirVec> { - inputs.iter().map(|arg_ty| { - self.rebuild_arg_ty_or_output(arg_ty, lifetime, anon_nums, region_names) - }).collect() - } - - fn rebuild_output(&self, ty: &hir::FunctionRetTy, - lifetime: hir::Lifetime, - anon_nums: &HashSet, - region_names: &HashSet) -> hir::FunctionRetTy { - match *ty { - hir::Return(ref ret_ty) => hir::Return( - self.rebuild_arg_ty_or_output(&ret_ty, lifetime, anon_nums, region_names) - ), - hir::DefaultReturn(span) => hir::DefaultReturn(span), - } - } - - fn rebuild_arg_ty_or_output(&self, - ty: &hir::Ty, - lifetime: hir::Lifetime, - anon_nums: &HashSet, - region_names: &HashSet) - -> P { - let mut new_ty = P(ty.clone()); - let mut ty_queue = vec![ty]; - while !ty_queue.is_empty() { - let cur_ty = ty_queue.remove(0); - match cur_ty.node { - hir::TyRptr(lt_opt, ref mut_ty) => { - let rebuild = match lt_opt { - Some(lt) => region_names.contains(<.name), - None => { - let anon = self.cur_anon.get(); - let rebuild = anon_nums.contains(&anon); - if rebuild { - self.track_anon(anon); - } - self.inc_and_offset_cur_anon(1); - rebuild - } - }; - if rebuild { - let to = hir::Ty { - id: cur_ty.id, - node: hir::TyRptr(Some(lifetime), mut_ty.clone()), - span: cur_ty.span - }; - new_ty = self.rebuild_ty(new_ty, P(to)); - } - ty_queue.push(&mut_ty.ty); - } - hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => { - match path.def { - Def::Enum(did) | Def::TyAlias(did) | - Def::Struct(did) | Def::Union(did) => { - let generics = self.tcx.item_generics(did); - - let expected = - generics.regions.len() as u32; - let lifetimes = - path.segments.last().unwrap().parameters.lifetimes(); - let mut insert = Vec::new(); - if lifetimes.is_empty() { - let anon = self.cur_anon.get(); - for (i, a) in (anon..anon+expected).enumerate() { - if anon_nums.contains(&a) { - insert.push(i as u32); - } - self.track_anon(a); - } - self.inc_and_offset_cur_anon(expected); - } else { - for (i, lt) in lifetimes.iter().enumerate() { - if region_names.contains(<.name) { - insert.push(i as u32); - } - } - } - let rebuild_info = RebuildPathInfo { - path: path, - indexes: insert, - expected: expected, - anon_nums: anon_nums, - region_names: region_names - }; - let new_path = self.rebuild_path(rebuild_info, lifetime); - let qself = maybe_qself.as_ref().map(|qself| { - self.rebuild_arg_ty_or_output(qself, lifetime, - anon_nums, region_names) - }); - let to = hir::Ty { - id: cur_ty.id, - node: hir::TyPath(hir::QPath::Resolved(qself, P(new_path))), - span: cur_ty.span - }; - new_ty = self.rebuild_ty(new_ty, P(to)); - } - _ => () - } - } - - hir::TyPtr(ref mut_ty) => { - ty_queue.push(&mut_ty.ty); - } - hir::TySlice(ref ty) | - hir::TyArray(ref ty, _) => { - ty_queue.push(&ty); - } - hir::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)), - _ => {} - } - } - new_ty - } - - fn rebuild_ty(&self, - from: P, - to: P) - -> P { - - fn build_to(from: P, - to: &mut Option>) - -> P { - if Some(from.id) == to.as_ref().map(|ty| ty.id) { - return to.take().expect("`to` type found more than once during rebuild"); - } - from.map(|hir::Ty {id, node, span}| { - let new_node = match node { - hir::TyRptr(lifetime, mut_ty) => { - hir::TyRptr(lifetime, hir::MutTy { - mutbl: mut_ty.mutbl, - ty: build_to(mut_ty.ty, to), - }) - } - hir::TyPtr(mut_ty) => { - hir::TyPtr(hir::MutTy { - mutbl: mut_ty.mutbl, - ty: build_to(mut_ty.ty, to), - }) - } - hir::TySlice(ty) => hir::TySlice(build_to(ty, to)), - hir::TyArray(ty, e) => { - hir::TyArray(build_to(ty, to), e) - } - hir::TyTup(tys) => { - hir::TyTup(tys.into_iter().map(|ty| build_to(ty, to)).collect()) - } - other => other - }; - hir::Ty { id: id, node: new_node, span: span } - }) - } - - build_to(from, &mut Some(to)) - } - - fn rebuild_path(&self, - rebuild_info: RebuildPathInfo, - lifetime: hir::Lifetime) - -> hir::Path - { - let RebuildPathInfo { - path, - indexes, - expected, - anon_nums, - region_names, - } = rebuild_info; - - let last_seg = path.segments.last().unwrap(); - let new_parameters = match last_seg.parameters { - hir::ParenthesizedParameters(..) => { - last_seg.parameters.clone() - } - - hir::AngleBracketedParameters(ref data) => { - let mut new_lts = Vec::new(); - if data.lifetimes.is_empty() { - // traverse once to see if there's a need to insert lifetime - let need_insert = (0..expected).any(|i| { - indexes.contains(&i) - }); - if need_insert { - for i in 0..expected { - if indexes.contains(&i) { - new_lts.push(lifetime); - } else { - new_lts.push(self.life_giver.give_lifetime()); - } - } - } - } else { - for (i, lt) in data.lifetimes.iter().enumerate() { - if indexes.contains(&(i as u32)) { - new_lts.push(lifetime); - } else { - new_lts.push(*lt); - } - } - } - let new_types = data.types.iter().map(|t| { - self.rebuild_arg_ty_or_output(&t, lifetime, anon_nums, region_names) - }).collect(); - let new_bindings = data.bindings.iter().map(|b| { - hir::TypeBinding { - id: b.id, - name: b.name, - ty: self.rebuild_arg_ty_or_output(&b.ty, - lifetime, - anon_nums, - region_names), - span: b.span - } - }).collect(); - hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: new_lts.into(), - types: new_types, - infer_types: data.infer_types, - bindings: new_bindings, - }) - } - }; - let new_seg = hir::PathSegment { - name: last_seg.name, - parameters: new_parameters - }; - let mut new_segs = Vec::new(); - new_segs.extend_from_slice(path.segments.split_last().unwrap().1); - new_segs.push(new_seg); - hir::Path { - span: path.span, - def: path.def, - segments: new_segs.into() - } - } -} - impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - fn give_expl_lifetime_param(&self, - err: &mut DiagnosticBuilder, - decl: &hir::FnDecl, - unsafety: hir::Unsafety, - constness: hir::Constness, - name: ast::Name, - generics: &hir::Generics, - span: Span, - body: hir::BodyId) { - let s = hir::print::to_string(&self.tcx.hir, |s| { - use syntax::abi::Abi; - use syntax::print::pprust::PrintState; - - s.head("")?; - s.print_fn(decl, - unsafety, - constness, - Abi::Rust, - Some(name), - generics, - &hir::Inherited, - &[], - Some(body))?; - s.end()?; // Close the head box - s.end() // Close the outer box - }); - let msg = format!("consider using an explicit lifetime parameter as shown: {}", s); - err.span_help(span, &msg[..]); - } - fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> DiagnosticBuilder<'tcx> { @@ -1890,114 +1289,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } -fn lifetimes_in_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - scope_id: ast::NodeId) - -> Vec { - let mut taken = Vec::new(); - let parent = tcx.hir.get_parent(scope_id); - let method_id_opt = match tcx.hir.find(parent) { - Some(node) => match node { - hir_map::NodeItem(item) => match item.node { - hir::ItemFn(.., ref gen, _) => { - taken.extend_from_slice(&gen.lifetimes); - None - }, - _ => None - }, - hir_map::NodeImplItem(ii) => { - match ii.node { - hir::ImplItemKind::Method(ref sig, _) => { - taken.extend_from_slice(&sig.generics.lifetimes); - Some(ii.id) - } - _ => None, - } - } - _ => None - }, - None => None - }; - if let Some(method_id) = method_id_opt { - let parent = tcx.hir.get_parent(method_id); - if let Some(node) = tcx.hir.find(parent) { - match node { - hir_map::NodeItem(item) => match item.node { - hir::ItemImpl(_, _, ref gen, ..) => { - taken.extend_from_slice(&gen.lifetimes); - } - _ => () - }, - _ => () - } - } - } - return taken; -} - -// LifeGiver is responsible for generating fresh lifetime names -struct LifeGiver { - taken: HashSet, - counter: Cell, - generated: RefCell>, -} - -impl LifeGiver { - fn with_taken(taken: &[hir::LifetimeDef]) -> LifeGiver { - let mut taken_ = HashSet::new(); - for lt in taken { - let lt_name = lt.lifetime.name.to_string(); - taken_.insert(lt_name); - } - LifeGiver { - taken: taken_, - counter: Cell::new(0), - generated: RefCell::new(Vec::new()), - } - } - - fn inc_counter(&self) { - let c = self.counter.get(); - self.counter.set(c+1); - } - - fn give_lifetime(&self) -> hir::Lifetime { - let lifetime; - loop { - let mut s = String::from("'"); - s.push_str(&num_to_string(self.counter.get())); - if !self.taken.contains(&s) { - lifetime = name_to_dummy_lifetime(Symbol::intern(&s)); - self.generated.borrow_mut().push(lifetime); - break; - } - self.inc_counter(); - } - self.inc_counter(); - return lifetime; - - // 0 .. 25 generates a .. z, 26 .. 51 generates aa .. zz, and so on - fn num_to_string(counter: usize) -> String { - let mut s = String::new(); - let (n, r) = (counter/26 + 1, counter % 26); - let letter: char = from_u32((r+97) as u32).unwrap(); - for _ in 0..n { - s.push(letter); - } - s - } - } - - fn get_generated_lifetimes(&self) -> Vec { - self.generated.borrow().clone() - } -} - -fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime { - hir::Lifetime { id: ast::DUMMY_NODE_ID, - span: syntax_pos::DUMMY_SP, - name: name } -} - impl<'tcx> ObligationCause<'tcx> { fn as_failure_str(&self) -> &'static str { use traits::ObligationCauseCode::*; @@ -2038,4 +1329,3 @@ impl<'tcx> ObligationCause<'tcx> { } } } - diff --git a/src/test/compile-fail/issue-13058.rs b/src/test/compile-fail/issue-13058.rs index de578257e4684..408c6d411de90 100644 --- a/src/test/compile-fail/issue-13058.rs +++ b/src/test/compile-fail/issue-13058.rs @@ -20,7 +20,6 @@ impl<'r> Itble<'r, usize, Range> for (usize, usize) { } fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool -//~^ HELP as shown: fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &'r T) { let cont_iter = cont.iter(); //~^ ERROR cannot infer an appropriate lifetime for autoref due to conflicting requirements diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs deleted file mode 100644 index d2d0dbf3e981f..0000000000000 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs +++ /dev/null @@ -1,36 +0,0 @@ -// 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. - -// ignore-tidy-linelength - -use std::ops::Range; - -trait Itble<'r, T, I: Iterator> { fn iter(&'r self) -> I; } - -impl<'r> Itble<'r, usize, Range> for (usize, usize) { - fn iter(&'r self) -> Range { - let &(min, max) = self; - min..max - } -} - -fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool { -//~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &'r T) - let cont_iter = cont.iter(); //~ ERROR: cannot infer - let result = cont_iter.fold(Some(0), |state, val| { - state.map_or(None, |mask| { - let bit = 1 << val; - if mask & bit == 0 {Some(mask|bit)} else {None} - }) - }); - result.is_some() -} - -fn main() {} diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs deleted file mode 100644 index 6b22d434804ff..0000000000000 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs +++ /dev/null @@ -1,32 +0,0 @@ -// 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. - -// ignore-tidy-linelength - -use std::marker::PhantomData; - -struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> } -fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) { - //~^ HELP consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32) - (x.bar, &x.baz, &x.baz) - //~^ ERROR E0312 - //~| ERROR cannot infer - //~| ERROR cannot infer -} - -fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a i32, &'a i32, &'a i32) { - //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32) - (x.bar, &x.baz, &x.baz) - //~^ ERROR E0312 - //~| ERROR cannot infer - //~| ERROR cannot infer -} - -fn main() { } diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs deleted file mode 100644 index 4323929e2e37a..0000000000000 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -// ignore-tidy-linelength - -use std::marker::PhantomData; - -struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> } -fn foo1<'a>(x: &Foo) -> &'a isize { -//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize - &x.bar //~ ERROR: cannot infer -} - -fn foo2<'a, 'b>(x: &'a Foo) -> &'b isize { -//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo2<'a>(x: &'a Foo) -> &'a isize - &x.bar //~ ERROR: cannot infer -} - -fn foo3<'a>(x: &Foo) -> (&'a isize, &'a isize) { -//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a isize, &'a isize) - (&x.bar, &x.bar) //~ ERROR: cannot infer - //~^ ERROR: cannot infer -} - -fn foo4<'a, 'b>(x: &'a Foo) -> (&'b isize, &'a isize, &'b isize) { -//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a isize, &'a isize, &'a isize) - (&x.bar, &x.bar, &x.bar) //~ ERROR: cannot infer - //~^ ERROR: cannot infer -} - -struct Cat<'x, T> { cat: &'x isize, t: T } -struct Dog<'y> { dog: &'y isize } - -fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x isize { - //~^ HELP consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x isize - x.t.dog //~ ERROR E0312 -} - -struct Baz<'x> { - bar: &'x isize -} - -impl<'a> Baz<'a> { - fn baz2<'b>(&self, x: &isize) -> (&'b isize, &'b isize) { - (self.bar, x) //~ ERROR E0312 - //~^ ERROR E0312 - } -} - -fn main() {} diff --git a/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs b/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs deleted file mode 100644 index 603f55af465f4..0000000000000 --- a/src/test/ui/lifetimes/consider-using-explicit-lifetime.rs +++ /dev/null @@ -1,28 +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 std::str::FromStr; - -pub struct Foo<'a> { - field: &'a str, -} - -impl<'a> Foo<'a> { - fn bar(path: &str) -> Result { - Ok(Foo { field: path }) - } -} - -impl<'a> FromStr for Foo<'a> { - type Err = (); - fn from_str(path: &str) -> Result { - Ok(Foo { field: path }) - } -} diff --git a/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr b/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr deleted file mode 100644 index 153aaa07833a8..0000000000000 --- a/src/test/ui/lifetimes/consider-using-explicit-lifetime.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: main function not found - -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/consider-using-explicit-lifetime.rs:19:12 - | -19 | Ok(Foo { field: path }) - | ^^^ - -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/consider-using-explicit-lifetime.rs:26:12 - | -26 | Ok(Foo { field: path }) - | ^^^ - | -help: consider using an explicit lifetime parameter as shown: fn from_str(path: &'a str) -> Result - --> $DIR/consider-using-explicit-lifetime.rs:25:5 - | -25 | fn from_str(path: &str) -> Result { - | _____^ starting here... -26 | | Ok(Foo { field: path }) -27 | | } - | |_____^ ...ending here - -error: aborting due to 2 previous errors - From b8036b69086c6a43c86a20f0ac5e0bbc2d03fb9d Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Fri, 27 Jan 2017 04:36:12 +0200 Subject: [PATCH 41/86] Fix another endian-ness issue in i128 trans Apparently LLVMArbitraryPrecisionInteger demands integers to be in low-endian 64-bytes, rather than host-endian 64-bytes. This is weird, and obviously, not documented. Also, fixed now. And rustc now works a teeny bit more on big endians. --- src/librustc_trans/common.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 419267cb269c9..0ba94fdfe635c 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -234,7 +234,8 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { pub fn C_big_integral(t: Type, u: u128, sign_extend: bool) -> ValueRef { if ::std::mem::size_of::() == 16 { unsafe { - llvm::LLVMConstIntOfArbitraryPrecision(t.to_ref(), 2, &u as *const u128 as *const u64) + let words = [u as u64, u.wrapping_shr(64) as u64]; + llvm::LLVMConstIntOfArbitraryPrecision(t.to_ref(), 2, words.as_ptr()) } } else { // SNAP: remove after snapshot From d83687f68c1eed7d9783d23a7464e93aa5e886c3 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Thu, 26 Jan 2017 21:51:20 -0800 Subject: [PATCH 42/86] Fix can_begin_expr keyword behavior --- src/libsyntax/parse/token.rs | 24 ++++++++++++++- src/test/compile-fail/can-begin-expr-check.rs | 30 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/can-begin-expr-check.rs diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index bf790b96e37f6..43ad1eacf33b0 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -80,6 +80,28 @@ impl Lit { } } +fn ident_can_begin_expr(ident: ast::Ident) -> bool { + let ident_token: Token = Ident(ident); + + !ident_token.is_any_keyword() || + ident_token.is_path_segment_keyword() || + [ + keywords::Box.name(), + keywords::Break.name(), + keywords::Continue.name(), + keywords::False.name(), + keywords::For.name(), + keywords::If.name(), + keywords::Loop.name(), + keywords::Match.name(), + keywords::Move.name(), + keywords::Return.name(), + keywords::True.name(), + keywords::Unsafe.name(), + keywords::While.name(), + ].contains(&ident.name) +} + #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)] pub enum Token { /* Expression-operator symbols. */ @@ -163,7 +185,7 @@ impl Token { pub fn can_begin_expr(&self) -> bool { match *self { OpenDelim(..) => true, - Ident(..) => true, + Ident(ident) => ident_can_begin_expr(ident), Literal(..) => true, Not => true, BinOp(Minus) => true, diff --git a/src/test/compile-fail/can-begin-expr-check.rs b/src/test/compile-fail/can-begin-expr-check.rs new file mode 100644 index 0000000000000..68f219c6ed993 --- /dev/null +++ b/src/test/compile-fail/can-begin-expr-check.rs @@ -0,0 +1,30 @@ +// 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. + +pub fn main() { + + return; + return (); + return as (); + return return as (); + return return return; + + return if true { + () + } else { + () + }; + + loop { + return break as (); + } + + return enum; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `enum` +} From a5561ce2b94c33add47d288e1826183c511ec9fa Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 22 Jan 2017 12:53:35 -0800 Subject: [PATCH 43/86] rustc: Don't export builtins/panic/alloc syms This hides symbols from various unstable and implementation-detail crates of the standard library. Although typically transitive exported `pub extern` functions are exported from cdylibs, these crates aren't necessary as they're all implementation details. Closes #34493 --- src/liballoc_jemalloc/build.rs | 11 +++++++ src/liballoc_jemalloc/lib.rs | 2 +- src/liballoc_jemalloc/pthread_atfork_dummy.c | 6 ++++ src/librustc_trans/back/symbol_export.rs | 33 +++++++++++++++++++- 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/liballoc_jemalloc/pthread_atfork_dummy.c diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs index 1edcb0b1f24de..1143df0c6302d 100644 --- a/src/liballoc_jemalloc/build.rs +++ b/src/liballoc_jemalloc/build.rs @@ -181,4 +181,15 @@ fn main() { } else if !target.contains("windows") && !target.contains("musl") { println!("cargo:rustc-link-lib=pthread"); } + + // The pthread_atfork symbols is used by jemalloc on android but the really + // old android we're building on doesn't have them defined, so just make + // sure the symbols are available. + if target.contains("androideabi") { + println!("cargo:rerun-if-changed=pthread_atfork_dummy.c"); + gcc::Config::new() + .flag("-fvisibility=hidden") + .file("pthread_atfork_dummy.c") + .compile("libpthread_atfork_dummy.a"); + } } diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 241f8149d24d2..fc8a5455d1d07 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -143,7 +143,7 @@ mod imp { // we're building on doesn't have them defined, so just make sure the symbols // are available. #[no_mangle] - #[cfg(target_os = "android")] + #[cfg(all(target_os = "android", not(cargobuild)))] pub extern "C" fn pthread_atfork(_prefork: *mut u8, _postfork_parent: *mut u8, _postfork_child: *mut u8) diff --git a/src/liballoc_jemalloc/pthread_atfork_dummy.c b/src/liballoc_jemalloc/pthread_atfork_dummy.c new file mode 100644 index 0000000000000..f798afe741f69 --- /dev/null +++ b/src/liballoc_jemalloc/pthread_atfork_dummy.c @@ -0,0 +1,6 @@ +// See comments in build.rs for why this exists +int pthread_atfork(void* prefork, + void* postfork_parent, + void* postfork_child) { + return 0; +} diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 81be2d02f125b..bea3ca8df70e0 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -81,11 +81,25 @@ impl ExportedSymbols { for cnum in scx.sess().cstore.crates() { debug_assert!(cnum != LOCAL_CRATE); + // If this crate is a plugin and/or a custom derive crate, then + // we're not even going to link those in so we skip those crates. if scx.sess().cstore.plugin_registrar_fn(cnum).is_some() || scx.sess().cstore.derive_registrar_fn(cnum).is_some() { continue; } + // Check to see if this crate is a "special runtime crate". These + // crates, implementation details of the standard library, typically + // have a bunch of `pub extern` and `#[no_mangle]` functions as the + // ABI between them. We don't want their symbols to have a `C` + // export level, however, as they're just implementation details. + // Down below we'll hardwire all of the symbols to the `Rust` export + // level instead. + let special_runtime_crate = + scx.sess().cstore.is_allocator(cnum) || + scx.sess().cstore.is_panic_runtime(cnum) || + scx.sess().cstore.is_compiler_builtins(cnum); + let crate_exports = scx .sess() .cstore @@ -93,7 +107,24 @@ impl ExportedSymbols { .iter() .map(|&def_id| { let name = Instance::mono(scx, def_id).symbol_name(scx); - let export_level = export_level(scx, def_id); + let export_level = if special_runtime_crate { + // We can probably do better here by just ensuring that + // it has hidden visibility rather than public + // visibility, as this is primarily here to ensure it's + // not stripped during LTO. + // + // In general though we won't link right if these + // symbols are stripped, and LTO currently strips them. + if name == "rust_eh_personality" || + name == "rust_eh_register_frames" || + name == "rust_eh_unregister_frames" { + SymbolExportLevel::C + } else { + SymbolExportLevel::Rust + } + } else { + export_level(scx, def_id) + }; debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); (name, export_level) }) From 3d6f263b2a162974725cdcb914ba9ad9c2dbef84 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 22 Jan 2017 12:58:56 -0800 Subject: [PATCH 44/86] std: Compile libbacktrace with -fvisibility=hidden We don't want these symbols exported from the standard library, this is just an internal implementation detail of the standard library currently. Closes #34984 --- src/liballoc_jemalloc/pthread_atfork_dummy.c | 10 ++++++++++ src/libstd/build.rs | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/liballoc_jemalloc/pthread_atfork_dummy.c b/src/liballoc_jemalloc/pthread_atfork_dummy.c index f798afe741f69..4e3df0ab26c37 100644 --- a/src/liballoc_jemalloc/pthread_atfork_dummy.c +++ b/src/liballoc_jemalloc/pthread_atfork_dummy.c @@ -1,3 +1,13 @@ +// Copyright 2017 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. + // See comments in build.rs for why this exists int pthread_atfork(void* prefork, void* postfork_parent, diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 5e1c3a2851568..9504194393f94 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -87,8 +87,9 @@ fn build_libbacktrace(host: &str, target: &str) { let compiler = gcc::Config::new().get_compiler(); // only msvc returns None for ar so unwrap is okay let ar = build_helper::cc2ar(compiler.path(), target).unwrap(); - let cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) - .collect::>().join(" "); + let mut cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) + .collect::>().join(" "); + cflags.push_str(" -fvisibility=hidden"); run(Command::new("sh") .current_dir(&build_dir) .arg(src_dir.join("configure").to_str().unwrap() From 450554ebf139d0b6ecde80f17c2ef89ff7de78bb Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 27 Jan 2017 11:33:24 +0200 Subject: [PATCH 45/86] Attempt at fixing dead code lints --- src/libstd/sys/unix/backtrace/mod.rs | 13 +++-- src/libstd/sys/windows/backtrace.rs | 52 ++----------------- src/libstd/sys/windows/backtrace_gnu.rs | 61 +++++++++++++++++++++++ src/libstd/sys/windows/c.rs | 45 +++++++++++------ src/libstd/sys/windows/mod.rs | 1 + src/libstd/sys_common/gnu/libbacktrace.rs | 2 +- 6 files changed, 106 insertions(+), 68 deletions(-) create mode 100644 src/libstd/sys/windows/backtrace_gnu.rs diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index e3f1b23f7a24b..62e9c24ac3045 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -83,9 +83,6 @@ /// to symbols. This is a bit of a hokey implementation as-is, but it works for /// all unix platforms we support right now, so it at least gets the job done. -use io; -use fs; - pub use self::tracing::write; // tracing impls: @@ -93,6 +90,12 @@ mod tracing; // symbol resolvers: mod printing; -pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { - Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))] +pub mod gnu { + use io; + use fs; + + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) + } } diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index e6182cda58a28..94aaf439f3d57 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -30,13 +30,9 @@ use io; use libc::c_void; use mem; use ptr; -use path::PathBuf; -use fs::{OpenOptions, File}; -use sys::ext::fs::OpenOptionsExt; use sys::c; use sys::dynamic_lib::DynamicLibrary; use sys::mutex::Mutex; -use sys::handle::Handle; macro_rules! sym { ($lib:expr, $e:expr, $t:ident) => ( @@ -55,6 +51,10 @@ mod printing; #[path = "printing/gnu.rs"] mod printing; +#[cfg(target_env = "gnu")] +#[path = "backtrace_gnu.rs"] +pub mod gnu; + type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL; @@ -161,47 +161,3 @@ unsafe fn _write(w: &mut Write) -> io::Result<()> { Ok(()) } - -fn query_full_process_image_name() -> io::Result { - unsafe { - let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, - c::FALSE, - c::GetCurrentProcessId())); - super::fill_utf16_buf(|buf, mut sz| { - if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { - 0 - } else { - sz - } - }, super::os2path) - } -} - -fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { - // We query the current image name, open the file without FILE_SHARE_DELETE so it - // can't be moved and then get the current image name again. If the names are the - // same than we have successfully locked the file - let image_name1 = query_full_process_image_name()?; - let file = OpenOptions::new() - .read(true) - .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) - .open(&image_name1)?; - let image_name2 = query_full_process_image_name()?; - - if image_name1 != image_name2 { - return Err(io::Error::new(io::ErrorKind::Other, - "executable moved while trying to lock it")); - } - - Ok((image_name1, file)) -} - -// Get the executable filename for libbacktrace -// This returns the path in the ANSI code page and a File which should remain open -// for as long as the path should remain valid -pub fn get_executable_filename() -> io::Result<(Vec, File)> { - let (executable, file) = lock_and_get_executable_filename()?; - let u16_executable = super::to_u16s(executable.into_os_string())?; - Ok((super::wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, - &u16_executable, true)?, file)) -} diff --git a/src/libstd/sys/windows/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace_gnu.rs new file mode 100644 index 0000000000000..8282174a59efe --- /dev/null +++ b/src/libstd/sys/windows/backtrace_gnu.rs @@ -0,0 +1,61 @@ +// 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. + +use io; +use sys::c; +use path::PathBuf; +use fs::{OpenOptions, File}; +use sys::ext::fs::OpenOptionsExt; +use sys::handle::Handle; +use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte}; + +fn query_full_process_image_name() -> io::Result { + unsafe { + let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, + c::FALSE, + c::GetCurrentProcessId())); + fill_utf16_buf(|buf, mut sz| { + if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { + 0 + } else { + sz + } + }, os2path) + } +} + +fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { + // We query the current image name, open the file without FILE_SHARE_DELETE so it + // can't be moved and then get the current image name again. If the names are the + // same than we have successfully locked the file + let image_name1 = query_full_process_image_name()?; + let file = OpenOptions::new() + .read(true) + .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) + .open(&image_name1)?; + let image_name2 = query_full_process_image_name()?; + + if image_name1 != image_name2 { + return Err(io::Error::new(io::ErrorKind::Other, + "executable moved while trying to lock it")); + } + + Ok((image_name1, file)) +} + +// Get the executable filename for libbacktrace +// This returns the path in the ANSI code page and a File which should remain open +// for as long as the path should remain valid +pub fn get_executable_filename() -> io::Result<(Vec, File)> { + let (executable, file) = lock_and_get_executable_filename()?; + let u16_executable = to_u16s(executable.into_os_string())?; + Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, + &u16_executable, true)?, file)) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index c6fac6d1759b1..1b29bf73c7aec 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -158,7 +158,6 @@ pub const WSAECONNREFUSED: c_int = 10061; pub const MAX_PROTOCOL_CHAIN: DWORD = 7; -pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; pub const TOKEN_READ: DWORD = 0x20008; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; @@ -220,10 +219,6 @@ pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200; pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400; pub const STARTF_USESTDHANDLES: DWORD = 0x00000100; -pub const CP_ACP: UINT = 0; - -pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; - pub const AF_INET: c_int = 2; pub const AF_INET6: c_int = 23; pub const SD_BOTH: c_int = 2; @@ -894,9 +889,6 @@ extern "system" { pNumArgs: *mut c_int) -> *mut *mut u16; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; - pub fn OpenProcess(dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwProcessId: DWORD) -> HANDLE; pub fn OpenProcessToken(ProcessHandle: HANDLE, DesiredAccess: DWORD, TokenHandle: *mut HANDLE) -> BOOL; @@ -1153,12 +1145,6 @@ compat_fn! { _dwFlags: DWORD) -> DWORD { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } - pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, - _dwFlags: DWORD, - _lpExeName: LPWSTR, - _lpdwSize: LPDWORD) -> BOOL { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 - } pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } @@ -1201,3 +1187,34 @@ compat_fn! { panic!("rwlocks not available") } } + +#[cfg(target_env = "gnu")] +mod gnu { + use super::*; + + pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; + + pub const CP_ACP: UINT = 0; + + pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; + + extern "system" { + pub fn OpenProcess(dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwProcessId: DWORD) -> HANDLE; + } + + compat_fn! { + kernel32: + + pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, + _dwFlags: DWORD, + _lpExeName: LPWSTR, + _lpdwSize: LPDWORD) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + } +} + +#[cfg(target_env = "gnu")] +pub use self::gnu::*; diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 4468cf574b38a..4424c6c6136c5 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -172,6 +172,7 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } +#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename() fn wide_char_to_multi_byte(code_page: u32, flags: u32, s: &[u16], diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs index 94d206f3ac3c1..d464a13ad1d3f 100644 --- a/src/libstd/sys_common/gnu/libbacktrace.rs +++ b/src/libstd/sys_common/gnu/libbacktrace.rs @@ -126,7 +126,7 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, static mut STATE: *mut backtrace_state = ptr::null_mut(); if !STATE.is_null() { return STATE } - let filename = match ::sys::backtrace::get_executable_filename() { + let filename = match ::sys::backtrace::gnu::get_executable_filename() { Ok((filename, file)) => { // filename is purposely leaked here since libbacktrace requires // it to stay allocated permanently, file is also leaked so that From 09b3903aecf2c8cafa62cb67eccbe10a3ca09b5d Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Fri, 27 Jan 2017 18:08:51 +0000 Subject: [PATCH 46/86] Fix a few links in the docs --- src/doc/book/ffi.md | 2 +- src/liballoc/arc.rs | 2 +- src/libcore/hash/mod.rs | 1 + src/libcore/iter/iterator.rs | 6 +++--- src/libcore/sync/atomic.rs | 4 ++-- src/libstd/env.rs | 2 +- src/libstd/thread/mod.rs | 4 ++-- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/doc/book/ffi.md b/src/doc/book/ffi.md index 50d4d0170fc70..8ab580e6aa9fd 100644 --- a/src/doc/book/ffi.md +++ b/src/doc/book/ffi.md @@ -710,7 +710,7 @@ Please note that [`catch_unwind()`] will only catch unwinding panics, not those who abort the process. See the documentation of [`catch_unwind()`] for more information. -[`catch_unwind()`]: https://doc.rust-lang.org/std/panic/fn.catch_unwind.html +[`catch_unwind()`]: ../std/panic/fn.catch_unwind.html # Representing opaque structs diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 459dc94f33686..38d843263ffda 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -59,7 +59,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is /// that atomic operations are more expensive than ordinary memory accesses. /// If you are not sharing reference-counted values between threads, consider -/// using [`rc::Rc`] for lower overhead. [`Rc`] is a safe default, because +/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because /// the compiler will catch any attempt to send an [`Rc`] between threads. /// However, a library might choose `Arc` in order to give library consumers /// more flexibility. diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 92657a6d0b1ca..dd6edc7d39af0 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -307,6 +307,7 @@ pub trait BuildHasher { /// [`BuildHasher`]: trait.BuildHasher.html /// [`Default`]: ../default/trait.Default.html /// [`Hasher`]: trait.Hasher.html +/// [`HashMap`]: ../../std/collections/struct.HashMap.html #[stable(since = "1.7.0", feature = "build_hasher")] pub struct BuildHasherDefault(marker::PhantomData); diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 91c09c5530565..3b406873d4b19 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1108,9 +1108,9 @@ pub trait Iterator { /// /// One of the keys to `collect()`'s power is that many things you might /// not think of as 'collections' actually are. For example, a [`String`] - /// is a collection of [`char`]s. And a collection of [`Result`] can - /// be thought of as single [`Result`]`, E>`. See the examples - /// below for more. + /// is a collection of [`char`]s. And a collection of + /// [`Result`][`Result`] can be thought of as single + /// [`Result`]`, E>`. See the examples below for more. /// /// Because `collect()` is so general, it can cause problems with type /// inference. As such, `collect()` is one of the few times you'll see diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index a3cb12844777b..743e3c41170a3 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -24,7 +24,7 @@ //! same as [LLVM atomic orderings][1]. For more information see the [nomicon][2]. //! //! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations -//! [2]: https://doc.rust-lang.org/nomicon/atomics.html +//! [2]: ../../../nomicon/atomics.html //! //! Atomic variables are safe to share between threads (they implement `Sync`) //! but they do not themselves provide the mechanism for sharing and follow the @@ -144,7 +144,7 @@ unsafe impl Sync for AtomicPtr {} /// LLVM's](http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). /// /// For more information see the [nomicon][1]. -/// [1]: https://doc.rust-lang.org/nomicon/atomics.html +/// [1]: ../../../nomicon/atomics.html #[stable(feature = "rust1", since = "1.0.0")] #[derive(Copy, Clone, Debug)] pub enum Ordering { diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 80c64ae860f8f..c3a6b2433ed88 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -222,7 +222,7 @@ fn _var_os(key: &OsStr) -> Option { /// Possible errors from the [`env::var`] function. /// -/// [env::var]: fn.var.html +/// [`env::var`]: fn.var.html #[derive(Debug, PartialEq, Eq, Clone)] #[stable(feature = "env", since = "1.0.0")] pub enum VarError { diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 07a9b4bed9920..8789006436c0c 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -391,7 +391,7 @@ impl Builder { /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html /// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join /// [`Err`]: ../../std/result/enum.Result.html#variant.Err -/// [`panic!`]: ../../std/macro.panic.html +/// [`panic`]: ../../std/macro.panic.html /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn /// /// # Examples @@ -974,7 +974,7 @@ impl JoinHandle { /// to [`panic`]. /// /// [`Err`]: ../../std/result/enum.Result.html#variant.Err - /// [`panic!`]: ../../std/macro.panic.html + /// [`panic`]: ../../std/macro.panic.html /// /// # Examples /// From 0f2a5f686f3fbc3d66dce301e965b43d5c3acd63 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 27 Jan 2017 14:29:11 -0500 Subject: [PATCH 47/86] Fix up @carols10cents' mailmap entry The previous ways didn't work; this does. cc rust-lang-nursery/thanks#45 --- .mailmap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index be18190e12b38..90a5e0f5f321e 100644 --- a/.mailmap +++ b/.mailmap @@ -43,8 +43,8 @@ Brian Anderson Brian Dawn Brian Leibig Brian Leibig Carl-Anton Ingmarsson -Carol (Nichols || Goulding) Carol Nichols -Carol (Nichols || Goulding) Carol Nichols +Carol (Nichols || Goulding) +Carol (Nichols || Goulding) Carol Willing Chris C Cerami Chris C Cerami Chris Pressey From 945177de8c78a8c727b6b591e6f3a3a840824bd2 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 27 Jan 2017 15:19:30 -0500 Subject: [PATCH 48/86] Fix @jethrogb's mailmap entry cc rust-lang-nursery/thanks#51 --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index be18190e12b38..12b9b30edad9f 100644 --- a/.mailmap +++ b/.mailmap @@ -102,6 +102,7 @@ Jason Toffaletti Jason Toffaletti Jauhien Piatlicki Jauhien Piatlicki Jay True Jeremy Letang +Jethro Beekman Jihyun Yu Jihyun Yu jihyun Jihyun Yu Jihyun Yu From 810b22bdb117cdffff06216c68e2875404e098eb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 27 Jan 2017 15:27:26 -0500 Subject: [PATCH 49/86] Fix cyryl's mailmap entry --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index be18190e12b38..f4103941db3c0 100644 --- a/.mailmap +++ b/.mailmap @@ -53,6 +53,7 @@ Clark Gaebel Clinton Ryan Corey Farwell Corey Farwell Corey Richardson Elaine "See More" Nemo +Cyryl PÅ‚otnicki Damien Schoof Daniel Ramos David Klein From f4010d7e618b38aea7ad073ffaf9bb90b12c6ca5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 27 Jan 2017 16:16:43 -0500 Subject: [PATCH 50/86] move `cast_kinds` into `TypeckTables` where it belongs --- src/librustc/ty/context.rs | 14 +++++++------- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_passes/consts.rs | 2 +- src/librustc_typeck/check/cast.rs | 4 ++-- src/librustc_typeck/check/writeback.rs | 10 ++++++++++ 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c78ba3b8a9bbf..931d83f5e188a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -231,7 +231,11 @@ pub struct TypeckTables<'tcx> { /// of the struct - this is needed because it is non-trivial to /// normalize while preserving regions. This table is used only in /// MIR construction and hence is not serialized to metadata. - pub fru_field_types: NodeMap>> + pub fru_field_types: NodeMap>>, + + /// Maps a cast expression to its kind. This is keyed on the + /// *from* expression of the cast, not the cast itself. + pub cast_kinds: NodeMap, } impl<'tcx> TypeckTables<'tcx> { @@ -246,7 +250,8 @@ impl<'tcx> TypeckTables<'tcx> { closure_tys: NodeMap(), closure_kinds: NodeMap(), liberated_fn_sigs: NodeMap(), - fru_field_types: NodeMap() + fru_field_types: NodeMap(), + cast_kinds: NodeMap(), } } @@ -533,10 +538,6 @@ pub struct GlobalCtxt<'tcx> { /// expression defining the closure. pub closure_kinds: RefCell>>, - /// Maps a cast expression to its kind. This is keyed on the - /// *from* expression of the cast, not the cast itself. - pub cast_kinds: RefCell>, - /// Maps Fn items to a collection of fragment infos. /// /// The main goal is to identify data (each of which may be moved @@ -792,7 +793,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), closure_tys: RefCell::new(DepTrackingMap::new(dep_graph.clone())), closure_kinds: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - cast_kinds: RefCell::new(NodeMap()), fragment_infos: RefCell::new(DefIdMap()), crate_name: Symbol::intern(crate_name), data_layout: data_layout, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 477a1086e815e..7eaf1fe139865 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -663,7 +663,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprCast(ref source, _) => { // Check to see if this cast is a "coercion cast", where the cast is actually done // using a coercion (or is a no-op). - if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) { + if let Some(&TyCastKind::CoercionCast) = cx.tables().cast_kinds.get(&source.id) { // Convert the lexpr to a vexpr. ExprKind::Use { source: source.to_ref() } } else { diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b6241c618df2f..0b55513f8318c 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -314,7 +314,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } hir::ExprCast(ref from, _) => { debug!("Checking const cast(id={})", from.id); - match v.tcx.cast_kinds.borrow().get(&from.id) { + match v.tables.cast_kinds.get(&from.id) { None => span_bug!(e.span, "no kind for cast"), Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => { v.promotable = false; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 265dcada1f810..0218f1c70ba8e 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -348,12 +348,12 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } else if self.try_coercion_cast(fcx) { self.trivial_cast_lint(fcx); debug!(" -> CoercionCast"); - fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id, CastKind::CoercionCast); + fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, CastKind::CoercionCast); } else { match self.do_check(fcx) { Ok(k) => { debug!(" -> {:?}", k); - fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id, k); + fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, k); } Err(e) => self.report_cast_error(fcx, e), }; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index b95126af56aa7..7f82d7829ce52 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -51,6 +51,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { wbcx.visit_anon_types(); wbcx.visit_deferred_obligations(item_id); wbcx.visit_type_nodes(); + wbcx.visit_cast_types(); let tables = self.tcx.alloc_tables(wbcx.tables); self.tcx.tables.borrow_mut().insert(item_def_id, tables); @@ -291,6 +292,15 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } + fn visit_cast_types(&mut self) { + if self.fcx.writeback_errors.get() { + return + } + + self.tables.cast_kinds.extend( + self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value))); + } + fn visit_anon_types(&self) { if self.fcx.writeback_errors.get() { return From 98bc300d697d0c9f68abb6bb6eef978bce8e25c5 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Fri, 27 Jan 2017 23:23:26 +0200 Subject: [PATCH 51/86] Use __SIZEOF_INT128__ to test __int128 presence Previously we tested whether a handful of preprocessor variables indicating certain 64 bit platforms, but this does not work for other 64 bit targets which have support for __int128 in C compiler. Use the __SIZEOF__INT128__ preprocessor variable instead. This variable gets set to 16 by gcc and clang for every target where __int128 is supported. --- src/rt/rust_test_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rt/rust_test_helpers.c b/src/rt/rust_test_helpers.c index 5900b21b6126a..2a14b3da7b7d0 100644 --- a/src/rt/rust_test_helpers.c +++ b/src/rt/rust_test_helpers.c @@ -269,7 +269,7 @@ LARGE_INTEGER increment_all_parts(LARGE_INTEGER li) { return li; } -#if !(defined(WIN32) || defined(_WIN32) || defined(__WIN32)) && defined(__amd64__) +#if __SIZEOF_INT128__ == 16 unsigned __int128 identity(unsigned __int128 a) { return a; From 460a3b20aac43cf4a1deaee566125d60e250496d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Jan 2017 16:59:35 +0100 Subject: [PATCH 52/86] Don't generate doc if doc comments only filled with 'white' characters --- src/librustdoc/html/markdown.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index f2427008a7d45..8cc3b60a18406 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -237,8 +237,9 @@ pub fn render(w: &mut fmt::Formatter, let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque); let text = (*orig_text).as_bytes(); let origtext = str::from_utf8(text).unwrap(); + let origtext = origtext.trim_left(); debug!("docblock: ==============\n{:?}\n=======", text); - let rendered = if lang.is_null() { + let rendered = if lang.is_null() || origtext.is_empty() { false } else { let rlang = (*lang).as_bytes(); From e2ef630a21ae7439477642c7b629cd9beaa1811e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 27 Jan 2017 14:51:47 -0800 Subject: [PATCH 53/86] rustdoc: Suppress warnings/errors with --test Threads spawned by the test framework have their output captured by default, so for `rustdoc --test` threads this propagates that capturing to the spawned thread that we now have. Closes #39327 --- src/librustdoc/test.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 1f224cac9e91f..ab0ac02fd88f1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -429,8 +429,12 @@ impl Collector { should_panic: testing::ShouldPanic::No, }, testfn: testing::DynTestFn(box move |()| { + let panic = io::set_panic(None); + let print = io::set_print(None); match { rustc_driver::in_rustc_thread(move || { + io::set_panic(panic); + io::set_print(print); runtest(&test, &cratename, cfgs, From 1b4a6c86fa2acc4385c3c420773484d61ecc22b8 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sat, 28 Jan 2017 01:01:16 +0200 Subject: [PATCH 54/86] Use libc::c_char instead of i8 due to platforms with unsigned char --- src/libstd/sys/unix/backtrace/mod.rs | 3 ++- src/libstd/sys/windows/backtrace_gnu.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index 62e9c24ac3045..1eef89bf66f74 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -94,8 +94,9 @@ mod printing; pub mod gnu { use io; use fs; + use libc::c_char; - pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) } } diff --git a/src/libstd/sys/windows/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace_gnu.rs index 8282174a59efe..f0d29dd4178d1 100644 --- a/src/libstd/sys/windows/backtrace_gnu.rs +++ b/src/libstd/sys/windows/backtrace_gnu.rs @@ -10,6 +10,7 @@ use io; use sys::c; +use libc::c_char; use path::PathBuf; use fs::{OpenOptions, File}; use sys::ext::fs::OpenOptionsExt; @@ -53,7 +54,7 @@ fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { // Get the executable filename for libbacktrace // This returns the path in the ANSI code page and a File which should remain open // for as long as the path should remain valid -pub fn get_executable_filename() -> io::Result<(Vec, File)> { +pub fn get_executable_filename() -> io::Result<(Vec, File)> { let (executable, file) = lock_and_get_executable_filename()?; let u16_executable = to_u16s(executable.into_os_string())?; Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, From 4f559f8c33634670a8113091fe71080b21562031 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 4 Jan 2017 14:32:44 +0200 Subject: [PATCH 55/86] rustc_typeck: force users of RegionScope to get anon_region's one by one. --- src/librustc_typeck/astconv.rs | 14 ++--- src/librustc_typeck/check/mod.rs | 8 ++- src/librustc_typeck/rscope.rs | 91 ++++++++++---------------------- 3 files changed, 39 insertions(+), 74 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1af8b59cdfa7d..166178d6c29c1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -306,9 +306,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ast_region_to_region(self.tcx(), lifetime) } - None => self.tcx().mk_region(match rscope.anon_regions(default_span, 1) { - Ok(rs) => rs[0], - Err(params) => { + None => { + self.tcx().mk_region(rscope.anon_region(default_span).unwrap_or_else(|params| { let ampersand_span = Span { hi: default_span.lo, ..default_span}; let mut err = struct_span_err!(self.tcx().sess, ampersand_span, E0106, @@ -320,8 +319,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } err.emit(); ty::ReStatic - } - }) + })) + } }; debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}", @@ -412,8 +411,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let regions = if expected_num_region_params == supplied_num_region_params { lifetimes.iter().map(|l| *ast_region_to_region(tcx, l)).collect() } else { - let anon_regions = - rscope.anon_regions(span, expected_num_region_params); + let anon_regions = (0..expected_num_region_params).map(|_| { + rscope.anon_region(span) + }).collect::, _>>(); if supplied_num_region_params != 0 || anon_regions.is_err() { report_lifetime_number_error(tcx, span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 20c4f8f95224d..1e76267f32c38 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1466,11 +1466,9 @@ impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> { *self.next_region_var(infer::MiscVariable(span)) } - fn anon_regions(&self, span: Span, count: usize) - -> Result, Option>> { - Ok((0..count).map(|_| { - *self.next_region_var(infer::MiscVariable(span)) - }).collect()) + fn anon_region(&self, span: Span) + -> Result>> { + Ok(*self.next_region_var(infer::MiscVariable(span))) } } diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 3f5e443a20a68..839eb8be9ace8 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -33,18 +33,16 @@ pub type ElidedLifetime = Result>>; /// Defines strategies for handling regions that are omitted. For /// example, if one writes the type `&Foo`, then the lifetime of /// this reference has been omitted. When converting this -/// type, the generic functions in astconv will invoke `anon_regions` +/// type, the generic functions in astconv will invoke `anon_region` /// on the provided region-scope to decide how to translate this /// omitted region. /// -/// It is not always legal to omit regions, therefore `anon_regions` +/// It is not always legal to omit regions, therefore `anon_region` /// can return `Err(())` to indicate that this is not a scope in which /// regions can legally be omitted. pub trait RegionScope { - fn anon_regions(&self, - span: Span, - count: usize) - -> Result, Option>>; + fn anon_region(&self, span: Span) + -> Result>>; /// If an object omits any explicit lifetime bound, and none can /// be derived from the object traits, what should we use? If @@ -117,11 +115,9 @@ impl RegionScope for MaybeWithAnonTypes { self.base_scope.object_lifetime_default(span) } - fn anon_regions(&self, - span: Span, - count: usize) - -> Result, Option>> { - self.base_scope.anon_regions(span, count) + fn anon_region(&self, span: Span) + -> Result>> { + self.base_scope.anon_region(span) } fn base_object_lifetime_default(&self, span: Span) -> ty::Region { @@ -139,10 +135,8 @@ impl RegionScope for MaybeWithAnonTypes { pub struct ExplicitRscope; impl RegionScope for ExplicitRscope { - fn anon_regions(&self, - _span: Span, - _count: usize) - -> Result, Option>> { + fn anon_region(&self, _span: Span) + -> Result>> { Err(None) } @@ -165,12 +159,9 @@ impl UnelidableRscope { } impl RegionScope for UnelidableRscope { - fn anon_regions(&self, - _span: Span, - _count: usize) - -> Result, Option>> { - let UnelidableRscope(ref v) = *self; - Err(v.clone()) + fn anon_region(&self, _span: Span) + -> Result>> { + Err(self.0.clone()) } fn object_lifetime_default(&self, span: Span) -> Option { @@ -208,12 +199,10 @@ impl RegionScope for ElidableRscope { ty::ReStatic } - fn anon_regions(&self, - _span: Span, - count: usize) - -> Result, Option>> + fn anon_region(&self, _span: Span) + -> Result>> { - Ok(vec![self.default; count]) + Ok(self.default) } } @@ -232,10 +221,8 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> StaticRscope<'a, 'gcx, 'tcx> { } impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> { - fn anon_regions(&self, - span: Span, - count: usize) - -> Result, Option>> { + fn anon_region(&self, span: Span) + -> Result>> { if !self.tcx.sess.features.borrow().static_in_const { self.tcx .sess @@ -244,7 +231,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> `static_in_const` feature, see #35897") .emit(); } - Ok(vec![ty::ReStatic; count]) + Ok(ty::ReStatic) } fn object_lifetime_default(&self, span: Span) -> Option { @@ -268,12 +255,6 @@ impl BindingRscope { anon_bindings: Cell::new(0), } } - - fn next_region(&self) -> ty::Region { - let idx = self.anon_bindings.get(); - self.anon_bindings.set(idx + 1); - ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(idx)) - } } impl RegionScope for BindingRscope { @@ -288,12 +269,12 @@ impl RegionScope for BindingRscope { ty::ReStatic } - fn anon_regions(&self, - _: Span, - count: usize) - -> Result, Option>> + fn anon_region(&self, _: Span) + -> Result>> { - Ok((0..count).map(|_| self.next_region()).collect()) + let idx = self.anon_bindings.get(); + self.anon_bindings.set(idx + 1); + Ok(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(idx))) } } @@ -334,12 +315,10 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { self.base_scope.base_object_lifetime_default(span) } - fn anon_regions(&self, - span: Span, - count: usize) - -> Result, Option>> + fn anon_region(&self, span: Span) + -> Result>> { - self.base_scope.anon_regions(span, count) + self.base_scope.anon_region(span) } fn anon_type_scope(&self) -> Option { @@ -369,22 +348,10 @@ impl<'r> RegionScope for ShiftedRscope<'r> { ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1) } - fn anon_regions(&self, - span: Span, - count: usize) - -> Result, Option>> + fn anon_region(&self, span: Span) + -> Result>> { - match self.base_scope.anon_regions(span, count) { - Ok(mut v) => { - for r in &mut v { - *r = ty::fold::shift_region(*r, 1); - } - Ok(v) - } - Err(errs) => { - Err(errs) - } - } + self.base_scope.anon_region(span).map(|r| ty::fold::shift_region(r, 1)) } fn anon_type_scope(&self) -> Option { From f79feba2053c78425b6490c8587359846fa6648f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 4 Jan 2017 23:23:11 +0200 Subject: [PATCH 56/86] rustc_typeck: pass all lifetimes through AstConv::opt_ast_region_to_region. --- src/librustc_typeck/astconv.rs | 200 +++++++++++++++---------------- src/librustc_typeck/check/mod.rs | 16 +-- src/librustc_typeck/collect.rs | 19 ++- src/librustc_typeck/rscope.rs | 24 ++-- 4 files changed, 129 insertions(+), 130 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 166178d6c29c1..0a836a8ba2229 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -64,7 +64,7 @@ use require_c_abi_if_variadic; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope, ElisionFailureInfo, ElidedLifetime}; -use rscope::{AnonTypeScope, MaybeWithAnonTypes}; +use rscope::{AnonTypeScope, MaybeWithAnonTypes, ExplicitRscope}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; use util::nodemap::{NodeMap, FxHashSet}; @@ -161,70 +161,6 @@ struct ConvertedBinding<'tcx> { /// This type must not appear anywhere in other converted types. const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0)); -pub fn ast_region_to_region<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - lifetime: &hir::Lifetime) - -> &'tcx ty::Region { - let r = match tcx.named_region_map.defs.get(&lifetime.id) { - None => { - // should have been recorded by the `resolve_lifetime` pass - span_bug!(lifetime.span, "unresolved lifetime"); - } - - Some(&rl::DefStaticRegion) => { - ty::ReStatic - } - - Some(&rl::DefLateBoundRegion(debruijn, id)) => { - // If this region is declared on a function, it will have - // an entry in `late_bound`, but if it comes from - // `for<'a>` in some type or something, it won't - // necessarily have one. In that case though, we won't be - // changed from late to early bound, so we can just - // substitute false. - let issue_32330 = tcx.named_region_map - .late_bound - .get(&id) - .cloned() - .unwrap_or(ty::Issue32330::WontChange); - ty::ReLateBound(debruijn, ty::BrNamed(tcx.hir.local_def_id(id), - lifetime.name, - issue_32330)) - } - - Some(&rl::DefEarlyBoundRegion(index, _)) => { - ty::ReEarlyBound(ty::EarlyBoundRegion { - index: index, - name: lifetime.name - }) - } - - Some(&rl::DefFreeRegion(scope, id)) => { - // As in DefLateBoundRegion above, could be missing for some late-bound - // regions, but also for early-bound regions. - let issue_32330 = tcx.named_region_map - .late_bound - .get(&id) - .cloned() - .unwrap_or(ty::Issue32330::WontChange); - ty::ReFree(ty::FreeRegion { - scope: scope.to_code_extent(&tcx.region_maps), - bound_region: ty::BrNamed(tcx.hir.local_def_id(id), - lifetime.name, - issue_32330) - }) - - // (*) -- not late-bound, won't change - } - }; - - debug!("ast_region_to_region(lifetime={:?} id={}) yields {:?}", - lifetime, - lifetime.id, - r); - - tcx.mk_region(r) -} - fn report_elision_failure( tcx: TyCtxt, db: &mut DiagnosticBuilder, @@ -296,38 +232,98 @@ fn report_elision_failure( } impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { - pub fn opt_ast_region_to_region(&self, + pub fn ast_region_to_region(&self, lifetime: &hir::Lifetime) -> &'tcx ty::Region { + self.opt_ast_region_to_region(&ExplicitRscope, lifetime.span, Some(lifetime), None) + } + + fn try_opt_ast_region_to_region(&self, rscope: &RegionScope, default_span: Span, - opt_lifetime: &Option) -> &'tcx ty::Region + opt_lifetime: Option<&hir::Lifetime>, + def: Option<&ty::RegionParameterDef>) + -> Result<&'tcx ty::Region, Option>> { - let r = match *opt_lifetime { - Some(ref lifetime) => { - ast_region_to_region(self.tcx(), lifetime) + let tcx = self.tcx(); + let name = opt_lifetime.map(|l| l.name); + let resolved = opt_lifetime.and_then(|l| tcx.named_region_map.defs.get(&l.id)); + let r = tcx.mk_region(match resolved { + Some(&rl::DefStaticRegion) => { + ty::ReStatic } - None => { - self.tcx().mk_region(rscope.anon_region(default_span).unwrap_or_else(|params| { - let ampersand_span = Span { hi: default_span.lo, ..default_span}; + Some(&rl::DefLateBoundRegion(debruijn, id)) => { + // If this region is declared on a function, it will have + // an entry in `late_bound`, but if it comes from + // `for<'a>` in some type or something, it won't + // necessarily have one. In that case though, we won't be + // changed from late to early bound, so we can just + // substitute false. + let issue_32330 = tcx.named_region_map + .late_bound + .get(&id) + .cloned() + .unwrap_or(ty::Issue32330::WontChange); + ty::ReLateBound(debruijn, ty::BrNamed(tcx.hir.local_def_id(id), + name.unwrap(), + issue_32330)) + } + + Some(&rl::DefEarlyBoundRegion(index, _)) => { + ty::ReEarlyBound(ty::EarlyBoundRegion { + index: index, + name: name.unwrap() + }) + } - let mut err = struct_span_err!(self.tcx().sess, ampersand_span, E0106, - "missing lifetime specifier"); - err.span_label(ampersand_span, &format!("expected lifetime parameter")); + Some(&rl::DefFreeRegion(scope, id)) => { + // As in DefLateBoundRegion above, could be missing for some late-bound + // regions, but also for early-bound regions. + let issue_32330 = tcx.named_region_map + .late_bound + .get(&id) + .cloned() + .unwrap_or(ty::Issue32330::WontChange); + ty::ReFree(ty::FreeRegion { + scope: scope.to_code_extent(&tcx.region_maps), + bound_region: ty::BrNamed(tcx.hir.local_def_id(id), + name.unwrap(), + issue_32330) + }) - if let Some(params) = params { - report_elision_failure(self.tcx(), &mut err, params); - } - err.emit(); - ty::ReStatic - })) + // (*) -- not late-bound, won't change } - }; + + None => rscope.anon_region(default_span, def)? + }); debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}", opt_lifetime, r); - r + Ok(r) + } + + pub fn opt_ast_region_to_region(&self, + rscope: &RegionScope, + default_span: Span, + opt_lifetime: Option<&hir::Lifetime>, + def: Option<&ty::RegionParameterDef>) -> &'tcx ty::Region + { + let tcx = self.tcx(); + self.try_opt_ast_region_to_region(rscope, default_span, opt_lifetime, def) + .unwrap_or_else(|params| { + let ampersand_span = Span { hi: default_span.lo, ..default_span}; + + let mut err = struct_span_err!(tcx.sess, ampersand_span, E0106, + "missing lifetime specifier"); + err.span_label(ampersand_span, &format!("expected lifetime parameter")); + + if let Some(params) = params { + report_elision_failure(tcx, &mut err, params); + } + err.emit(); + tcx.mk_region(ty::ReStatic) + }) } /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, @@ -408,25 +404,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }; let expected_num_region_params = decl_generics.regions.len(); let supplied_num_region_params = lifetimes.len(); - let regions = if expected_num_region_params == supplied_num_region_params { - lifetimes.iter().map(|l| *ast_region_to_region(tcx, l)).collect() - } else { - let anon_regions = (0..expected_num_region_params).map(|_| { - rscope.anon_region(span) - }).collect::, _>>(); - - if supplied_num_region_params != 0 || anon_regions.is_err() { + let has_exact_lifetimes = expected_num_region_params == supplied_num_region_params; + let mut can_report_lifetime_count_mismatch = !has_exact_lifetimes; + let mut maybe_report_lifetime_count_mismatch = || { + if can_report_lifetime_count_mismatch { + can_report_lifetime_count_mismatch = false; report_lifetime_number_error(tcx, span, supplied_num_region_params, expected_num_region_params); } - - match anon_regions { - Ok(anon_regions) => anon_regions, - Err(_) => (0..expected_num_region_params).map(|_| ty::ReStatic).collect() - } }; + if supplied_num_region_params != 0 { + maybe_report_lifetime_count_mismatch(); + } + // If a self-type was declared, one should be provided. assert_eq!(decl_generics.has_self, self_ty.is_some()); @@ -452,7 +444,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut output_assoc_binding = None; let substs = Substs::for_item(tcx, def_id, |def, _| { let i = def.index as usize - self_ty.is_some() as usize; - tcx.mk_region(regions[i]) + let l = if has_exact_lifetimes { + Some(&lifetimes[i]) + } else { + None + }; + self.try_opt_ast_region_to_region(rscope, span, l, Some(def)).unwrap_or_else(|_| { + maybe_report_lifetime_count_mismatch(); + tcx.mk_region(ty::ReStatic) + }) }, |def, substs| { let i = def.index as usize; @@ -1472,7 +1472,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }) } hir::TyRptr(ref region, ref mt) => { - let r = self.opt_ast_region_to_region(rscope, ast_ty.span, region); + let r = self.opt_ast_region_to_region(rscope, ast_ty.span, region.as_ref(), None); debug!("TyRef r={:?}", r); let rscope1 = &ObjectLifetimeDefaultRscope::new( @@ -1823,7 +1823,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if let Some(&r) = explicit_region_bounds.get(0) { // Explicitly specified region bound. Use that. - return Some(ast_region_to_region(tcx, r)); + return Some(self.ast_region_to_region(r)); } if let Some(principal) = existential_predicates.principal() { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1e76267f32c38..e7544c10be3e7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -80,7 +80,7 @@ pub use self::Expectation::*; pub use self::compare_method::{compare_impl_method, compare_const_impl}; use self::TupleArgumentsFlag::*; -use astconv::{AstConv, ast_region_to_region}; +use astconv::AstConv; use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; use hir::def::{Def, CtorKind}; @@ -1466,9 +1466,13 @@ impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> { *self.next_region_var(infer::MiscVariable(span)) } - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) -> Result>> { - Ok(*self.next_region_var(infer::MiscVariable(span))) + let v = match def { + Some(def) => infer::EarlyBoundRegion(span, def.name), + None => infer::MiscVariable(span) + }; + Ok(*self.next_region_var(v)) } } @@ -4404,11 +4408,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => &[] }; - if let Some(ast_lifetime) = lifetimes.get(i) { - ast_region_to_region(self.tcx, ast_lifetime) - } else { - self.region_var_for_def(span, def) - } + AstConv::opt_ast_region_to_region(self, self, span, lifetimes.get(i), Some(def)) }, |def, substs| { let mut i = def.index as usize; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1fd03b33a7612..f954d2a5d6168 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -57,7 +57,7 @@ There are some shortcomings in this design: */ -use astconv::{AstConv, ast_region_to_region, Bounds, PartitionedBounds, partition_bounds}; +use astconv::{AstConv, Bounds, PartitionedBounds, partition_bounds}; use lint; use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; @@ -1472,7 +1472,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, index: own_start + i as u32, def_id: tcx.hir.local_def_id(l.lifetime.id), bounds: l.bounds.iter().map(|l| { - ast_region_to_region(tcx, l) + AstConv::ast_region_to_region(&ccx.icx(&()), l) }).collect(), pure_wrt_drop: l.pure_wrt_drop, } @@ -1765,7 +1765,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, name: param.lifetime.name })); for bound in ¶m.bounds { - let bound_region = ast_region_to_region(ccx.tcx, bound); + let bound_region = AstConv::ast_region_to_region(&ccx.icx(&()), bound); let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region)); predicates.push(outlives.to_predicate()); } @@ -1816,7 +1816,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } &hir::TyParamBound::RegionTyParamBound(ref lifetime) => { - let region = ast_region_to_region(tcx, lifetime); + let region = AstConv::ast_region_to_region(&ccx.icx(&()), lifetime); let pred = ty::Binder(ty::OutlivesPredicate(ty, region)); predicates.push(ty::Predicate::TypeOutlives(pred)) } @@ -1825,9 +1825,9 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } &hir::WherePredicate::RegionPredicate(ref region_pred) => { - let r1 = ast_region_to_region(tcx, ®ion_pred.lifetime); + let r1 = AstConv::ast_region_to_region(&ccx.icx(&()), ®ion_pred.lifetime); for bound in ®ion_pred.bounds { - let r2 = ast_region_to_region(tcx, bound); + let r2 = AstConv::ast_region_to_region(&ccx.icx(&()), bound); let pred = ty::Binder(ty::OutlivesPredicate(r1, r2)); predicates.push(ty::Predicate::RegionOutlives(pred)) } @@ -1935,7 +1935,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, hir::TraitTyParamBound(..) => None, hir::RegionTyParamBound(ref lifetime) => - Some(ast_region_to_region(ccx.tcx, lifetime)), + Some(AstConv::ast_region_to_region(&ccx.icx(&()), lifetime)), } }) .collect() @@ -1981,7 +1981,6 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, span: Span) -> Bounds<'tcx> { - let tcx = astconv.tcx(); let PartitionedBounds { trait_bounds, region_bounds @@ -1998,7 +1997,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, }).collect(); let region_bounds = region_bounds.into_iter().map(|r| { - ast_region_to_region(tcx, r) + astconv.ast_region_to_region(r) }).collect(); trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id())); @@ -2040,7 +2039,7 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, .collect() } hir::RegionTyParamBound(ref lifetime) => { - let region = ast_region_to_region(astconv.tcx(), lifetime); + let region = astconv.ast_region_to_region(lifetime); let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region)); vec![ty::Predicate::TypeOutlives(pred)] } diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 839eb8be9ace8..2ad1a7c3d685f 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -41,7 +41,7 @@ pub type ElidedLifetime = Result>>; /// can return `Err(())` to indicate that this is not a scope in which /// regions can legally be omitted. pub trait RegionScope { - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) -> Result>>; /// If an object omits any explicit lifetime bound, and none can @@ -115,9 +115,9 @@ impl RegionScope for MaybeWithAnonTypes { self.base_scope.object_lifetime_default(span) } - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) -> Result>> { - self.base_scope.anon_region(span) + self.base_scope.anon_region(span, def) } fn base_object_lifetime_default(&self, span: Span) -> ty::Region { @@ -135,7 +135,7 @@ impl RegionScope for MaybeWithAnonTypes { pub struct ExplicitRscope; impl RegionScope for ExplicitRscope { - fn anon_region(&self, _span: Span) + fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) -> Result>> { Err(None) } @@ -159,7 +159,7 @@ impl UnelidableRscope { } impl RegionScope for UnelidableRscope { - fn anon_region(&self, _span: Span) + fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) -> Result>> { Err(self.0.clone()) } @@ -199,7 +199,7 @@ impl RegionScope for ElidableRscope { ty::ReStatic } - fn anon_region(&self, _span: Span) + fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) -> Result>> { Ok(self.default) @@ -221,7 +221,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> StaticRscope<'a, 'gcx, 'tcx> { } impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> { - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, _: Option<&ty::RegionParameterDef>) -> Result>> { if !self.tcx.sess.features.borrow().static_in_const { self.tcx @@ -269,7 +269,7 @@ impl RegionScope for BindingRscope { ty::ReStatic } - fn anon_region(&self, _: Span) + fn anon_region(&self, _: Span, _: Option<&ty::RegionParameterDef>) -> Result>> { let idx = self.anon_bindings.get(); @@ -315,10 +315,10 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { self.base_scope.base_object_lifetime_default(span) } - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) -> Result>> { - self.base_scope.anon_region(span) + self.base_scope.anon_region(span, def) } fn anon_type_scope(&self) -> Option { @@ -348,10 +348,10 @@ impl<'r> RegionScope for ShiftedRscope<'r> { ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1) } - fn anon_region(&self, span: Span) + fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) -> Result>> { - self.base_scope.anon_region(span).map(|r| ty::fold::shift_region(r, 1)) + self.base_scope.anon_region(span, def).map(|r| ty::fold::shift_region(r, 1)) } fn anon_type_scope(&self) -> Option { From 7a2a669bb70633a8c9ac4be708813b311c52ff93 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 9 Jan 2017 17:46:11 +0200 Subject: [PATCH 57/86] rustc: always include elidable lifetimes in HIR types. --- src/librustc/hir/intravisit.rs | 4 +- src/librustc/hir/lowering.rs | 150 ++++++++++++++---- src/librustc/hir/mod.rs | 45 ++---- src/librustc/hir/print.rs | 63 +++----- src/librustc/middle/cstore.rs | 3 + src/librustc/middle/resolve_lifetime.rs | 3 + src/librustc_borrowck/borrowck/mod.rs | 4 +- src/librustc_lint/bad_style.rs | 4 +- src/librustc_metadata/cstore_impl.rs | 5 + src/librustc_metadata/decoder.rs | 15 +- src/librustc_metadata/encoder.rs | 14 +- src/librustc_metadata/schema.rs | 15 +- src/librustc_typeck/astconv.rs | 27 ++-- src/librustdoc/clean/mod.rs | 22 ++- .../unboxed-closure-sugar-region.rs | 4 +- 15 files changed, 246 insertions(+), 132 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index d4095c6875c1d..d71263bea0046 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -547,8 +547,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyPtr(ref mutable_type) => { visitor.visit_ty(&mutable_type.ty) } - TyRptr(ref opt_lifetime, ref mutable_type) => { - walk_list!(visitor, visit_lifetime, opt_lifetime); + TyRptr(ref lifetime, ref mutable_type) => { + visitor.visit_lifetime(lifetime); visitor.visit_ty(&mutable_type.ty) } TyNever => {}, diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 88d461cab9f40..4160ec5b74a92 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -41,12 +41,12 @@ // in the HIR, especially for multiple identifiers. use hir; -use hir::map::Definitions; +use hir::map::{Definitions, DefKey}; use hir::map::definitions::DefPathData; use hir::def_id::{DefIndex, DefId}; use hir::def::{Def, PathResolution}; use session::Session; -use util::nodemap::{NodeMap, FxHashMap}; +use util::nodemap::{DefIdMap, NodeMap, FxHashMap}; use std::collections::BTreeMap; use std::iter; @@ -78,6 +78,8 @@ pub struct LoweringContext<'a> { trait_items: BTreeMap, impl_items: BTreeMap, bodies: FxHashMap, + + type_def_lifetime_params: DefIdMap, } pub trait Resolver { @@ -110,6 +112,7 @@ pub fn lower_crate(sess: &Session, trait_items: BTreeMap::new(), impl_items: BTreeMap::new(), bodies: FxHashMap(), + type_def_lifetime_params: DefIdMap(), }.lower_crate(krate) } @@ -123,24 +126,33 @@ enum ParamMode { impl<'a> LoweringContext<'a> { fn lower_crate(mut self, c: &Crate) -> hir::Crate { - self.lower_items(c); - let module = self.lower_mod(&c.module); - let attrs = self.lower_attrs(&c.attrs); - let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(); + /// Full-crate AST visitor that inserts into a fresh + /// `LoweringContext` any information that may be + /// needed from arbitrary locations in the crate. + /// E.g. The number of lifetime generic parameters + /// declared for every type and trait definition. + struct MiscCollector<'lcx, 'interner: 'lcx> { + lctx: &'lcx mut LoweringContext<'interner>, + } - hir::Crate { - module: module, - attrs: attrs, - span: c.span, - exported_macros: exported_macros, - items: self.items, - trait_items: self.trait_items, - impl_items: self.impl_items, - bodies: self.bodies, + impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> { + fn visit_item(&mut self, item: &'lcx Item) { + match item.node { + ItemKind::Struct(_, ref generics) | + ItemKind::Union(_, ref generics) | + ItemKind::Enum(_, ref generics) | + ItemKind::Ty(_, ref generics) | + ItemKind::Trait(_, ref generics, ..) => { + let def_id = self.lctx.resolver.definitions().local_def_id(item.id); + let count = generics.lifetimes.len(); + self.lctx.type_def_lifetime_params.insert(def_id, count); + } + _ => {} + } + visit::walk_item(self, item); + } } - } - fn lower_items(&mut self, c: &Crate) { struct ItemLowerer<'lcx, 'interner: 'lcx> { lctx: &'lcx mut LoweringContext<'interner>, } @@ -167,8 +179,23 @@ impl<'a> LoweringContext<'a> { } } - let mut item_lowerer = ItemLowerer { lctx: self }; - visit::walk_crate(&mut item_lowerer, c); + visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c); + visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c); + + let module = self.lower_mod(&c.module); + let attrs = self.lower_attrs(&c.attrs); + let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(); + + hir::Crate { + module: module, + attrs: attrs, + span: c.span, + exported_macros: exported_macros, + items: self.items, + trait_items: self.trait_items, + impl_items: self.impl_items, + bodies: self.bodies, + } } fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) @@ -232,6 +259,14 @@ impl<'a> LoweringContext<'a> { result } + fn def_key(&mut self, id: DefId) -> DefKey { + if id.is_local() { + self.resolver.definitions().def_key(id.index) + } else { + self.sess.cstore.def_key(id) + } + } + fn lower_opt_sp_ident(&mut self, o_id: Option>) -> Option> { o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name)) } @@ -279,7 +314,11 @@ impl<'a> LoweringContext<'a> { TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)), TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)), TyKind::Rptr(ref region, ref mt) => { - hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt)) + let lifetime = match *region { + Some(ref lt) => self.lower_lifetime(lt), + None => self.elided_lifetime(t.span) + }; + hir::TyRptr(lifetime, self.lower_mt(mt)) } TyKind::BareFn(ref f) => { hir::TyBareFn(P(hir::BareFnTy { @@ -377,7 +416,40 @@ impl<'a> LoweringContext<'a> { } _ => param_mode }; - self.lower_path_segment(segment, param_mode) + + // Figure out if this is a type/trait segment, + // which may need lifetime elision performed. + let parent_def_id = |this: &mut Self, def_id: DefId| { + DefId { + krate: def_id.krate, + index: this.def_key(def_id).parent.expect("missing parent") + } + }; + let type_def_id = match resolution.base_def { + Def::AssociatedTy(def_id) if i + 2 == proj_start => { + Some(parent_def_id(self, def_id)) + } + Def::Variant(def_id) if i + 1 == proj_start => { + Some(parent_def_id(self, def_id)) + } + Def::Struct(def_id) | + Def::Union(def_id) | + Def::Enum(def_id) | + Def::TyAlias(def_id) | + Def::Trait(def_id) if i + 1 == proj_start => Some(def_id), + _ => None + }; + + let num_lifetimes = type_def_id.map_or(0, |def_id| { + if let Some(&n) = self.type_def_lifetime_params.get(&def_id) { + return n; + } + assert!(!def_id.is_local()); + let (n, _) = self.sess.cstore.item_generics_own_param_counts(def_id); + self.type_def_lifetime_params.insert(def_id, n); + n + }); + self.lower_path_segment(p.span, segment, param_mode, num_lifetimes) }).collect(), span: p.span, }); @@ -411,7 +483,7 @@ impl<'a> LoweringContext<'a> { // 3. `<>::IntoIter>::Item` // * final path is `<<>::IntoIter>::Item>::clone` for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { - let segment = P(self.lower_path_segment(segment, param_mode)); + let segment = P(self.lower_path_segment(p.span, segment, param_mode, 0)); let qpath = hir::QPath::TypeRelative(ty, segment); // It's finished, return the extension of the right node type. @@ -443,7 +515,7 @@ impl<'a> LoweringContext<'a> { hir::Path { def: self.expect_full_def(id), segments: segments.map(|segment| { - self.lower_path_segment(segment, param_mode) + self.lower_path_segment(p.span, segment, param_mode, 0) }).chain(name.map(|name| { hir::PathSegment { name: name, @@ -464,10 +536,12 @@ impl<'a> LoweringContext<'a> { } fn lower_path_segment(&mut self, + path_span: Span, segment: &PathSegment, - param_mode: ParamMode) + param_mode: ParamMode, + expected_lifetimes: usize) -> hir::PathSegment { - let parameters = if let Some(ref parameters) = segment.parameters { + let mut parameters = if let Some(ref parameters) = segment.parameters { match **parameters { PathParameters::AngleBracketed(ref data) => { let data = self.lower_angle_bracketed_parameter_data(data, param_mode); @@ -482,6 +556,14 @@ impl<'a> LoweringContext<'a> { hir::AngleBracketedParameters(data) }; + if let hir::AngleBracketedParameters(ref mut data) = parameters { + if data.lifetimes.is_empty() { + data.lifetimes = (0..expected_lifetimes).map(|_| { + self.elided_lifetime(path_span) + }).collect(); + } + } + hir::PathSegment { name: segment.identifier.name, parameters: parameters, @@ -628,10 +710,6 @@ impl<'a> LoweringContext<'a> { lts.iter().map(|l| self.lower_lifetime_def(l)).collect() } - fn lower_opt_lifetime(&mut self, o_lt: &Option) -> Option { - o_lt.as_ref().map(|lt| self.lower_lifetime(lt)) - } - fn lower_generics(&mut self, g: &Generics) -> hir::Generics { // Collect `?Trait` bounds in where clause and move them to parameter definitions. let mut add_bounds = NodeMap(); @@ -751,8 +829,12 @@ impl<'a> LoweringContext<'a> { } fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef { + let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit) { + hir::QPath::Resolved(None, path) => path.and_then(|path| path), + qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath) + }; hir::TraitRef { - path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit, false), + path: path, ref_id: p.ref_id, } } @@ -2276,4 +2358,12 @@ impl<'a> LoweringContext<'a> { span: span, }) } + + fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime { + hir::Lifetime { + id: self.next_id(), + span: span, + name: keywords::Invalid.name() + } + } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index fe086347884b0..94cb33b138c58 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -77,6 +77,13 @@ pub mod svh; pub struct Lifetime { pub id: NodeId, pub span: Span, + + /// Either "'a", referring to a named lifetime definition, + /// or "" (aka keywords::Invalid), for elision placeholders. + /// + /// HIR lowering inserts these placeholders in type paths that + /// refer to type definitions needing lifetime parameters, + /// `&T` and `&mut T`, and trait objects without `... + 'a`. pub name: Name, } @@ -89,6 +96,12 @@ impl fmt::Debug for Lifetime { } } +impl Lifetime { + pub fn is_elided(&self) -> bool { + self.name == keywords::Invalid.name() + } +} + /// A lifetime definition, eg `'a: 'b+'c+'d` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct LifetimeDef { @@ -165,30 +178,6 @@ impl PathParameters { }) } - pub fn is_empty(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => data.is_empty(), - - // Even if the user supplied no types, something like - // `X()` is equivalent to `X<(),()>`. - ParenthesizedParameters(..) => false, - } - } - - pub fn has_lifetimes(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), - ParenthesizedParameters(_) => false, - } - } - - pub fn has_types(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => !data.types.is_empty(), - ParenthesizedParameters(..) => true, - } - } - /// Returns the types that the user wrote. Note that these do not necessarily map to the type /// parameters in the parenthesized case. pub fn types(&self) -> HirVec<&P> { @@ -245,12 +234,6 @@ pub struct AngleBracketedParameterData { pub bindings: HirVec, } -impl AngleBracketedParameterData { - fn is_empty(&self) -> bool { - self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty() - } -} - /// A path like `Foo(A,B) -> C` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct ParenthesizedParameterData { @@ -1208,7 +1191,7 @@ pub enum Ty_ { /// A raw pointer (`*const T` or `*mut T`) TyPtr(MutTy), /// A reference (`&'a T` or `&'a mut T`) - TyRptr(Option, MutTy), + TyRptr(Lifetime, MutTy), /// A bare function (e.g. `fn(usize) -> bool`) TyBareFn(P), /// The never type (`!`) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d4bb2d37091b2..8e866f5717498 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -26,6 +26,7 @@ use syntax_pos::{self, BytePos}; use hir; use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd}; +use std::cell::Cell; use std::io::{self, Write, Read}; pub enum AnnNode<'a> { @@ -359,9 +360,9 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_opt_lifetime(&mut self, lifetime: &Option) -> io::Result<()> { - if let Some(l) = *lifetime { - self.print_lifetime(&l)?; + pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { + if !lifetime.is_elided() { + self.print_lifetime(lifetime)?; self.nbsp()?; } Ok(()) @@ -1553,65 +1554,49 @@ impl<'a> State<'a> { parameters: &hir::PathParameters, colons_before_params: bool) -> io::Result<()> { - if parameters.is_empty() { - let infer_types = match *parameters { - hir::AngleBracketedParameters(ref data) => data.infer_types, - hir::ParenthesizedParameters(_) => false - }; - - // FIXME(eddyb) See the comment below about infer_types. - if !(infer_types && false) { - return Ok(()); - } - } - - if colons_before_params { - word(&mut self.s, "::")? - } - match *parameters { hir::AngleBracketedParameters(ref data) => { - word(&mut self.s, "<")?; + let start = if colons_before_params { "::<" } else { "<" }; + let empty = Cell::new(true); + let start_or_comma = |this: &mut Self| { + if empty.get() { + empty.set(false); + word(&mut this.s, start) + } else { + this.word_space(",") + } + }; - let mut comma = false; - for lifetime in &data.lifetimes { - if comma { - self.word_space(",")? + if !data.lifetimes.iter().all(|lt| lt.is_elided()) { + for lifetime in &data.lifetimes { + start_or_comma(self)?; + self.print_lifetime(lifetime)?; } - self.print_lifetime(lifetime)?; - comma = true; } if !data.types.is_empty() { - if comma { - self.word_space(",")? - } + start_or_comma(self)?; self.commasep(Inconsistent, &data.types, |s, ty| s.print_type(&ty))?; - comma = true; } // FIXME(eddyb) This would leak into error messages, e.g.: // "non-exhaustive patterns: `Some::<..>(_)` not covered". if data.infer_types && false { - if comma { - self.word_space(",")? - } + start_or_comma(self)?; word(&mut self.s, "..")?; - comma = true; } for binding in data.bindings.iter() { - if comma { - self.word_space(",")? - } + start_or_comma(self)?; self.print_name(binding.name)?; space(&mut self.s)?; self.word_space("=")?; self.print_type(&binding.ty)?; - comma = true; } - word(&mut self.s, ">")? + if !empty.get() { + word(&mut self.s, ">")? + } } hir::ParenthesizedParameters(ref data) => { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 496a3d4a49847..8cf13cddc8c7f 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -182,6 +182,7 @@ pub trait CrateStore<'tcx> { -> ty::GenericPredicates<'tcx>; fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::Generics<'tcx>; + fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize); fn item_attrs(&self, def_id: DefId) -> Vec; fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef; fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef; @@ -331,6 +332,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") } fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::Generics<'tcx> { bug!("item_generics") } + fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize) + { bug!("item_generics_own_param_counts") } fn item_attrs(&self, def_id: DefId) -> Vec { bug!("item_attrs") } fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef { bug!("trait_def") } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index dd99aea909faa..a09f0ed7552bf 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -279,6 +279,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { + if lifetime_ref.is_elided() { + return; + } if lifetime_ref.name == keywords::StaticLifetime.name() { self.insert_lifetime(lifetime_ref, DefStaticRegion); return; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4ce6c9527571e..46179b31d5cb4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -939,12 +939,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { /// Given a type, if it is an immutable reference, return a suggestion to make it mutable fn suggest_mut_for_immutable(&self, pty: &hir::Ty) -> Option { // Check wether the argument is an immutable reference - if let hir::TyRptr(opt_lifetime, hir::MutTy { + if let hir::TyRptr(lifetime, hir::MutTy { mutbl: hir::Mutability::MutImmutable, ref ty }) = pty.node { // Account for existing lifetimes when generating the message - if let Some(lifetime) = opt_lifetime { + if !lifetime.is_elided() { if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(ty.span) { if let Ok(lifetime_snippet) = self.tcx.sess.codemap() .span_to_snippet(lifetime.span) { diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index d4ab31da8a31e..05ba262ef90c0 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -377,8 +377,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node { - if path.segments.len() == 1 && path.segments[0].parameters.is_empty() { - if let Def::Const(..) = path.def { + if let Def::Const(..) = path.def { + if path.segments.len() == 1 { NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern", path.segments[0].name, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index d100cb53a8b01..03b2b0114f19c 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -110,6 +110,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).get_generics(def.index, tcx) } + fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize) { + self.dep_graph.read(DepNode::MetaData(def)); + self.get_crate_data(def.krate).generics_own_param_counts(def.index) + } + fn item_attrs(&self, def_id: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def_id)); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 101531b52afb8..bfc4257bda013 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -598,7 +598,20 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Generics<'tcx> { - self.entry(item_id).generics.unwrap().decode((self, tcx)) + let g = self.entry(item_id).generics.unwrap().decode(self); + ty::Generics { + parent: g.parent, + parent_regions: g.parent_regions, + parent_types: g.parent_types, + regions: g.regions.decode((self, tcx)).collect(), + types: g.types.decode((self, tcx)).collect(), + has_self: g.has_self, + } + } + + pub fn generics_own_param_counts(&self, item_id: DefIndex) -> (usize, usize) { + let g = self.entry(item_id).generics.unwrap().decode(self); + (g.regions.len, g.types.len) } pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 2f71776ecf758..c407c27b096e1 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -417,9 +417,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - fn encode_generics(&mut self, def_id: DefId) -> Lazy> { + fn encode_generics(&mut self, def_id: DefId) -> Lazy> { let tcx = self.tcx; - self.lazy(tcx.item_generics(def_id)) + let g = tcx.item_generics(def_id); + let regions = self.lazy_seq_ref(&g.regions); + let types = self.lazy_seq_ref(&g.types); + self.lazy(&Generics { + parent: g.parent, + parent_regions: g.parent_regions, + parent_types: g.parent_types, + regions: regions, + types: types, + has_self: g.has_self, + }) } fn encode_predicates(&mut self, def_id: DefId) -> Lazy> { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 74825a5c6e3f6..4f9f2d23f5d3e 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -213,7 +213,7 @@ pub struct Entry<'tcx> { pub ty: Option>>, pub inherent_impls: LazySeq, pub variances: LazySeq, - pub generics: Option>>, + pub generics: Option>>, pub predicates: Option>>, pub ast: Option>>, @@ -247,6 +247,19 @@ pub enum EntryKind<'tcx> { AssociatedConst(AssociatedContainer), } +/// A copy of `ty::Generics` which allows lazy decoding of +/// `regions` and `types` (e.g. knowing the number of type +/// and lifetime parameters before `TyCtxt` is created). +#[derive(RustcEncodable, RustcDecodable)] +pub struct Generics<'tcx> { + pub parent: Option, + pub parent_regions: u32, + pub parent_types: u32, + pub regions: LazySeq>, + pub types: LazySeq>, + pub has_self: bool, +} + #[derive(RustcEncodable, RustcDecodable)] pub struct ModData { pub reexports: LazySeq, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0a836a8ba2229..bc8e56e811ed2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -404,19 +404,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }; let expected_num_region_params = decl_generics.regions.len(); let supplied_num_region_params = lifetimes.len(); - let has_exact_lifetimes = expected_num_region_params == supplied_num_region_params; - let mut can_report_lifetime_count_mismatch = !has_exact_lifetimes; - let mut maybe_report_lifetime_count_mismatch = || { - if can_report_lifetime_count_mismatch { - can_report_lifetime_count_mismatch = false; + let mut reported_lifetime_count_mismatch = false; + let mut report_lifetime_count_mismatch = || { + if !reported_lifetime_count_mismatch { + reported_lifetime_count_mismatch = true; + let all_infer = lifetimes.iter().all(|lt| lt.is_elided()); + let supplied = if all_infer { 0 } else { supplied_num_region_params }; report_lifetime_number_error(tcx, span, - supplied_num_region_params, + supplied, expected_num_region_params); } }; - if supplied_num_region_params != 0 { - maybe_report_lifetime_count_mismatch(); + if expected_num_region_params != supplied_num_region_params { + report_lifetime_count_mismatch(); } // If a self-type was declared, one should be provided. @@ -444,13 +445,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut output_assoc_binding = None; let substs = Substs::for_item(tcx, def_id, |def, _| { let i = def.index as usize - self_ty.is_some() as usize; - let l = if has_exact_lifetimes { - Some(&lifetimes[i]) - } else { - None - }; + let l = lifetimes.get(i); self.try_opt_ast_region_to_region(rscope, span, l, Some(def)).unwrap_or_else(|_| { - maybe_report_lifetime_count_mismatch(); + report_lifetime_count_mismatch(); tcx.mk_region(ty::ReStatic) }) }, |def, substs| { @@ -1472,7 +1469,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }) } hir::TyRptr(ref region, ref mt) => { - let r = self.opt_ast_region_to_region(rscope, ast_ty.span, region.as_ref(), None); + let r = self.opt_ast_region_to_region(rscope, ast_ty.span, Some(region), None); debug!("TyRef r={:?}", r); let rscope1 = &ObjectLifetimeDefaultRscope::new( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 080bc5072d69b..54a5b9f43c0dc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1688,9 +1688,15 @@ impl Clean for hir::Ty { match self.node { TyNever => Never, TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), - TyRptr(ref l, ref m) => - BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx), - type_: box m.ty.clean(cx)}, + TyRptr(ref l, ref m) => { + let lifetime = if l.is_elided() { + None + } else { + Some(l.clean(cx)) + }; + BorrowedRef {lifetime: lifetime, mutability: m.mutbl.clean(cx), + type_: box m.ty.clean(cx)} + } TySlice(ref ty) => Vector(box ty.clean(cx)), TyArray(ref ty, length) => { use rustc_const_eval::eval_length; @@ -1729,7 +1735,9 @@ impl Clean for hir::Ty { for (i, lt_param) in generics.lifetimes.iter().enumerate() { if let Some(lt) = provided_params.lifetimes().get(i).cloned() .cloned() { - lt_substs.insert(lt_param.lifetime.id, lt.clean(cx)); + if !lt.is_elided() { + lt_substs.insert(lt_param.lifetime.id, lt.clean(cx)); + } } } return cx.enter_alias(ty_substs, lt_substs, || ty.clean(cx)); @@ -2242,7 +2250,11 @@ impl Clean for hir::PathParameters { match *self { hir::AngleBracketedParameters(ref data) => { PathParameters::AngleBracketed { - lifetimes: data.lifetimes.clean(cx), + lifetimes: if data.lifetimes.iter().all(|lt| lt.is_elided()) { + vec![] + } else { + data.lifetimes.clean(cx) + }, types: data.types.clean(cx), bindings: data.bindings.clean(cx) } diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs index 057b496bd43eb..18a1185d695f7 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-region.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs @@ -38,9 +38,9 @@ fn test<'a,'b>() { } fn test2(x: &Foo<(isize,),Output=()>, y: &Foo(isize)) { +//~^ ERROR wrong number of lifetime parameters: expected 1, found 0 // Here, the omitted lifetimes are expanded to distinct things. - same_type(x, y) //~ ERROR cannot infer - //~^ ERROR cannot infer + same_type(x, y) } fn main() { } From 0682a75f44c7fee5e7c60d72030deea8e4841732 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 8 Jan 2017 22:40:04 +0200 Subject: [PATCH 58/86] rustc: clean up the style of middle::resolve_lifetime. --- src/librustc/middle/resolve_lifetime.rs | 168 ++++++++++++-------- src/librustc_typeck/astconv.rs | 10 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 8 +- 4 files changed, 109 insertions(+), 79 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index a09f0ed7552bf..c92722c40d575 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -15,9 +15,6 @@ //! used between functions, and they operate in a purely top-down //! way. Therefore we break lifetime name resolution into a separate pass. -pub use self::DefRegion::*; -use self::ScopeChain::*; - use dep_graph::DepNode; use hir::map::Map; use session::Session; @@ -36,22 +33,19 @@ use hir; use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] -pub enum DefRegion { - DefStaticRegion, - DefEarlyBoundRegion(/* index */ u32, - /* lifetime decl */ ast::NodeId), - DefLateBoundRegion(ty::DebruijnIndex, - /* lifetime decl */ ast::NodeId), - DefFreeRegion(region::CallSiteScopeData, - /* lifetime decl */ ast::NodeId), +pub enum Region { + Static, + EarlyBound(/* index */ u32, /* lifetime decl */ ast::NodeId), + LateBound(ty::DebruijnIndex, /* lifetime decl */ ast::NodeId), + Free(region::CallSiteScopeData, /* lifetime decl */ ast::NodeId), } // Maps the id of each lifetime reference to the lifetime decl // that it corresponds to. pub struct NamedRegionMap { // maps from every use of a named (not anonymous) lifetime to a - // `DefRegion` describing how that region is bound - pub defs: NodeMap, + // `Region` describing how that region is bound + pub defs: NodeMap, // the set of lifetime def ids that are late-bound; late-bound ids // are named regions appearing in fn arguments that do not appear @@ -63,7 +57,7 @@ struct LifetimeContext<'a, 'tcx: 'a> { sess: &'a Session, hir_map: &'a Map<'tcx>, map: &'a mut NamedRegionMap, - scope: Scope<'a>, + scope: ScopeRef<'a>, // Deep breath. Our representation for poly trait refs contains a single // binder and thus we only allow a single level of quantification. However, // the syntax of Rust permits quantification in two places, e.g., `T: for <'a> Foo<'a>` @@ -86,25 +80,36 @@ struct LifetimeContext<'a, 'tcx: 'a> { } #[derive(PartialEq, Debug)] -enum ScopeChain<'a> { - /// EarlyScope(['a, 'b, ...], start, s) extends s with early-bound - /// lifetimes, with consecutive parameter indices from `start`. - /// That is, 'a has index `start`, 'b has index `start + 1`, etc. +enum Scope<'a> { + /// Extends `s` with early-bound `lifetimes`, having consecutive parameter + /// indices from `start`, i.e. `lifetimes[i]` has index `start + i`. /// Indices before `start` correspond to other generic parameters /// of a parent item (trait/impl of a method), or `Self` in traits. - EarlyScope(&'a [hir::LifetimeDef], u32, Scope<'a>), - /// LateScope(['a, 'b, ...], s) extends s with late-bound - /// lifetimes introduced by the declaration binder_id. - LateScope(&'a [hir::LifetimeDef], Scope<'a>), - - /// lifetimes introduced by a fn are scoped to the call-site for that fn. - FnScope { fn_id: ast::NodeId, body_id: ast::NodeId, s: Scope<'a> }, - RootScope + Early { + lifetimes: &'a [hir::LifetimeDef], + start: u32, + s: ScopeRef<'a> + }, + + /// Extends `s` with late-bound `lifetimes`. + Late { + lifetimes: &'a [hir::LifetimeDef], + s: ScopeRef<'a> + }, + + /// Lifetimes introduced by a fn are scoped to the call-site for that fn. + Fn { + fn_id: ast::NodeId, + body_id: ast::NodeId, + s: ScopeRef<'a> + }, + + Root } -type Scope<'a> = &'a ScopeChain<'a>; +type ScopeRef<'a> = &'a Scope<'a>; -static ROOT_SCOPE: ScopeChain<'static> = RootScope; +const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root; pub fn krate(sess: &Session, hir_map: &Map) @@ -120,7 +125,7 @@ pub fn krate(sess: &Session, sess: sess, hir_map: hir_map, map: &mut map, - scope: &ROOT_SCOPE, + scope: ROOT_SCOPE, trait_ref_hack: false, labels_in_fn: vec![], }, krate); @@ -140,7 +145,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let saved_labels_in_fn = replace(&mut self.labels_in_fn, vec![]); // Items always introduce a new root scope - self.with(RootScope, |_, this| { + self.with(Scope::Root, |_, this| { match item.node { hir::ItemFn(..) => { // Fn lifetimes get added in visit_fn below: @@ -169,7 +174,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } else { 0 }; - this.with(EarlyScope(lifetimes, start, &ROOT_SCOPE), |old_scope, this| { + let early = Scope::Early { + lifetimes: lifetimes, + start: start, + s: ROOT_SCOPE + }; + this.with(early, |old_scope, this| { this.check_lifetime_defs(old_scope, lifetimes); intravisit::walk_item(this, item); }); @@ -187,7 +197,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let saved = replace(&mut self.labels_in_fn, vec![]); // Items always introduce a new root scope - self.with(RootScope, |_, this| { + self.with(Scope::Root, |_, this| { match item.node { hir::ForeignItemFn(ref decl, _, ref generics) => { this.visit_early_late(item.id, decl, generics, |this| { @@ -233,7 +243,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty) { match ty.node { hir::TyBareFn(ref c) => { - self.with(LateScope(&c.lifetimes, self.scope), |old_scope, this| { + let late = Scope::Late { + lifetimes: &c.lifetimes, + s: self.scope + }; + self.with(late, |old_scope, this| { // a bare fn has no bounds, so everything // contained within is scoped within its binder. this.check_lifetime_defs(old_scope, &c.lifetimes); @@ -245,7 +259,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // a trait ref, which introduces a binding scope. match path.def { Def::Trait(..) => { - self.with(LateScope(&[], self.scope), |_, this| { + self.with(Scope::Late { lifetimes: &[], s: self.scope }, |_, this| { this.visit_path(path, ty.id); }); } @@ -283,7 +297,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { return; } if lifetime_ref.name == keywords::StaticLifetime.name() { - self.insert_lifetime(lifetime_ref, DefStaticRegion); + self.insert_lifetime(lifetime_ref, Region::Static); return; } self.resolve_lifetime_ref(lifetime_ref); @@ -304,8 +318,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { .. }) => { if !bound_lifetimes.is_empty() { self.trait_ref_hack = true; - let result = self.with(LateScope(bound_lifetimes, self.scope), - |old_scope, this| { + let late = Scope::Late { + lifetimes: bound_lifetimes, + s: self.scope + }; + let result = self.with(late, |old_scope, this| { this.check_lifetime_defs(old_scope, bound_lifetimes); this.visit_ty(&bounded_ty); walk_list!(this, visit_ty_param_bound, bounds); @@ -346,7 +363,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { span_err!(self.sess, trait_ref.span, E0316, "nested quantification of lifetimes"); } - self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |old_scope, this| { + let late = Scope::Late { + lifetimes: &trait_ref.bound_lifetimes, + s: self.scope + }; + self.with(late, |old_scope, this| { this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes); for lifetime in &trait_ref.bound_lifetimes { this.visit_lifetime_def(lifetime); @@ -412,7 +433,7 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { struct GatherLabels<'a> { sess: &'a Session, - scope: Scope<'a>, + scope: ScopeRef<'a>, labels_in_fn: &'a mut Vec<(ast::Name, Span)>, } @@ -471,16 +492,16 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { } fn check_if_label_shadows_lifetime<'a>(sess: &'a Session, - mut scope: Scope<'a>, + mut scope: ScopeRef<'a>, label: ast::Name, label_span: Span) { loop { match *scope { - FnScope { s, .. } => { scope = s; } - RootScope => { return; } + Scope::Fn { s, .. } => { scope = s; } + Scope::Root => { return; } - EarlyScope(lifetimes, _, s) | - LateScope(lifetimes, s) => { + Scope::Early { lifetimes, s, .. } | + Scope::Late { lifetimes, s } => { for lifetime_def in lifetimes { // FIXME (#24278): non-hygienic comparison if label == lifetime_def.lifetime.name { @@ -524,7 +545,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // `self.labels_in_fn`. extract_labels(self, fb); - self.with(FnScope { fn_id: fn_id, body_id: fb.node_id, s: self.scope }, + self.with(Scope::Fn { fn_id: fn_id, body_id: fb.node_id, s: self.scope }, |_old_scope, this| this.visit_nested_body(fb)) } @@ -535,8 +556,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { f(self) } - fn with(&mut self, wrap_scope: ScopeChain, f: F) where - F: for<'b> FnOnce(Scope, &mut LifetimeContext<'b, 'tcx>), + fn with(&mut self, wrap_scope: Scope, f: F) where + F: for<'b> FnOnce(ScopeRef, &mut LifetimeContext<'b, 'tcx>), { let LifetimeContext {sess, hir_map, ref mut map, ..} = *self; let mut this = LifetimeContext { @@ -591,7 +612,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // Find the start of nested early scopes, e.g. in methods. let mut start = 0; - if let EarlyScope(..) = *self.scope { + if let Scope::Early {..} = *self.scope { let parent = self.hir_map.expect_item(self.hir_map.get_parent(fn_id)); if let hir::ItemTrait(..) = parent.node { start += 1; // Self comes first. @@ -605,8 +626,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - self.with(EarlyScope(&early, start as u32, self.scope), move |old_scope, this| { - this.with(LateScope(&late, this.scope), move |_, this| { + let early = Scope::Early { + lifetimes: &early, + start: start as u32, + s: self.scope + }; + self.with(early, move |old_scope, this| { + let late = Scope::Late { + lifetimes: &late, + s: this.scope + }; + this.with(late, move |_, this| { this.check_lifetime_defs(old_scope, &generics.lifetimes); this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)` }); @@ -624,22 +654,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut scope = self.scope; loop { match *scope { - FnScope {fn_id, body_id, s } => { + Scope::Fn { fn_id, body_id, s } => { return self.resolve_free_lifetime_ref( region::CallSiteScopeData { fn_id: fn_id, body_id: body_id }, lifetime_ref, s); } - RootScope => { + Scope::Root => { break; } - EarlyScope(lifetimes, start, s) => { + Scope::Early { lifetimes, start, s } => { match search_lifetimes(lifetimes, lifetime_ref) { Some((index, lifetime_def)) => { let decl_id = lifetime_def.id; - let def = DefEarlyBoundRegion(start + index, decl_id); + let def = Region::EarlyBound(start + index, decl_id); self.insert_lifetime(lifetime_ref, def); return; } @@ -649,12 +679,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - LateScope(lifetimes, s) => { + Scope::Late { lifetimes, s } => { match search_lifetimes(lifetimes, lifetime_ref) { Some((_index, lifetime_def)) => { let decl_id = lifetime_def.id; let debruijn = ty::DebruijnIndex::new(late_depth + 1); - let def = DefLateBoundRegion(debruijn, decl_id); + let def = Region::LateBound(debruijn, decl_id); self.insert_lifetime(lifetime_ref, def); return; } @@ -674,7 +704,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn resolve_free_lifetime_ref(&mut self, scope_data: region::CallSiteScopeData, lifetime_ref: &hir::Lifetime, - scope: Scope) { + scope: ScopeRef) { debug!("resolve_free_lifetime_ref \ scope_data: {:?} lifetime_ref: {:?} scope: {:?}", scope_data, lifetime_ref, scope); @@ -690,19 +720,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope_data: {:?} scope: {:?} search_result: {:?}", scope_data, scope, search_result); match *scope { - FnScope { fn_id, body_id, s } => { + Scope::Fn { fn_id, body_id, s } => { scope_data = region::CallSiteScopeData { fn_id: fn_id, body_id: body_id }; scope = s; } - RootScope => { + Scope::Root => { break; } - EarlyScope(lifetimes, _, s) | - LateScope(lifetimes, s) => { + Scope::Early { lifetimes, s, .. } | + Scope::Late { lifetimes, s } => { search_result = search_lifetimes(lifetimes, lifetime_ref); if search_result.is_some() { break; @@ -714,7 +744,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { match search_result { Some((_depth, lifetime)) => { - let def = DefFreeRegion(scope_data, lifetime.id); + let def = Region::Free(scope_data, lifetime.id); self.insert_lifetime(lifetime_ref, def); } @@ -732,7 +762,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .emit(); } - fn check_lifetime_defs(&mut self, old_scope: Scope, lifetimes: &[hir::LifetimeDef]) { + fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::LifetimeDef]) { for i in 0..lifetimes.len() { let lifetime_i = &lifetimes[i]; @@ -773,7 +803,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn check_lifetime_def_for_shadowing(&self, - mut old_scope: Scope, + mut old_scope: ScopeRef, lifetime: &hir::Lifetime) { for &(label, label_span) in &self.labels_in_fn { @@ -789,16 +819,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { loop { match *old_scope { - FnScope { s, .. } => { + Scope::Fn { s, .. } => { old_scope = s; } - RootScope => { + Scope::Root => { return; } - EarlyScope(lifetimes, _, s) | - LateScope(lifetimes, s) => { + Scope::Early { lifetimes, s, .. } | + Scope::Late { lifetimes, s } => { if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) { signal_shadowing_problem( self.sess, @@ -816,7 +846,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn insert_lifetime(&mut self, lifetime_ref: &hir::Lifetime, - def: DefRegion) { + def: Region) { if lifetime_ref.id == ast::DUMMY_NODE_ID { span_bug!(lifetime_ref.span, "lifetime reference not renumbered, \ diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index bc8e56e811ed2..3338daeb77440 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -247,11 +247,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let name = opt_lifetime.map(|l| l.name); let resolved = opt_lifetime.and_then(|l| tcx.named_region_map.defs.get(&l.id)); let r = tcx.mk_region(match resolved { - Some(&rl::DefStaticRegion) => { + Some(&rl::Region::Static) => { ty::ReStatic } - Some(&rl::DefLateBoundRegion(debruijn, id)) => { + Some(&rl::Region::LateBound(debruijn, id)) => { // If this region is declared on a function, it will have // an entry in `late_bound`, but if it comes from // `for<'a>` in some type or something, it won't @@ -268,15 +268,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { issue_32330)) } - Some(&rl::DefEarlyBoundRegion(index, _)) => { + Some(&rl::Region::EarlyBound(index, _)) => { ty::ReEarlyBound(ty::EarlyBoundRegion { index: index, name: name.unwrap() }) } - Some(&rl::DefFreeRegion(scope, id)) => { - // As in DefLateBoundRegion above, could be missing for some late-bound + Some(&rl::Region::Free(scope, id)) => { + // As in Region::LateBound above, could be missing for some late-bound // regions, but also for early-bound regions. let issue_32330 = tcx.named_region_map .late_bound diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 55033330a4490..ba00f237684e6 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -154,7 +154,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let tcx = self.terms_cx.tcx; assert!(is_lifetime(&tcx.hir, param_id)); match tcx.named_region_map.defs.get(¶m_id) { - Some(&rl::DefEarlyBoundRegion(_, lifetime_decl_id)) => lifetime_decl_id, + Some(&rl::Region::EarlyBound(_, lifetime_decl_id)) => lifetime_decl_id, Some(_) => bug!("should not encounter non early-bound cases"), // The lookup should only fail when `param_id` is diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 54a5b9f43c0dc..4182dca715311 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -28,7 +28,7 @@ use syntax::symbol::keywords; use syntax_pos::{self, DUMMY_SP, Pos}; use rustc::middle::privacy::AccessLevels; -use rustc::middle::resolve_lifetime::DefRegion::*; +use rustc::middle::resolve_lifetime as rl; use rustc::middle::lang_items; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -765,9 +765,9 @@ impl Clean for hir::Lifetime { fn clean(&self, cx: &DocContext) -> Lifetime { let def = cx.tcx.named_region_map.defs.get(&self.id).cloned(); match def { - Some(DefEarlyBoundRegion(_, node_id)) | - Some(DefLateBoundRegion(_, node_id)) | - Some(DefFreeRegion(_, node_id)) => { + Some(rl::Region::EarlyBound(_, node_id)) | + Some(rl::Region::LateBound(_, node_id)) | + Some(rl::Region::Free(_, node_id)) => { if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { return lt; } From bbc341424cd19f1d0a66fb2df78b22a3ad0e6856 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 11 Jan 2017 17:35:54 +0200 Subject: [PATCH 59/86] rustc: simplify scope-tracking in resolve_lifetime. --- src/librustc/lib.rs | 1 + src/librustc/middle/resolve_lifetime.rs | 540 ++++++++++-------------- 2 files changed, 220 insertions(+), 321 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 619a3e995c3a5..11fdf6919ccbe 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -30,6 +30,7 @@ #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(libc)] +#![feature(loop_break_value)] #![feature(nonzero)] #![feature(pub_restricted)] #![feature(quote)] diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index c92722c40d575..c76ce9dac6fb7 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -26,11 +26,10 @@ use std::mem::replace; use syntax::ast; use syntax::symbol::keywords; use syntax_pos::Span; -use util::nodemap::NodeMap; +use util::nodemap::{NodeMap, FxHashSet, FxHashMap}; -use rustc_data_structures::fx::FxHashSet; use hir; -use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap}; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum Region { @@ -40,6 +39,37 @@ pub enum Region { Free(region::CallSiteScopeData, /* lifetime decl */ ast::NodeId), } +impl Region { + fn early(index: &mut u32, def: &hir::LifetimeDef) -> (ast::Name, Region) { + let i = *index; + *index += 1; + (def.lifetime.name, Region::EarlyBound(i, def.lifetime.id)) + } + + fn late(def: &hir::LifetimeDef) -> (ast::Name, Region) { + let depth = ty::DebruijnIndex::new(1); + (def.lifetime.name, Region::LateBound(depth, def.lifetime.id)) + } + + fn id(&self) -> Option { + match *self { + Region::Static => None, + Region::EarlyBound(_, id) | + Region::LateBound(_, id) | + Region::Free(_, id) => Some(id) + } + } + + fn shifted(self, amount: u32) -> Region { + match self { + Region::LateBound(depth, id) => { + Region::LateBound(depth.shifted(amount), id) + } + _ => self + } + } +} + // Maps the id of each lifetime reference to the lifetime decl // that it corresponds to. pub struct NamedRegionMap { @@ -79,28 +109,21 @@ struct LifetimeContext<'a, 'tcx: 'a> { labels_in_fn: Vec<(ast::Name, Span)>, } -#[derive(PartialEq, Debug)] +#[derive(Debug)] enum Scope<'a> { - /// Extends `s` with early-bound `lifetimes`, having consecutive parameter - /// indices from `start`, i.e. `lifetimes[i]` has index `start + i`. - /// Indices before `start` correspond to other generic parameters - /// of a parent item (trait/impl of a method), or `Self` in traits. - Early { - lifetimes: &'a [hir::LifetimeDef], - start: u32, - s: ScopeRef<'a> - }, - - /// Extends `s` with late-bound `lifetimes`. - Late { - lifetimes: &'a [hir::LifetimeDef], + /// Declares lifetimes, and each can be early-bound or late-bound. + /// The `DebruijnIndex` of late-bound lifetimes starts at `1` and + /// it should be shifted by the number of `Binder`s in between the + /// declaration `Binder` and the location it's referenced from. + Binder { + lifetimes: FxHashMap, s: ScopeRef<'a> }, - /// Lifetimes introduced by a fn are scoped to the call-site for that fn. - Fn { - fn_id: ast::NodeId, - body_id: ast::NodeId, + /// Lifetimes introduced by a fn are scoped to the call-site for that fn, + /// if this is a fn body, otherwise the original definitions are used. + Body { + id: hir::BodyId, s: ScopeRef<'a> }, @@ -121,121 +144,93 @@ pub fn krate(sess: &Session, late_bound: NodeMap(), }; sess.track_errors(|| { - intravisit::walk_crate(&mut LifetimeContext { + let mut visitor = LifetimeContext { sess: sess, hir_map: hir_map, map: &mut map, scope: ROOT_SCOPE, trait_ref_hack: false, labels_in_fn: vec![], - }, krate); + }; + for (_, item) in &krate.items { + visitor.visit_item(item); + } })?; Ok(map) } impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { - // Override the nested functions -- lifetimes follow lexical scope, - // so it's convenient to walk the tree in lexical order. fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::All(&self.hir_map) + NestedVisitorMap::All(self.hir_map) + } + + // We want to nest trait/impl items in their parent, but nothing else. + fn visit_nested_item(&mut self, _: hir::ItemId) {} + + fn visit_nested_body(&mut self, body: hir::BodyId) { + // Each body has their own set of labels, save labels. + let saved = replace(&mut self.labels_in_fn, vec![]); + let body = self.hir_map.body(body); + extract_labels(self, body); + self.with(Scope::Body { id: body.id(), s: self.scope }, |_, this| { + this.visit_body(body); + }); + replace(&mut self.labels_in_fn, saved); } fn visit_item(&mut self, item: &'tcx hir::Item) { - // Save labels for nested items. - let saved_labels_in_fn = replace(&mut self.labels_in_fn, vec![]); - - // Items always introduce a new root scope - self.with(Scope::Root, |_, this| { - match item.node { - hir::ItemFn(..) => { - // Fn lifetimes get added in visit_fn below: + match item.node { + hir::ItemFn(ref decl, _, _, _, ref generics, _) => { + self.visit_early_late(item.id, None, decl, generics, |this| { intravisit::walk_item(this, item); - } - hir::ItemExternCrate(_) | - hir::ItemUse(..) | - hir::ItemMod(..) | - hir::ItemDefaultImpl(..) | - hir::ItemForeignMod(..) | - hir::ItemStatic(..) | - hir::ItemConst(..) => { - // These sorts of items have no lifetime parameters at all. + }); + } + hir::ItemExternCrate(_) | + hir::ItemUse(..) | + hir::ItemMod(..) | + hir::ItemDefaultImpl(..) | + hir::ItemForeignMod(..) | + hir::ItemStatic(..) | + hir::ItemConst(..) => { + // These sorts of items have no lifetime parameters at all. + intravisit::walk_item(self, item); + } + hir::ItemTy(_, ref generics) | + hir::ItemEnum(_, ref generics) | + hir::ItemStruct(_, ref generics) | + hir::ItemUnion(_, ref generics) | + hir::ItemTrait(_, ref generics, ..) | + hir::ItemImpl(_, _, ref generics, ..) => { + // These kinds of items have only early bound lifetime parameters. + let mut index = if let hir::ItemTrait(..) = item.node { + 1 // Self comes before lifetimes + } else { + 0 + }; + let lifetimes = generics.lifetimes.iter().map(|def| { + Region::early(&mut index, def) + }).collect(); + let scope = Scope::Binder { + lifetimes: lifetimes, + s: ROOT_SCOPE + }; + self.with(scope, |old_scope, this| { + this.check_lifetime_defs(old_scope, &generics.lifetimes); intravisit::walk_item(this, item); - } - hir::ItemTy(_, ref generics) | - hir::ItemEnum(_, ref generics) | - hir::ItemStruct(_, ref generics) | - hir::ItemUnion(_, ref generics) | - hir::ItemTrait(_, ref generics, ..) | - hir::ItemImpl(_, _, ref generics, ..) => { - // These kinds of items have only early bound lifetime parameters. - let lifetimes = &generics.lifetimes; - let start = if let hir::ItemTrait(..) = item.node { - 1 // Self comes before lifetimes - } else { - 0 - }; - let early = Scope::Early { - lifetimes: lifetimes, - start: start, - s: ROOT_SCOPE - }; - this.with(early, |old_scope, this| { - this.check_lifetime_defs(old_scope, lifetimes); - intravisit::walk_item(this, item); - }); - } + }); } - }); - - // Done traversing the item; remove any labels it created - self.labels_in_fn = saved_labels_in_fn; + } } fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) { - // Items save/restore the set of labels. This way inner items - // can freely reuse names, be they loop labels or lifetimes. - let saved = replace(&mut self.labels_in_fn, vec![]); - - // Items always introduce a new root scope - self.with(Scope::Root, |_, this| { - match item.node { - hir::ForeignItemFn(ref decl, _, ref generics) => { - this.visit_early_late(item.id, decl, generics, |this| { - intravisit::walk_foreign_item(this, item); - }) - } - hir::ForeignItemStatic(..) => { + match item.node { + hir::ForeignItemFn(ref decl, _, ref generics) => { + self.visit_early_late(item.id, None, decl, generics, |this| { intravisit::walk_foreign_item(this, item); - } - } - }); - - // Done traversing the item; restore saved set of labels. - replace(&mut self.labels_in_fn, saved); - } - - fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl, - b: hir::BodyId, s: Span, fn_id: ast::NodeId) { - match fk { - FnKind::ItemFn(_, generics, ..) => { - self.visit_early_late(fn_id,decl, generics, |this| { - this.add_scope_and_walk_fn(fk, decl, b, s, fn_id) }) } - FnKind::Method(_, sig, ..) => { - self.visit_early_late( - fn_id, - decl, - &sig.generics, - |this| this.add_scope_and_walk_fn(fk, decl, b, s, fn_id)); - } - FnKind::Closure(_) => { - // Closures have their own set of labels, save labels just - // like for foreign items above. - let saved = replace(&mut self.labels_in_fn, vec![]); - let result = self.add_scope_and_walk_fn(fk, decl, b, s, fn_id); - replace(&mut self.labels_in_fn, saved); - result + hir::ForeignItemStatic(..) => { + intravisit::walk_foreign_item(self, item); } } } @@ -243,11 +238,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty) { match ty.node { hir::TyBareFn(ref c) => { - let late = Scope::Late { - lifetimes: &c.lifetimes, + let scope = Scope::Binder { + lifetimes: c.lifetimes.iter().map(Region::late).collect(), s: self.scope }; - self.with(late, |old_scope, this| { + self.with(scope, |old_scope, this| { // a bare fn has no bounds, so everything // contained within is scoped within its binder. this.check_lifetime_defs(old_scope, &c.lifetimes); @@ -259,7 +254,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // a trait ref, which introduces a binding scope. match path.def { Def::Trait(..) => { - self.with(Scope::Late { lifetimes: &[], s: self.scope }, |_, this| { + let scope = Scope::Binder { + lifetimes: FxHashMap(), + s: self.scope + }; + self.with(scope, |_, this| { this.visit_path(path, ty.id); }); } @@ -275,21 +274,27 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { - // We reset the labels on every trait item, so that different - // methods in an impl can reuse label names. - let saved = replace(&mut self.labels_in_fn, vec![]); - - if let hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(_)) = - trait_item.node { + if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node { self.visit_early_late( trait_item.id, + Some(self.hir_map.get_parent(trait_item.id)), &sig.decl, &sig.generics, |this| intravisit::walk_trait_item(this, trait_item)) } else { intravisit::walk_trait_item(self, trait_item); } + } - replace(&mut self.labels_in_fn, saved); + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { + self.visit_early_late( + impl_item.id, + Some(self.hir_map.get_parent(impl_item.id)), + &sig.decl, &sig.generics, + |this| intravisit::walk_impl_item(this, impl_item)) + } else { + intravisit::walk_impl_item(self, impl_item); + } } fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { @@ -318,11 +323,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { .. }) => { if !bound_lifetimes.is_empty() { self.trait_ref_hack = true; - let late = Scope::Late { - lifetimes: bound_lifetimes, + let scope = Scope::Binder { + lifetimes: bound_lifetimes.iter().map(Region::late).collect(), s: self.scope }; - let result = self.with(late, |old_scope, this| { + let result = self.with(scope, |old_scope, this| { this.check_lifetime_defs(old_scope, bound_lifetimes); this.visit_ty(&bounded_ty); walk_list!(this, visit_ty_param_bound, bounds); @@ -363,11 +368,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { span_err!(self.sess, trait_ref.span, E0316, "nested quantification of lifetimes"); } - let late = Scope::Late { - lifetimes: &trait_ref.bound_lifetimes, + let scope = Scope::Binder { + lifetimes: trait_ref.bound_lifetimes.iter().map(Region::late).collect(), s: self.scope }; - self.with(late, |old_scope, this| { + self.with(scope, |old_scope, this| { this.check_lifetime_defs(old_scope, &trait_ref.bound_lifetimes); for lifetime in &trait_ref.bound_lifetimes { this.visit_lifetime_def(lifetime); @@ -391,8 +396,8 @@ fn original_label(span: Span) -> Original { fn shadower_label(span: Span) -> Shadower { Shadower { kind: ShadowKind::Label, span: span } } -fn original_lifetime(l: &hir::Lifetime) -> Original { - Original { kind: ShadowKind::Lifetime, span: l.span } +fn original_lifetime(span: Span) -> Original { + Original { kind: ShadowKind::Lifetime, span: span } } fn shadower_lifetime(l: &hir::Lifetime) -> Shadower { Shadower { kind: ShadowKind::Lifetime, span: l.span } @@ -430,33 +435,28 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning // if one of the label shadows a lifetime or another label. -fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { - struct GatherLabels<'a> { +fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { + struct GatherLabels<'a, 'tcx: 'a> { sess: &'a Session, + hir_map: &'a Map<'tcx>, scope: ScopeRef<'a>, labels_in_fn: &'a mut Vec<(ast::Name, Span)>, } let mut gather = GatherLabels { sess: ctxt.sess, + hir_map: ctxt.hir_map, scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn, }; - gather.visit_body(ctxt.hir_map.body(b)); - return; + gather.visit_body(body); - impl<'v, 'a> Visitor<'v> for GatherLabels<'a> { + impl<'v, 'a, 'tcx> Visitor<'v> for GatherLabels<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { NestedVisitorMap::None } - fn visit_expr(&mut self, ex: &'v hir::Expr) { - // do not recurse into closures defined in the block - // since they are treated as separate fns from the POV of - // labels_in_fn - if let hir::ExprClosure(..) = ex.node { - return - } + fn visit_expr(&mut self, ex: &hir::Expr) { if let Some((label, label_span)) = expression_label(ex) { for &(prior, prior_span) in &self.labels_in_fn[..] { // FIXME (#24278): non-hygienic comparison @@ -469,6 +469,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { } check_if_label_shadows_lifetime(self.sess, + self.hir_map, self.scope, label, label_span); @@ -492,26 +493,24 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { } fn check_if_label_shadows_lifetime<'a>(sess: &'a Session, + hir_map: &Map, mut scope: ScopeRef<'a>, label: ast::Name, label_span: Span) { loop { match *scope { - Scope::Fn { s, .. } => { scope = s; } + Scope::Body { s, .. } => { scope = s; } Scope::Root => { return; } - Scope::Early { lifetimes, s, .. } | - Scope::Late { lifetimes, s } => { - for lifetime_def in lifetimes { - // FIXME (#24278): non-hygienic comparison - if label == lifetime_def.lifetime.name { - signal_shadowing_problem( - sess, - label, - original_lifetime(&lifetime_def.lifetime), - shadower_label(label_span)); - return; - } + Scope::Binder { ref lifetimes, s } => { + // FIXME (#24278): non-hygienic comparison + if let Some(def) = lifetimes.get(&label) { + signal_shadowing_problem( + sess, + label, + original_lifetime(hir_map.span(def.id().unwrap())), + shadower_label(label_span)); + return; } scope = s; } @@ -521,34 +520,6 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: hir::BodyId) { } impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { - fn add_scope_and_walk_fn(&mut self, - fk: FnKind<'tcx>, - fd: &'tcx hir::FnDecl, - fb: hir::BodyId, - _span: Span, - fn_id: ast::NodeId) { - match fk { - FnKind::ItemFn(_, generics, ..) => { - intravisit::walk_fn_decl(self, fd); - self.visit_generics(generics); - } - FnKind::Method(_, sig, ..) => { - intravisit::walk_fn_decl(self, fd); - self.visit_generics(&sig.generics); - } - FnKind::Closure(_) => { - intravisit::walk_fn_decl(self, fd); - } - } - - // After inpsecting the decl, add all labels from the body to - // `self.labels_in_fn`. - extract_labels(self, fb); - - self.with(Scope::Fn { fn_id: fn_id, body_id: fb.node_id, s: self.scope }, - |_old_scope, this| this.visit_nested_body(fb)) - } - // FIXME(#37666) this works around a limitation in the region inferencer fn hack(&mut self, f: F) where F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>), @@ -560,17 +531,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { F: for<'b> FnOnce(ScopeRef, &mut LifetimeContext<'b, 'tcx>), { let LifetimeContext {sess, hir_map, ref mut map, ..} = *self; + let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); let mut this = LifetimeContext { sess: sess, hir_map: hir_map, map: *map, scope: &wrap_scope, trait_ref_hack: self.trait_ref_hack, - labels_in_fn: self.labels_in_fn.clone(), + labels_in_fn: labels_in_fn, }; debug!("entering scope {:?}", this.scope); f(self.scope, &mut this); debug!("exiting scope {:?}", this.scope); + self.labels_in_fn = this.labels_in_fn; } /// Visits self by adding a scope and handling recursive walk over the contents with `walk`. @@ -593,6 +566,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// ordering is not important there. fn visit_early_late(&mut self, fn_id: ast::NodeId, + parent_id: Option, decl: &'tcx hir::FnDecl, generics: &'tcx hir::Generics, walk: F) where @@ -604,162 +578,98 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { decl, generics); - let (late, early): (Vec<_>, _) = - generics.lifetimes - .iter() - .cloned() - .partition(|l| self.map.late_bound.contains_key(&l.lifetime.id)); - // Find the start of nested early scopes, e.g. in methods. - let mut start = 0; - if let Scope::Early {..} = *self.scope { - let parent = self.hir_map.expect_item(self.hir_map.get_parent(fn_id)); + let mut index = 0; + if let Some(parent_id) = parent_id { + let parent = self.hir_map.expect_item(parent_id); if let hir::ItemTrait(..) = parent.node { - start += 1; // Self comes first. + index += 1; // Self comes first. } match parent.node { hir::ItemTrait(_, ref generics, ..) | hir::ItemImpl(_, _, ref generics, ..) => { - start += generics.lifetimes.len() + generics.ty_params.len(); + index += (generics.lifetimes.len() + generics.ty_params.len()) as u32; } _ => {} } } - let early = Scope::Early { - lifetimes: &early, - start: start as u32, + let lifetimes = generics.lifetimes.iter().map(|def| { + if self.map.late_bound.contains_key(&def.lifetime.id) { + Region::late(def) + } else { + Region::early(&mut index, def) + } + }).collect(); + + let scope = Scope::Binder { + lifetimes: lifetimes, s: self.scope }; - self.with(early, move |old_scope, this| { - let late = Scope::Late { - lifetimes: &late, - s: this.scope - }; - this.with(late, move |_, this| { - this.check_lifetime_defs(old_scope, &generics.lifetimes); - this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)` - }); + self.with(scope, move |old_scope, this| { + this.check_lifetime_defs(old_scope, &generics.lifetimes); + this.hack(walk); // FIXME(#37666) workaround in place of `walk(this)` }); } fn resolve_lifetime_ref(&mut self, lifetime_ref: &hir::Lifetime) { // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the - // given name or we run out of scopes. If we encounter a code - // block, then the lifetime is not bound but free, so switch - // over to `resolve_free_lifetime_ref()` to complete the + // given name or we run out of scopes. // search. let mut late_depth = 0; let mut scope = self.scope; - loop { + let mut outermost_body = None; + let result = loop { match *scope { - Scope::Fn { fn_id, body_id, s } => { - return self.resolve_free_lifetime_ref( - region::CallSiteScopeData { fn_id: fn_id, body_id: body_id }, - lifetime_ref, - s); + Scope::Body { id, s } => { + outermost_body = Some(id); + scope = s; } Scope::Root => { - break; + break None; } - Scope::Early { lifetimes, start, s } => { - match search_lifetimes(lifetimes, lifetime_ref) { - Some((index, lifetime_def)) => { - let decl_id = lifetime_def.id; - let def = Region::EarlyBound(start + index, decl_id); - self.insert_lifetime(lifetime_ref, def); - return; - } - None => { - scope = s; - } - } - } - - Scope::Late { lifetimes, s } => { - match search_lifetimes(lifetimes, lifetime_ref) { - Some((_index, lifetime_def)) => { - let decl_id = lifetime_def.id; - let debruijn = ty::DebruijnIndex::new(late_depth + 1); - let def = Region::LateBound(debruijn, decl_id); - self.insert_lifetime(lifetime_ref, def); - return; - } - - None => { - late_depth += 1; - scope = s; - } + Scope::Binder { ref lifetimes, s } => { + if let Some(&def) = lifetimes.get(&lifetime_ref.name) { + break Some(def.shifted(late_depth)); + } else { + late_depth += 1; + scope = s; } } } - } - - self.unresolved_lifetime_ref(lifetime_ref); - } - - fn resolve_free_lifetime_ref(&mut self, - scope_data: region::CallSiteScopeData, - lifetime_ref: &hir::Lifetime, - scope: ScopeRef) { - debug!("resolve_free_lifetime_ref \ - scope_data: {:?} lifetime_ref: {:?} scope: {:?}", - scope_data, lifetime_ref, scope); - - // Walk up the scope chain, tracking the outermost free scope, - // until we encounter a scope that contains the named lifetime - // or we run out of scopes. - let mut scope_data = scope_data; - let mut scope = scope; - let mut search_result = None; - loop { - debug!("resolve_free_lifetime_ref \ - scope_data: {:?} scope: {:?} search_result: {:?}", - scope_data, scope, search_result); - match *scope { - Scope::Fn { fn_id, body_id, s } => { - scope_data = region::CallSiteScopeData { - fn_id: fn_id, body_id: body_id - }; - scope = s; - } - - Scope::Root => { - break; - } + }; - Scope::Early { lifetimes, s, .. } | - Scope::Late { lifetimes, s } => { - search_result = search_lifetimes(lifetimes, lifetime_ref); - if search_result.is_some() { - break; + if let Some(mut def) = result { + if let Some(body_id) = outermost_body { + let fn_id = self.hir_map.body_owner(body_id); + let scope_data = region::CallSiteScopeData { + fn_id: fn_id, body_id: body_id.node_id + }; + match self.hir_map.get(fn_id) { + hir::map::NodeItem(&hir::Item { + node: hir::ItemFn(..), .. + }) | + hir::map::NodeTraitItem(&hir::TraitItem { + node: hir::TraitItemKind::Method(..), .. + }) | + hir::map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(..), .. + }) => { + def = Region::Free(scope_data, def.id().unwrap()); } - scope = s; + _ => {} } } + self.insert_lifetime(lifetime_ref, def); + } else { + struct_span_err!(self.sess, lifetime_ref.span, E0261, + "use of undeclared lifetime name `{}`", lifetime_ref.name) + .span_label(lifetime_ref.span, &format!("undeclared lifetime")) + .emit(); } - - match search_result { - Some((_depth, lifetime)) => { - let def = Region::Free(scope_data, lifetime.id); - self.insert_lifetime(lifetime_ref, def); - } - - None => { - self.unresolved_lifetime_ref(lifetime_ref); - } - } - - } - - fn unresolved_lifetime_ref(&self, lifetime_ref: &hir::Lifetime) { - struct_span_err!(self.sess, lifetime_ref.span, E0261, - "use of undeclared lifetime name `{}`", lifetime_ref.name) - .span_label(lifetime_ref.span, &format!("undeclared lifetime")) - .emit(); } fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::LifetimeDef]) { @@ -819,7 +729,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { loop { match *old_scope { - Scope::Fn { s, .. } => { + Scope::Body { s, .. } => { old_scope = s; } @@ -827,13 +737,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } - Scope::Early { lifetimes, s, .. } | - Scope::Late { lifetimes, s } => { - if let Some((_, lifetime_def)) = search_lifetimes(lifetimes, lifetime) { + Scope::Binder { ref lifetimes, s } => { + if let Some(&def) = lifetimes.get(&lifetime.name) { signal_shadowing_problem( self.sess, lifetime.name, - original_lifetime(&lifetime_def), + original_lifetime(self.hir_map.span(def.id().unwrap())), shadower_lifetime(&lifetime)); return; } @@ -861,17 +770,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } -fn search_lifetimes<'a>(lifetimes: &'a [hir::LifetimeDef], - lifetime_ref: &hir::Lifetime) - -> Option<(u32, &'a hir::Lifetime)> { - for (i, lifetime_decl) in lifetimes.iter().enumerate() { - if lifetime_decl.lifetime.name == lifetime_ref.name { - return Some((i as u32, &lifetime_decl.lifetime)); - } - } - return None; -} - /////////////////////////////////////////////////////////////////////////// /// Detects late-bound lifetimes and inserts them into From ba1849daecf0ae8fee54cc32f378809a9531e5ed Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 13 Jan 2017 15:09:56 +0200 Subject: [PATCH 60/86] rustc: move most of lifetime elision to resolve_lifetimes. --- src/librustc/diagnostics.rs | 63 +++ src/librustc/hir/lowering.rs | 3 +- src/librustc/middle/resolve_lifetime.rs | 502 +++++++++++++++++- src/librustc_typeck/astconv.rs | 337 ++---------- src/librustc_typeck/check/mod.rs | 26 +- src/librustc_typeck/collect.rs | 82 +-- src/librustc_typeck/diagnostics.rs | 72 +-- src/librustc_typeck/rscope.rs | 168 ------ src/test/compile-fail/E0106.rs | 12 + src/test/compile-fail/E0107.rs | 3 - ...iated-types-project-from-hrtb-in-struct.rs | 9 +- ...-return-type-requires-explicit-lifetime.rs | 24 + src/test/compile-fail/rfc1623.rs | 4 +- 13 files changed, 703 insertions(+), 602 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 2878ff5e2846e..b51a7d4104ab9 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -327,6 +327,69 @@ struct ListNode { This works because `Box` is a pointer, so its size is well-known. "##, +E0106: r##" +This error indicates that a lifetime is missing from a type. If it is an error +inside a function signature, the problem may be with failing to adhere to the +lifetime elision rules (see below). + +Here are some simple examples of where you'll run into this error: + +```compile_fail,E0106 +struct Foo { x: &bool } // error +struct Foo<'a> { x: &'a bool } // correct + +enum Bar { A(u8), B(&bool), } // error +enum Bar<'a> { A(u8), B(&'a bool), } // correct + +type MyStr = &str; // error +type MyStr<'a> = &'a str; // correct +``` + +Lifetime elision is a special, limited kind of inference for lifetimes in +function signatures which allows you to leave out lifetimes in certain cases. +For more background on lifetime elision see [the book][book-le]. + +The lifetime elision rules require that any function signature with an elided +output lifetime must either have + + - exactly one input lifetime + - or, multiple input lifetimes, but the function must also be a method with a + `&self` or `&mut self` receiver + +In the first case, the output lifetime is inferred to be the same as the unique +input lifetime. In the second case, the lifetime is instead inferred to be the +same as the lifetime on `&self` or `&mut self`. + +Here are some examples of elision errors: + +```compile_fail,E0106 +// error, no input lifetimes +fn foo() -> &str { } + +// error, `x` and `y` have distinct lifetimes inferred +fn bar(x: &str, y: &str) -> &str { } + +// error, `y`'s lifetime is inferred to be distinct from `x`'s +fn baz<'a>(x: &'a str, y: &str) -> &str { } +``` + +Here's an example that is currently an error, but may work in a future version +of Rust: + +```compile_fail,E0106 +struct Foo<'a>(&'a str); + +trait Quux { } +impl Quux for Foo { } +``` + +Lifetime elision in implementation headers was part of the lifetime elision +RFC. It is, however, [currently unimplemented][iss15872]. + +[book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision +[iss15872]: https://github.com/rust-lang/rust/issues/15872 +"##, + E0109: r##" You tried to give a type parameter to a type which doesn't need it. Erroneous code example: diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4160ec5b74a92..7ca251f3ff91d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -314,9 +314,10 @@ impl<'a> LoweringContext<'a> { TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)), TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)), TyKind::Rptr(ref region, ref mt) => { + let span = Span { hi: t.span.lo, ..t.span }; let lifetime = match *region { Some(ref lt) => self.lower_lifetime(lt), - None => self.elided_lifetime(t.span) + None => self.elided_lifetime(span) }; hir::TyRptr(lifetime, self.lower_mt(mt)) } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index c76ce9dac6fb7..4e02485a40b7d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -22,11 +22,16 @@ use hir::def::Def; use hir::def_id::DefId; use middle::region; use ty; + +use std::cell::Cell; use std::mem::replace; use syntax::ast; +use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; +use errors::DiagnosticBuilder; use util::nodemap::{NodeMap, FxHashSet, FxHashMap}; +use rustc_back::slice; use hir; use hir::intravisit::{self, Visitor, NestedVisitorMap}; @@ -36,6 +41,7 @@ pub enum Region { Static, EarlyBound(/* index */ u32, /* lifetime decl */ ast::NodeId), LateBound(ty::DebruijnIndex, /* lifetime decl */ ast::NodeId), + LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), Free(region::CallSiteScopeData, /* lifetime decl */ ast::NodeId), } @@ -51,9 +57,18 @@ impl Region { (def.lifetime.name, Region::LateBound(depth, def.lifetime.id)) } + fn late_anon(index: &Cell) -> Region { + let i = index.get(); + index.set(i + 1); + let depth = ty::DebruijnIndex::new(1); + Region::LateBoundAnon(depth, i) + } + fn id(&self) -> Option { match *self { - Region::Static => None, + Region::Static | + Region::LateBoundAnon(..) => None, + Region::EarlyBound(_, id) | Region::LateBound(_, id) | Region::Free(_, id) => Some(id) @@ -65,6 +80,25 @@ impl Region { Region::LateBound(depth, id) => { Region::LateBound(depth.shifted(amount), id) } + Region::LateBoundAnon(depth, index) => { + Region::LateBoundAnon(depth.shifted(amount), index) + } + _ => self + } + } + + fn from_depth(self, depth: u32) -> Region { + match self { + Region::LateBound(debruijn, id) => { + Region::LateBound(ty::DebruijnIndex { + depth: debruijn.depth - (depth - 1) + }, id) + } + Region::LateBoundAnon(debruijn, index) => { + Region::LateBoundAnon(ty::DebruijnIndex { + depth: debruijn.depth - (depth - 1) + }, index) + } _ => self } } @@ -122,14 +156,46 @@ enum Scope<'a> { /// Lifetimes introduced by a fn are scoped to the call-site for that fn, /// if this is a fn body, otherwise the original definitions are used. + /// Unspecified lifetimes are inferred, unless an elision scope is nested, + /// e.g. `(&T, fn(&T) -> &T);` becomes `(&'_ T, for<'a> fn(&'a T) -> &'a T)`. Body { id: hir::BodyId, s: ScopeRef<'a> }, + /// A scope which either determines unspecified lifetimes or errors + /// on them (e.g. due to ambiguity). For more details, see `Elide`. + Elision { + elide: Elide, + s: ScopeRef<'a> + }, + Root } +#[derive(Clone, Debug)] +enum Elide { + /// Use a fresh anonymous late-bound lifetime each time, by + /// incrementing the counter to generate sequential indices. + FreshLateAnon(Cell), + /// Always use this one lifetime. + Exact(Region), + /// Like `Exact(Static)` but requires `#![feature(static_in_const)]`. + Static, + /// Less or more than one lifetime were found, error on unspecified. + Error(Vec) +} + +#[derive(Clone, Debug)] +struct ElisionFailureInfo { + /// Where we can find the argument pattern. + parent: Option, + /// The index of the argument in the original definition. + index: usize, + lifetime_count: usize, + have_bound_regions: bool +} + type ScopeRef<'a> = &'a Scope<'a>; const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root; @@ -189,12 +255,19 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::ItemUse(..) | hir::ItemMod(..) | hir::ItemDefaultImpl(..) | - hir::ItemForeignMod(..) | - hir::ItemStatic(..) | - hir::ItemConst(..) => { + hir::ItemForeignMod(..) => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); } + hir::ItemStatic(..) | + hir::ItemConst(..) => { + // No lifetime parameters, but implied 'static. + let scope = Scope::Elision { + elide: Elide::Static, + s: ROOT_SCOPE + }; + self.with(scope, |_, this| intravisit::walk_item(this, item)); + } hir::ItemTy(_, ref generics) | hir::ItemEnum(_, ref generics) | hir::ItemStruct(_, ref generics) | @@ -299,6 +372,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { if lifetime_ref.is_elided() { + self.resolve_elided_lifetimes(slice::ref_slice(lifetime_ref)); return; } if lifetime_ref.name == keywords::StaticLifetime.name() { @@ -308,6 +382,31 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.resolve_lifetime_ref(lifetime_ref); } + fn visit_path_parameters(&mut self, _: Span, params: &'tcx hir::PathParameters) { + match *params { + hir::AngleBracketedParameters(ref data) => { + if data.lifetimes.iter().all(|l| l.is_elided()) { + self.resolve_elided_lifetimes(&data.lifetimes); + } else { + for l in &data.lifetimes { self.visit_lifetime(l); } + } + for ty in &data.types { self.visit_ty(ty); } + for b in &data.bindings { self.visit_assoc_type_binding(b); } + } + hir::ParenthesizedParameters(ref data) => { + self.visit_fn_like_elision(&data.inputs, data.output.as_ref()); + } + } + } + + fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) { + let output = match fd.output { + hir::DefaultReturn(_) => None, + hir::Return(ref ty) => Some(ty) + }; + self.visit_fn_like_elision(&fd.inputs, output); + } + fn visit_generics(&mut self, generics: &'tcx hir::Generics) { for ty_param in generics.ty_params.iter() { walk_list!(self, visit_ty_param_bound, &ty_param.bounds); @@ -478,10 +577,6 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { } intravisit::walk_expr(self, ex) } - - fn visit_item(&mut self, _: &hir::Item) { - // do not recurse into items defined in the block - } } fn expression_label(ex: &hir::Expr) -> Option<(ast::Name, Span)> { @@ -499,7 +594,9 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { label_span: Span) { loop { match *scope { - Scope::Body { s, .. } => { scope = s; } + Scope::Body { s, .. } | + Scope::Elision { s, .. } => { scope = s; } + Scope::Root => { return; } Scope::Binder { ref lifetimes, s } => { @@ -639,6 +736,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } } + + Scope::Elision { s, .. } => { + scope = s; + } } }; @@ -672,6 +773,386 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + fn visit_fn_like_elision(&mut self, inputs: &'tcx [P], + output: Option<&'tcx P>) { + let mut arg_elide = Elide::FreshLateAnon(Cell::new(0)); + let arg_scope = Scope::Elision { + elide: arg_elide.clone(), + s: self.scope + }; + self.with(arg_scope, |_, this| { + for input in inputs { + this.visit_ty(input); + } + match *this.scope { + Scope::Elision { ref elide, .. } => { + arg_elide = elide.clone(); + } + _ => bug!() + } + }); + + let output = match output { + Some(ty) => ty, + None => return + }; + + // Figure out if there's a body we can get argument names from, + // and whether there's a `self` argument (treated specially). + let mut assoc_item_kind = None; + let mut impl_self = None; + let parent = self.hir_map.get_parent_node(output.id); + let body = match self.hir_map.get(parent) { + // `fn` definitions and methods. + hir::map::NodeItem(&hir::Item { + node: hir::ItemFn(.., body), .. + }) => Some(body), + + hir::map::NodeTraitItem(&hir::TraitItem { + node: hir::TraitItemKind::Method(_, ref m), .. + }) => { + match self.hir_map.expect_item(self.hir_map.get_parent(parent)).node { + hir::ItemTrait(.., ref trait_items) => { + assoc_item_kind = trait_items.iter().find(|ti| ti.id.node_id == parent) + .map(|ti| ti.kind); + } + _ => {} + } + match *m { + hir::TraitMethod::Required(_) => None, + hir::TraitMethod::Provided(body) => Some(body), + } + } + + hir::map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(_, body), .. + }) => { + match self.hir_map.expect_item(self.hir_map.get_parent(parent)).node { + hir::ItemImpl(.., ref self_ty, ref impl_items) => { + impl_self = Some(self_ty); + assoc_item_kind = impl_items.iter().find(|ii| ii.id.node_id == parent) + .map(|ii| ii.kind); + } + _ => {} + } + Some(body) + } + + // `fn(...) -> R` and `Trait(...) -> R` (both types and bounds). + hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => None, + + // Foreign `fn` decls are terrible because we messed up, + // and their return types get argument type elision. + // And now too much code out there is abusing this rule. + hir::map::NodeForeignItem(_) => { + let arg_scope = Scope::Elision { + elide: arg_elide, + s: self.scope + }; + self.with(arg_scope, |_, this| this.visit_ty(output)); + return; + } + + // Everything else (only closures?) doesn't + // actually enjoy elision in return types. + _ => { + self.visit_ty(output); + return; + } + }; + + let has_self = match assoc_item_kind { + Some(hir::AssociatedItemKind::Method { has_self }) => has_self, + _ => false + }; + + // In accordance with the rules for lifetime elision, we can determine + // what region to use for elision in the output type in two ways. + // First (determined here), if `self` is by-reference, then the + // implied output region is the region of the self parameter. + if has_self { + // Look for `self: &'a Self` - also desugared from `&'a self`, + // and if that matches, use it for elision and return early. + let is_self_ty = |def: Def| { + if let Def::SelfTy(..) = def { + return true; + } + + // Can't always rely on literal (or implied) `Self` due + // to the way elision rules were originally specified. + let impl_self = impl_self.map(|ty| &ty.node); + if let Some(&hir::TyPath(hir::QPath::Resolved(None, ref path))) = impl_self { + match path.def { + // Whitelist the types that unambiguously always + // result in the same type constructor being used + // (it can't differ between `Self` and `self`). + Def::Struct(_) | + Def::Union(_) | + Def::Enum(_) | + Def::Trait(_) | + Def::PrimTy(_) => return def == path.def, + _ => {} + } + } + + false + }; + + if let hir::TyRptr(lifetime_ref, ref mt) = inputs[0].node { + if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = mt.ty.node { + if is_self_ty(path.def) { + if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) { + let scope = Scope::Elision { + elide: Elide::Exact(lifetime), + s: self.scope + }; + self.with(scope, |_, this| this.visit_ty(output)); + return; + } + } + } + } + } + + // Second, if there was exactly one lifetime (either a substitution or a + // reference) in the arguments, then any anonymous regions in the output + // have that lifetime. + let mut possible_implied_output_region = None; + let mut lifetime_count = 0; + let arg_lifetimes = inputs.iter().enumerate().skip(has_self as usize).map(|(i, input)| { + let mut gather = GatherLifetimes { + map: self.map, + binder_depth: 1, + have_bound_regions: false, + lifetimes: FxHashSet() + }; + gather.visit_ty(input); + + lifetime_count += gather.lifetimes.len(); + + if lifetime_count == 1 && gather.lifetimes.len() == 1 { + // there's a chance that the unique lifetime of this + // iteration will be the appropriate lifetime for output + // parameters, so lets store it. + possible_implied_output_region = gather.lifetimes.iter().cloned().next(); + } + + ElisionFailureInfo { + parent: body, + index: i, + lifetime_count: gather.lifetimes.len(), + have_bound_regions: gather.have_bound_regions + } + }).collect(); + + let elide = if lifetime_count == 1 { + Elide::Exact(possible_implied_output_region.unwrap()) + } else { + Elide::Error(arg_lifetimes) + }; + + let scope = Scope::Elision { + elide: elide, + s: self.scope + }; + self.with(scope, |_, this| this.visit_ty(output)); + + struct GatherLifetimes<'a> { + map: &'a NamedRegionMap, + binder_depth: u32, + have_bound_regions: bool, + lifetimes: FxHashSet, + } + + impl<'v, 'a> Visitor<'v> for GatherLifetimes<'a> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { + NestedVisitorMap::None + } + + fn visit_ty(&mut self, ty: &hir::Ty) { + let delta = match ty.node { + hir::TyBareFn(_) => 1, + hir::TyPath(hir::QPath::Resolved(None, ref path)) => { + // if this path references a trait, then this will resolve to + // a trait ref, which introduces a binding scope. + match path.def { + Def::Trait(..) => 1, + _ => 0 + } + } + _ => 0 + }; + self.binder_depth += delta; + intravisit::walk_ty(self, ty); + self.binder_depth -= delta; + } + + fn visit_poly_trait_ref(&mut self, + trait_ref: &hir::PolyTraitRef, + modifier: &hir::TraitBoundModifier) { + self.binder_depth += 1; + intravisit::walk_poly_trait_ref(self, trait_ref, modifier); + self.binder_depth -= 1; + } + + fn visit_lifetime_def(&mut self, lifetime_def: &hir::LifetimeDef) { + for l in &lifetime_def.bounds { self.visit_lifetime(l); } + } + + fn visit_lifetime(&mut self, lifetime_ref: &hir::Lifetime) { + if let Some(&lifetime) = self.map.defs.get(&lifetime_ref.id) { + match lifetime { + Region::LateBound(debruijn, _) | + Region::LateBoundAnon(debruijn, _) + if debruijn.depth < self.binder_depth => { + self.have_bound_regions = true; + } + _ => { + self.lifetimes.insert(lifetime.from_depth(self.binder_depth)); + } + } + } + } + } + + } + + fn resolve_elided_lifetimes(&mut self, lifetime_refs: &[hir::Lifetime]) { + if lifetime_refs.is_empty() { + return; + } + + let span = lifetime_refs[0].span; + let mut late_depth = 0; + let mut scope = self.scope; + let error = loop { + match *scope { + // Do not assign any resolution, it will be inferred. + Scope::Body { .. } => return, + + Scope::Root => break None, + + Scope::Binder { s, .. } => { + late_depth += 1; + scope = s; + } + + Scope::Elision { ref elide, .. } => { + let lifetime = match *elide { + Elide::FreshLateAnon(ref counter) => { + for lifetime_ref in lifetime_refs { + let lifetime = Region::late_anon(counter).shifted(late_depth); + self.insert_lifetime(lifetime_ref, lifetime); + } + return; + } + Elide::Exact(l) => l.shifted(late_depth), + Elide::Static => { + if !self.sess.features.borrow().static_in_const { + self.sess + .struct_span_err(span, + "this needs a `'static` lifetime or the \ + `static_in_const` feature, see #35897") + .emit(); + } + Region::Static + } + Elide::Error(ref e) => break Some(e) + }; + for lifetime_ref in lifetime_refs { + self.insert_lifetime(lifetime_ref, lifetime); + } + return; + } + } + }; + + let mut err = struct_span_err!(self.sess, span, E0106, + "missing lifetime specifier{}", + if lifetime_refs.len() > 1 { "s" } else { "" }); + let msg = if lifetime_refs.len() > 1 { + format!("expected {} lifetime parameters", lifetime_refs.len()) + } else { + format!("expected lifetime parameter") + }; + err.span_label(span, &msg); + + if let Some(params) = error { + if lifetime_refs.len() == 1 { + self.report_elision_failure(&mut err, params); + } + } + err.emit(); + } + + fn report_elision_failure(&mut self, + db: &mut DiagnosticBuilder, + params: &[ElisionFailureInfo]) { + let mut m = String::new(); + let len = params.len(); + + let elided_params: Vec<_> = params.iter().cloned() + .filter(|info| info.lifetime_count > 0) + .collect(); + + let elided_len = elided_params.len(); + + for (i, info) in elided_params.into_iter().enumerate() { + let ElisionFailureInfo { + parent, index, lifetime_count: n, have_bound_regions + } = info; + + let help_name = if let Some(body) = parent { + let arg = &self.hir_map.body(body).arguments[index]; + format!("`{}`", self.hir_map.node_to_pretty_string(arg.pat.id)) + } else { + format!("argument {}", index + 1) + }; + + m.push_str(&(if n == 1 { + help_name + } else { + format!("one of {}'s {} elided {}lifetimes", help_name, n, + if have_bound_regions { "free " } else { "" } ) + })[..]); + + if elided_len == 2 && i == 0 { + m.push_str(" or "); + } else if i + 2 == elided_len { + m.push_str(", or "); + } else if i != elided_len - 1 { + m.push_str(", "); + } + + } + + if len == 0 { + help!(db, + "this function's return type contains a borrowed value, but \ + there is no value for it to be borrowed from"); + help!(db, + "consider giving it a 'static lifetime"); + } else if elided_len == 0 { + help!(db, + "this function's return type contains a borrowed value with \ + an elided lifetime, but the lifetime cannot be derived from \ + the arguments"); + help!(db, + "consider giving it an explicit bounded or 'static \ + lifetime"); + } else if elided_len == 1 { + help!(db, + "this function's return type contains a borrowed value, but \ + the signature does not say which {} it is borrowed from", + m); + } else { + help!(db, + "this function's return type contains a borrowed value, but \ + the signature does not say whether it is borrowed from {}", + m); + } + } + fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::LifetimeDef]) { for i in 0..lifetimes.len() { let lifetime_i = &lifetimes[i]; @@ -729,7 +1210,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { loop { match *old_scope { - Scope::Body { s, .. } => { + Scope::Body { s, .. } | + Scope::Elision { s, .. } => { old_scope = s; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 3338daeb77440..42a220e1b9b4b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -61,9 +61,7 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; use rustc_back::slice; use require_c_abi_if_variadic; -use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, - ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope, - ElisionFailureInfo, ElidedLifetime}; +use rscope::{RegionScope, ObjectLifetimeDefaultRscope, ShiftedRscope}; use rscope::{AnonTypeScope, MaybeWithAnonTypes, ExplicitRscope}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; use util::nodemap::{NodeMap, FxHashSet}; @@ -74,7 +72,6 @@ use syntax::{abi, ast}; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::symbol::{Symbol, keywords}; use syntax_pos::Span; -use errors::DiagnosticBuilder; pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; @@ -111,6 +108,10 @@ pub trait AstConv<'gcx, 'tcx> { /// See ParameterEnvironment::free_substs for more information. fn get_free_substs(&self) -> Option<&Substs<'tcx>>; + /// What lifetime should we use when a lifetime is omitted (and not elided)? + fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>) + -> &'tcx ty::Region; + /// What type should we use when a type is omitted? fn ty_infer(&self, span: Span) -> Ty<'tcx>; @@ -161,94 +162,16 @@ struct ConvertedBinding<'tcx> { /// This type must not appear anywhere in other converted types. const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0)); -fn report_elision_failure( - tcx: TyCtxt, - db: &mut DiagnosticBuilder, - params: Vec) -{ - let mut m = String::new(); - let len = params.len(); - - let elided_params: Vec<_> = params.into_iter() - .filter(|info| info.lifetime_count > 0) - .collect(); - - let elided_len = elided_params.len(); - - for (i, info) in elided_params.into_iter().enumerate() { - let ElisionFailureInfo { - parent, index, lifetime_count: n, have_bound_regions - } = info; - - let help_name = if let Some(body) = parent { - let arg = &tcx.hir.body(body).arguments[index]; - format!("`{}`", tcx.hir.node_to_pretty_string(arg.pat.id)) - } else { - format!("argument {}", index + 1) - }; - - m.push_str(&(if n == 1 { - help_name - } else { - format!("one of {}'s {} elided {}lifetimes", help_name, n, - if have_bound_regions { "free " } else { "" } ) - })[..]); - - if elided_len == 2 && i == 0 { - m.push_str(" or "); - } else if i + 2 == elided_len { - m.push_str(", or "); - } else if i != elided_len - 1 { - m.push_str(", "); - } - - } - - if len == 0 { - help!(db, - "this function's return type contains a borrowed value, but \ - there is no value for it to be borrowed from"); - help!(db, - "consider giving it a 'static lifetime"); - } else if elided_len == 0 { - help!(db, - "this function's return type contains a borrowed value with \ - an elided lifetime, but the lifetime cannot be derived from \ - the arguments"); - help!(db, - "consider giving it an explicit bounded or 'static \ - lifetime"); - } else if elided_len == 1 { - help!(db, - "this function's return type contains a borrowed value, but \ - the signature does not say which {} it is borrowed from", - m); - } else { - help!(db, - "this function's return type contains a borrowed value, but \ - the signature does not say whether it is borrowed from {}", - m); - } -} - impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { - pub fn ast_region_to_region(&self, lifetime: &hir::Lifetime) -> &'tcx ty::Region { - self.opt_ast_region_to_region(&ExplicitRscope, lifetime.span, Some(lifetime), None) - } - - fn try_opt_ast_region_to_region(&self, - rscope: &RegionScope, - default_span: Span, - opt_lifetime: Option<&hir::Lifetime>, + pub fn ast_region_to_region(&self, + lifetime: &hir::Lifetime, def: Option<&ty::RegionParameterDef>) - -> Result<&'tcx ty::Region, Option>> + -> &'tcx ty::Region { let tcx = self.tcx(); - let name = opt_lifetime.map(|l| l.name); - let resolved = opt_lifetime.and_then(|l| tcx.named_region_map.defs.get(&l.id)); - let r = tcx.mk_region(match resolved { + let r = match tcx.named_region_map.defs.get(&lifetime.id) { Some(&rl::Region::Static) => { - ty::ReStatic + tcx.mk_region(ty::ReStatic) } Some(&rl::Region::LateBound(debruijn, id)) => { @@ -263,16 +186,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { .get(&id) .cloned() .unwrap_or(ty::Issue32330::WontChange); - ty::ReLateBound(debruijn, ty::BrNamed(tcx.hir.local_def_id(id), - name.unwrap(), - issue_32330)) + let name = tcx.hir.name(id); + tcx.mk_region(ty::ReLateBound(debruijn, + ty::BrNamed(tcx.hir.local_def_id(id), name, issue_32330))) + } + + Some(&rl::Region::LateBoundAnon(debruijn, index)) => { + tcx.mk_region(ty::ReLateBound(debruijn, ty::BrAnon(index))) } - Some(&rl::Region::EarlyBound(index, _)) => { - ty::ReEarlyBound(ty::EarlyBoundRegion { + Some(&rl::Region::EarlyBound(index, id)) => { + let name = tcx.hir.name(id); + tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { index: index, - name: name.unwrap() - }) + name: name + })) } Some(&rl::Region::Free(scope, id)) => { @@ -283,47 +211,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { .get(&id) .cloned() .unwrap_or(ty::Issue32330::WontChange); - ty::ReFree(ty::FreeRegion { - scope: scope.to_code_extent(&tcx.region_maps), - bound_region: ty::BrNamed(tcx.hir.local_def_id(id), - name.unwrap(), - issue_32330) - }) + let name = tcx.hir.name(id); + tcx.mk_region(ty::ReFree(ty::FreeRegion { + scope: scope.to_code_extent(&tcx.region_maps), + bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name, issue_32330) + })) // (*) -- not late-bound, won't change } - None => rscope.anon_region(default_span, def)? - }); + None => self.re_infer(lifetime.span, def) + }; - debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {:?}", - opt_lifetime, + debug!("ast_region_to_region(lifetime={:?}) yields {:?}", + lifetime, r); - Ok(r) - } - - pub fn opt_ast_region_to_region(&self, - rscope: &RegionScope, - default_span: Span, - opt_lifetime: Option<&hir::Lifetime>, - def: Option<&ty::RegionParameterDef>) -> &'tcx ty::Region - { - let tcx = self.tcx(); - self.try_opt_ast_region_to_region(rscope, default_span, opt_lifetime, def) - .unwrap_or_else(|params| { - let ampersand_span = Span { hi: default_span.lo, ..default_span}; - - let mut err = struct_span_err!(tcx.sess, ampersand_span, E0106, - "missing lifetime specifier"); - err.span_label(ampersand_span, &format!("expected lifetime parameter")); - - if let Some(params) = params { - report_elision_failure(tcx, &mut err, params); - } - err.emit(); - tcx.mk_region(ty::ReStatic) - }) + r } /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, @@ -404,20 +308,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }; let expected_num_region_params = decl_generics.regions.len(); let supplied_num_region_params = lifetimes.len(); - let mut reported_lifetime_count_mismatch = false; - let mut report_lifetime_count_mismatch = || { - if !reported_lifetime_count_mismatch { - reported_lifetime_count_mismatch = true; - let all_infer = lifetimes.iter().all(|lt| lt.is_elided()); - let supplied = if all_infer { 0 } else { supplied_num_region_params }; - report_lifetime_number_error(tcx, span, - supplied, - expected_num_region_params); - } - }; - if expected_num_region_params != supplied_num_region_params { - report_lifetime_count_mismatch(); + report_lifetime_number_error(tcx, span, + supplied_num_region_params, + expected_num_region_params); } // If a self-type was declared, one should be provided. @@ -445,11 +339,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut output_assoc_binding = None; let substs = Substs::for_item(tcx, def_id, |def, _| { let i = def.index as usize - self_ty.is_some() as usize; - let l = lifetimes.get(i); - self.try_opt_ast_region_to_region(rscope, span, l, Some(def)).unwrap_or_else(|_| { - report_lifetime_count_mismatch(); + if let Some(lifetime) = lifetimes.get(i) { + self.ast_region_to_region(lifetime, Some(def)) + } else { tcx.mk_region(ty::ReStatic) - }) + } }, |def, substs| { let i = def.index as usize; @@ -533,72 +427,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { (substs, assoc_bindings) } - /// Returns the appropriate lifetime to use for any output lifetimes - /// (if one exists) and a vector of the (pattern, number of lifetimes) - /// corresponding to each input type/pattern. - fn find_implied_output_region(&self, - input_tys: &[Ty<'tcx>], - parent: Option, - input_indices: I) -> ElidedLifetime - where I: Iterator - { - let tcx = self.tcx(); - let mut lifetimes_for_params = Vec::with_capacity(input_tys.len()); - let mut possible_implied_output_region = None; - let mut lifetimes = 0; - - for (input_type, index) in input_tys.iter().zip(input_indices) { - let mut regions = FxHashSet(); - let have_bound_regions = tcx.collect_regions(input_type, &mut regions); - - debug!("find_implied_output_regions: collected {:?} from {:?} \ - have_bound_regions={:?}", ®ions, input_type, have_bound_regions); - - lifetimes += regions.len(); - - if lifetimes == 1 && regions.len() == 1 { - // there's a chance that the unique lifetime of this - // iteration will be the appropriate lifetime for output - // parameters, so lets store it. - possible_implied_output_region = regions.iter().cloned().next(); - } - - lifetimes_for_params.push(ElisionFailureInfo { - parent: parent, - index: index, - lifetime_count: regions.len(), - have_bound_regions: have_bound_regions - }); - } - - if lifetimes == 1 { - Ok(*possible_implied_output_region.unwrap()) - } else { - Err(Some(lifetimes_for_params)) - } - } - - fn convert_ty_with_lifetime_elision(&self, - elided_lifetime: ElidedLifetime, - ty: &hir::Ty, - anon_scope: Option) - -> Ty<'tcx> - { - match elided_lifetime { - Ok(implied_output_region) => { - let rb = ElidableRscope::new(implied_output_region); - self.ast_ty_to_ty(&MaybeWithAnonTypes::new(rb, anon_scope), ty) - } - Err(param_lifetimes) => { - // All regions must be explicitly specified in the output - // if the lifetime elision rules do not apply. This saves - // the user from potentially-confusing errors. - let rb = UnelidableRscope::new(param_lifetimes); - self.ast_ty_to_ty(&MaybeWithAnonTypes::new(rb, anon_scope), ty) - } - } - } - fn convert_parenthesized_parameters(&self, rscope: &RegionScope, region_substs: &[Kind<'tcx>], @@ -606,19 +434,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { -> (Ty<'tcx>, ConvertedBinding<'tcx>) { let anon_scope = rscope.anon_type_scope(); - let binding_rscope = MaybeWithAnonTypes::new(BindingRscope::new(), anon_scope); + let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope); let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| { - self.ast_ty_arg_to_ty(&binding_rscope, None, region_substs, a_t) + self.ast_ty_arg_to_ty(&rscope, None, region_substs, a_t) })); - let input_params = 0..inputs.len(); - let implied_output_region = self.find_implied_output_region(&inputs, None, input_params); let (output, output_span) = match data.output { Some(ref output_ty) => { - (self.convert_ty_with_lifetime_elision(implied_output_region, - &output_ty, - anon_scope), - output_ty.span) + (self.ast_ty_to_ty(&rscope, output_ty), output_ty.span) } None => { (self.tcx().mk_nil(), data.span) @@ -1469,7 +1292,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { }) } hir::TyRptr(ref region, ref mt) => { - let r = self.opt_ast_region_to_region(rscope, ast_ty.span, Some(region), None); + let r = self.ast_region_to_region(region, None); debug!("TyRef r={:?}", r); let rscope1 = &ObjectLifetimeDefaultRscope::new( @@ -1489,9 +1312,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let anon_scope = rscope.anon_type_scope(); let bare_fn_ty = self.ty_of_method_or_bare_fn(bf.unsafety, bf.abi, - None, &bf.decl, - None, anon_scope, anon_scope); @@ -1626,37 +1447,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } - pub fn ty_of_method(&self, - sig: &hir::MethodSig, - opt_self_value_ty: Option>, - body: Option, - anon_scope: Option) - -> &'tcx ty::BareFnTy<'tcx> { - self.ty_of_method_or_bare_fn(sig.unsafety, - sig.abi, - opt_self_value_ty, - &sig.decl, - body, - None, - anon_scope) - } - - pub fn ty_of_bare_fn(&self, - unsafety: hir::Unsafety, - abi: abi::Abi, - decl: &hir::FnDecl, - body: hir::BodyId, - anon_scope: Option) - -> &'tcx ty::BareFnTy<'tcx> { - self.ty_of_method_or_bare_fn(unsafety, abi, None, decl, Some(body), None, anon_scope) + pub fn ty_of_fn(&self, + unsafety: hir::Unsafety, + abi: abi::Abi, + decl: &hir::FnDecl, + anon_scope: Option) + -> &'tcx ty::BareFnTy<'tcx> { + self.ty_of_method_or_bare_fn(unsafety, abi, decl, None, anon_scope) } fn ty_of_method_or_bare_fn(&self, unsafety: hir::Unsafety, abi: abi::Abi, - opt_self_value_ty: Option>, decl: &hir::FnDecl, - body: Option, arg_anon_scope: Option, ret_anon_scope: Option) -> &'tcx ty::BareFnTy<'tcx> @@ -1665,40 +1468,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // New region names that appear inside of the arguments of the function // declaration are bound to that function type. - let rb = MaybeWithAnonTypes::new(BindingRscope::new(), arg_anon_scope); + let rb = MaybeWithAnonTypes::new(ExplicitRscope, arg_anon_scope); let input_tys: Vec = decl.inputs.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect(); - let has_self = opt_self_value_ty.is_some(); - let explicit_self = opt_self_value_ty.map(|self_value_ty| { - ExplicitSelf::determine(self_value_ty, input_tys[0]) - }); - - let implied_output_region = match explicit_self { - // `implied_output_region` is the region that will be assumed for any - // region parameters in the return type. In accordance with the rules for - // lifetime elision, we can determine it in two ways. First (determined - // here), if self is by-reference, then the implied output region is the - // region of the self parameter. - Some(ExplicitSelf::ByReference(region, _)) => Ok(*region), - - // Second, if there was exactly one lifetime (either a substitution or a - // reference) in the arguments, then any anonymous regions in the output - // have that lifetime. - _ => { - let arg_tys = &input_tys[has_self as usize..]; - let arg_params = has_self as usize..input_tys.len(); - self.find_implied_output_region(arg_tys, body, arg_params) - - } - }; - let output_ty = match decl.output { hir::Return(ref output) => - self.convert_ty_with_lifetime_elision(implied_output_region, - &output, - ret_anon_scope), + self.ast_ty_to_ty(&MaybeWithAnonTypes::new(ExplicitRscope, ret_anon_scope), output), hir::DefaultReturn(..) => self.tcx().mk_nil(), }; @@ -1725,10 +1502,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { debug!("ty_of_closure(expected_sig={:?})", expected_sig); - // new region names that appear inside of the fn decl are bound to - // that function type - let rb = rscope::BindingRscope::new(); - let input_tys = decl.inputs.iter().enumerate().map(|(i, a)| { let expected_arg_ty = expected_sig.as_ref().and_then(|e| { // no guarantee that the correct number of expected args @@ -1739,7 +1512,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { None } }); - self.ty_of_arg(&rb, a, expected_arg_ty) + self.ty_of_arg(&ExplicitRscope, a, expected_arg_ty) }); let expected_ret_ty = expected_sig.as_ref().map(|e| e.output()); @@ -1755,7 +1528,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { expected_ret_ty.unwrap(), _ if is_infer => self.ty_infer(decl.output.span()), hir::Return(ref output) => - self.ast_ty_to_ty(&rb, &output), + self.ast_ty_to_ty(&ExplicitRscope, &output), hir::DefaultReturn(..) => bug!(), }; @@ -1820,7 +1593,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if let Some(&r) = explicit_region_bounds.get(0) { // Explicitly specified region bound. Use that. - return Some(self.ast_region_to_region(r)); + return Some(self.ast_region_to_region(r, None)); } if let Some(principal) = existential_predicates.principal() { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e7544c10be3e7..a8b5d718f81d0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,7 @@ use rustc::ty::adjustment; use rustc::ty::fold::{BottomUpFolder, TypeFoldable}; use rustc::ty::util::{Representability, IntTypeExt}; use require_c_abi_if_variadic; -use rscope::{ElisionFailureInfo, RegionScope}; +use rscope::RegionScope; use session::{Session, CompileResult}; use CrateCtxt; use TypeAndSubsts; @@ -1410,6 +1410,15 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { Ok(r) } + fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>) + -> &'tcx ty::Region { + let v = match def { + Some(def) => infer::EarlyBoundRegion(span, def.name), + None => infer::MiscVariable(span) + }; + self.next_region_var(v) + } + fn ty_infer(&self, span: Span) -> Ty<'tcx> { self.next_ty_var(TypeVariableOrigin::TypeInference(span)) } @@ -1465,15 +1474,6 @@ impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> { // be some expression). *self.next_region_var(infer::MiscVariable(span)) } - - fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> Result>> { - let v = match def { - Some(def) => infer::EarlyBoundRegion(span, def.name), - None => infer::MiscVariable(span) - }; - Ok(*self.next_region_var(v)) - } } /// Controls whether the arguments are tupled. This is used for the call @@ -4408,7 +4408,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None => &[] }; - AstConv::opt_ast_region_to_region(self, self, span, lifetimes.get(i), Some(def)) + if let Some(lifetime) = lifetimes.get(i) { + AstConv::ast_region_to_region(self, lifetime, Some(def)) + } else { + self.re_infer(span, Some(def)) + } }, |def, substs| { let mut i = def.index as usize; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f954d2a5d6168..70bd43751ebdf 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -437,6 +437,11 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { None } + fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>) + -> &'tcx ty::Region { + span_bug!(span, "unelided lifetime in signature"); + } + fn ty_infer(&self, span: Span) -> Ty<'tcx> { struct_span_err!( self.tcx().sess, @@ -639,8 +644,6 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, container: AssociatedItemContainer, id: ast::NodeId, sig: &hir::MethodSig, - untransformed_rcvr_ty: Ty<'tcx>, - body: Option, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,) { let def_id = ccx.tcx.hir.local_def_id(id); let ty_generics = generics_of_def_id(ccx, def_id); @@ -652,14 +655,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ImplContainer(_) => Some(AnonTypeScope::new(def_id)), TraitContainer(_) => None }; - let assoc_item = ccx.tcx.associated_item(def_id); - let self_value_ty = if assoc_item.method_has_self_argument { - Some(untransformed_rcvr_ty) - } else { - None - }; - let fty = AstConv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), - sig, self_value_ty, body, anon_scope); + let fty = AstConv::ty_of_fn(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), + sig.unsafety, sig.abi, &sig.decl, anon_scope); let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), ccx.tcx.hir.span(id), def_id); @@ -876,14 +873,9 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { convert_associated_type(ccx, TraitContainer(trait_def_id), trait_item.id, typ); } - hir::TraitItemKind::Method(ref sig, ref method) => { - let body = match *method { - hir::TraitMethod::Required(_) => None, - hir::TraitMethod::Provided(body) => Some(body) - }; + hir::TraitItemKind::Method(ref sig, _) => { convert_method(ccx, TraitContainer(trait_def_id), - trait_item.id, sig, tcx.mk_self_type(), - body, &trait_predicates); + trait_item.id, sig, &trait_predicates); } } } @@ -896,7 +888,6 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { let impl_def_id = tcx.hir.get_parent_did(impl_item.id); let impl_predicates = tcx.item_predicates(impl_def_id); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); - let impl_self_ty = tcx.item_type(impl_def_id); match impl_item.node { hir::ImplItemKind::Const(ref ty, _) => { @@ -923,10 +914,8 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { convert_associated_type(ccx, ImplContainer(impl_def_id), impl_item.id, Some(typ)); } - hir::ImplItemKind::Method(ref sig, body) => { - convert_method(ccx, ImplContainer(impl_def_id), - impl_item.id, sig, impl_self_ty, - Some(body), &impl_predicates); + hir::ImplItemKind::Method(ref sig, _) => { + convert_method(ccx, ImplContainer(impl_def_id), impl_item.id, sig, &impl_predicates); } } } @@ -1472,7 +1461,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, index: own_start + i as u32, def_id: tcx.hir.local_def_id(l.lifetime.id), bounds: l.bounds.iter().map(|l| { - AstConv::ast_region_to_region(&ccx.icx(&()), l) + AstConv::ast_region_to_region(&ccx.icx(&()), l, None) }).collect(), pure_wrt_drop: l.pure_wrt_drop, } @@ -1545,11 +1534,11 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, NodeItem(item) => { match item.node { ItemStatic(ref t, ..) | ItemConst(ref t, _) => { - ccx.icx(&()).to_ty(&StaticRscope::new(&ccx.tcx), &t) + ccx.icx(&()).to_ty(&ExplicitRscope, &t) } - ItemFn(ref decl, unsafety, _, abi, ref generics, body) => { - let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl, - body, Some(AnonTypeScope::new(def_id))); + ItemFn(ref decl, unsafety, _, abi, ref generics, _) => { + let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl, + Some(AnonTypeScope::new(def_id))); let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id); ccx.tcx.mk_fn_def(def_id, substs, tofd) } @@ -1765,7 +1754,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, name: param.lifetime.name })); for bound in ¶m.bounds { - let bound_region = AstConv::ast_region_to_region(&ccx.icx(&()), bound); + let bound_region = AstConv::ast_region_to_region(&ccx.icx(&()), bound, None); let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region)); predicates.push(outlives.to_predicate()); } @@ -1816,7 +1805,9 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } &hir::TyParamBound::RegionTyParamBound(ref lifetime) => { - let region = AstConv::ast_region_to_region(&ccx.icx(&()), lifetime); + let region = AstConv::ast_region_to_region(&ccx.icx(&()), + lifetime, + None); let pred = ty::Binder(ty::OutlivesPredicate(ty, region)); predicates.push(ty::Predicate::TypeOutlives(pred)) } @@ -1825,9 +1816,9 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } &hir::WherePredicate::RegionPredicate(ref region_pred) => { - let r1 = AstConv::ast_region_to_region(&ccx.icx(&()), ®ion_pred.lifetime); + let r1 = AstConv::ast_region_to_region(&ccx.icx(&()), ®ion_pred.lifetime, None); for bound in ®ion_pred.bounds { - let r2 = AstConv::ast_region_to_region(&ccx.icx(&()), bound); + let r2 = AstConv::ast_region_to_region(&ccx.icx(&()), bound, None); let pred = ty::Binder(ty::OutlivesPredicate(r1, r2)); predicates.push(ty::Predicate::RegionOutlives(pred)) } @@ -1935,7 +1926,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, hir::TraitTyParamBound(..) => None, hir::RegionTyParamBound(ref lifetime) => - Some(AstConv::ast_region_to_region(&ccx.icx(&()), lifetime)), + Some(AstConv::ast_region_to_region(&ccx.icx(&()), lifetime, None)), } }) .collect() @@ -1997,7 +1988,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, }).collect(); let region_bounds = region_bounds.into_iter().map(|r| { - astconv.ast_region_to_region(r) + astconv.ast_region_to_region(r, None) }).collect(); trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id())); @@ -2039,7 +2030,7 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, .collect() } hir::RegionTyParamBound(ref lifetime) => { - let region = astconv.ast_region_to_region(lifetime); + let region = astconv.ast_region_to_region(lifetime, None); let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region)); vec![ty::Predicate::TypeOutlives(pred)] } @@ -2057,18 +2048,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( abi: abi::Abi) -> Ty<'tcx> { - let rb = BindingRscope::new(); - let input_tys = decl.inputs - .iter() - .map(|a| AstConv::ty_of_arg(&ccx.icx(ast_generics), &rb, a, None)) - .collect::>(); - - let output = match decl.output { - hir::Return(ref ty) => - AstConv::ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &ty), - hir::DefaultReturn(..) => - ccx.tcx.mk_nil(), - }; + let fty = AstConv::ty_of_fn(&ccx.icx(ast_generics), hir::Unsafety::Unsafe, abi, decl, None); // feature gate SIMD types in FFI, since I (huonw) am not sure the // ABIs are handled at all correctly. @@ -2084,21 +2064,17 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( .emit(); } }; - for (input, ty) in decl.inputs.iter().zip(&input_tys) { + for (input, ty) in decl.inputs.iter().zip(*fty.sig.inputs().skip_binder()) { check(&input, ty) } if let hir::Return(ref ty) = decl.output { - check(&ty, output) + check(&ty, *fty.sig.output().skip_binder()) } } let id = ccx.tcx.hir.as_local_node_id(def_id).unwrap(); let substs = mk_item_substs(&ccx.icx(ast_generics), ccx.tcx.hir.span(id), def_id); - ccx.tcx.mk_fn_def(def_id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy { - abi: abi, - unsafety: hir::Unsafety::Unsafe, - sig: ty::Binder(ccx.tcx.mk_fn_sig(input_tys.into_iter(), output, decl.variadic)), - })) + ccx.tcx.mk_fn_def(def_id, substs, fty) } pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 6d943f3ca2ef6..7f8c508bf2224 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1412,85 +1412,19 @@ fn main() { ``` "##, -E0106: r##" -This error indicates that a lifetime is missing from a type. If it is an error -inside a function signature, the problem may be with failing to adhere to the -lifetime elision rules (see below). - -Here are some simple examples of where you'll run into this error: - -```compile_fail,E0106 -struct Foo { x: &bool } // error -struct Foo<'a> { x: &'a bool } // correct - -enum Bar { A(u8), B(&bool), } // error -enum Bar<'a> { A(u8), B(&'a bool), } // correct - -type MyStr = &str; // error -type MyStr<'a> = &'a str; // correct -``` - -Lifetime elision is a special, limited kind of inference for lifetimes in -function signatures which allows you to leave out lifetimes in certain cases. -For more background on lifetime elision see [the book][book-le]. - -The lifetime elision rules require that any function signature with an elided -output lifetime must either have - - - exactly one input lifetime - - or, multiple input lifetimes, but the function must also be a method with a - `&self` or `&mut self` receiver - -In the first case, the output lifetime is inferred to be the same as the unique -input lifetime. In the second case, the lifetime is instead inferred to be the -same as the lifetime on `&self` or `&mut self`. - -Here are some examples of elision errors: - -```compile_fail,E0106 -// error, no input lifetimes -fn foo() -> &str { } - -// error, `x` and `y` have distinct lifetimes inferred -fn bar(x: &str, y: &str) -> &str { } - -// error, `y`'s lifetime is inferred to be distinct from `x`'s -fn baz<'a>(x: &'a str, y: &str) -> &str { } -``` - -[book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision -"##, - E0107: r##" This error means that an incorrect number of lifetime parameters were provided -for a type (like a struct or enum) or trait. - -Some basic examples include: +for a type (like a struct or enum) or trait: ```compile_fail,E0107 -struct Foo<'a>(&'a str); +struct Foo<'a, 'b>(&'a str, &'b str); enum Bar { A, B, C } struct Baz<'a> { - foo: Foo, // error: expected 1, found 0 + foo: Foo<'a>, // error: expected 2, found 1 bar: Bar<'a>, // error: expected 0, found 1 } ``` - -Here's an example that is currently an error, but may work in a future version -of Rust: - -```compile_fail,E0107 -struct Foo<'a>(&'a str); - -trait Quux { } -impl Quux for Foo { } // error: expected 1, found 0 -``` - -Lifetime elision in implementation headers was part of the lifetime elision -RFC. It is, however, [currently unimplemented][iss15872]. - -[iss15872]: https://github.com/rust-lang/rust/issues/15872 "##, E0116: r##" diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 2ad1a7c3d685f..3ac917c396cf1 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -8,28 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::hir; use rustc::hir::def_id::DefId; use rustc::ty; use rustc::ty::subst::Substs; use astconv::AstConv; -use std::cell::Cell; use syntax_pos::Span; -#[derive(Clone)] -pub struct ElisionFailureInfo { - /// Where we can find the argument pattern. - pub parent: Option, - /// The index of the argument in the original definition. - pub index: usize, - pub lifetime_count: usize, - pub have_bound_regions: bool -} - -pub type ElidedLifetime = Result>>; - /// Defines strategies for handling regions that are omitted. For /// example, if one writes the type `&Foo`, then the lifetime of /// this reference has been omitted. When converting this @@ -41,9 +27,6 @@ pub type ElidedLifetime = Result>>; /// can return `Err(())` to indicate that this is not a scope in which /// regions can legally be omitted. pub trait RegionScope { - fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> Result>>; - /// If an object omits any explicit lifetime bound, and none can /// be derived from the object traits, what should we use? If /// `None` is returned, an explicit annotation is required. @@ -115,11 +98,6 @@ impl RegionScope for MaybeWithAnonTypes { self.base_scope.object_lifetime_default(span) } - fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> Result>> { - self.base_scope.anon_region(span, def) - } - fn base_object_lifetime_default(&self, span: Span) -> ty::Region { self.base_scope.base_object_lifetime_default(span) } @@ -135,105 +113,6 @@ impl RegionScope for MaybeWithAnonTypes { pub struct ExplicitRscope; impl RegionScope for ExplicitRscope { - fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) - -> Result>> { - Err(None) - } - - fn object_lifetime_default(&self, span: Span) -> Option { - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, _span: Span) -> ty::Region { - ty::ReStatic - } -} - -// Same as `ExplicitRscope`, but provides some extra information for diagnostics -pub struct UnelidableRscope(Option>); - -impl UnelidableRscope { - pub fn new(v: Option>) -> UnelidableRscope { - UnelidableRscope(v) - } -} - -impl RegionScope for UnelidableRscope { - fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) - -> Result>> { - Err(self.0.clone()) - } - - fn object_lifetime_default(&self, span: Span) -> Option { - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, _span: Span) -> ty::Region { - ty::ReStatic - } -} - -// A scope in which omitted anonymous region defaults to -// `default`. This is used after the `->` in function signatures. The -// latter use may go away. Note that object-lifetime defaults work a -// bit differently, as specified in RFC #599. -pub struct ElidableRscope { - default: ty::Region, -} - -impl ElidableRscope { - pub fn new(r: ty::Region) -> ElidableRscope { - ElidableRscope { default: r } - } -} - -impl RegionScope for ElidableRscope { - fn object_lifetime_default(&self, span: Span) -> Option { - // Per RFC #599, object-lifetimes default to 'static unless - // overridden by context, and this takes precedence over - // lifetime elision. - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, _span: Span) -> ty::Region { - ty::ReStatic - } - - fn anon_region(&self, _span: Span, _: Option<&ty::RegionParameterDef>) - -> Result>> - { - Ok(self.default) - } -} - -/// A scope that behaves as an ElidabeRscope with a `'static` default region -/// that should also warn if the `static_in_const` feature is unset. -#[derive(Copy, Clone)] -pub struct StaticRscope<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { - tcx: &'a ty::TyCtxt<'a, 'gcx, 'tcx>, -} - -impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> StaticRscope<'a, 'gcx, 'tcx> { - /// create a new StaticRscope from a reference to the `TyCtxt` - pub fn new(tcx: &'a ty::TyCtxt<'a, 'gcx, 'tcx>) -> Self { - StaticRscope { tcx: tcx } - } -} - -impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> { - fn anon_region(&self, span: Span, _: Option<&ty::RegionParameterDef>) - -> Result>> { - if !self.tcx.sess.features.borrow().static_in_const { - self.tcx - .sess - .struct_span_err(span, - "this needs a `'static` lifetime or the \ - `static_in_const` feature, see #35897") - .emit(); - } - Ok(ty::ReStatic) - } - fn object_lifetime_default(&self, span: Span) -> Option { Some(self.base_object_lifetime_default(span)) } @@ -243,41 +122,6 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> RegionScope for StaticRscope<'a, 'gcx, 'tcx> } } -/// A scope in which we generate anonymous, late-bound regions for -/// omitted regions. This occurs in function signatures. -pub struct BindingRscope { - anon_bindings: Cell, -} - -impl BindingRscope { - pub fn new() -> BindingRscope { - BindingRscope { - anon_bindings: Cell::new(0), - } - } -} - -impl RegionScope for BindingRscope { - fn object_lifetime_default(&self, span: Span) -> Option { - // Per RFC #599, object-lifetimes default to 'static unless - // overridden by context, and this takes precedence over the - // binding defaults in a fn signature. - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, _span: Span) -> ty::Region { - ty::ReStatic - } - - fn anon_region(&self, _: Span, _: Option<&ty::RegionParameterDef>) - -> Result>> - { - let idx = self.anon_bindings.get(); - self.anon_bindings.set(idx + 1); - Ok(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(idx))) - } -} - /// A scope which overrides the default object lifetime but has no other effect. pub struct ObjectLifetimeDefaultRscope<'r> { base_scope: &'r (RegionScope+'r), @@ -315,12 +159,6 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { self.base_scope.base_object_lifetime_default(span) } - fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> Result>> - { - self.base_scope.anon_region(span, def) - } - fn anon_type_scope(&self) -> Option { self.base_scope.anon_type_scope() } @@ -348,12 +186,6 @@ impl<'r> RegionScope for ShiftedRscope<'r> { ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1) } - fn anon_region(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> Result>> - { - self.base_scope.anon_region(span, def).map(|r| ty::fold::shift_region(r, 1)) - } - fn anon_type_scope(&self) -> Option { self.base_scope.anon_type_scope() } diff --git a/src/test/compile-fail/E0106.rs b/src/test/compile-fail/E0106.rs index dab03f0bccfd0..d5644ab060887 100644 --- a/src/test/compile-fail/E0106.rs +++ b/src/test/compile-fail/E0106.rs @@ -23,5 +23,17 @@ type MyStr = &str; //~^ ERROR E0106 //~| NOTE expected lifetime parameter +struct Baz<'a>(&'a str); +struct Buzz<'a, 'b>(&'a str, &'b str); + +struct Quux { + baz: Baz, + //~^ ERROR E0106 + //~| expected lifetime parameter + buzz: Buzz, + //~^ ERROR E0106 + //~| expected 2 lifetime parameters +} + fn main() { } diff --git a/src/test/compile-fail/E0107.rs b/src/test/compile-fail/E0107.rs index 5f333e17c478e..16ebd3e9ca5f2 100644 --- a/src/test/compile-fail/E0107.rs +++ b/src/test/compile-fail/E0107.rs @@ -18,9 +18,6 @@ enum Bar { } struct Baz<'a, 'b, 'c> { - foo: Foo, - //~^ ERROR E0107 - //~| expected 1 lifetime parameter buzz: Buzz<'a>, //~^ ERROR E0107 //~| expected 2 lifetime parameters diff --git a/src/test/compile-fail/associated-types-project-from-hrtb-in-struct.rs b/src/test/compile-fail/associated-types-project-from-hrtb-in-struct.rs index 44ad0bb01138f..e6251a0d318a3 100644 --- a/src/test/compile-fail/associated-types-project-from-hrtb-in-struct.rs +++ b/src/test/compile-fail/associated-types-project-from-hrtb-in-struct.rs @@ -22,10 +22,11 @@ struct SomeStruct Foo<&'x isize>> { //~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context } -struct AnotherStruct Foo<&'x isize>> { - field: >::A - //~^ ERROR missing lifetime specifier -} +// FIXME(eddyb) This one doesn't even compile because of the unsupported syntax. + +// struct AnotherStruct Foo<&'x isize>> { +// field: Foo<&'y isize>>::A +// } struct YetAnotherStruct<'a, I : for<'x> Foo<&'x isize>> { field: >::A diff --git a/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs index 7355c70ff95e8..43371eb6340f4 100644 --- a/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs +++ b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs @@ -38,4 +38,28 @@ fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier panic!() } +// Cases which used to work but now don't. + +type StaticStr = &'static str; // hides 'static +trait WithLifetime<'a> { + type Output; // can hide 'a +} + +// This worked because the type of the first argument contains +// 'static, although StaticStr doesn't even have parameters. +fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier +//~^ HELP this function's return type contains a borrowed value +//~| HELP consider giving it an explicit bounded or 'static lifetime + panic!() +} + +// This worked because the compiler resolved the argument type +// to >::Output which has the hidden 'a. +fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize { +//~^ ERROR missing lifetime specifier +//~| HELP this function's return type contains a borrowed value +//~| HELP consider giving it an explicit bounded or 'static lifetime + panic!() +} + fn main() {} diff --git a/src/test/compile-fail/rfc1623.rs b/src/test/compile-fail/rfc1623.rs index 083cc218eecf3..93635e7fddea7 100644 --- a/src/test/compile-fail/rfc1623.rs +++ b/src/test/compile-fail/rfc1623.rs @@ -15,8 +15,10 @@ fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { } // the boundaries of elision -static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = &(non_elidable as fn(&u8, &u8) -> &u8); +static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = //~^ ERROR missing lifetime specifier [E0106] + &(non_elidable as fn(&u8, &u8) -> &u8); + //~^ ERROR missing lifetime specifier [E0106] struct SomeStruct<'x, 'y, 'z: 'x> { foo: &'x Foo<'z>, From 9783947c2adfcadba3c0e036548cf6fd3e12553a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 13 Jan 2017 15:10:37 +0200 Subject: [PATCH 61/86] rustc_typeck: move impl Trait checks out of RegionScope. --- src/librustc_typeck/astconv.rs | 94 +++++++++++-------- src/librustc_typeck/collect.rs | 32 ++----- src/librustc_typeck/lib.rs | 1 + src/librustc_typeck/rscope.rs | 79 ---------------- .../compile-fail/impl-trait/disallowed.rs | 2 +- 5 files changed, 65 insertions(+), 143 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 42a220e1b9b4b..90efe7cad3999 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -62,7 +62,7 @@ use rustc::ty::wf::object_region_bounds; use rustc_back::slice; use require_c_abi_if_variadic; use rscope::{RegionScope, ObjectLifetimeDefaultRscope, ShiftedRscope}; -use rscope::{AnonTypeScope, MaybeWithAnonTypes, ExplicitRscope}; +use rscope::ExplicitRscope; use util::common::{ErrorReported, FN_OUTPUT_NAME}; use util::nodemap::{NodeMap, FxHashSet}; @@ -361,8 +361,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::ParenthesizedParameters(ref data) => { assert_eq!(i, 0); - let (ty, assoc) = - self.convert_parenthesized_parameters(rscope, substs, data); + let (ty, assoc) = self.convert_parenthesized_parameters(substs, data); output_assoc_binding = Some(assoc); ty } @@ -416,7 +415,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { vec![output_assoc_binding.unwrap_or_else(|| { // This is an error condition, but we should // get the associated type binding anyway. - self.convert_parenthesized_parameters(rscope, substs, data).1 + self.convert_parenthesized_parameters(substs, data).1 })] } }; @@ -428,20 +427,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn convert_parenthesized_parameters(&self, - rscope: &RegionScope, region_substs: &[Kind<'tcx>], data: &hir::ParenthesizedParameterData) -> (Ty<'tcx>, ConvertedBinding<'tcx>) { - let anon_scope = rscope.anon_type_scope(); - let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope); let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| { - self.ast_ty_arg_to_ty(&rscope, None, region_substs, a_t) + self.ast_ty_arg_to_ty(&ExplicitRscope, None, region_substs, a_t) })); let (output, output_span) = match data.output { Some(ref output_ty) => { - (self.ast_ty_to_ty(&rscope, output_ty), output_ty.span) + (self.ast_ty_to_ty(&ExplicitRscope, output_ty), output_ty.span) } None => { (self.tcx().mk_nil(), data.span) @@ -1309,12 +1305,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::TyBareFn(ref bf) => { require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); - let anon_scope = rscope.anon_type_scope(); - let bare_fn_ty = self.ty_of_method_or_bare_fn(bf.unsafety, - bf.abi, - &bf.decl, - anon_scope, - anon_scope); + let bare_fn_ty = self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl); // Find any late-bound regions declared in return type that do // not appear in the arguments. These are not wellformed. @@ -1361,16 +1352,54 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::TyImplTrait(ref bounds) => { use collect::{compute_bounds, SizedByDefault}; + // Figure out if we can allow an `impl Trait` here, by walking up + // to a `fn` or inherent `impl` method, going only through `Ty` + // or `TraitRef` nodes (as nothing else should be in types) and + // ensuring that we reach the `fn`/method signature's return type. + let mut node_id = ast_ty.id; + let fn_decl = loop { + let parent = tcx.hir.get_parent_node(node_id); + match tcx.hir.get(parent) { + hir::map::NodeItem(&hir::Item { + node: hir::ItemFn(ref fn_decl, ..), .. + }) => break Some(fn_decl), + + hir::map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(ref sig, _), .. + }) => { + match tcx.hir.expect_item(tcx.hir.get_parent(parent)).node { + hir::ItemImpl(.., None, _, _) => { + break Some(&sig.decl) + } + _ => break None + } + } + + hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => {} + + _ => break None + } + node_id = parent; + }; + let allow = fn_decl.map_or(false, |fd| { + match fd.output { + hir::DefaultReturn(_) => false, + hir::Return(ref ty) => ty.id == node_id + } + }); + // Create the anonymized type. - let def_id = tcx.hir.local_def_id(ast_ty.id); - if let Some(anon_scope) = rscope.anon_type_scope() { - let substs = anon_scope.fresh_substs(self, ast_ty.span); + if allow { + let def_id = tcx.hir.local_def_id(ast_ty.id); + if let Err(ErrorReported) = self.get_generics(ast_ty.span, def_id) { + return tcx.types.err; + } + let substs = Substs::identity_for_item(tcx, def_id); let ty = tcx.mk_anon(tcx.hir.local_def_id(ast_ty.id), substs); // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`. let bounds = compute_bounds(self, ty, bounds, SizedByDefault::Yes, - Some(anon_scope), ast_ty.span); let predicates = bounds.predicates(tcx, ty); let predicates = tcx.lift_to_global(&predicates).unwrap(); @@ -1450,36 +1479,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { pub fn ty_of_fn(&self, unsafety: hir::Unsafety, abi: abi::Abi, - decl: &hir::FnDecl, - anon_scope: Option) + decl: &hir::FnDecl) -> &'tcx ty::BareFnTy<'tcx> { - self.ty_of_method_or_bare_fn(unsafety, abi, decl, None, anon_scope) - } - - fn ty_of_method_or_bare_fn(&self, - unsafety: hir::Unsafety, - abi: abi::Abi, - decl: &hir::FnDecl, - arg_anon_scope: Option, - ret_anon_scope: Option) - -> &'tcx ty::BareFnTy<'tcx> - { - debug!("ty_of_method_or_bare_fn"); - - // New region names that appear inside of the arguments of the function - // declaration are bound to that function type. - let rb = MaybeWithAnonTypes::new(ExplicitRscope, arg_anon_scope); + debug!("ty_of_fn"); let input_tys: Vec = - decl.inputs.iter().map(|a| self.ty_of_arg(&rb, a, None)).collect(); + decl.inputs.iter().map(|a| self.ty_of_arg(&ExplicitRscope, a, None)).collect(); let output_ty = match decl.output { - hir::Return(ref output) => - self.ast_ty_to_ty(&MaybeWithAnonTypes::new(ExplicitRscope, ret_anon_scope), output), + hir::Return(ref output) => self.ast_ty_to_ty(&ExplicitRscope, output), hir::DefaultReturn(..) => self.tcx().mk_nil(), }; - debug!("ty_of_method_or_bare_fn: output_ty={:?}", output_ty); + debug!("ty_of_fn: output_ty={:?}", output_ty); self.tcx().mk_bare_fn(ty::BareFnTy { unsafety: unsafety, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 70bd43751ebdf..1bfa4fc7b682c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -641,7 +641,6 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, - container: AssociatedItemContainer, id: ast::NodeId, sig: &hir::MethodSig, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,) { @@ -651,12 +650,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let ty_generic_predicates = ty_generic_predicates(ccx, &sig.generics, ty_generics.parent, vec![], false); - let anon_scope = match container { - ImplContainer(_) => Some(AnonTypeScope::new(def_id)), - TraitContainer(_) => None - }; let fty = AstConv::ty_of_fn(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), - sig.unsafety, sig.abi, &sig.decl, anon_scope); + sig.unsafety, sig.abi, &sig.decl); let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), ccx.tcx.hir.span(id), def_id); @@ -874,8 +869,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { } hir::TraitItemKind::Method(ref sig, _) => { - convert_method(ccx, TraitContainer(trait_def_id), - trait_item.id, sig, &trait_predicates); + convert_method(ccx, trait_item.id, sig, &trait_predicates); } } } @@ -915,7 +909,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { } hir::ImplItemKind::Method(ref sig, _) => { - convert_method(ccx, ImplContainer(impl_def_id), impl_item.id, sig, &impl_predicates); + convert_method(ccx, impl_item.id, sig, &impl_predicates); } } } @@ -1186,7 +1180,6 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, self_param_ty, bounds, SizedByDefault::No, - None, item.span); let superbounds1 = superbounds1.predicates(tcx, self_param_ty); @@ -1323,7 +1316,6 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) assoc_ty, bounds, SizedByDefault::Yes, - None, trait_item.span); bounds.predicates(ccx.tcx, assoc_ty).into_iter() @@ -1537,8 +1529,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.icx(&()).to_ty(&ExplicitRscope, &t) } ItemFn(ref decl, unsafety, _, abi, ref generics, _) => { - let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl, - Some(AnonTypeScope::new(def_id))); + let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl); let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id); ccx.tcx.mk_fn_def(def_id, substs, tofd) } @@ -1770,7 +1761,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, param_ty, ¶m.bounds, SizedByDefault::Yes, - None, param.span); predicates.extend(bounds.predicates(ccx.tcx, param_ty)); } @@ -1968,7 +1958,6 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, param_ty: ty::Ty<'tcx>, ast_bounds: &[hir::TyParamBound], sized_by_default: SizedByDefault, - anon_scope: Option, span: Span) -> Bounds<'tcx> { @@ -1979,9 +1968,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, let mut projection_bounds = vec![]; - let rscope = MaybeWithAnonTypes::new(ExplicitRscope, anon_scope); let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - astconv.instantiate_poly_trait_ref(&rscope, + astconv.instantiate_poly_trait_ref(&ExplicitRscope, bound, param_ty, &mut projection_bounds) @@ -2048,7 +2036,7 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( abi: abi::Abi) -> Ty<'tcx> { - let fty = AstConv::ty_of_fn(&ccx.icx(ast_generics), hir::Unsafety::Unsafe, abi, decl, None); + let fty = AstConv::ty_of_fn(&ccx.icx(ast_generics), hir::Unsafety::Unsafe, abi, decl); // feature gate SIMD types in FFI, since I (huonw) am not sure the // ABIs are handled at all correctly. @@ -2077,10 +2065,10 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( ccx.tcx.mk_fn_def(def_id, substs, fty) } -pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, - span: Span, - def_id: DefId) - -> &'tcx Substs<'tcx> { +fn mk_item_substs<'tcx>(astconv: &AstConv<'tcx, 'tcx>, + span: Span, + def_id: DefId) + -> &'tcx Substs<'tcx> { let tcx = astconv.tcx(); // FIXME(eddyb) Do this request from Substs::for_item in librustc. if let Err(ErrorReported) = astconv.get_generics(span, def_id) { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 0e7daa03404c5..90ce77cc5f4bc 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -77,6 +77,7 @@ This API is completely unstable and subject to change. #![feature(box_patterns)] #![feature(box_syntax)] #![feature(conservative_impl_trait)] +#![feature(loop_break_value)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index 3ac917c396cf1..d982c91e388d1 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -8,11 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::hir::def_id::DefId; use rustc::ty; -use rustc::ty::subst::Substs; - -use astconv::AstConv; use syntax_pos::Span; @@ -38,73 +34,6 @@ pub trait RegionScope { /// computing `object_lifetime_default` (in particular, in legacy /// modes, it may not be relevant). fn base_object_lifetime_default(&self, span: Span) -> ty::Region; - - /// If this scope allows anonymized types, return the generics in - /// scope, that anonymized types will close over. For example, - /// if you have a function like: - /// - /// fn foo<'a, T>() -> impl Trait { ... } - /// - /// then, for the rscope that is used when handling the return type, - /// `anon_type_scope()` would return a `Some(AnonTypeScope {...})`, - /// on which `.fresh_substs(...)` can be used to obtain identity - /// Substs for `'a` and `T`, to track them in `TyAnon`. This property - /// is controlled by the region scope because it's fine-grained enough - /// to allow restriction of anonymized types to the syntactical extent - /// of a function's return type. - fn anon_type_scope(&self) -> Option { - None - } -} - -#[derive(Copy, Clone)] -pub struct AnonTypeScope { - enclosing_item: DefId -} - -impl<'gcx: 'tcx, 'tcx> AnonTypeScope { - pub fn new(enclosing_item: DefId) -> AnonTypeScope { - AnonTypeScope { - enclosing_item: enclosing_item - } - } - - pub fn fresh_substs(&self, astconv: &AstConv<'gcx, 'tcx>, span: Span) - -> &'tcx Substs<'tcx> { - use collect::mk_item_substs; - - mk_item_substs(astconv, span, self.enclosing_item) - } -} - -/// A scope wrapper which optionally allows anonymized types. -#[derive(Copy, Clone)] -pub struct MaybeWithAnonTypes { - base_scope: R, - anon_scope: Option -} - -impl MaybeWithAnonTypes { - pub fn new(base_scope: R, anon_scope: Option) -> Self { - MaybeWithAnonTypes { - base_scope: base_scope, - anon_scope: anon_scope - } - } -} - -impl RegionScope for MaybeWithAnonTypes { - fn object_lifetime_default(&self, span: Span) -> Option { - self.base_scope.object_lifetime_default(span) - } - - fn base_object_lifetime_default(&self, span: Span) -> ty::Region { - self.base_scope.base_object_lifetime_default(span) - } - - fn anon_type_scope(&self) -> Option { - self.anon_scope - } } // A scope in which all regions must be explicitly named. This is used @@ -158,10 +87,6 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { fn base_object_lifetime_default(&self, span: Span) -> ty::Region { self.base_scope.base_object_lifetime_default(span) } - - fn anon_type_scope(&self) -> Option { - self.base_scope.anon_type_scope() - } } /// A scope which simply shifts the Debruijn index of other scopes @@ -185,8 +110,4 @@ impl<'r> RegionScope for ShiftedRscope<'r> { fn base_object_lifetime_default(&self, span: Span) -> ty::Region { ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1) } - - fn anon_type_scope(&self) -> Option { - self.base_scope.anon_type_scope() - } } diff --git a/src/test/compile-fail/impl-trait/disallowed.rs b/src/test/compile-fail/impl-trait/disallowed.rs index 09aba5d8c9168..0467c49b0311d 100644 --- a/src/test/compile-fail/impl-trait/disallowed.rs +++ b/src/test/compile-fail/impl-trait/disallowed.rs @@ -26,9 +26,9 @@ trait LazyToString { //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types } -// Note that the following impl doesn't error, because the trait is invalid. impl LazyToString for String { fn lazy_to_string<'a>(&'a self) -> impl Fn() -> String { + //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types || self.clone() } } From 41553d6fbc36ee05364dcdccf43e8b8141a5cfe3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 17 Jan 2017 16:46:23 +0200 Subject: [PATCH 62/86] rustc: lower trait type paths as TyTraitObject. --- src/librustc/hir/lowering.rs | 42 +++++++++++++++++++------ src/librustc/lib.rs | 1 + src/librustc/middle/resolve_lifetime.rs | 39 ++++------------------- src/librustc_typeck/astconv.rs | 18 +---------- src/librustc_typeck/check/mod.rs | 2 +- 5 files changed, 42 insertions(+), 60 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ca251f3ff91d..f7d40350dc932 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -337,7 +337,8 @@ impl<'a> LoweringContext<'a> { return self.lower_ty(ty); } TyKind::Path(ref qself, ref path) => { - hir::TyPath(self.lower_qpath(t.id, qself, path, ParamMode::Explicit)) + let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit); + return self.ty_path(t.id, t.span, qpath); } TyKind::ImplicitSelf => { hir::TyPath(hir::QPath::Resolved(None, P(hir::Path { @@ -470,7 +471,8 @@ impl<'a> LoweringContext<'a> { // Otherwise, the base path is an implicit `Self` type path, // e.g. `Vec` in `Vec::new` or `::Item` in // `::Item::default`. - self.ty(p.span, hir::TyPath(hir::QPath::Resolved(qself, path))) + let new_id = self.next_id(); + self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)) }; // Anything after the base path are associated "extensions", @@ -493,7 +495,8 @@ impl<'a> LoweringContext<'a> { } // Wrap the associated extension in another type node. - ty = self.ty(p.span, hir::TyPath(qpath)); + let new_id = self.next_id(); + ty = self.ty_path(new_id, p.span, qpath); } // Should've returned in the for loop above. @@ -2352,12 +2355,33 @@ impl<'a> LoweringContext<'a> { self.expr_block(block, attrs) } - fn ty(&mut self, span: Span, node: hir::Ty_) -> P { - P(hir::Ty { - id: self.next_id(), - node: node, - span: span, - }) + fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P { + let mut id = id; + let node = match qpath { + hir::QPath::Resolved(None, path) => { + // Turn trait object paths into `TyTraitObject` instead. + if let Def::Trait(_) = path.def { + let principal = hir::TraitTyParamBound(hir::PolyTraitRef { + bound_lifetimes: hir_vec![], + trait_ref: hir::TraitRef { + path: path.and_then(|path| path), + ref_id: id, + }, + span, + }, hir::TraitBoundModifier::None); + + // The original ID is taken by the `PolyTraitRef`, + // so the `Ty` itself needs a different one. + id = self.next_id(); + + hir::TyTraitObject(hir_vec![principal]) + } else { + hir::TyPath(hir::QPath::Resolved(None, path)) + } + } + _ => hir::TyPath(qpath) + }; + P(hir::Ty { id, node, span }) } fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 11fdf6919ccbe..0ff9626ae11a8 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -29,6 +29,7 @@ #![feature(conservative_impl_trait)] #![feature(const_fn)] #![feature(core_intrinsics)] +#![feature(field_init_shorthand)] #![feature(libc)] #![feature(loop_break_value)] #![feature(nonzero)] diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 4e02485a40b7d..aa118891d9825 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -322,24 +322,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_ty(this, ty); }); } - hir::TyPath(hir::QPath::Resolved(None, ref path)) => { - // if this path references a trait, then this will resolve to - // a trait ref, which introduces a binding scope. - match path.def { - Def::Trait(..) => { - let scope = Scope::Binder { - lifetimes: FxHashMap(), - s: self.scope - }; - self.with(scope, |_, this| { - this.visit_path(path, ty.id); - }); - } - _ => { - intravisit::walk_ty(self, ty); - } - } - } _ => { intravisit::walk_ty(self, ty) } @@ -889,7 +871,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Def::Struct(_) | Def::Union(_) | Def::Enum(_) | - Def::Trait(_) | Def::PrimTy(_) => return def == path.def, _ => {} } @@ -970,21 +951,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn visit_ty(&mut self, ty: &hir::Ty) { - let delta = match ty.node { - hir::TyBareFn(_) => 1, - hir::TyPath(hir::QPath::Resolved(None, ref path)) => { - // if this path references a trait, then this will resolve to - // a trait ref, which introduces a binding scope. - match path.def { - Def::Trait(..) => 1, - _ => 0 - } - } - _ => 0 - }; - self.binder_depth += delta; + if let hir::TyBareFn(_) = ty.node { + self.binder_depth += 1; + } intravisit::walk_ty(self, ty); - self.binder_depth -= delta; + if let hir::TyBareFn(_) = ty.node { + self.binder_depth -= 1; + } } fn visit_poly_trait_ref(&mut self, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 90efe7cad3999..324d569cb8dce 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1151,7 +1151,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope: &RegionScope, opt_self_ty: Option>, path: &hir::Path, - path_id: ast::NodeId, permit_variants: bool) -> Ty<'tcx> { let tcx = self.tcx(); @@ -1161,21 +1160,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let span = path.span; match path.def { - Def::Trait(trait_def_id) => { - // N.B. this case overlaps somewhat with - // TyTraitObject, see that fn for details - - assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path.segments.split_last().unwrap().1); - - self.trait_path_to_object_type(rscope, - span, - trait_def_id, - path_id, - path.segments.last().unwrap(), - span, - partition_bounds(&[])) - } Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => { assert_eq!(opt_self_ty, None); tcx.prohibit_type_params(path.segments.split_last().unwrap().1); @@ -1421,7 +1405,7 @@ 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) }); - self.def_to_ty(rscope, opt_self_ty, path, ast_ty.id, false) + self.def_to_ty(rscope, opt_self_ty, path, false) } hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a8b5d718f81d0..4d1b2cec32e5f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3976,7 +3976,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match *qpath { hir::QPath::Resolved(ref maybe_qself, ref path) => { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself)); - let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, node_id, true); + let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, true); (path.def, ty) } hir::QPath::TypeRelative(ref qself, ref segment) => { From c5befdc6308f8624b4b5fa8808ba0af70d2fbcf1 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 24 Jan 2017 17:17:06 +0200 Subject: [PATCH 63/86] rustc: always keep an explicit lifetime in trait objects. --- src/librustc/hir/intravisit.rs | 13 +- src/librustc/hir/lowering.rs | 24 ++- src/librustc/hir/mod.rs | 2 +- src/librustc/hir/print.rs | 17 +- src/librustc/middle/resolve_lifetime.rs | 12 +- .../calculate_svh/svh_visitor.rs | 2 +- src/librustc_passes/ast_validation.rs | 11 ++ src/librustc_passes/diagnostics.rs | 1 + src/librustc_typeck/astconv.rs | 167 ++++-------------- src/librustc_typeck/collect.rs | 19 +- src/librustc_typeck/diagnostics.rs | 1 - src/librustdoc/clean/mod.rs | 28 +-- ...n-bounds-on-objects-and-type-parameters.rs | 6 +- 13 files changed, 137 insertions(+), 166 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index d71263bea0046..4b3e0d29101e4 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -301,7 +301,7 @@ pub trait Visitor<'v> : Sized { fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) { walk_ty_param_bound(self, bounds) } - fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) { walk_poly_trait_ref(self, t, m) } fn visit_variant_data(&mut self, @@ -421,7 +421,7 @@ pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v PolyTraitRef, - _modifier: &'v TraitBoundModifier) + _modifier: TraitBoundModifier) where V: Visitor<'v> { walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes); @@ -566,8 +566,11 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { visitor.visit_ty(ty); visitor.visit_nested_body(length) } - TyTraitObject(ref bounds) => { - walk_list!(visitor, visit_ty_param_bound, bounds); + TyTraitObject(ref bounds, ref lifetime) => { + for bound in bounds { + visitor.visit_poly_trait_ref(bound, TraitBoundModifier::None); + } + visitor.visit_lifetime(lifetime); } TyImplTrait(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); @@ -695,7 +698,7 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) { match *bound { - TraitTyParamBound(ref typ, ref modifier) => { + TraitTyParamBound(ref typ, modifier) => { visitor.visit_poly_trait_ref(typ, modifier); } RegionTyParamBound(ref lifetime) => { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f7d40350dc932..8a4acb3d03880 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -360,7 +360,23 @@ impl<'a> LoweringContext<'a> { hir::TyTypeof(self.record_body(expr, None)) } TyKind::TraitObject(ref bounds) => { - hir::TyTraitObject(self.lower_bounds(bounds)) + let mut lifetime_bound = None; + let bounds = bounds.iter().filter_map(|bound| { + match *bound { + TraitTyParamBound(ref ty, TraitBoundModifier::None) => { + Some(self.lower_poly_trait_ref(ty)) + } + TraitTyParamBound(_, TraitBoundModifier::Maybe) => None, + RegionTyParamBound(ref lifetime) => { + lifetime_bound = Some(self.lower_lifetime(lifetime)); + None + } + } + }).collect(); + let lifetime_bound = lifetime_bound.unwrap_or_else(|| { + self.elided_lifetime(t.span) + }); + hir::TyTraitObject(bounds, lifetime_bound) } TyKind::ImplTrait(ref bounds) => { hir::TyImplTrait(self.lower_bounds(bounds)) @@ -2361,20 +2377,20 @@ impl<'a> LoweringContext<'a> { hir::QPath::Resolved(None, path) => { // Turn trait object paths into `TyTraitObject` instead. if let Def::Trait(_) = path.def { - let principal = hir::TraitTyParamBound(hir::PolyTraitRef { + let principal = hir::PolyTraitRef { bound_lifetimes: hir_vec![], trait_ref: hir::TraitRef { path: path.and_then(|path| path), ref_id: id, }, span, - }, hir::TraitBoundModifier::None); + }; // The original ID is taken by the `PolyTraitRef`, // so the `Ty` itself needs a different one. id = self.next_id(); - hir::TyTraitObject(hir_vec![principal]) + hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span)) } else { hir::TyPath(hir::QPath::Resolved(None, path)) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 94cb33b138c58..4ebe416e1bfe6 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1205,7 +1205,7 @@ pub enum Ty_ { TyPath(QPath), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. - TyTraitObject(TyParamBounds), + TyTraitObject(HirVec, Lifetime), /// An `impl Bound1 + Bound2 + Bound3` type /// where `Bound` is a trait or a lifetime. TyImplTrait(TyParamBounds), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 8e866f5717498..e058c48c59149 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -416,8 +416,21 @@ impl<'a> State<'a> { hir::TyPath(ref qpath) => { self.print_qpath(qpath, false)? } - hir::TyTraitObject(ref bounds) => { - self.print_bounds("", &bounds[..])?; + hir::TyTraitObject(ref bounds, ref lifetime) => { + let mut first = true; + for bound in bounds { + self.nbsp()?; + if first { + first = false; + } else { + self.word_space("+")?; + } + self.print_poly_trait_ref(bound)?; + } + if !lifetime.is_elided() { + self.word_space("+")?; + self.print_lifetime(lifetime)?; + } } hir::TyImplTrait(ref bounds) => { self.print_bounds("impl ", &bounds[..])?; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index aa118891d9825..88da47c2f0c44 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -322,6 +322,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_ty(this, ty); }); } + hir::TyTraitObject(ref bounds, ref lifetime) => { + for bound in bounds { + self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); + } + if !lifetime.is_elided() { + self.visit_lifetime(lifetime); + } + } _ => { intravisit::walk_ty(self, ty) } @@ -441,7 +449,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef, - _modifier: &'tcx hir::TraitBoundModifier) { + _modifier: hir::TraitBoundModifier) { debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref); if !self.trait_ref_hack || !trait_ref.bound_lifetimes.is_empty() { @@ -962,7 +970,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn visit_poly_trait_ref(&mut self, trait_ref: &hir::PolyTraitRef, - modifier: &hir::TraitBoundModifier) { + modifier: hir::TraitBoundModifier) { self.binder_depth += 1; intravisit::walk_poly_trait_ref(self, trait_ref, modifier); self.binder_depth -= 1; diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 69237f406760d..c7512f2971b33 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -828,7 +828,7 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has visit::walk_ty_param_bound(self, bounds) } - fn visit_poly_trait_ref(&mut self, t: &'tcx PolyTraitRef, m: &'tcx TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, t: &'tcx PolyTraitRef, m: TraitBoundModifier) { debug!("visit_poly_trait_ref: st={:?}", self.st); SawPolyTraitRef.hash(self.st); m.hash(self.st); diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 9720bb8426475..0933fdfd357cd 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -144,6 +144,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); } TyKind::TraitObject(ref bounds) => { + let mut any_lifetime_bounds = false; + for bound in bounds { + if let RegionTyParamBound(ref lifetime) = *bound { + if any_lifetime_bounds { + span_err!(self.session, lifetime.span, E0226, + "only a single explicit lifetime bound is permitted"); + break; + } + any_lifetime_bounds = true; + } + } self.no_questions_in_bounds(bounds, "trait object types", false); } TyKind::ImplTrait(ref bounds) => { diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index c414d71836818..ef871959176af 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -244,6 +244,7 @@ match 5u32 { } register_diagnostics! { + E0226, // only a single explicit lifetime bound is permitted E0472, // asm! is unsupported on this target E0561, // patterns aren't allowed in function pointer types E0571, // `break` with a value in a non-`loop`-loop diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 324d569cb8dce..5c71947c2077e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -453,24 +453,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { (self.tcx().mk_ty(ty::TyTuple(inputs)), output_binding) } - pub fn instantiate_poly_trait_ref(&self, - rscope: &RegionScope, - ast_trait_ref: &hir::PolyTraitRef, - self_ty: Ty<'tcx>, - poly_projections: &mut Vec>) - -> ty::PolyTraitRef<'tcx> - { - let trait_ref = &ast_trait_ref.trait_ref; - let trait_def_id = self.trait_def_id(trait_ref); - self.ast_path_to_poly_trait_ref(rscope, - trait_ref.path.span, - trait_def_id, - self_ty, - trait_ref.ref_id, - trait_ref.path.segments.last().unwrap(), - poly_projections) - } - /// Instantiates the path for the given trait reference, assuming that it's /// bound to a valid trait type. Returns the def_id for the defining trait. /// Fails if the type is a type other than a trait type. @@ -505,17 +487,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } - fn ast_path_to_poly_trait_ref(&self, + pub fn instantiate_poly_trait_ref(&self, rscope: &RegionScope, - span: Span, - trait_def_id: DefId, + ast_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, - path_id: ast::NodeId, - trait_segment: &hir::PathSegment, poly_projections: &mut Vec>) -> ty::PolyTraitRef<'tcx> { - debug!("ast_path_to_poly_trait_ref(trait_segment={:?})", trait_segment); + let trait_ref = &ast_trait_ref.trait_ref; + let trait_def_id = self.trait_def_id(trait_ref); + + debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); // The trait reference introduces a binding level here, so // we need to shift the `rscope`. It'd be nice if we could // do away with this rscope stuff and work this knowledge @@ -525,23 +507,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let (substs, assoc_bindings) = self.create_substs_for_ast_trait_ref(shifted_rscope, - span, + trait_ref.path.span, trait_def_id, self_ty, - trait_segment); + trait_ref.path.segments.last().unwrap()); let poly_trait_ref = ty::Binder(ty::TraitRef::new(trait_def_id, substs)); poly_projections.extend(assoc_bindings.iter().filter_map(|binding| { // specify type to assert that error was already reported in Err case: let predicate: Result<_, ErrorReported> = - self.ast_type_binding_to_poly_projection_predicate(path_id, + self.ast_type_binding_to_poly_projection_predicate(trait_ref.ref_id, poly_trait_ref, binding); predicate.ok() // ok to ignore Err() because ErrorReported (see above) })); - debug!("ast_path_to_poly_trait_ref(trait_segment={:?}, projections={:?}) -> {:?}", - trait_segment, poly_projections, poly_trait_ref); + debug!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}", + trait_ref, poly_projections, poly_trait_ref); poly_trait_ref } @@ -754,32 +736,29 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref) } - fn trait_path_to_object_type(&self, - rscope: &RegionScope, - path_span: Span, - trait_def_id: DefId, - trait_path_ref_id: ast::NodeId, - trait_segment: &hir::PathSegment, - span: Span, - partitioned_bounds: PartitionedBounds) - -> Ty<'tcx> { + fn conv_object_ty_poly_trait_ref(&self, + rscope: &RegionScope, + span: Span, + trait_bounds: &[hir::PolyTraitRef], + lifetime: &hir::Lifetime) + -> Ty<'tcx> + { let tcx = self.tcx(); + if trait_bounds.is_empty() { + span_err!(tcx.sess, span, E0224, + "at least one non-builtin trait is required for an object type"); + return tcx.types.err; + } + let mut projection_bounds = vec![]; let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); - let principal = self.ast_path_to_poly_trait_ref(rscope, - path_span, - trait_def_id, + let principal = self.instantiate_poly_trait_ref(rscope, + &trait_bounds[0], dummy_self, - trait_path_ref_id, - trait_segment, &mut projection_bounds); - let PartitionedBounds { trait_bounds, - region_bounds } = - partitioned_bounds; - - let (auto_traits, trait_bounds) = split_auto_traits(tcx, trait_bounds); + let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]); if !trait_bounds.is_empty() { let b = &trait_bounds[0]; @@ -854,13 +833,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { v.sort_by(|a, b| a.cmp(tcx, b)); let existential_predicates = ty::Binder(tcx.mk_existential_predicates(v.into_iter())); - let region_bound = self.compute_object_lifetime_bound(span, - ®ion_bounds, - existential_predicates); - let region_bound = match region_bound { - Some(r) => r, - None => { + // Explicitly specified region bound. Use that. + let region_bound = if !lifetime.is_elided() { + self.ast_region_to_region(lifetime, None) + } else { + self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { tcx.mk_region(match rscope.object_lifetime_default(span) { Some(r) => r, None => { @@ -870,7 +848,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ty::ReStatic } }) - } + }) }; debug!("region_bound: {:?}", region_bound); @@ -1330,8 +1308,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } tcx.mk_fn_ptr(bare_fn_ty) } - hir::TyTraitObject(ref bounds) => { - self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds) + hir::TyTraitObject(ref bounds, ref lifetime) => { + self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds, lifetime) } hir::TyImplTrait(ref bounds) => { use collect::{compute_bounds, SizedByDefault}; @@ -1537,33 +1515,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } - fn conv_object_ty_poly_trait_ref(&self, - rscope: &RegionScope, - span: Span, - ast_bounds: &[hir::TyParamBound]) - -> Ty<'tcx> - { - let mut partitioned_bounds = partition_bounds(ast_bounds); - - let trait_bound = if !partitioned_bounds.trait_bounds.is_empty() { - partitioned_bounds.trait_bounds.remove(0) - } else { - span_err!(self.tcx().sess, span, E0224, - "at least one non-builtin trait is required for an object type"); - return self.tcx().types.err; - }; - - let trait_ref = &trait_bound.trait_ref; - let trait_def_id = self.trait_def_id(trait_ref); - self.trait_path_to_object_type(rscope, - trait_ref.path.span, - trait_def_id, - trait_ref.ref_id, - trait_ref.path.segments.last().unwrap(), - span, - partitioned_bounds) - } - /// Given the bounds on an object, determines what single region bound (if any) we can /// use to summarize this type. The basic idea is that we will use the bound the user /// provided, if they provided one, and otherwise search the supertypes of trait bounds @@ -1571,27 +1522,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// we return `None`. fn compute_object_lifetime_bound(&self, span: Span, - explicit_region_bounds: &[&hir::Lifetime], existential_predicates: ty::Binder<&'tcx ty::Slice>>) -> Option<&'tcx ty::Region> // if None, use the default { let tcx = self.tcx(); - debug!("compute_opt_region_bound(explicit_region_bounds={:?}, \ - existential_predicates={:?})", - explicit_region_bounds, + debug!("compute_opt_region_bound(existential_predicates={:?})", existential_predicates); - if explicit_region_bounds.len() > 1 { - span_err!(tcx.sess, explicit_region_bounds[1].span, E0226, - "only a single explicit lifetime bound is permitted"); - } - - if let Some(&r) = explicit_region_bounds.get(0) { - // Explicitly specified region bound. Use that. - return Some(self.ast_region_to_region(r, None)); - } - if let Some(principal) = existential_predicates.principal() { if let Err(ErrorReported) = self.ensure_super_predicates(span, principal.def_id()) { return Some(tcx.mk_region(ty::ReStatic)); @@ -1627,18 +1565,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } -pub struct PartitionedBounds<'a> { - pub trait_bounds: Vec<&'a hir::PolyTraitRef>, - pub region_bounds: Vec<&'a hir::Lifetime>, -} - /// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the /// remaining general trait bounds. fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - trait_bounds: Vec<&'b hir::PolyTraitRef>) + trait_bounds: &'b [hir::PolyTraitRef]) -> (Vec, Vec<&'b hir::PolyTraitRef>) { - let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.into_iter().partition(|bound| { + let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| { match bound.trait_ref.path.def { Def::Trait(trait_did) => { // Checks whether `trait_did` refers to one of the builtin @@ -1675,30 +1608,6 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, (auto_traits, trait_bounds) } -/// Divides a list of bounds from the AST into two groups: general trait bounds and region bounds -pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(ast_bounds: &'b [hir::TyParamBound]) - -> PartitionedBounds<'b> -{ - let mut region_bounds = Vec::new(); - let mut trait_bounds = Vec::new(); - for ast_bound in ast_bounds { - match *ast_bound { - hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => { - trait_bounds.push(b); - } - hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {} - hir::RegionTyParamBound(ref l) => { - region_bounds.push(l); - } - } - } - - PartitionedBounds { - trait_bounds: trait_bounds, - region_bounds: region_bounds, - } -} - fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize, ty_param_defs: &[ty::TypeParameterDef]) { let accepted = ty_param_defs.len(); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1bfa4fc7b682c..90e2f821b10b5 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -57,7 +57,7 @@ There are some shortcomings in this design: */ -use astconv::{AstConv, Bounds, PartitionedBounds, partition_bounds}; +use astconv::{AstConv, Bounds}; use lint; use constrained_type_params as ctp; use middle::lang_items::SizedTraitLangItem; @@ -1961,10 +1961,19 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, span: Span) -> Bounds<'tcx> { - let PartitionedBounds { - trait_bounds, - region_bounds - } = partition_bounds(&ast_bounds); + let mut region_bounds = vec![]; + let mut trait_bounds = vec![]; + for ast_bound in ast_bounds { + match *ast_bound { + hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => { + trait_bounds.push(b); + } + hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {} + hir::RegionTyParamBound(ref l) => { + region_bounds.push(l); + } + } + } let mut projection_bounds = vec![]; diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 7f8c508bf2224..c41d40b41e42a 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4096,7 +4096,6 @@ register_diagnostics! { // E0222, // Error code E0045 (variadic function must have C calling // convention) duplicate E0224, // at least one non-builtin train is required for an object type - E0226, // only a single explicit lifetime bound is permitted E0227, // ambiguous lifetime bound, explicit lifetime bound required E0228, // explicit lifetime bound required E0231, // only named substitution parameters are allowed diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4182dca715311..f1ced233dde7b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1776,20 +1776,20 @@ impl Clean for hir::Ty { trait_: box resolve_type(cx, trait_path.clean(cx), self.id) } } - TyTraitObject(ref bounds) => { - let lhs_ty = bounds[0].clean(cx); - match lhs_ty { - TraitBound(poly_trait, ..) => { - match poly_trait.trait_ { - ResolvedPath { path, typarams: None, did, is_generic } => { - ResolvedPath { - path: path, - typarams: Some(bounds[1..].clean(cx)), - did: did, - is_generic: is_generic, - } - } - _ => Infer // shouldn't happen + TyTraitObject(ref bounds, ref lifetime) => { + match bounds[0].clean(cx).trait_ { + ResolvedPath { path, typarams: None, did, is_generic } => { + let mut bounds: Vec<_> = bounds[1..].iter().map(|bound| { + TraitBound(bound.clean(cx), hir::TraitBoundModifier::None) + }).collect(); + if !lifetime.is_elided() { + bounds.push(RegionBound(lifetime.clean(cx))); + } + ResolvedPath { + path: path, + typarams: Some(bounds), + did: did, + is_generic: is_generic, } } _ => Infer // shouldn't happen diff --git a/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs b/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs index b8cbbdbe9ec3e..503b577b1f1b4 100644 --- a/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs +++ b/src/test/compile-fail/region-bounds-on-objects-and-type-parameters.rs @@ -18,7 +18,7 @@ trait SomeTrait { } // Bounds on object types: -struct Foo<'a,'b,'c> { +struct Foo<'a,'b,'c> { //~ ERROR parameter `'b` is never used // All of these are ok, because we can derive exactly one bound: a: Box, b: Box>, @@ -28,7 +28,9 @@ struct Foo<'a,'b,'c> { f: Box, // OK, defaults to 'static due to RFC 599. g: Box, - z: Box+'b+'c>, //~ ERROR only a single explicit lifetime bound is permitted + z: Box+'b+'c>, + //~^ ERROR only a single explicit lifetime bound is permitted + //~| ERROR lifetime bound not satisfied } fn test< From 4eac052a33f38688d582d3bb5242728f543a3c8f Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 25 Jan 2017 17:32:44 +0200 Subject: [PATCH 64/86] rustc: move object default lifetimes to resolve_lifetimes. --- src/librustc/middle/cstore.rs | 6 + src/librustc/middle/resolve_lifetime.rs | 343 ++++++++++++++++-- src/librustc/ty/mod.rs | 19 - src/librustc/ty/structural_impls.rs | 26 +- src/librustc/util/ppaux.rs | 10 - src/librustc_metadata/cstore_impl.rs | 7 + src/librustc_metadata/decoder.rs | 7 + src/librustc_metadata/encoder.rs | 7 + src/librustc_metadata/schema.rs | 2 + src/librustc_typeck/astconv.rs | 175 +++------ src/librustc_typeck/check/mod.rs | 28 +- src/librustc_typeck/collect.rs | 136 +------ src/librustc_typeck/lib.rs | 1 - src/librustc_typeck/rscope.rs | 113 ------ ...object-lifetime-default-from-ref-struct.rs | 18 + .../object-lifetime-default-from-rptr.rs | 6 + 16 files changed, 445 insertions(+), 459 deletions(-) delete mode 100644 src/librustc_typeck/rscope.rs diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 8cf13cddc8c7f..d11e6e3fc72bd 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -28,6 +28,7 @@ use hir::map as hir_map; use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData}; use hir::svh::Svh; use middle::lang_items; +use middle::resolve_lifetime::ObjectLifetimeDefault; use ty::{self, Ty, TyCtxt}; use mir::Mir; use session::Session; @@ -183,6 +184,8 @@ pub trait CrateStore<'tcx> { fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::Generics<'tcx>; fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize); + fn item_generics_object_lifetime_defaults(&self, def: DefId) + -> Vec; fn item_attrs(&self, def_id: DefId) -> Vec; fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef; fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef; @@ -334,6 +337,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { -> ty::Generics<'tcx> { bug!("item_generics") } fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize) { bug!("item_generics_own_param_counts") } + fn item_generics_object_lifetime_defaults(&self, def: DefId) + -> Vec + { bug!("item_generics_object_lifetime_defaults") } fn item_attrs(&self, def_id: DefId) -> Vec { bug!("item_attrs") } fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef { bug!("trait_def") } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 88da47c2f0c44..88ef2c69a04dc 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -26,11 +26,12 @@ use ty; use std::cell::Cell; use std::mem::replace; use syntax::ast; +use syntax::attr; use syntax::ptr::P; use syntax::symbol::keywords; use syntax_pos::Span; use errors::DiagnosticBuilder; -use util::nodemap::{NodeMap, FxHashSet, FxHashMap}; +use util::nodemap::{NodeMap, FxHashSet, FxHashMap, DefIdMap}; use rustc_back::slice; use hir; @@ -102,8 +103,46 @@ impl Region { _ => self } } + + fn subst(self, params: &[hir::Lifetime], map: &NamedRegionMap) + -> Option { + if let Region::EarlyBound(index, _) = self { + params.get(index as usize).and_then(|lifetime| { + map.defs.get(&lifetime.id).cloned() + }) + } else { + Some(self) + } + } } +/// A set containing, at most, one known element. +/// If two distinct values are inserted into a set, then it +/// becomes `Many`, which can be used to detect ambiguities. +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +pub enum Set1 { + Empty, + One(T), + Many +} + +impl Set1 { + pub fn insert(&mut self, value: T) { + if let Set1::Empty = *self { + *self = Set1::One(value); + return; + } + if let Set1::One(ref old) = *self { + if *old == value { + return; + } + } + *self = Set1::Many; + } +} + +pub type ObjectLifetimeDefault = Set1; + // Maps the id of each lifetime reference to the lifetime decl // that it corresponds to. pub struct NamedRegionMap { @@ -115,6 +154,10 @@ pub struct NamedRegionMap { // are named regions appearing in fn arguments that do not appear // in where-clauses pub late_bound: NodeMap, + + // For each type and trait definition, maps type parameters + // to the trait object lifetime defaults computed from them. + pub object_lifetime_defaults: NodeMap>, } struct LifetimeContext<'a, 'tcx: 'a> { @@ -141,6 +184,9 @@ struct LifetimeContext<'a, 'tcx: 'a> { // List of labels in the function/method currently under analysis. labels_in_fn: Vec<(ast::Name, Span)>, + + // Cache for cross-crate per-definition object lifetime defaults. + xcrate_object_lifetime_defaults: DefIdMap>, } #[derive(Debug)] @@ -170,6 +216,14 @@ enum Scope<'a> { s: ScopeRef<'a> }, + /// Use a specific lifetime (if `Some`) or leave it unset (to be + /// inferred in a function body or potentially error outside one), + /// for the default choice of lifetime in a trait object type. + ObjectLifetimeDefault { + lifetime: Option, + s: ScopeRef<'a> + }, + Root } @@ -208,6 +262,7 @@ pub fn krate(sess: &Session, let mut map = NamedRegionMap { defs: NodeMap(), late_bound: NodeMap(), + object_lifetime_defaults: compute_object_lifetime_defaults(sess, hir_map), }; sess.track_errors(|| { let mut visitor = LifetimeContext { @@ -217,6 +272,7 @@ pub fn krate(sess: &Session, scope: ROOT_SCOPE, trait_ref_hack: false, labels_in_fn: vec![], + xcrate_object_lifetime_defaults: DefIdMap(), }; for (_, item) in &krate.items { visitor.visit_item(item); @@ -326,10 +382,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for bound in bounds { self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); } - if !lifetime.is_elided() { + if lifetime.is_elided() { + self.resolve_object_lifetime_default(lifetime) + } else { self.visit_lifetime(lifetime); } } + hir::TyRptr(ref lifetime_ref, ref mt) => { + self.visit_lifetime(lifetime_ref); + let scope = Scope::ObjectLifetimeDefault { + lifetime: self.map.defs.get(&lifetime_ref.id).cloned(), + s: self.scope + }; + self.with(scope, |_, this| this.visit_ty(&mt.ty)); + } _ => { intravisit::walk_ty(self, ty) } @@ -372,20 +438,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.resolve_lifetime_ref(lifetime_ref); } - fn visit_path_parameters(&mut self, _: Span, params: &'tcx hir::PathParameters) { - match *params { - hir::AngleBracketedParameters(ref data) => { - if data.lifetimes.iter().all(|l| l.is_elided()) { - self.resolve_elided_lifetimes(&data.lifetimes); - } else { - for l in &data.lifetimes { self.visit_lifetime(l); } - } - for ty in &data.types { self.visit_ty(ty); } - for b in &data.bindings { self.visit_assoc_type_binding(b); } - } - hir::ParenthesizedParameters(ref data) => { - self.visit_fn_like_elision(&data.inputs, data.output.as_ref()); - } + fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) { + for (i, segment) in path.segments.iter().enumerate() { + let depth = path.segments.len() - i - 1; + self.visit_segment_parameters(path.def, depth, &segment.parameters); } } @@ -466,7 +522,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for lifetime in &trait_ref.bound_lifetimes { this.visit_lifetime_def(lifetime); } - intravisit::walk_path(this, &trait_ref.trait_ref.path) + this.visit_trait_ref(&trait_ref.trait_ref) }) } else { self.visit_trait_ref(&trait_ref.trait_ref) @@ -585,7 +641,8 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { loop { match *scope { Scope::Body { s, .. } | - Scope::Elision { s, .. } => { scope = s; } + Scope::Elision { s, .. } | + Scope::ObjectLifetimeDefault { s, .. } => { scope = s; } Scope::Root => { return; } @@ -606,6 +663,103 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { } } +fn compute_object_lifetime_defaults(sess: &Session, hir_map: &Map) + -> NodeMap> { + let mut map = NodeMap(); + for item in hir_map.krate().items.values() { + match item.node { + hir::ItemStruct(_, ref generics) | + hir::ItemUnion(_, ref generics) | + hir::ItemEnum(_, ref generics) | + hir::ItemTy(_, ref generics) | + hir::ItemTrait(_, ref generics, ..) => { + let result = object_lifetime_defaults_for_item(hir_map, generics); + + // Debugging aid. + if attr::contains_name(&item.attrs, "rustc_object_lifetime_default") { + let object_lifetime_default_reprs: String = + result.iter().map(|set| { + match *set { + Set1::Empty => "BaseDefault".to_string(), + Set1::One(Region::Static) => "'static".to_string(), + Set1::One(Region::EarlyBound(i, _)) => { + generics.lifetimes[i as usize].lifetime.name.to_string() + } + Set1::One(_) => bug!(), + Set1::Many => "Ambiguous".to_string(), + } + }).collect::>().join(","); + sess.span_err(item.span, &object_lifetime_default_reprs); + } + + map.insert(item.id, result); + } + _ => {} + } + } + map +} + +/// Scan the bounds and where-clauses on parameters to extract bounds +/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault` +/// for each type parameter. +fn object_lifetime_defaults_for_item(hir_map: &Map, generics: &hir::Generics) + -> Vec { + fn add_bounds(set: &mut Set1, bounds: &[hir::TyParamBound]) { + for bound in bounds { + if let hir::RegionTyParamBound(ref lifetime) = *bound { + set.insert(lifetime.name); + } + } + } + + generics.ty_params.iter().map(|param| { + let mut set = Set1::Empty; + + add_bounds(&mut set, ¶m.bounds); + + let param_def_id = hir_map.local_def_id(param.id); + for predicate in &generics.where_clause.predicates { + // Look for `type: ...` where clauses. + let data = match *predicate { + hir::WherePredicate::BoundPredicate(ref data) => data, + _ => continue + }; + + // Ignore `for<'a> type: ...` as they can change what + // lifetimes mean (although we could "just" handle it). + if !data.bound_lifetimes.is_empty() { + continue; + } + + let def = match data.bounded_ty.node { + hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def, + _ => continue + }; + + if def == Def::TyParam(param_def_id) { + add_bounds(&mut set, &data.bounds); + } + } + + match set { + Set1::Empty => Set1::Empty, + Set1::One(name) => { + if name == keywords::StaticLifetime.name() { + Set1::One(Region::Static) + } else { + generics.lifetimes.iter().enumerate().find(|&(_, def)| { + def.lifetime.name == name + }).map_or(Set1::Many, |(i, def)| { + Set1::One(Region::EarlyBound(i as u32, def.lifetime.id)) + }) + } + } + Set1::Many => Set1::Many + } + }).collect() +} + impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // FIXME(#37666) this works around a limitation in the region inferencer fn hack(&mut self, f: F) where @@ -619,6 +773,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { { let LifetimeContext {sess, hir_map, ref mut map, ..} = *self; let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); + let xcrate_object_lifetime_defaults = + replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap()); let mut this = LifetimeContext { sess: sess, hir_map: hir_map, @@ -626,11 +782,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope: &wrap_scope, trait_ref_hack: self.trait_ref_hack, labels_in_fn: labels_in_fn, + xcrate_object_lifetime_defaults: xcrate_object_lifetime_defaults, }; debug!("entering scope {:?}", this.scope); f(self.scope, &mut this); debug!("exiting scope {:?}", this.scope); self.labels_in_fn = this.labels_in_fn; + self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; } /// Visits self by adding a scope and handling recursive walk over the contents with `walk`. @@ -727,7 +885,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - Scope::Elision { s, .. } => { + Scope::Elision { s, .. } | + Scope::ObjectLifetimeDefault { s, .. } => { scope = s; } } @@ -763,6 +922,109 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + fn visit_segment_parameters(&mut self, + def: Def, + depth: usize, + params: &'tcx hir::PathParameters) { + let data = match *params { + hir::ParenthesizedParameters(ref data) => { + self.visit_fn_like_elision(&data.inputs, data.output.as_ref()); + return; + } + hir::AngleBracketedParameters(ref data) => data + }; + + if data.lifetimes.iter().all(|l| l.is_elided()) { + self.resolve_elided_lifetimes(&data.lifetimes); + } else { + for l in &data.lifetimes { self.visit_lifetime(l); } + } + + // Figure out if this is a type/trait segment, + // which requires object lifetime defaults. + let parent_def_id = |this: &mut Self, def_id: DefId| { + let def_key = if def_id.is_local() { + this.hir_map.def_key(def_id) + } else { + this.sess.cstore.def_key(def_id) + }; + DefId { + krate: def_id.krate, + index: def_key.parent.expect("missing parent") + } + }; + let type_def_id = match def { + Def::AssociatedTy(def_id) if depth == 1 => { + Some(parent_def_id(self, def_id)) + } + Def::Variant(def_id) if depth == 0 => { + Some(parent_def_id(self, def_id)) + } + Def::Struct(def_id) | + Def::Union(def_id) | + Def::Enum(def_id) | + Def::TyAlias(def_id) | + Def::Trait(def_id) if depth == 0 => Some(def_id), + _ => None + }; + + let object_lifetime_defaults = type_def_id.map_or(vec![], |def_id| { + let in_body = { + let mut scope = self.scope; + loop { + match *scope { + Scope::Root => break false, + + Scope::Body { .. } => break true, + + Scope::Binder { s, .. } | + Scope::Elision { s, .. } | + Scope::ObjectLifetimeDefault { s, .. } => { + scope = s; + } + } + } + }; + + let map = &self.map; + let unsubst = if let Some(id) = self.hir_map.as_local_node_id(def_id) { + &map.object_lifetime_defaults[&id] + } else { + let cstore = &self.sess.cstore; + self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| { + cstore.item_generics_object_lifetime_defaults(def_id) + }) + }; + unsubst.iter().map(|set| { + match *set { + Set1::Empty => { + if in_body { + None + } else { + Some(Region::Static) + } + } + Set1::One(r) => r.subst(&data.lifetimes, map), + Set1::Many => None + } + }).collect() + }); + + for (i, ty) in data.types.iter().enumerate() { + if let Some(<) = object_lifetime_defaults.get(i) { + let scope = Scope::ObjectLifetimeDefault { + lifetime: lt, + s: self.scope + }; + self.with(scope, |_, this| this.visit_ty(ty)); + } else { + self.visit_ty(ty); + } + } + + for b in &data.bindings { self.visit_assoc_type_binding(b); } + } + fn visit_fn_like_elision(&mut self, inputs: &'tcx [P], output: Option<&'tcx P>) { let mut arg_elide = Elide::FreshLateAnon(Cell::new(0)); @@ -962,7 +1224,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if let hir::TyBareFn(_) = ty.node { self.binder_depth += 1; } - intravisit::walk_ty(self, ty); + if let hir::TyTraitObject(ref bounds, ref lifetime) = ty.node { + for bound in bounds { + self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); + } + + // Stay on the safe side and don't include the object + // lifetime default (which may not end up being used). + if !lifetime.is_elided() { + self.visit_lifetime(lifetime); + } + } else { + intravisit::walk_ty(self, ty); + } if let hir::TyBareFn(_) = ty.node { self.binder_depth -= 1; } @@ -1045,6 +1319,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } return; } + + Scope::ObjectLifetimeDefault { s, .. } => { + scope = s; + } } }; @@ -1134,6 +1412,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + fn resolve_object_lifetime_default(&mut self, lifetime_ref: &hir::Lifetime) { + let mut late_depth = 0; + let mut scope = self.scope; + let lifetime = loop { + match *scope { + Scope::Binder { s, .. } => { + late_depth += 1; + scope = s; + } + + Scope::Root | + Scope::Elision { .. } => break Region::Static, + + Scope::Body { .. } | + Scope::ObjectLifetimeDefault { lifetime: None, .. } => return, + + Scope::ObjectLifetimeDefault { lifetime: Some(l), .. } => break l + } + }; + self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth)); + } + fn check_lifetime_defs(&mut self, old_scope: ScopeRef, lifetimes: &[hir::LifetimeDef]) { for i in 0..lifetimes.len() { let lifetime_i = &lifetimes[i]; @@ -1192,7 +1492,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { loop { match *old_scope { Scope::Body { s, .. } | - Scope::Elision { s, .. } => { + Scope::Elision { s, .. } | + Scope::ObjectLifetimeDefault { s, .. } => { old_scope = s; } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 36fc5149b40d8..6ea083b314fef 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -592,24 +592,6 @@ pub enum IntVarValue { UintType(ast::UintTy), } -/// Default region to use for the bound of objects that are -/// supplied as the value for this type parameter. This is derived -/// from `T:'a` annotations appearing in the type definition. If -/// this is `None`, then the default is inherited from the -/// surrounding context. See RFC #599 for details. -#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub enum ObjectLifetimeDefault<'tcx> { - /// Require an explicit annotation. Occurs when multiple - /// `T:'a` constraints are found. - Ambiguous, - - /// Use the base default, typically 'static, but in a fn body it is a fresh variable - BaseDefault, - - /// Use the given region as the default. - Specific(&'tcx Region), -} - #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct TypeParameterDef<'tcx> { pub name: Name, @@ -617,7 +599,6 @@ pub struct TypeParameterDef<'tcx> { pub index: u32, pub default_def_id: DefId, // for use in error reporing about defaults pub default: Option>, - pub object_lifetime_default: ObjectLifetimeDefault<'tcx>, /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute /// on generic parameter `T`, asserts data behind the parameter diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0f0478bc8cdb0..56f5dbc735de4 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -726,36 +726,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { index: self.index, default: self.default.fold_with(folder), default_def_id: self.default_def_id, - object_lifetime_default: self.object_lifetime_default.fold_with(folder), pure_wrt_drop: self.pure_wrt_drop, } } fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.default.visit_with(visitor) || - self.object_lifetime_default.visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - ty::ObjectLifetimeDefault::Ambiguous => - ty::ObjectLifetimeDefault::Ambiguous, - - ty::ObjectLifetimeDefault::BaseDefault => - ty::ObjectLifetimeDefault::BaseDefault, - - ty::ObjectLifetimeDefault::Specific(r) => - ty::ObjectLifetimeDefault::Specific(r.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ty::ObjectLifetimeDefault::Specific(r) => r.visit_with(visitor), - _ => false, - } + self.default.visit_with(visitor) } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index e90e1a94be951..0522ea90522c1 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -523,16 +523,6 @@ impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> { } } -impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"), - ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"), - ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r), - } - } -} - impl fmt::Display for ty::Region { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if verbose() { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 03b2b0114f19c..39581a4696088 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -17,6 +17,7 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, ExternC use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro}; use rustc::hir::def::{self, Def}; use rustc::middle::lang_items; +use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -115,6 +116,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).generics_own_param_counts(def.index) } + fn item_generics_object_lifetime_defaults(&self, def: DefId) + -> Vec { + self.dep_graph.read(DepNode::MetaData(def)); + self.get_crate_data(def.krate).generics_object_lifetime_defaults(def.index) + } + fn item_attrs(&self, def_id: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def_id)); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index bfc4257bda013..dd44ef202dc27 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -20,6 +20,7 @@ use rustc::middle::cstore::LinkagePreference; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::middle::lang_items; +use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; @@ -614,6 +615,12 @@ impl<'a, 'tcx> CrateMetadata { (g.regions.len, g.types.len) } + pub fn generics_object_lifetime_defaults(&self, item_id: DefIndex) + -> Vec { + self.entry(item_id).generics.unwrap().decode(self) + .object_lifetime_defaults.decode(self).collect() + } + pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { self.entry(id).ty.unwrap().decode((self, tcx)) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index c407c27b096e1..028555d1df848 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -422,6 +422,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let g = tcx.item_generics(def_id); let regions = self.lazy_seq_ref(&g.regions); let types = self.lazy_seq_ref(&g.types); + let mut object_lifetime_defaults = LazySeq::empty(); + if let Some(id) = tcx.hir.as_local_node_id(def_id) { + if let Some(o) = tcx.named_region_map.object_lifetime_defaults.get(&id) { + object_lifetime_defaults = self.lazy_seq_ref(o); + } + } self.lazy(&Generics { parent: g.parent, parent_regions: g.parent_regions, @@ -429,6 +435,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { regions: regions, types: types, has_self: g.has_self, + object_lifetime_defaults: object_lifetime_defaults, }) } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 4f9f2d23f5d3e..91375d42823fb 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -16,6 +16,7 @@ use rustc::hir::def::{self, CtorKind}; use rustc::hir::def_id::{DefIndex, DefId}; use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary}; use rustc::middle::lang_items; +use rustc::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc::mir; use rustc::ty::{self, Ty}; use rustc_back::PanicStrategy; @@ -258,6 +259,7 @@ pub struct Generics<'tcx> { pub regions: LazySeq>, pub types: LazySeq>, pub has_self: bool, + pub object_lifetime_defaults: LazySeq, } #[derive(RustcEncodable, RustcDecodable)] diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5c71947c2077e..56de539cbfe99 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -10,7 +10,7 @@ //! Conversion from AST representation of types to the ty.rs //! representation. The main routine here is `ast_ty_to_ty()`: each use -//! is parameterized by an instance of `AstConv` and a `RegionScope`. +//! is parameterized by an instance of `AstConv`. //! //! The parameterization of `ast_ty_to_ty()` is because it behaves //! somewhat differently during the collect and check phases, @@ -22,31 +22,6 @@ //! an error). In the check phase, when the FnCtxt is used as the //! `AstConv`, `get_item_type()` just looks up the item type in //! `tcx.types` (using `TyCtxt::item_type`). -//! -//! The `RegionScope` trait controls what happens when the user does -//! not specify a region in some location where a region is required -//! (e.g., if the user writes `&Foo` as a type rather than `&'a Foo`). -//! See the `rscope` module for more details. -//! -//! Unlike the `AstConv` trait, the region scope can change as we descend -//! the type. This is to accommodate the fact that (a) fn types are binding -//! scopes and (b) the default region may change. To understand case (a), -//! consider something like: -//! -//! type foo = { x: &a.int, y: |&a.int| } -//! -//! The type of `x` is an error because there is no region `a` in scope. -//! In the type of `y`, however, region `a` is considered a bound region -//! as it does not already appear in scope. -//! -//! Case (b) says that if you have a type: -//! type foo<'a> = ...; -//! type bar = fn(&foo, &a.foo) -//! The fully expanded version of type bar is: -//! type bar = fn(&'foo &, &a.foo<'a>) -//! Note that the self region for the `foo` defaulted to `&` in the first -//! case but `&a` in the second. Basically, defaults that appear inside -//! an rptr (`&r.T`) use the region `r` that appears in the rptr. use rustc_const_eval::eval_length; use rustc_data_structures::accumulate_vec::AccumulateVec; @@ -61,8 +36,6 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::wf::object_region_bounds; use rustc_back::slice; use require_c_abi_if_variadic; -use rscope::{RegionScope, ObjectLifetimeDefaultRscope, ShiftedRscope}; -use rscope::ExplicitRscope; use util::common::{ErrorReported, FN_OUTPUT_NAME}; use util::nodemap::{NodeMap, FxHashSet}; @@ -110,7 +83,7 @@ pub trait AstConv<'gcx, 'tcx> { /// What lifetime should we use when a lifetime is omitted (and not elided)? fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>) - -> &'tcx ty::Region; + -> Option<&'tcx ty::Region>; /// What type should we use when a type is omitted? fn ty_infer(&self, span: Span) -> Ty<'tcx>; @@ -220,7 +193,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // (*) -- not late-bound, won't change } - None => self.re_infer(lifetime.span, def) + None => { + self.re_infer(lifetime.span, def).expect("unelided lifetime in signature") + } }; debug!("ast_region_to_region(lifetime={:?}) yields {:?}", @@ -233,7 +208,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`, /// returns an appropriate set of substitutions for this particular reference to `I`. pub fn ast_path_substs_for_ty(&self, - rscope: &RegionScope, span: Span, def_id: DefId, item_segment: &hir::PathSegment) @@ -258,8 +232,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } let (substs, assoc_bindings) = - self.create_substs_for_ast_path(rscope, - span, + self.create_substs_for_ast_path(span, def_id, &item_segment.parameters, None); @@ -275,7 +248,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// /// Note that the type listing given here is *exactly* what the user provided. fn create_substs_for_ast_path(&self, - rscope: &RegionScope, span: Span, def_id: DefId, parameters: &hir::PathParameters, @@ -357,11 +329,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // A provided type parameter. match *parameters { hir::AngleBracketedParameters(ref data) => { - self.ast_ty_arg_to_ty(rscope, Some(def), substs, &data.types[i]) + self.ast_ty_to_ty(&data.types[i]) } hir::ParenthesizedParameters(ref data) => { assert_eq!(i, 0); - let (ty, assoc) = self.convert_parenthesized_parameters(substs, data); + let (ty, assoc) = self.convert_parenthesized_parameters(data); output_assoc_binding = Some(assoc); ty } @@ -406,7 +378,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { data.bindings.iter().map(|b| { ConvertedBinding { item_name: b.name, - ty: self.ast_ty_to_ty(rscope, &b.ty), + ty: self.ast_ty_to_ty(&b.ty), span: b.span } }).collect() @@ -415,7 +387,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { vec![output_assoc_binding.unwrap_or_else(|| { // This is an error condition, but we should // get the associated type binding anyway. - self.convert_parenthesized_parameters(substs, data).1 + self.convert_parenthesized_parameters(data).1 })] } }; @@ -427,17 +399,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn convert_parenthesized_parameters(&self, - region_substs: &[Kind<'tcx>], data: &hir::ParenthesizedParameterData) -> (Ty<'tcx>, ConvertedBinding<'tcx>) { let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| { - self.ast_ty_arg_to_ty(&ExplicitRscope, None, region_substs, a_t) + self.ast_ty_to_ty(a_t) })); let (output, output_span) = match data.output { Some(ref output_ty) => { - (self.ast_ty_to_ty(&ExplicitRscope, output_ty), output_ty.span) + (self.ast_ty_to_ty(output_ty), output_ty.span) } None => { (self.tcx().mk_nil(), data.span) @@ -460,14 +431,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// If the `projections` argument is `None`, then assoc type bindings like `Foo` /// are disallowed. Otherwise, they are pushed onto the vector given. pub fn instantiate_mono_trait_ref(&self, - rscope: &RegionScope, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { let trait_def_id = self.trait_def_id(trait_ref); - self.ast_path_to_mono_trait_ref(rscope, - trait_ref.path.span, + self.ast_path_to_mono_trait_ref(trait_ref.path.span, trait_def_id, self_ty, trait_ref.path.segments.last().unwrap()) @@ -488,7 +457,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } pub fn instantiate_poly_trait_ref(&self, - rscope: &RegionScope, ast_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, poly_projections: &mut Vec>) @@ -498,16 +466,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let trait_def_id = self.trait_def_id(trait_ref); debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); - // The trait reference introduces a binding level here, so - // we need to shift the `rscope`. It'd be nice if we could - // do away with this rscope stuff and work this knowledge - // into resolve_lifetimes, as we do with non-omitted - // lifetimes. Oh well, not there yet. - let shifted_rscope = &ShiftedRscope::new(rscope); let (substs, assoc_bindings) = - self.create_substs_for_ast_trait_ref(shifted_rscope, - trait_ref.path.span, + self.create_substs_for_ast_trait_ref(trait_ref.path.span, trait_def_id, self_ty, trait_ref.path.segments.last().unwrap()); @@ -528,7 +489,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn ast_path_to_mono_trait_ref(&self, - rscope: &RegionScope, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, @@ -536,8 +496,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { -> ty::TraitRef<'tcx> { let (substs, assoc_bindings) = - self.create_substs_for_ast_trait_ref(rscope, - span, + self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, trait_segment); @@ -546,7 +505,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn create_substs_for_ast_trait_ref(&self, - rscope: &RegionScope, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, @@ -590,8 +548,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } - self.create_substs_for_ast_path(rscope, - span, + self.create_substs_for_ast_path(span, trait_def_id, &trait_segment.parameters, Some(self_ty)) @@ -700,7 +657,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn ast_path_to_ty(&self, - rscope: &RegionScope, span: Span, did: DefId, item_segment: &hir::PathSegment) @@ -714,8 +670,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } }; - let substs = self.ast_path_substs_for_ty(rscope, - span, + let substs = self.ast_path_substs_for_ty(span, did, item_segment); @@ -737,7 +692,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn conv_object_ty_poly_trait_ref(&self, - rscope: &RegionScope, span: Span, trait_bounds: &[hir::PolyTraitRef], lifetime: &hir::Lifetime) @@ -753,8 +707,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let mut projection_bounds = vec![]; let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); - let principal = self.instantiate_poly_trait_ref(rscope, - &trait_bounds[0], + let principal = self.instantiate_poly_trait_ref(&trait_bounds[0], dummy_self, &mut projection_bounds); @@ -839,15 +792,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.ast_region_to_region(lifetime, None) } else { self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| { - tcx.mk_region(match rscope.object_lifetime_default(span) { - Some(r) => r, - None => { - span_err!(self.tcx().sess, span, E0228, + if tcx.named_region_map.defs.contains_key(&lifetime.id) { + self.ast_region_to_region(lifetime, None) + } else { + self.re_infer(span, None).unwrap_or_else(|| { + span_err!(tcx.sess, span, E0228, "the lifetime bound for this object type cannot be deduced \ from context; please supply an explicit bound"); - ty::ReStatic - } - }) + tcx.mk_region(ty::ReStatic) + }) + } }) }; @@ -1059,7 +1013,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } fn qpath_to_ty(&self, - rscope: &RegionScope, span: Span, opt_self_ty: Option>, trait_def_id: DefId, @@ -1084,8 +1037,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { debug!("qpath_to_ty: self_type={:?}", self_ty); - let trait_ref = self.ast_path_to_mono_trait_ref(rscope, - span, + let trait_ref = self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment); @@ -1095,38 +1047,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { self.projected_ty(span, trait_ref, item_segment.name) } - /// Convert a type supplied as value for a type argument from AST into our - /// our internal representation. This is the same as `ast_ty_to_ty` but that - /// it applies the object lifetime default. - /// - /// # Parameters - /// - /// * `this`, `rscope`: the surrounding context - /// * `def`: the type parameter being instantiated (if available) - /// * `region_substs`: a partial substitution consisting of - /// only the region type parameters being supplied to this type. - /// * `ast_ty`: the ast representation of the type being supplied - fn ast_ty_arg_to_ty(&self, - rscope: &RegionScope, - def: Option<&ty::TypeParameterDef<'tcx>>, - region_substs: &[Kind<'tcx>], - ast_ty: &hir::Ty) - -> Ty<'tcx> - { - let tcx = self.tcx(); - - if let Some(def) = def { - let object_lifetime_default = def.object_lifetime_default.subst(tcx, region_substs); - let rscope1 = &ObjectLifetimeDefaultRscope::new(rscope, object_lifetime_default); - self.ast_ty_to_ty(rscope1, ast_ty) - } else { - self.ast_ty_to_ty(rscope, ast_ty) - } - } - // Check a type Path and convert it to a Ty. pub fn def_to_ty(&self, - rscope: &RegionScope, opt_self_ty: Option>, path: &hir::Path, permit_variants: bool) @@ -1141,15 +1063,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => { assert_eq!(opt_self_ty, None); tcx.prohibit_type_params(path.segments.split_last().unwrap().1); - self.ast_path_to_ty(rscope, span, did, path.segments.last().unwrap()) + self.ast_path_to_ty(span, did, path.segments.last().unwrap()) } Def::Variant(did) if permit_variants => { // Convert "variant type" as if it were a real type. // The resulting `Ty` is type of the variant's enum for now. assert_eq!(opt_self_ty, None); tcx.prohibit_type_params(path.segments.split_last().unwrap().1); - self.ast_path_to_ty(rscope, - span, + self.ast_path_to_ty(span, tcx.parent_def_id(did).unwrap(), path.segments.last().unwrap()) } @@ -1207,8 +1128,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::AssociatedTy(def_id) => { tcx.prohibit_type_params(&path.segments[..path.segments.len()-2]); let trait_did = tcx.parent_def_id(def_id).unwrap(); - self.qpath_to_ty(rscope, - span, + self.qpath_to_ty(span, opt_self_ty, trait_did, &path.segments[path.segments.len()-2], @@ -1228,7 +1148,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { /// Parses the programmer's textual representation of a type into our /// internal notion of a type. - pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> { + pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})", ast_ty.id, ast_ty); @@ -1241,29 +1161,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let result_ty = match ast_ty.node { hir::TySlice(ref ty) => { - tcx.mk_slice(self.ast_ty_to_ty(rscope, &ty)) + tcx.mk_slice(self.ast_ty_to_ty(&ty)) } hir::TyPtr(ref mt) => { tcx.mk_ptr(ty::TypeAndMut { - ty: self.ast_ty_to_ty(rscope, &mt.ty), + ty: self.ast_ty_to_ty(&mt.ty), mutbl: mt.mutbl }) } hir::TyRptr(ref region, ref mt) => { let r = self.ast_region_to_region(region, None); debug!("TyRef r={:?}", r); - let rscope1 = - &ObjectLifetimeDefaultRscope::new( - rscope, - ty::ObjectLifetimeDefault::Specific(r)); - let t = self.ast_ty_to_ty(rscope1, &mt.ty); + let t = self.ast_ty_to_ty(&mt.ty); tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl}) } hir::TyNever => { tcx.types.never }, hir::TyTup(ref fields) => { - tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(rscope, &t))) + tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t))) } hir::TyBareFn(ref bf) => { require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); @@ -1309,7 +1225,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.mk_fn_ptr(bare_fn_ty) } hir::TyTraitObject(ref bounds, ref lifetime) => { - self.conv_object_ty_poly_trait_ref(rscope, ast_ty.span, bounds, lifetime) + self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime) } hir::TyImplTrait(ref bounds) => { use collect::{compute_bounds, SizedByDefault}; @@ -1381,13 +1297,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => { debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path); let opt_self_ty = maybe_qself.as_ref().map(|qself| { - self.ast_ty_to_ty(rscope, qself) + self.ast_ty_to_ty(qself) }); - self.def_to_ty(rscope, opt_self_ty, path, false) + self.def_to_ty(opt_self_ty, path, false) } hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); - let ty = self.ast_ty_to_ty(rscope, qself); + let ty = self.ast_ty_to_ty(qself); let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node { path.def @@ -1398,7 +1314,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::TyArray(ref ty, length) => { if let Ok(length) = eval_length(tcx.global_tcx(), length, "array length") { - tcx.mk_array(self.ast_ty_to_ty(rscope, &ty), length) + tcx.mk_array(self.ast_ty_to_ty(&ty), length) } else { self.tcx().types.err } @@ -1426,7 +1342,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } pub fn ty_of_arg(&self, - rscope: &RegionScope, ty: &hir::Ty, expected_ty: Option>) -> Ty<'tcx> @@ -1434,7 +1349,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { match ty.node { hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(), hir::TyInfer => self.ty_infer(ty.span), - _ => self.ast_ty_to_ty(rscope, ty), + _ => self.ast_ty_to_ty(ty), } } @@ -1446,10 +1361,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { debug!("ty_of_fn"); let input_tys: Vec = - decl.inputs.iter().map(|a| self.ty_of_arg(&ExplicitRscope, a, None)).collect(); + decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect(); let output_ty = match decl.output { - hir::Return(ref output) => self.ast_ty_to_ty(&ExplicitRscope, output), + hir::Return(ref output) => self.ast_ty_to_ty(output), hir::DefaultReturn(..) => self.tcx().mk_nil(), }; @@ -1486,7 +1401,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { None } }); - self.ty_of_arg(&ExplicitRscope, a, expected_arg_ty) + self.ty_of_arg(a, expected_arg_ty) }); let expected_ret_ty = expected_sig.as_ref().map(|e| e.output()); @@ -1502,7 +1417,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { expected_ret_ty.unwrap(), _ if is_infer => self.ty_infer(decl.output.span()), hir::Return(ref output) => - self.ast_ty_to_ty(&ExplicitRscope, &output), + self.ast_ty_to_ty(&output), hir::DefaultReturn(..) => bug!(), }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4d1b2cec32e5f..c2f32c2b52bbe 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,6 @@ use rustc::ty::adjustment; use rustc::ty::fold::{BottomUpFolder, TypeFoldable}; use rustc::ty::util::{Representability, IntTypeExt}; use require_c_abi_if_variadic; -use rscope::RegionScope; use session::{Session, CompileResult}; use CrateCtxt; use TypeAndSubsts; @@ -1411,12 +1410,12 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { } fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>) - -> &'tcx ty::Region { + -> Option<&'tcx ty::Region> { let v = match def { Some(def) => infer::EarlyBoundRegion(span, def.name), None => infer::MiscVariable(span) }; - self.next_region_var(v) + Some(self.next_region_var(v)) } fn ty_infer(&self, span: Span) -> Ty<'tcx> { @@ -1459,23 +1458,6 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> RegionScope for FnCtxt<'a, 'gcx, 'tcx> { - fn object_lifetime_default(&self, span: Span) -> Option { - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, span: Span) -> ty::Region { - // RFC #599 specifies that object lifetime defaults take - // precedence over other defaults. But within a fn body we - // don't have a *default* region, rather we use inference to - // find the *correct* region, which is strictly more general - // (and anyway, within a fn body the right region may not even - // be something the user can write explicitly, since it might - // be some expression). - *self.next_region_var(infer::MiscVariable(span)) - } -} - /// Controls whether the arguments are tupled. This is used for the call /// operator. /// @@ -1832,7 +1814,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> { - let t = AstConv::ast_ty_to_ty(self, self, ast_t); + let t = AstConv::ast_ty_to_ty(self, ast_t); self.register_wf_obligation(t, ast_t.span, traits::MiscObligation); t } @@ -3976,7 +3958,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match *qpath { hir::QPath::Resolved(ref maybe_qself, ref path) => { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself)); - let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, true); + let ty = AstConv::def_to_ty(self, opt_self_ty, path, true); (path.def, ty) } hir::QPath::TypeRelative(ref qself, ref segment) => { @@ -4411,7 +4393,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(lifetime) = lifetimes.get(i) { AstConv::ast_region_to_region(self, lifetime, Some(def)) } else { - self.re_infer(span, Some(def)) + self.re_infer(span, Some(def)).unwrap() } }, |def, substs| { let mut i = def.index as usize; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 90e2f821b10b5..6f0825a25f947 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -68,10 +68,9 @@ use rustc::ty::subst::Substs; use rustc::ty::{ToPredicate, ImplContainer, AssociatedItemContainer, TraitContainer}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::util::IntTypeExt; -use rscope::*; use rustc::dep_graph::DepNode; use util::common::{ErrorReported, MemoizationMap}; -use util::nodemap::{NodeMap, FxHashMap, FxHashSet}; +use util::nodemap::{NodeMap, FxHashMap}; use CrateCtxt; use rustc_const_math::ConstInt; @@ -373,8 +372,8 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { } impl<'a,'tcx> ItemCtxt<'a,'tcx> { - fn to_ty(&self, rs: &RS, ast_ty: &hir::Ty) -> Ty<'tcx> { - AstConv::ast_ty_to_ty(self, rs, ast_ty) + fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { + AstConv::ast_ty_to_ty(self, ast_ty) } } @@ -437,9 +436,9 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { None } - fn re_infer(&self, span: Span, _def: Option<&ty::RegionParameterDef>) - -> &'tcx ty::Region { - span_bug!(span, "unelided lifetime in signature"); + fn re_infer(&self, _span: Span, _def: Option<&ty::RegionParameterDef>) + -> Option<&'tcx ty::Region> { + None } fn ty_infer(&self, span: Span) -> Ty<'tcx> { @@ -631,7 +630,7 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, field: &hir::StructField, ty_f: &'tcx ty::FieldDef) { - let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty); + let tt = ccx.icx(struct_predicates).to_ty(&field.ty); ccx.tcx.item_types.borrow_mut().insert(ty_f.did, tt); let def_id = ccx.tcx.hir.local_def_id(field.id); @@ -757,7 +756,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { hir::ItemDefaultImpl(_, ref ast_trait_ref) => { let trait_ref = AstConv::instantiate_mono_trait_ref(&ccx.icx(&()), - &ExplicitRscope, ast_trait_ref, tcx.mk_self_type()); @@ -779,12 +777,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { debug!("convert: impl_bounds={:?}", ty_predicates); - let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &selfty); + let selfty = ccx.icx(&ty_predicates).to_ty(&selfty); tcx.item_types.borrow_mut().insert(def_id, selfty); let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| { AstConv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates), - &ExplicitRscope, ast_trait_ref, selfty) }); @@ -850,8 +847,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { hir::TraitItemKind::Const(ref ty, _) => { let const_def_id = ccx.tcx.hir.local_def_id(trait_item.id); generics_of_def_id(ccx, const_def_id); - let ty = ccx.icx(&trait_predicates) - .to_ty(&ExplicitRscope, &ty); + let ty = ccx.icx(&trait_predicates).to_ty(&ty); tcx.item_types.borrow_mut().insert(const_def_id, ty); convert_associated_const(ccx, TraitContainer(trait_def_id), trait_item.id, ty); @@ -862,7 +858,7 @@ fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { generics_of_def_id(ccx, type_def_id); let typ = opt_ty.as_ref().map({ - |ty| ccx.icx(&trait_predicates).to_ty(&ExplicitRscope, &ty) + |ty| ccx.icx(&trait_predicates).to_ty(&ty) }); convert_associated_type(ccx, TraitContainer(trait_def_id), trait_item.id, typ); @@ -887,8 +883,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { hir::ImplItemKind::Const(ref ty, _) => { let const_def_id = ccx.tcx.hir.local_def_id(impl_item.id); generics_of_def_id(ccx, const_def_id); - let ty = ccx.icx(&impl_predicates) - .to_ty(&ExplicitRscope, &ty); + let ty = ccx.icx(&impl_predicates).to_ty(&ty); tcx.item_types.borrow_mut().insert(const_def_id, ty); convert_associated_const(ccx, ImplContainer(impl_def_id), impl_item.id, ty); @@ -903,7 +898,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { "associated types are not allowed in inherent impls"); } - let typ = ccx.icx(&impl_predicates).to_ty(&ExplicitRscope, ty); + let typ = ccx.icx(&impl_predicates).to_ty(ty); convert_associated_type(ccx, ImplContainer(impl_def_id), impl_item.id, Some(typ)); } @@ -1410,7 +1405,6 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: tcx.hir.local_def_id(param_id), default_def_id: tcx.hir.local_def_id(parent), default: None, - object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault, pure_wrt_drop: false, }; tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone()); @@ -1463,7 +1457,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let type_start = own_start + regions.len() as u32; let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| { let i = type_start + i as u32; - get_or_create_type_parameter_def(ccx, ast_generics, i, p, allow_defaults) + get_or_create_type_parameter_def(ccx, i, p, allow_defaults) }); let mut types: Vec<_> = opt_self.into_iter().chain(types).collect(); @@ -1478,24 +1472,11 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, def_id: def_id, default_def_id: parent_def_id.unwrap(), default: None, - object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault, pure_wrt_drop: false, })); }); } - // Debugging aid. - if tcx.has_attr(def_id, "rustc_object_lifetime_default") { - let object_lifetime_default_reprs: String = - types.iter().map(|t| { - match t.object_lifetime_default { - ty::ObjectLifetimeDefault::Specific(r) => r.to_string(), - d => format!("{:?}", d), - } - }).collect::>().join(","); - tcx.sess.span_err(tcx.hir.span(node_id), &object_lifetime_default_reprs); - } - tcx.alloc_generics(ty::Generics { parent: parent_def_id, parent_regions: parent_regions, @@ -1526,7 +1507,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, NodeItem(item) => { match item.node { ItemStatic(ref t, ..) | ItemConst(ref t, _) => { - ccx.icx(&()).to_ty(&ExplicitRscope, &t) + ccx.icx(&()).to_ty(&t) } ItemFn(ref decl, unsafety, _, abi, ref generics, _) => { let tofd = AstConv::ty_of_fn(&ccx.icx(generics), unsafety, abi, &decl); @@ -1534,7 +1515,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.mk_fn_def(def_id, substs, tofd) } ItemTy(ref t, ref generics) => { - ccx.icx(generics).to_ty(&ExplicitRscope, &t) + ccx.icx(generics).to_ty(&t) } ItemEnum(ref ei, ref generics) => { let def = convert_enum_def(ccx, item, ei); @@ -1575,7 +1556,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, fn_decl, generics, abi) } ForeignItemStatic(ref t, _) => { - ccx.icx(&()).to_ty(&ExplicitRscope, t) + ccx.icx(&()).to_ty(t) } } } @@ -1771,7 +1752,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, match predicate { &hir::WherePredicate::BoundPredicate(ref bound_pred) => { let ty = AstConv::ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)), - &ExplicitRscope, &bound_pred.bounded_ty); for bound in bound_pred.bounds.iter() { @@ -1782,7 +1762,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let trait_ref = AstConv::instantiate_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)), - &ExplicitRscope, poly_trait_ref, ty, &mut projections); @@ -1827,7 +1806,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - ast_generics: &hir::Generics, index: u32, param: &hir::TyParam, allow_defaults: bool) @@ -1840,11 +1818,7 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } let default = - param.default.as_ref().map(|def| ccx.icx(&()).to_ty(&ExplicitRscope, def)); - - let object_lifetime_default = - compute_object_lifetime_default(ccx, param.id, - ¶m.bounds, &ast_generics.where_clause); + param.default.as_ref().map(|def| ccx.icx(&()).to_ty(def)); let parent = tcx.hir.get_parent(param.id); @@ -1865,7 +1839,6 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, def_id: ccx.tcx.hir.local_def_id(param.id), default_def_id: ccx.tcx.hir.local_def_id(parent), default: default, - object_lifetime_default: object_lifetime_default, pure_wrt_drop: param.pure_wrt_drop, }; @@ -1880,75 +1853,6 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, def } -/// Scan the bounds and where-clauses on a parameter to extract bounds -/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`. -/// This runs as part of computing the minimal type scheme, so we -/// intentionally avoid just asking astconv to convert all the where -/// clauses into a `ty::Predicate`. This is because that could induce -/// artificial cycles. -fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - param_id: ast::NodeId, - param_bounds: &[hir::TyParamBound], - where_clause: &hir::WhereClause) - -> ty::ObjectLifetimeDefault<'tcx> -{ - let inline_bounds = from_bounds(ccx, param_bounds); - let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates); - let all_bounds: FxHashSet<_> = inline_bounds.into_iter() - .chain(where_bounds) - .collect(); - return if all_bounds.len() > 1 { - ty::ObjectLifetimeDefault::Ambiguous - } else if all_bounds.len() == 0 { - ty::ObjectLifetimeDefault::BaseDefault - } else { - ty::ObjectLifetimeDefault::Specific( - all_bounds.into_iter().next().unwrap()) - }; - - fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - bounds: &[hir::TyParamBound]) - -> Vec<&'tcx ty::Region> - { - bounds.iter() - .filter_map(|bound| { - match *bound { - hir::TraitTyParamBound(..) => - None, - hir::RegionTyParamBound(ref lifetime) => - Some(AstConv::ast_region_to_region(&ccx.icx(&()), lifetime, None)), - } - }) - .collect() - } - - fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - param_id: ast::NodeId, - predicates: &[hir::WherePredicate]) - -> Vec<&'tcx ty::Region> - { - predicates.iter() - .flat_map(|predicate| { - match *predicate { - hir::WherePredicate::BoundPredicate(ref data) => { - if data.bound_lifetimes.is_empty() && - is_param(ccx.tcx, &data.bounded_ty, param_id) - { - from_bounds(ccx, &data.bounds).into_iter() - } else { - Vec::new().into_iter() - } - } - hir::WherePredicate::RegionPredicate(..) | - hir::WherePredicate::EqPredicate(..) => { - Vec::new().into_iter() - } - } - }) - .collect() - } -} - pub enum SizedByDefault { Yes, No, } /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or @@ -1978,8 +1882,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, let mut projection_bounds = vec![]; let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - astconv.instantiate_poly_trait_ref(&ExplicitRscope, - bound, + astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds) }).collect(); @@ -2017,8 +1920,7 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, match *bound { hir::TraitTyParamBound(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); - let pred = astconv.instantiate_poly_trait_ref(&ExplicitRscope, - tr, + let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); projections.into_iter() diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 90ce77cc5f4bc..4ed116b88f6d9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -127,7 +127,6 @@ pub mod diagnostics; pub mod check; pub mod check_unused; -mod rscope; mod astconv; pub mod collect; mod constrained_type_params; diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs deleted file mode 100644 index d982c91e388d1..0000000000000 --- a/src/librustc_typeck/rscope.rs +++ /dev/null @@ -1,113 +0,0 @@ -// 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. - -use rustc::ty; - -use syntax_pos::Span; - -/// Defines strategies for handling regions that are omitted. For -/// example, if one writes the type `&Foo`, then the lifetime of -/// this reference has been omitted. When converting this -/// type, the generic functions in astconv will invoke `anon_region` -/// on the provided region-scope to decide how to translate this -/// omitted region. -/// -/// It is not always legal to omit regions, therefore `anon_region` -/// can return `Err(())` to indicate that this is not a scope in which -/// regions can legally be omitted. -pub trait RegionScope { - /// If an object omits any explicit lifetime bound, and none can - /// be derived from the object traits, what should we use? If - /// `None` is returned, an explicit annotation is required. - fn object_lifetime_default(&self, span: Span) -> Option; - - /// The "base" default is the initial default for a scope. This is - /// 'static except for in fn bodies, where it is a fresh inference - /// variable. You shouldn't call this except for as part of - /// computing `object_lifetime_default` (in particular, in legacy - /// modes, it may not be relevant). - fn base_object_lifetime_default(&self, span: Span) -> ty::Region; -} - -// A scope in which all regions must be explicitly named. This is used -// for types that appear in structs and so on. -#[derive(Copy, Clone)] -pub struct ExplicitRscope; - -impl RegionScope for ExplicitRscope { - fn object_lifetime_default(&self, span: Span) -> Option { - Some(self.base_object_lifetime_default(span)) - } - - fn base_object_lifetime_default(&self, _span: Span) -> ty::Region { - ty::ReStatic - } -} - -/// A scope which overrides the default object lifetime but has no other effect. -pub struct ObjectLifetimeDefaultRscope<'r> { - base_scope: &'r (RegionScope+'r), - default: ty::ObjectLifetimeDefault<'r>, -} - -impl<'r> ObjectLifetimeDefaultRscope<'r> { - pub fn new(base_scope: &'r (RegionScope+'r), - default: ty::ObjectLifetimeDefault<'r>) - -> ObjectLifetimeDefaultRscope<'r> - { - ObjectLifetimeDefaultRscope { - base_scope: base_scope, - default: default, - } - } -} - -impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { - fn object_lifetime_default(&self, span: Span) -> Option { - match self.default { - ty::ObjectLifetimeDefault::Ambiguous => - None, - - ty::ObjectLifetimeDefault::BaseDefault => - // NB: This behavior changed in Rust 1.3. - Some(self.base_object_lifetime_default(span)), - - ty::ObjectLifetimeDefault::Specific(r) => - Some(*r), - } - } - - fn base_object_lifetime_default(&self, span: Span) -> ty::Region { - self.base_scope.base_object_lifetime_default(span) - } -} - -/// A scope which simply shifts the Debruijn index of other scopes -/// to account for binding levels. -pub struct ShiftedRscope<'r> { - base_scope: &'r (RegionScope+'r) -} - -impl<'r> ShiftedRscope<'r> { - pub fn new(base_scope: &'r (RegionScope+'r)) -> ShiftedRscope<'r> { - ShiftedRscope { base_scope: base_scope } - } -} - -impl<'r> RegionScope for ShiftedRscope<'r> { - fn object_lifetime_default(&self, span: Span) -> Option { - self.base_scope.object_lifetime_default(span) - .map(|r| ty::fold::shift_region(r, 1)) - } - - fn base_object_lifetime_default(&self, span: Span) -> ty::Region { - ty::fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1) - } -} diff --git a/src/test/run-pass/object-lifetime-default-from-ref-struct.rs b/src/test/run-pass/object-lifetime-default-from-ref-struct.rs index 910d933d46f08..6aaf892097136 100644 --- a/src/test/run-pass/object-lifetime-default-from-ref-struct.rs +++ b/src/test/run-pass/object-lifetime-default-from-ref-struct.rs @@ -15,6 +15,8 @@ #![allow(dead_code)] +use std::fmt::Display; + trait Test { fn foo(&self) { } } @@ -23,6 +25,11 @@ struct Ref<'a,T:'a+?Sized> { r: &'a T } +struct Ref2<'a,'b,T:'a+'b+?Sized> { + a: &'a T, + b: &'b T +} + struct SomeStruct<'a> { t: Ref<'a,Test>, u: Ref<'a,Test+'a>, @@ -44,6 +51,17 @@ fn d<'a>(t: Ref<'a,Test+'a>, mut ss: SomeStruct<'a>) { ss.u = t; } +fn e<'a>(_: Ref<'a, Display+'static>) {} +fn g<'a, 'b>(_: Ref2<'a, 'b, Display+'static>) {} + fn main() { + // Inside a function body, we can just infer all + // lifetimes, to allow Ref<'tmp, Display+'static> + // and Ref2<'tmp, 'tmp, Display+'static>. + let x = &0 as &(Display+'static); + let r: Ref = Ref { r: x }; + let r2: Ref2 = Ref2 { a: x, b: x }; + e(r); + g(r2); } diff --git a/src/test/run-pass/object-lifetime-default-from-rptr.rs b/src/test/run-pass/object-lifetime-default-from-rptr.rs index d9e0b22fbfa4b..cbff0d4dbaa3c 100644 --- a/src/test/run-pass/object-lifetime-default-from-rptr.rs +++ b/src/test/run-pass/object-lifetime-default-from-rptr.rs @@ -15,6 +15,8 @@ #![allow(dead_code)] +use std::fmt::Display; + trait Test { fn foo(&self) { } } @@ -40,6 +42,10 @@ fn d<'a>(t: &'a (Test+'a), mut ss: SomeStruct<'a>) { ss.u = t; } +fn e<'a>(_: &'a (Display+'static)) {} fn main() { + // Inside a function body, we can just infer both + // lifetimes, to allow &'tmp (Display+'static). + e(&0 as &Display); } From 9a0af1638a2e91f6979c10e4d4b37159ed5bf951 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 25 Jan 2017 18:39:21 +0200 Subject: [PATCH 65/86] rustc: remove unused `bounds` field from `RegionParameterDef`. --- src/librustc/ty/mod.rs | 11 +++++------ src/librustc/ty/structural_impls.rs | 18 +----------------- src/librustc/util/ppaux.rs | 7 +++---- src/librustc_metadata/schema.rs | 2 +- src/librustc_typeck/collect.rs | 3 --- src/librustdoc/clean/mod.rs | 9 ++------- 6 files changed, 12 insertions(+), 38 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 6ea083b314fef..cc813d0bf831e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -606,12 +606,11 @@ pub struct TypeParameterDef<'tcx> { pub pure_wrt_drop: bool, } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct RegionParameterDef<'tcx> { +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] +pub struct RegionParameterDef { pub name: Name, pub def_id: DefId, pub index: u32, - pub bounds: Vec<&'tcx ty::Region>, /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute /// on generic parameter `'a`, asserts data of lifetime `'a` @@ -619,7 +618,7 @@ pub struct RegionParameterDef<'tcx> { pub pure_wrt_drop: bool, } -impl<'tcx> RegionParameterDef<'tcx> { +impl RegionParameterDef { pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion { ty::EarlyBoundRegion { index: self.index, @@ -640,7 +639,7 @@ pub struct Generics<'tcx> { pub parent: Option, pub parent_regions: u32, pub parent_types: u32, - pub regions: Vec>, + pub regions: Vec, pub types: Vec>, pub has_self: bool, } @@ -658,7 +657,7 @@ impl<'tcx> Generics<'tcx> { self.parent_count() + self.own_count() } - pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef<'tcx> { + pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef { &self.regions[param.index as usize - self.has_self as usize] } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 56f5dbc735de4..06ba1b2a1fafc 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -353,7 +353,7 @@ macro_rules! CopyImpls { } } -CopyImpls! { (), hir::Unsafety, abi::Abi } +CopyImpls! { (), hir::Unsafety, abi::Abi, ty::RegionParameterDef } impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) { @@ -735,22 +735,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::RegionParameterDef { - name: self.name, - def_id: self.def_id, - index: self.index, - bounds: self.bounds.fold_with(folder), - pure_wrt_drop: self.pure_wrt_drop, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.bounds.visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::Generics { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0522ea90522c1..74e27f84fddc2 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -336,13 +336,12 @@ impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> { } } -impl<'tcx> fmt::Debug for ty::RegionParameterDef<'tcx> { +impl fmt::Debug for ty::RegionParameterDef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "RegionParameterDef({}, {:?}, {}, {:?})", + write!(f, "RegionParameterDef({}, {:?}, {})", self.name, self.def_id, - self.index, - self.bounds) + self.index) } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 91375d42823fb..d9c639f2bc573 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -256,7 +256,7 @@ pub struct Generics<'tcx> { pub parent: Option, pub parent_regions: u32, pub parent_types: u32, - pub regions: LazySeq>, + pub regions: LazySeq, pub types: LazySeq>, pub has_self: bool, pub object_lifetime_defaults: LazySeq, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 6f0825a25f947..bbd0c8058151f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1446,9 +1446,6 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, name: l.lifetime.name, index: own_start + i as u32, def_id: tcx.hir.local_def_id(l.lifetime.id), - bounds: l.bounds.iter().map(|l| { - AstConv::ast_region_to_region(&ccx.icx(&()), l, None) - }).collect(), pure_wrt_drop: l.pure_wrt_drop, } }).collect::>(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f1ced233dde7b..7591475c5d3fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -794,7 +794,7 @@ impl Clean for hir::LifetimeDef { } } -impl<'tcx> Clean for ty::RegionParameterDef<'tcx> { +impl Clean for ty::RegionParameterDef { fn clean(&self, _: &DocContext) -> Lifetime { Lifetime(self.name.to_string()) } @@ -970,11 +970,6 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, Some(tp.clean(cx)) } }).collect::>(); - let stripped_lifetimes = gens.regions.iter().map(|rp| { - let mut srp = rp.clone(); - srp.bounds = Vec::new(); - srp.clean(cx) - }).collect::>(); let mut where_predicates = preds.predicates.to_vec().clean(cx); @@ -1017,7 +1012,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, Generics { type_params: simplify::ty_params(stripped_typarams), - lifetimes: stripped_lifetimes, + lifetimes: gens.regions.clean(cx), where_predicates: simplify::where_clauses(cx, where_predicates), } } From c0e474d9a6d11518e602b7e20ccf2bf36725f0ad Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 27 Jan 2017 19:03:59 +0200 Subject: [PATCH 66/86] test: add missing lifetime in recently added test. --- src/test/compile-fail/where-equality-constraints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/where-equality-constraints.rs b/src/test/compile-fail/where-equality-constraints.rs index 5b2fe2901c4ce..e449a736c753a 100644 --- a/src/test/compile-fail/where-equality-constraints.rs +++ b/src/test/compile-fail/where-equality-constraints.rs @@ -10,7 +10,7 @@ fn f() where u8 = u16 {} //~^ ERROR equality constraints are not yet supported in where clauses -fn g() where for<'a> &(u8,) == u16, {} +fn g() where for<'a> &'static (u8,) == u16, {} //~^ ERROR equality constraints are not yet supported in where clauses fn main() {} From 15411fb0fafc65719ea8ce0f1a479a5df19a090a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Sat, 28 Jan 2017 17:00:43 +0300 Subject: [PATCH 67/86] Fix typos in libsyntax/tokenstream.rs --- src/libsyntax/tokenstream.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index ab5dc8181e05b..0ca0538c03a3d 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -17,7 +17,7 @@ //! expansion). //! //! ## Ownership -//! TokenStreams are persistant data structures construced as ropes with reference +//! TokenStreams are persistent data structures constructed as ropes with reference //! counted-children. In general, this means that calling an operation on a TokenStream //! (such as `slice`) produces an entirely new TokenStream from the borrowed reference to //! the original. This essentially coerces TokenStreams into 'views' of their subparts, From ab21314c3fbf093c92123abee62101d15846c1e2 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sat, 28 Jan 2017 21:52:31 +0200 Subject: [PATCH 68/86] Disable backtrace tests on i686-pc-windows-gnu since it's broken by FPO --- src/test/run-pass/backtrace-debuginfo.rs | 1 + src/test/run-pass/backtrace.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 626eccfc9ec86..015ba75d432ad 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -37,6 +37,7 @@ macro_rules! dump_and_die { target_os = "ios", target_os = "android", all(target_os = "linux", target_arch = "arm"), + all(target_os = "windows", target_pointer_width = "32"), target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 834ce984e6632..e892f5e7728b3 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -104,6 +104,10 @@ fn runtest(me: &str) { } fn main() { + if cfg!(windows) && cfg!(target_env = "gnu") && cfg!(target_pointer_width = "32") { + return + } + let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "fail" { foo(); From 339bdc158f37e3c9073c29d59de06899c93a1c90 Mon Sep 17 00:00:00 2001 From: Denis Andrejew Date: Sat, 28 Jan 2017 22:16:16 +0000 Subject: [PATCH 69/86] Fix typo in liballoc/lib.rs --- src/liballoc/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index c67106cf57aaf..0c01eabd593ff 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -47,7 +47,7 @@ //! that the contained type `T` is shareable. Additionally, `Arc` is itself //! sendable while `Rc` is not. //! -//! This types allows for shared access to the contained data, and is often +//! This type allows for shared access to the contained data, and is often //! paired with synchronization primitives such as mutexes to allow mutation of //! shared resources. //! From 7e73884941b64625417faa20135d84c68b07c18a Mon Sep 17 00:00:00 2001 From: Caleb Reach Date: Sat, 28 Jan 2017 23:01:22 -0500 Subject: [PATCH 70/86] Fix typo in librustc_trans/collector.rs --- src/librustc_trans/collector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index d30766dc5392a..fa8bad5807aaf 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -52,7 +52,7 @@ //! the LLVM artifact produced for A references the LLVM artifact produced //! for B. //! -//! - Translation items and the references between them for a directed graph, +//! - Translation items and the references between them form a directed graph, //! where the translation items are the nodes and references form the edges. //! Let's call this graph the "translation item graph". //! From 3f1d3948d6d434b34dd47f132c126a6cb6b8a4ab Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sat, 28 Jan 2017 21:54:59 +0200 Subject: [PATCH 71/86] Fix backtraces on i686-pc-windows-gnu by disabling FPO This might have performance implications. But do note that MSVC disables FPO by default nowadays and it's use is limited in exception heavy languages like C++. Closes: #28218 --- src/librustc_back/target/i686_pc_windows_gnu.rs | 1 + src/test/run-pass/backtrace-debuginfo.rs | 1 - src/test/run-pass/backtrace.rs | 4 ---- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_back/target/i686_pc_windows_gnu.rs b/src/librustc_back/target/i686_pc_windows_gnu.rs index 0c2c5433e6c41..2947726139207 100644 --- a/src/librustc_back/target/i686_pc_windows_gnu.rs +++ b/src/librustc_back/target/i686_pc_windows_gnu.rs @@ -14,6 +14,7 @@ pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); + base.eliminate_frame_pointer = false; // Required for backtraces // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 015ba75d432ad..626eccfc9ec86 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -37,7 +37,6 @@ macro_rules! dump_and_die { target_os = "ios", target_os = "android", all(target_os = "linux", target_arch = "arm"), - all(target_os = "windows", target_pointer_width = "32"), target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index e892f5e7728b3..834ce984e6632 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -104,10 +104,6 @@ fn runtest(me: &str) { } fn main() { - if cfg!(windows) && cfg!(target_env = "gnu") && cfg!(target_pointer_width = "32") { - return - } - let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "fail" { foo(); From 7ed78fcbdf3648403ff9811e36c10b96bf49b93f Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 29 Jan 2017 06:07:45 +0100 Subject: [PATCH 72/86] Remove dead recursive partial eq impl Its nowhere used (if it had been used used, the rust stack would have overflown due to the recursion). Its presence was confusing for mrustc. --- src/librustc_data_structures/accumulate_vec.rs | 2 +- src/librustc_data_structures/array_vec.rs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/librustc_data_structures/accumulate_vec.rs b/src/librustc_data_structures/accumulate_vec.rs index 78af655852d1b..d4bd9e707fdcb 100644 --- a/src/librustc_data_structures/accumulate_vec.rs +++ b/src/librustc_data_structures/accumulate_vec.rs @@ -25,7 +25,7 @@ use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use array_vec::{self, Array, ArrayVec}; -#[derive(PartialEq, Eq, Hash, Debug)] +#[derive(Hash, Debug)] pub enum AccumulateVec { Array(ArrayVec), Heap(Vec) diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index c0b5b7f517330..51e6e09ab5003 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -52,14 +52,6 @@ impl Hash for ArrayVec } } -impl PartialEq for ArrayVec { - fn eq(&self, other: &Self) -> bool { - self == other - } -} - -impl Eq for ArrayVec {} - impl Clone for ArrayVec where A: Array, A::Element: Clone { From 23e8f70b460f03aa90b810394d3c6c84056a9f07 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 28 Jan 2017 21:25:11 -0800 Subject: [PATCH 73/86] travis: move IBM backwards in time Using Ubuntu's cross-toolchains for powerpc* and s390x meant they were depending on glibc symbols from Ubuntu 16.04. And if that host is ever updated to a new release, the toolchains would raise the bar too. This switches powerpc, powerpc64, and s390x to use crosstool-ng toolchains, configured approximately like RHEL6 with kernel 2.6.32 and glibc 2.12. This ABI level should also be compatible with Debian 7 (wheezy) and Ubuntu 12.04 (precise). For powerpc64le, the challenge was that only glibc-2.19 officially added support, but RHEL7 backported those changes to glibc-2.17. The backport patches are complex and numerous, so instead of trying to push those into crosstool-ng, this just uses glibc binaries directly from CentOS 7 and builds the toolchain manually. This is ported from rust-lang/rust-buildbot#149. r? @alexcrichton --- src/ci/docker/README.md | 55 ++ src/ci/docker/dist-powerpc-linux/Dockerfile | 64 ++- .../build-powerpc-toolchain.sh | 36 ++ ...PC-Remove-unnecessary-mnew-mnemonics.patch | 24 + .../powerpc-linux-gnu.config | 528 ++++++++++++++++++ src/ci/docker/dist-powerpc64-linux/Dockerfile | 73 ++- .../build-powerpc64-toolchain.sh | 36 ++ .../build-powerpc64le-toolchain.sh | 70 +++ ...PC-Remove-unnecessary-mnew-mnemonics.patch | 24 + ...Prevent-inlining-in-PPC64-initfini.s.patch | 26 + .../powerpc64-linux-gnu.config | 528 ++++++++++++++++++ .../docker/dist-s390x-linux-netbsd/Dockerfile | 74 ++- ...toolchain.sh => build-netbsd-toolchain.sh} | 0 .../build-s390x-toolchain.sh | 36 ++ ...prevent-AS-from-complaining-about-z9.patch | 63 +++ .../s390x-linux-gnu.config | 508 +++++++++++++++++ 16 files changed, 2110 insertions(+), 35 deletions(-) create mode 100755 src/ci/docker/dist-powerpc-linux/build-powerpc-toolchain.sh create mode 100644 src/ci/docker/dist-powerpc-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch create mode 100644 src/ci/docker/dist-powerpc-linux/powerpc-linux-gnu.config create mode 100755 src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh create mode 100755 src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh create mode 100644 src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch create mode 100644 src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/002-Prevent-inlining-in-PPC64-initfini.s.patch create mode 100644 src/ci/docker/dist-powerpc64-linux/powerpc64-linux-gnu.config rename src/ci/docker/dist-s390x-linux-netbsd/{build-toolchain.sh => build-netbsd-toolchain.sh} (100%) mode change 100644 => 100755 create mode 100755 src/ci/docker/dist-s390x-linux-netbsd/build-s390x-toolchain.sh create mode 100644 src/ci/docker/dist-s390x-linux-netbsd/patches/glibc/2.12.2/001-Use-.machine-to-prevent-AS-from-complaining-about-z9.patch create mode 100644 src/ci/docker/dist-s390x-linux-netbsd/s390x-linux-gnu.config diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 9a0a4c8cb530a..52f74ba90de6e 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -143,3 +143,58 @@ For targets: `aarch64-unknown-linux-gnu` - C-library > glibc version = 2.17 -- aarch64 support was introduced in this version - C compiler > gcc version = 5.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM + +## `powerpc-linux-gnu.config` + +For targets: `powerpc-unknown-linux-gnu` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Patches origin = Bundled, then local +- Path and misc options > Local patch directory = /tmp/patches +- Target options > Target Architecture = powerpc +- Target options > Emit assembly for CPU = power4 -- (+) +- Target options > Tune for CPU = power6 -- (+) +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel +- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc +- C compiler > gcc version = 4.9.3 +- C compiler > Core gcc extra config = --with-cpu-32=power4 --with-cpu=default32 -- (+) +- C compiler > gcc extra config = --with-cpu-32=power4 --with-cpu=default32 -- (+) +- C compiler > C++ = ENABLE -- to cross compile LLVM + +(+) These CPU options match the configuration of the toolchains in RHEL6. + +## `powerpc64-linux-gnu.config` + +For targets: `powerpc64-unknown-linux-gnu` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Patches origin = Bundled, then local +- Path and misc options > Local patch directory = /tmp/patches +- Target options > Target Architecture = powerpc +- Target options > Bitness = 64-bit +- Target options > Emit assembly for CPU = power4 -- (+) +- Target options > Tune for CPU = power6 -- (+) +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel +- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc +- C compiler > gcc version = 4.9.3 +- C compiler > C++ = ENABLE -- to cross compile LLVM + +(+) These CPU options match the configuration of the toolchains in RHEL6. + +## `s390x-linux-gnu.config` + +For targets: `s390x-unknown-linux-gnu` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Patches origin = Bundled, then local +- Path and misc options > Local patch directory = /build/patches +- Target options > Target Architecture = s390 +- Target options > Bitness = 64-bit +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 2.6.32.68 -- ~RHEL6 kernel +- C-library > glibc version = 2.12.2 -- ~RHEL6 glibc +- C compiler > gcc version = 4.9.3 +- C compiler > gcc extra config = --with-arch=z10 -- LLVM's minimum support +- C compiler > C++ = ENABLE -- to cross compile LLVM diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile index ed4e9a35960f6..640bacc54eb30 100644 --- a/src/ci/docker/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc-linux/Dockerfile @@ -1,18 +1,29 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ + automake \ + bison \ + bzip2 \ + ca-certificates \ + cmake \ + curl \ + file \ + flex \ g++ \ + gawk \ + gdb \ + git \ + gperf \ + help2man \ + libncurses-dev \ + libtool-bin \ make \ - file \ - curl \ - ca-certificates \ + patch \ python2.7 \ - git \ - cmake \ sudo \ - gdb \ - xz-utils \ - g++-powerpc-linux-gnu + texinfo \ + wget \ + xz-utils ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783 RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \ @@ -23,6 +34,43 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini rm dumb-init_*.deb ENTRYPOINT ["/usr/bin/dumb-init", "--"] +# Ubuntu 16.04 (this contianer) ships with make 4, but something in the +# toolchains we build below chokes on that, so go back to make 3 +RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \ + cd make-3.81 && \ + ./configure --prefix=/usr && \ + make && \ + make install && \ + cd .. && \ + rm -rf make-3.81 + +RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \ + tar xjf - && \ + cd crosstool-ng && \ + ./configure --prefix=/usr/local && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf crosstool-ng + +RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild +RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools +USER rustbuild +WORKDIR /tmp + +COPY patches/ /tmp/patches/ +COPY powerpc-linux-gnu.config build-powerpc-toolchain.sh /tmp/ +RUN ./build-powerpc-toolchain.sh + +USER root + +ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin + +ENV \ + CC_powerpc_unknown_linux_gnu=powerpc-unknown-linux-gnu-gcc \ + AR_powerpc_unknown_linux_gnu=powerpc-unknown-linux-gnu-ar \ + CXX_powerpc_unknown_linux_gnu=powerpc-unknown-linux-gnu-g++ + ENV HOSTS=powerpc-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended diff --git a/src/ci/docker/dist-powerpc-linux/build-powerpc-toolchain.sh b/src/ci/docker/dist-powerpc-linux/build-powerpc-toolchain.sh new file mode 100755 index 0000000000000..90a4df0c19583 --- /dev/null +++ b/src/ci/docker/dist-powerpc-linux/build-powerpc-toolchain.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2017 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. + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir build +cd build +cp ../powerpc-linux-gnu.config .config +hide_output ct-ng build +cd .. +rm -rf build diff --git a/src/ci/docker/dist-powerpc-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch b/src/ci/docker/dist-powerpc-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch new file mode 100644 index 0000000000000..744eb180cd1f6 --- /dev/null +++ b/src/ci/docker/dist-powerpc-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch @@ -0,0 +1,24 @@ +From b3563932f85d60bb0d38b0a5f3b8f4abc133f890 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Thu, 1 Nov 2012 18:00:06 -0500 +Subject: [PATCH] PowerPC: Remove unnecessary -mnew-mnemonics. + +--- + sysdeps/powerpc/Makefile | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile +index 79dd6fa976d5..7442b6709ad1 100644 +--- a/sysdeps/powerpc/Makefile ++++ b/sysdeps/powerpc/Makefile +@@ -1,7 +1,3 @@ +-# We always want to use the new mnemonic syntax even if we are on a RS6000 +-# machine. +-+cflags += -mnew-mnemonics +- + ifeq ($(subdir),gmon) + sysdep_routines += ppc-mcount + endif +-- +2.9.3 + diff --git a/src/ci/docker/dist-powerpc-linux/powerpc-linux-gnu.config b/src/ci/docker/dist-powerpc-linux/powerpc-linux-gnu.config new file mode 100644 index 0000000000000..26e2de863a0f9 --- /dev/null +++ b/src/ci/docker/dist-powerpc-linux/powerpc-linux-gnu.config @@ -0,0 +1,528 @@ +# +# Automatically generated file; DO NOT EDIT. +# Crosstool-NG Configuration +# +CT_CONFIGURE_has_make381=y +CT_CONFIGURE_has_xz=y +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +# CT_EXPERIMENTAL is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="" +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_INSTALL_DIR="${CT_PREFIX_DIR}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +# CT_ONLY_DOWNLOAD is not set +# CT_USE_MIRROR is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +# CT_PATCH_BUNDLED is not set +# CT_PATCH_LOCAL is not set +CT_PATCH_BUNDLED_LOCAL=y +# CT_PATCH_LOCAL_BUNDLED is not set +# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set +# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set +# CT_PATCH_NONE is not set +CT_PATCH_ORDER="bundled,local" +CT_PATCH_USE_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +CT_LOG_INFO=y +# CT_LOG_EXTRA is not set +# CT_LOG_ALL is not set +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="INFO" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_PROGRESS_BAR=y +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +CT_ARCH="powerpc" +CT_ARCH_SUPPORTS_BOTH_ENDIAN=y +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_SUPPORTS_WITH_ABI=y +CT_ARCH_SUPPORTS_WITH_CPU=y +CT_ARCH_SUPPORTS_WITH_TUNE=y +CT_ARCH_SUPPORTS_WITH_FLOAT=y +CT_ARCH_DEFAULT_BE=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_ABI="" +CT_ARCH_CPU="power4" +CT_ARCH_TUNE="power6" +CT_ARCH_BE=y +# CT_ARCH_LE is not set +CT_ARCH_32=y +# CT_ARCH_64 is not set +CT_ARCH_BITNESS=32 +# CT_ARCH_FLOAT_HW is not set +# CT_ARCH_FLOAT_SW is not set +CT_TARGET_CFLAGS="" +CT_TARGET_LDFLAGS="" +# CT_ARCH_alpha is not set +# CT_ARCH_arm is not set +# CT_ARCH_avr is not set +# CT_ARCH_m68k is not set +# CT_ARCH_mips is not set +# CT_ARCH_nios2 is not set +CT_ARCH_powerpc=y +# CT_ARCH_s390 is not set +# CT_ARCH_sh is not set +# CT_ARCH_sparc is not set +# CT_ARCH_x86 is not set +# CT_ARCH_xtensa is not set +CT_ARCH_alpha_AVAILABLE=y +CT_ARCH_arm_AVAILABLE=y +CT_ARCH_avr_AVAILABLE=y +CT_ARCH_m68k_AVAILABLE=y +CT_ARCH_microblaze_AVAILABLE=y +CT_ARCH_mips_AVAILABLE=y +CT_ARCH_nios2_AVAILABLE=y +CT_ARCH_powerpc_AVAILABLE=y +CT_ARCH_s390_AVAILABLE=y +CT_ARCH_sh_AVAILABLE=y +CT_ARCH_sparc_AVAILABLE=y +CT_ARCH_x86_AVAILABLE=y +CT_ARCH_xtensa_AVAILABLE=y +CT_ARCH_SUFFIX="" + +# +# Generic target options +# +# CT_MULTILIB is not set +CT_ARCH_USE_MMU=y +CT_ARCH_ENDIAN="big" + +# +# Target optimisations +# +CT_ARCH_FLOAT_AUTO=y +CT_ARCH_FLOAT="auto" + +# +# powerpc other options +# +CT_ARCH_powerpc_ABI="" +CT_ARCH_powerpc_ABI_DEFAULT=y +# CT_ARCH_powerpc_ABI_SPE is not set + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +# CT_STATIC_TOOLCHAIN is not set +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +CT_CROSS=y +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +CT_KERNEL="linux" +CT_KERNEL_VERSION="2.6.32.68" +# CT_KERNEL_bare_metal is not set +CT_KERNEL_linux=y +CT_KERNEL_bare_metal_AVAILABLE=y +CT_KERNEL_linux_AVAILABLE=y +# CT_KERNEL_V_4_3 is not set +# CT_KERNEL_V_4_2 is not set +# CT_KERNEL_V_4_1 is not set +# CT_KERNEL_V_3_18 is not set +# CT_KERNEL_V_3_14 is not set +# CT_KERNEL_V_3_12 is not set +# CT_KERNEL_V_3_10 is not set +# CT_KERNEL_V_3_4 is not set +# CT_KERNEL_V_3_2 is not set +CT_KERNEL_V_2_6_32=y +# CT_KERNEL_LINUX_CUSTOM is not set +CT_KERNEL_windows_AVAILABLE=y + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# linux other options +# +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS="binutils" +CT_BINUTILS_binutils=y + +# +# GNU binutils +# +# CT_CC_BINUTILS_SHOW_LINARO is not set +CT_BINUTILS_V_2_25_1=y +# CT_BINUTILS_V_2_25 is not set +# CT_BINUTILS_V_2_24 is not set +# CT_BINUTILS_V_2_23_2 is not set +# CT_BINUTILS_V_2_23_1 is not set +# CT_BINUTILS_V_2_22 is not set +# CT_BINUTILS_V_2_21_53 is not set +# CT_BINUTILS_V_2_21_1a is not set +# CT_BINUTILS_V_2_20_1a is not set +# CT_BINUTILS_V_2_19_1a is not set +# CT_BINUTILS_V_2_18a is not set +CT_BINUTILS_VERSION="2.25.1" +CT_BINUTILS_2_25_1_or_later=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_2_24_or_later=y +CT_BINUTILS_2_23_or_later=y +CT_BINUTILS_2_22_or_later=y +CT_BINUTILS_2_21_or_later=y +CT_BINUTILS_2_20_or_later=y +CT_BINUTILS_2_19_or_later=y +CT_BINUTILS_2_18_or_later=y +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_FORCE_LD_BFD=y +CT_BINUTILS_LINKER_LD=y +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set + +# +# binutils other options +# + +# +# C-library +# +CT_LIBC="glibc" +CT_LIBC_VERSION="2.12.2" +CT_LIBC_glibc=y +# CT_LIBC_musl is not set +# CT_LIBC_uClibc is not set +CT_LIBC_avr_libc_AVAILABLE=y +CT_LIBC_glibc_AVAILABLE=y +CT_THREADS="nptl" +# CT_CC_GLIBC_SHOW_LINARO is not set +# CT_LIBC_GLIBC_V_2_22 is not set +# CT_LIBC_GLIBC_V_2_21 is not set +# CT_LIBC_GLIBC_V_2_20 is not set +# CT_LIBC_GLIBC_V_2_19 is not set +# CT_LIBC_GLIBC_V_2_18 is not set +# CT_LIBC_GLIBC_V_2_17 is not set +# CT_LIBC_GLIBC_V_2_16_0 is not set +# CT_LIBC_GLIBC_V_2_15 is not set +# CT_LIBC_GLIBC_V_2_14_1 is not set +# CT_LIBC_GLIBC_V_2_14 is not set +# CT_LIBC_GLIBC_V_2_13 is not set +CT_LIBC_GLIBC_V_2_12_2=y +# CT_LIBC_GLIBC_V_2_12_1 is not set +# CT_LIBC_GLIBC_V_2_11_1 is not set +# CT_LIBC_GLIBC_V_2_11 is not set +# CT_LIBC_GLIBC_V_2_10_1 is not set +# CT_LIBC_GLIBC_V_2_9 is not set +# CT_LIBC_GLIBC_V_2_8 is not set +CT_LIBC_mingw_AVAILABLE=y +CT_LIBC_musl_AVAILABLE=y +CT_LIBC_newlib_AVAILABLE=y +CT_LIBC_none_AVAILABLE=y +CT_LIBC_uClibc_AVAILABLE=y +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +CT_LIBC_XLDD=y + +# +# glibc other options +# +CT_LIBC_GLIBC_PORTS_EXTERNAL=y +CT_LIBC_glibc_familly=y +CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_LIBC_GLIBC_CONFIGPARMS="" +CT_LIBC_GLIBC_EXTRA_CFLAGS="" +CT_LIBC_EXTRA_CC_ARGS="" +# CT_LIBC_DISABLE_VERSIONING is not set +CT_LIBC_OLDEST_ABI="" +CT_LIBC_GLIBC_FORCE_UNWIND=y +# CT_LIBC_GLIBC_USE_PORTS is not set +CT_LIBC_ADDONS_LIST="" +# CT_LIBC_LOCALES is not set +# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set +CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y +# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_LIBC_GLIBC_MIN_KERNEL="2.6.32.68" + +# +# C compiler +# +CT_CC="gcc" +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_gcc=y +# CT_CC_GCC_SHOW_LINARO is not set +# CT_CC_GCC_V_5_2_0 is not set +CT_CC_GCC_V_4_9_3=y +# CT_CC_GCC_V_4_8_5 is not set +# CT_CC_GCC_V_4_7_4 is not set +# CT_CC_GCC_V_4_6_4 is not set +# CT_CC_GCC_V_4_5_4 is not set +# CT_CC_GCC_V_4_4_7 is not set +# CT_CC_GCC_V_4_3_6 is not set +# CT_CC_GCC_V_4_2_4 is not set +CT_CC_GCC_4_2_or_later=y +CT_CC_GCC_4_3_or_later=y +CT_CC_GCC_4_4_or_later=y +CT_CC_GCC_4_5_or_later=y +CT_CC_GCC_4_6_or_later=y +CT_CC_GCC_4_7_or_later=y +CT_CC_GCC_4_8_or_later=y +CT_CC_GCC_4_9=y +CT_CC_GCC_4_9_or_later=y +CT_CC_GCC_HAS_GRAPHITE=y +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_HAS_LTO=y +CT_CC_GCC_USE_LTO=y +CT_CC_GCC_HAS_PKGVERSION_BUGURL=y +CT_CC_GCC_HAS_BUILD_ID=y +CT_CC_GCC_HAS_LNK_HASH_STYLE=y +CT_CC_GCC_USE_GMP_MPFR=y +CT_CC_GCC_USE_MPC=y +CT_CC_GCC_HAS_LIBQUADMATH=y +CT_CC_GCC_HAS_LIBSANITIZER=y +CT_CC_GCC_VERSION="4.9.3" +# CT_CC_LANG_FORTRAN is not set +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="--with-cpu-32=power4 --with-cpu=default32" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-cpu-32=power4 --with-cpu=default32" +CT_CC_GCC_EXTRA_ENV_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set + +# +# Optimisation features +# + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_JAVA=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_JAVA is not set + +# +# Debug facilities +# +# CT_DEBUG_dmalloc is not set +# CT_DEBUG_duma is not set +# CT_DEBUG_gdb is not set +# CT_DEBUG_ltrace is not set +# CT_DEBUG_strace is not set + +# +# Companion libraries +# +CT_COMPLIBS_NEEDED=y +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_CLOOG_NEEDED=y +CT_MPC_NEEDED=y +CT_COMPLIBS=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_CLOOG=y +CT_MPC=y +CT_LIBICONV_V_1_14=y +CT_LIBICONV_VERSION="1.14" +CT_GETTEXT_V_0_19_6=y +CT_GETTEXT_VERSION="0.19.6" +CT_GMP_V_6_0_0=y +# CT_GMP_V_5_1_3 is not set +# CT_GMP_V_5_1_1 is not set +# CT_GMP_V_5_0_2 is not set +# CT_GMP_V_5_0_1 is not set +# CT_GMP_V_4_3_2 is not set +# CT_GMP_V_4_3_1 is not set +# CT_GMP_V_4_3_0 is not set +CT_GMP_5_0_2_or_later=y +CT_GMP_VERSION="6.0.0a" +CT_MPFR_V_3_1_3=y +# CT_MPFR_V_3_1_2 is not set +# CT_MPFR_V_3_1_0 is not set +# CT_MPFR_V_3_0_1 is not set +# CT_MPFR_V_3_0_0 is not set +# CT_MPFR_V_2_4_2 is not set +# CT_MPFR_V_2_4_1 is not set +# CT_MPFR_V_2_4_0 is not set +CT_MPFR_VERSION="3.1.3" +CT_ISL_V_0_14=y +CT_ISL_V_0_14_or_later=y +CT_ISL_V_0_12_or_later=y +CT_ISL_VERSION="0.14" +CT_CLOOG_V_0_18_4=y +# CT_CLOOG_V_0_18_1 is not set +# CT_CLOOG_V_0_18_0 is not set +CT_CLOOG_VERSION="0.18.4" +CT_CLOOG_0_18_4_or_later=y +CT_CLOOG_0_18_or_later=y +CT_MPC_V_1_0_3=y +# CT_MPC_V_1_0_2 is not set +# CT_MPC_V_1_0_1 is not set +# CT_MPC_V_1_0 is not set +# CT_MPC_V_0_9 is not set +# CT_MPC_V_0_8_2 is not set +# CT_MPC_V_0_8_1 is not set +# CT_MPC_V_0_7 is not set +CT_MPC_VERSION="1.0.3" + +# +# Companion libraries common options +# +# CT_COMPLIBS_CHECK is not set + +# +# Companion tools +# + +# +# READ HELP before you say 'Y' below !!! +# +# CT_COMP_TOOLS is not set diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile index 6c04048f4ddf8..42842d2368ac4 100644 --- a/src/ci/docker/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile @@ -1,19 +1,29 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ + automake \ + bison \ + bzip2 \ + ca-certificates \ + cmake \ + curl \ + file \ + flex \ g++ \ + gawk \ + gdb \ + git \ + gperf \ + help2man \ + libncurses-dev \ + libtool-bin \ make \ - file \ - curl \ - ca-certificates \ + patch \ python2.7 \ - git \ - cmake \ sudo \ - gdb \ - xz-utils \ - g++-powerpc64-linux-gnu \ - g++-powerpc64le-linux-gnu + texinfo \ + wget \ + xz-utils ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783 RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \ @@ -24,10 +34,49 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini rm dumb-init_*.deb ENTRYPOINT ["/usr/bin/dumb-init", "--"] +# Ubuntu 16.04 (this contianer) ships with make 4, but something in the +# toolchains we build below chokes on that, so go back to make 3 +RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \ + cd make-3.81 && \ + ./configure --prefix=/usr && \ + make && \ + make install && \ + cd .. && \ + rm -rf make-3.81 + +RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \ + tar xjf - && \ + cd crosstool-ng && \ + ./configure --prefix=/usr/local && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf crosstool-ng + +RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild +RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools +USER rustbuild +WORKDIR /tmp + +COPY patches/ /tmp/patches/ +COPY powerpc64-linux-gnu.config build-powerpc64-toolchain.sh /tmp/ +RUN ./build-powerpc64-toolchain.sh + +USER root + +RUN apt-get install -y --no-install-recommends rpm2cpio cpio +COPY build-powerpc64le-toolchain.sh /tmp/ +RUN ./build-powerpc64le-toolchain.sh + +ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnueabihf/bin + ENV \ - AR_powerpc64_unknown_linux_gnu=powerpc64-linux-gnu-ar \ - CC_powerpc64_unknown_linux_gnu=powerpc64-linux-gnu-gcc \ - CXX_powerpc64_unknown_linux_gnu=powerpc64-linux-gnu-g++ + AR_powerpc64_unknown_linux_gnu=powerpc64-unknown-linux-gnu-ar \ + CC_powerpc64_unknown_linux_gnu=powerpc64-unknown-linux-gnu-gcc \ + CXX_powerpc64_unknown_linux_gnu=powerpc64-unknown-linux-gnu-g++ \ + AR_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-ar \ + CC_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-gcc \ + CXX_powerpc64le_unknown_linux_gnu=powerpc64le-linux-gnu-g++ ENV HOSTS=powerpc64-unknown-linux-gnu ENV HOSTS=$HOSTS,powerpc64le-unknown-linux-gnu diff --git a/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh b/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh new file mode 100755 index 0000000000000..d70947d2dd9d6 --- /dev/null +++ b/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2017 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. + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir build +cd build +cp ../powerpc64-linux-gnu.config .config +hide_output ct-ng build +cd .. +rm -rf build diff --git a/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh b/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh new file mode 100755 index 0000000000000..98fbe5045452e --- /dev/null +++ b/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +set -ex + +BINUTILS=2.25.1 +GCC=5.3.0 +TARGET=powerpc64le-linux-gnu +SYSROOT=/usr/local/$TARGET/sysroot + +# First, download the CentOS7 glibc.ppc64le and relevant header files. +# (upstream ppc64le support wasn't added until 2.19, which el7 backported.) +mkdir -p $SYSROOT +pushd $SYSROOT + +centos_base=http://mirror.centos.org/altarch/7.3.1611/os/ppc64le/Packages +glibc_v=2.17-157.el7 +kernel_v=3.10.0-514.el7 +for package in glibc{,-devel,-headers}-$glibc_v kernel-headers-$kernel_v; do + curl $centos_base/$package.ppc64le.rpm | \ + rpm2cpio - | cpio -idm +done + +ln -sT lib64 lib +ln -sT lib64 usr/lib + +popd + +# Next, download and build binutils. +mkdir binutils-$TARGET +pushd binutils-$TARGET +curl https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS.tar.bz2 | tar xjf - +mkdir binutils-build +cd binutils-build +../binutils-$BINUTILS/configure --target=$TARGET --with-sysroot=$SYSROOT +make -j10 +make install +popd +rm -rf binutils-$TARGET + +# Finally, download and build gcc. +mkdir gcc-$TARGET +pushd gcc-$TARGET +curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf - +cd gcc-$GCC +./contrib/download_prerequisites + +mkdir ../gcc-build +cd ../gcc-build +../gcc-$GCC/configure \ + --enable-languages=c,c++ \ + --target=$TARGET \ + --with-cpu=power8 \ + --with-sysroot=$SYSROOT \ + --disable-libcilkrts \ + --disable-multilib \ + --disable-nls \ + --disable-libgomp \ + --disable-libquadmath \ + --disable-libssp \ + --disable-libvtv \ + --disable-libcilkrt \ + --disable-libada \ + --disable-libsanitizer \ + --disable-libquadmath-support \ + --disable-lto +make -j10 +make install + +popd +rm -rf gcc-$TARGET diff --git a/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch b/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch new file mode 100644 index 0000000000000..744eb180cd1f6 --- /dev/null +++ b/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/001-PowerPC-Remove-unnecessary-mnew-mnemonics.patch @@ -0,0 +1,24 @@ +From b3563932f85d60bb0d38b0a5f3b8f4abc133f890 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Thu, 1 Nov 2012 18:00:06 -0500 +Subject: [PATCH] PowerPC: Remove unnecessary -mnew-mnemonics. + +--- + sysdeps/powerpc/Makefile | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile +index 79dd6fa976d5..7442b6709ad1 100644 +--- a/sysdeps/powerpc/Makefile ++++ b/sysdeps/powerpc/Makefile +@@ -1,7 +1,3 @@ +-# We always want to use the new mnemonic syntax even if we are on a RS6000 +-# machine. +-+cflags += -mnew-mnemonics +- + ifeq ($(subdir),gmon) + sysdep_routines += ppc-mcount + endif +-- +2.9.3 + diff --git a/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/002-Prevent-inlining-in-PPC64-initfini.s.patch b/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/002-Prevent-inlining-in-PPC64-initfini.s.patch new file mode 100644 index 0000000000000..47cc8b28d225a --- /dev/null +++ b/src/ci/docker/dist-powerpc64-linux/patches/glibc/2.12.2/002-Prevent-inlining-in-PPC64-initfini.s.patch @@ -0,0 +1,26 @@ +From a4f388e111ce05e2ab7912cff3c9070334bb74ae Mon Sep 17 00:00:00 2001 +From: Josh Stone +Date: Fri, 20 Jan 2017 15:41:56 -0800 +Subject: [PATCH] Prevent inlining in PPC64 initfini.s + +Ref: https://sourceware.org/ml/libc-alpha/2012-01/msg00195.html +--- + sysdeps/powerpc/powerpc64/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysdeps/powerpc/powerpc64/Makefile b/sysdeps/powerpc/powerpc64/Makefile +index 78d4f07e575f..fe96aae4d43e 100644 +--- a/sysdeps/powerpc/powerpc64/Makefile ++++ b/sysdeps/powerpc/powerpc64/Makefile +@@ -28,7 +28,7 @@ elide-routines.os += hp-timing + ifneq ($(elf),no) + # The initfini generation code doesn't work in the presence of -fPIC, so + # we use -fpic instead which is much better. +-CFLAGS-initfini.s += -fpic -O1 ++CFLAGS-initfini.s += -fpic -O1 -fno-inline + endif + endif + +-- +2.9.3 + diff --git a/src/ci/docker/dist-powerpc64-linux/powerpc64-linux-gnu.config b/src/ci/docker/dist-powerpc64-linux/powerpc64-linux-gnu.config new file mode 100644 index 0000000000000..c2d02ee85cf25 --- /dev/null +++ b/src/ci/docker/dist-powerpc64-linux/powerpc64-linux-gnu.config @@ -0,0 +1,528 @@ +# +# Automatically generated file; DO NOT EDIT. +# Crosstool-NG Configuration +# +CT_CONFIGURE_has_make381=y +CT_CONFIGURE_has_xz=y +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +# CT_EXPERIMENTAL is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="" +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_INSTALL_DIR="${CT_PREFIX_DIR}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +# CT_ONLY_DOWNLOAD is not set +# CT_USE_MIRROR is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +# CT_PATCH_BUNDLED is not set +# CT_PATCH_LOCAL is not set +CT_PATCH_BUNDLED_LOCAL=y +# CT_PATCH_LOCAL_BUNDLED is not set +# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set +# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set +# CT_PATCH_NONE is not set +CT_PATCH_ORDER="bundled,local" +CT_PATCH_USE_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +CT_LOG_INFO=y +# CT_LOG_EXTRA is not set +# CT_LOG_ALL is not set +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="INFO" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_PROGRESS_BAR=y +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +CT_ARCH="powerpc" +CT_ARCH_SUPPORTS_BOTH_ENDIAN=y +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_SUPPORTS_WITH_ABI=y +CT_ARCH_SUPPORTS_WITH_CPU=y +CT_ARCH_SUPPORTS_WITH_TUNE=y +CT_ARCH_SUPPORTS_WITH_FLOAT=y +CT_ARCH_DEFAULT_BE=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_ABI="" +CT_ARCH_CPU="power4" +CT_ARCH_TUNE="power6" +CT_ARCH_BE=y +# CT_ARCH_LE is not set +# CT_ARCH_32 is not set +CT_ARCH_64=y +CT_ARCH_BITNESS=64 +# CT_ARCH_FLOAT_HW is not set +# CT_ARCH_FLOAT_SW is not set +CT_TARGET_CFLAGS="" +CT_TARGET_LDFLAGS="" +# CT_ARCH_alpha is not set +# CT_ARCH_arm is not set +# CT_ARCH_avr is not set +# CT_ARCH_m68k is not set +# CT_ARCH_mips is not set +# CT_ARCH_nios2 is not set +CT_ARCH_powerpc=y +# CT_ARCH_s390 is not set +# CT_ARCH_sh is not set +# CT_ARCH_sparc is not set +# CT_ARCH_x86 is not set +# CT_ARCH_xtensa is not set +CT_ARCH_alpha_AVAILABLE=y +CT_ARCH_arm_AVAILABLE=y +CT_ARCH_avr_AVAILABLE=y +CT_ARCH_m68k_AVAILABLE=y +CT_ARCH_microblaze_AVAILABLE=y +CT_ARCH_mips_AVAILABLE=y +CT_ARCH_nios2_AVAILABLE=y +CT_ARCH_powerpc_AVAILABLE=y +CT_ARCH_s390_AVAILABLE=y +CT_ARCH_sh_AVAILABLE=y +CT_ARCH_sparc_AVAILABLE=y +CT_ARCH_x86_AVAILABLE=y +CT_ARCH_xtensa_AVAILABLE=y +CT_ARCH_SUFFIX="" + +# +# Generic target options +# +# CT_MULTILIB is not set +CT_ARCH_USE_MMU=y +CT_ARCH_ENDIAN="big" + +# +# Target optimisations +# +CT_ARCH_FLOAT_AUTO=y +CT_ARCH_FLOAT="auto" + +# +# powerpc other options +# +CT_ARCH_powerpc_ABI="" +CT_ARCH_powerpc_ABI_DEFAULT=y +# CT_ARCH_powerpc_ABI_SPE is not set + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +# CT_STATIC_TOOLCHAIN is not set +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +CT_CROSS=y +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +CT_KERNEL="linux" +CT_KERNEL_VERSION="2.6.32.68" +# CT_KERNEL_bare_metal is not set +CT_KERNEL_linux=y +CT_KERNEL_bare_metal_AVAILABLE=y +CT_KERNEL_linux_AVAILABLE=y +# CT_KERNEL_V_4_3 is not set +# CT_KERNEL_V_4_2 is not set +# CT_KERNEL_V_4_1 is not set +# CT_KERNEL_V_3_18 is not set +# CT_KERNEL_V_3_14 is not set +# CT_KERNEL_V_3_12 is not set +# CT_KERNEL_V_3_10 is not set +# CT_KERNEL_V_3_4 is not set +# CT_KERNEL_V_3_2 is not set +CT_KERNEL_V_2_6_32=y +# CT_KERNEL_LINUX_CUSTOM is not set +CT_KERNEL_windows_AVAILABLE=y + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# linux other options +# +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS="binutils" +CT_BINUTILS_binutils=y + +# +# GNU binutils +# +# CT_CC_BINUTILS_SHOW_LINARO is not set +CT_BINUTILS_V_2_25_1=y +# CT_BINUTILS_V_2_25 is not set +# CT_BINUTILS_V_2_24 is not set +# CT_BINUTILS_V_2_23_2 is not set +# CT_BINUTILS_V_2_23_1 is not set +# CT_BINUTILS_V_2_22 is not set +# CT_BINUTILS_V_2_21_53 is not set +# CT_BINUTILS_V_2_21_1a is not set +# CT_BINUTILS_V_2_20_1a is not set +# CT_BINUTILS_V_2_19_1a is not set +# CT_BINUTILS_V_2_18a is not set +CT_BINUTILS_VERSION="2.25.1" +CT_BINUTILS_2_25_1_or_later=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_2_24_or_later=y +CT_BINUTILS_2_23_or_later=y +CT_BINUTILS_2_22_or_later=y +CT_BINUTILS_2_21_or_later=y +CT_BINUTILS_2_20_or_later=y +CT_BINUTILS_2_19_or_later=y +CT_BINUTILS_2_18_or_later=y +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_FORCE_LD_BFD=y +CT_BINUTILS_LINKER_LD=y +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set + +# +# binutils other options +# + +# +# C-library +# +CT_LIBC="glibc" +CT_LIBC_VERSION="2.12.2" +CT_LIBC_glibc=y +# CT_LIBC_musl is not set +# CT_LIBC_uClibc is not set +CT_LIBC_avr_libc_AVAILABLE=y +CT_LIBC_glibc_AVAILABLE=y +CT_THREADS="nptl" +# CT_CC_GLIBC_SHOW_LINARO is not set +# CT_LIBC_GLIBC_V_2_22 is not set +# CT_LIBC_GLIBC_V_2_21 is not set +# CT_LIBC_GLIBC_V_2_20 is not set +# CT_LIBC_GLIBC_V_2_19 is not set +# CT_LIBC_GLIBC_V_2_18 is not set +# CT_LIBC_GLIBC_V_2_17 is not set +# CT_LIBC_GLIBC_V_2_16_0 is not set +# CT_LIBC_GLIBC_V_2_15 is not set +# CT_LIBC_GLIBC_V_2_14_1 is not set +# CT_LIBC_GLIBC_V_2_14 is not set +# CT_LIBC_GLIBC_V_2_13 is not set +CT_LIBC_GLIBC_V_2_12_2=y +# CT_LIBC_GLIBC_V_2_12_1 is not set +# CT_LIBC_GLIBC_V_2_11_1 is not set +# CT_LIBC_GLIBC_V_2_11 is not set +# CT_LIBC_GLIBC_V_2_10_1 is not set +# CT_LIBC_GLIBC_V_2_9 is not set +# CT_LIBC_GLIBC_V_2_8 is not set +CT_LIBC_mingw_AVAILABLE=y +CT_LIBC_musl_AVAILABLE=y +CT_LIBC_newlib_AVAILABLE=y +CT_LIBC_none_AVAILABLE=y +CT_LIBC_uClibc_AVAILABLE=y +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +CT_LIBC_XLDD=y + +# +# glibc other options +# +CT_LIBC_GLIBC_PORTS_EXTERNAL=y +CT_LIBC_glibc_familly=y +CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_LIBC_GLIBC_CONFIGPARMS="" +CT_LIBC_GLIBC_EXTRA_CFLAGS="" +CT_LIBC_EXTRA_CC_ARGS="" +# CT_LIBC_DISABLE_VERSIONING is not set +CT_LIBC_OLDEST_ABI="" +CT_LIBC_GLIBC_FORCE_UNWIND=y +# CT_LIBC_GLIBC_USE_PORTS is not set +CT_LIBC_ADDONS_LIST="" +# CT_LIBC_LOCALES is not set +# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set +CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y +# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_LIBC_GLIBC_MIN_KERNEL="2.6.32.68" + +# +# C compiler +# +CT_CC="gcc" +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_gcc=y +# CT_CC_GCC_SHOW_LINARO is not set +# CT_CC_GCC_V_5_2_0 is not set +CT_CC_GCC_V_4_9_3=y +# CT_CC_GCC_V_4_8_5 is not set +# CT_CC_GCC_V_4_7_4 is not set +# CT_CC_GCC_V_4_6_4 is not set +# CT_CC_GCC_V_4_5_4 is not set +# CT_CC_GCC_V_4_4_7 is not set +# CT_CC_GCC_V_4_3_6 is not set +# CT_CC_GCC_V_4_2_4 is not set +CT_CC_GCC_4_2_or_later=y +CT_CC_GCC_4_3_or_later=y +CT_CC_GCC_4_4_or_later=y +CT_CC_GCC_4_5_or_later=y +CT_CC_GCC_4_6_or_later=y +CT_CC_GCC_4_7_or_later=y +CT_CC_GCC_4_8_or_later=y +CT_CC_GCC_4_9=y +CT_CC_GCC_4_9_or_later=y +CT_CC_GCC_HAS_GRAPHITE=y +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_HAS_LTO=y +CT_CC_GCC_USE_LTO=y +CT_CC_GCC_HAS_PKGVERSION_BUGURL=y +CT_CC_GCC_HAS_BUILD_ID=y +CT_CC_GCC_HAS_LNK_HASH_STYLE=y +CT_CC_GCC_USE_GMP_MPFR=y +CT_CC_GCC_USE_MPC=y +CT_CC_GCC_HAS_LIBQUADMATH=y +CT_CC_GCC_HAS_LIBSANITIZER=y +CT_CC_GCC_VERSION="4.9.3" +# CT_CC_LANG_FORTRAN is not set +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_ENV_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set + +# +# Optimisation features +# + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_JAVA=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_JAVA is not set + +# +# Debug facilities +# +# CT_DEBUG_dmalloc is not set +# CT_DEBUG_duma is not set +# CT_DEBUG_gdb is not set +# CT_DEBUG_ltrace is not set +# CT_DEBUG_strace is not set + +# +# Companion libraries +# +CT_COMPLIBS_NEEDED=y +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_CLOOG_NEEDED=y +CT_MPC_NEEDED=y +CT_COMPLIBS=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_CLOOG=y +CT_MPC=y +CT_LIBICONV_V_1_14=y +CT_LIBICONV_VERSION="1.14" +CT_GETTEXT_V_0_19_6=y +CT_GETTEXT_VERSION="0.19.6" +CT_GMP_V_6_0_0=y +# CT_GMP_V_5_1_3 is not set +# CT_GMP_V_5_1_1 is not set +# CT_GMP_V_5_0_2 is not set +# CT_GMP_V_5_0_1 is not set +# CT_GMP_V_4_3_2 is not set +# CT_GMP_V_4_3_1 is not set +# CT_GMP_V_4_3_0 is not set +CT_GMP_5_0_2_or_later=y +CT_GMP_VERSION="6.0.0a" +CT_MPFR_V_3_1_3=y +# CT_MPFR_V_3_1_2 is not set +# CT_MPFR_V_3_1_0 is not set +# CT_MPFR_V_3_0_1 is not set +# CT_MPFR_V_3_0_0 is not set +# CT_MPFR_V_2_4_2 is not set +# CT_MPFR_V_2_4_1 is not set +# CT_MPFR_V_2_4_0 is not set +CT_MPFR_VERSION="3.1.3" +CT_ISL_V_0_14=y +CT_ISL_V_0_14_or_later=y +CT_ISL_V_0_12_or_later=y +CT_ISL_VERSION="0.14" +CT_CLOOG_V_0_18_4=y +# CT_CLOOG_V_0_18_1 is not set +# CT_CLOOG_V_0_18_0 is not set +CT_CLOOG_VERSION="0.18.4" +CT_CLOOG_0_18_4_or_later=y +CT_CLOOG_0_18_or_later=y +CT_MPC_V_1_0_3=y +# CT_MPC_V_1_0_2 is not set +# CT_MPC_V_1_0_1 is not set +# CT_MPC_V_1_0 is not set +# CT_MPC_V_0_9 is not set +# CT_MPC_V_0_8_2 is not set +# CT_MPC_V_0_8_1 is not set +# CT_MPC_V_0_7 is not set +CT_MPC_VERSION="1.0.3" + +# +# Companion libraries common options +# +# CT_COMPLIBS_CHECK is not set + +# +# Companion tools +# + +# +# READ HELP before you say 'Y' below !!! +# +# CT_COMP_TOOLS is not set diff --git a/src/ci/docker/dist-s390x-linux-netbsd/Dockerfile b/src/ci/docker/dist-s390x-linux-netbsd/Dockerfile index ec38855fe3a01..589b5fd530fc7 100644 --- a/src/ci/docker/dist-s390x-linux-netbsd/Dockerfile +++ b/src/ci/docker/dist-s390x-linux-netbsd/Dockerfile @@ -1,37 +1,81 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ + automake \ + bison \ + bzip2 \ + ca-certificates \ + cmake \ + curl \ + file \ + flex \ g++ \ + gawk \ + gdb \ + git \ + gperf \ + help2man \ + libncurses-dev \ + libtool-bin \ make \ - file \ - curl \ - ca-certificates \ + patch \ python2.7 \ - git \ - cmake \ sudo \ - bzip2 \ - xz-utils \ + texinfo \ wget \ - patch \ - g++-s390x-linux-gnu + xz-utils -COPY build-toolchain.sh /tmp/ -RUN sh /tmp/build-toolchain.sh +ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783 +RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \ + tar xJf - -C /usr/local/bin --strip-components=1 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ dpkg -i dumb-init_*.deb && \ rm dumb-init_*.deb ENTRYPOINT ["/usr/bin/dumb-init", "--"] -ENV SCCACHE_DIGEST=7237e38e029342fa27b7ac25412cb9d52554008b12389727320bd533fd7f05b6a96d55485f305caf95e5c8f5f97c3313e10012ccad3e752aba2518f3522ba783 -RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST | \ - tar xJf - -C /usr/local/bin --strip-components=1 +# Ubuntu 16.04 (this contianer) ships with make 4, but something in the +# toolchains we build below chokes on that, so go back to make 3 +RUN curl https://ftp.gnu.org/gnu/make/make-3.81.tar.gz | tar xzf - && \ + cd make-3.81 && \ + ./configure --prefix=/usr && \ + make && \ + make install && \ + cd .. && \ + rm -rf make-3.81 + +RUN curl http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2 | \ + tar xjf - && \ + cd crosstool-ng && \ + ./configure --prefix=/usr/local && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf crosstool-ng + +RUN groupadd -r rustbuild && useradd -m -r -g rustbuild rustbuild +RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools +USER rustbuild +WORKDIR /tmp + +COPY patches/ /tmp/patches/ +COPY s390x-linux-gnu.config build-s390x-toolchain.sh /tmp/ +RUN ./build-s390x-toolchain.sh + +USER root + +COPY build-netbsd-toolchain.sh /tmp/ +RUN ./build-netbsd-toolchain.sh + +ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin ENV \ AR_x86_64_unknown_netbsd=x86_64-unknown-netbsd-ar \ CC_x86_64_unknown_netbsd=x86_64-unknown-netbsd-gcc \ - CXX_x86_64_unknown_netbsd=x86_64-unknown-netbsd-g++ + CXX_x86_64_unknown_netbsd=x86_64-unknown-netbsd-g++ \ + CC_s390x_unknown_linux_gnu=s390x-ibm-linux-gnu-gcc \ + AR_s390x_unknown_linux_gnu=s390x-ibm-linux-gnu-ar \ + CXX_s390x_unknown_linux_gnu=s390x-ibm-linux-gnu-g++ ENV HOSTS=x86_64-unknown-netbsd ENV HOSTS=$HOSTS,s390x-unknown-linux-gnu diff --git a/src/ci/docker/dist-s390x-linux-netbsd/build-toolchain.sh b/src/ci/docker/dist-s390x-linux-netbsd/build-netbsd-toolchain.sh old mode 100644 new mode 100755 similarity index 100% rename from src/ci/docker/dist-s390x-linux-netbsd/build-toolchain.sh rename to src/ci/docker/dist-s390x-linux-netbsd/build-netbsd-toolchain.sh diff --git a/src/ci/docker/dist-s390x-linux-netbsd/build-s390x-toolchain.sh b/src/ci/docker/dist-s390x-linux-netbsd/build-s390x-toolchain.sh new file mode 100755 index 0000000000000..b4995e20dc69b --- /dev/null +++ b/src/ci/docker/dist-s390x-linux-netbsd/build-s390x-toolchain.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2017 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. + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir build +cd build +cp ../s390x-linux-gnu.config .config +hide_output ct-ng build +cd .. +rm -rf build diff --git a/src/ci/docker/dist-s390x-linux-netbsd/patches/glibc/2.12.2/001-Use-.machine-to-prevent-AS-from-complaining-about-z9.patch b/src/ci/docker/dist-s390x-linux-netbsd/patches/glibc/2.12.2/001-Use-.machine-to-prevent-AS-from-complaining-about-z9.patch new file mode 100644 index 0000000000000..cba416ed2f70b --- /dev/null +++ b/src/ci/docker/dist-s390x-linux-netbsd/patches/glibc/2.12.2/001-Use-.machine-to-prevent-AS-from-complaining-about-z9.patch @@ -0,0 +1,63 @@ +From 2739047682590b1df473401b4febf424f857fccf Mon Sep 17 00:00:00 2001 +From: Andreas Krebbel +Date: Sun, 17 Apr 2011 20:43:59 -0400 +Subject: [PATCH] Use .machine to prevent AS from complaining about z9-109 + instructions in iconv modules + +--- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 5 ++++- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 5 ++++- + sysdeps/s390/s390-64/utf8-utf32-z9.c | 5 ++++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +index 14daf2118fe5..5bcaaaedec9c 100644 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c +@@ -169,7 +169,10 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen asm("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile ("0: " INSTRUCTION " \n\t" \ ++ asm volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ + " jo 0b \n\t" \ + " ipm %2 \n" \ + : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 5f73f3c59e21..812a42fae44c 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -151,7 +151,10 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen asm("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile ("0: " INSTRUCTION " \n\t" \ ++ asm volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ + " jo 0b \n\t" \ + " ipm %2 \n" \ + : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +index 17ef8bc890c3..0ffd848c8124 100644 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf32-z9.c +@@ -155,7 +155,10 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen asm("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile ("0: " INSTRUCTION " \n\t" \ ++ asm volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ + " jo 0b \n\t" \ + " ipm %2 \n" \ + : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +-- +2.9.3 + diff --git a/src/ci/docker/dist-s390x-linux-netbsd/s390x-linux-gnu.config b/src/ci/docker/dist-s390x-linux-netbsd/s390x-linux-gnu.config new file mode 100644 index 0000000000000..fa5e4510987f1 --- /dev/null +++ b/src/ci/docker/dist-s390x-linux-netbsd/s390x-linux-gnu.config @@ -0,0 +1,508 @@ +# +# Automatically generated file; DO NOT EDIT. +# Crosstool-NG Configuration +# +CT_CONFIGURE_has_make381=y +CT_CONFIGURE_has_xz=y +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +# CT_EXPERIMENTAL is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="" +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_INSTALL_DIR="${CT_PREFIX_DIR}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +# CT_ONLY_DOWNLOAD is not set +# CT_USE_MIRROR is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +# CT_PATCH_BUNDLED is not set +# CT_PATCH_LOCAL is not set +CT_PATCH_BUNDLED_LOCAL=y +# CT_PATCH_LOCAL_BUNDLED is not set +# CT_PATCH_BUNDLED_FALLBACK_LOCAL is not set +# CT_PATCH_LOCAL_FALLBACK_BUNDLED is not set +# CT_PATCH_NONE is not set +CT_PATCH_ORDER="bundled,local" +CT_PATCH_USE_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +CT_LOG_INFO=y +# CT_LOG_EXTRA is not set +# CT_LOG_ALL is not set +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="INFO" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_PROGRESS_BAR=y +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +CT_ARCH="s390" +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_SUPPORTS_WITH_FPU=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_FPU="" +# CT_ARCH_32 is not set +CT_ARCH_64=y +CT_ARCH_BITNESS=64 +CT_TARGET_CFLAGS="" +CT_TARGET_LDFLAGS="" +# CT_ARCH_alpha is not set +# CT_ARCH_arm is not set +# CT_ARCH_avr is not set +# CT_ARCH_m68k is not set +# CT_ARCH_mips is not set +# CT_ARCH_nios2 is not set +# CT_ARCH_powerpc is not set +CT_ARCH_s390=y +# CT_ARCH_sh is not set +# CT_ARCH_sparc is not set +# CT_ARCH_x86 is not set +# CT_ARCH_xtensa is not set +CT_ARCH_alpha_AVAILABLE=y +CT_ARCH_arm_AVAILABLE=y +CT_ARCH_avr_AVAILABLE=y +CT_ARCH_m68k_AVAILABLE=y +CT_ARCH_microblaze_AVAILABLE=y +CT_ARCH_mips_AVAILABLE=y +CT_ARCH_nios2_AVAILABLE=y +CT_ARCH_powerpc_AVAILABLE=y +CT_ARCH_s390_AVAILABLE=y +CT_ARCH_sh_AVAILABLE=y +CT_ARCH_sparc_AVAILABLE=y +CT_ARCH_x86_AVAILABLE=y +CT_ARCH_xtensa_AVAILABLE=y +CT_ARCH_SUFFIX="" + +# +# Generic target options +# +# CT_MULTILIB is not set +CT_ARCH_USE_MMU=y + +# +# Target optimisations +# +CT_ARCH_FLOAT="" + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +# CT_STATIC_TOOLCHAIN is not set +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +CT_CROSS=y +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +CT_KERNEL="linux" +CT_KERNEL_VERSION="2.6.32.68" +# CT_KERNEL_bare_metal is not set +CT_KERNEL_linux=y +CT_KERNEL_bare_metal_AVAILABLE=y +CT_KERNEL_linux_AVAILABLE=y +# CT_KERNEL_V_4_3 is not set +# CT_KERNEL_V_4_2 is not set +# CT_KERNEL_V_4_1 is not set +# CT_KERNEL_V_3_18 is not set +# CT_KERNEL_V_3_14 is not set +# CT_KERNEL_V_3_12 is not set +# CT_KERNEL_V_3_10 is not set +# CT_KERNEL_V_3_4 is not set +# CT_KERNEL_V_3_2 is not set +CT_KERNEL_V_2_6_32=y +# CT_KERNEL_LINUX_CUSTOM is not set +CT_KERNEL_windows_AVAILABLE=y + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# linux other options +# +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS="binutils" +CT_BINUTILS_binutils=y + +# +# GNU binutils +# +# CT_CC_BINUTILS_SHOW_LINARO is not set +CT_BINUTILS_V_2_25_1=y +# CT_BINUTILS_V_2_25 is not set +# CT_BINUTILS_V_2_24 is not set +# CT_BINUTILS_V_2_23_2 is not set +# CT_BINUTILS_V_2_23_1 is not set +# CT_BINUTILS_V_2_22 is not set +# CT_BINUTILS_V_2_21_53 is not set +# CT_BINUTILS_V_2_21_1a is not set +# CT_BINUTILS_V_2_20_1a is not set +# CT_BINUTILS_V_2_19_1a is not set +# CT_BINUTILS_V_2_18a is not set +CT_BINUTILS_VERSION="2.25.1" +CT_BINUTILS_2_25_1_or_later=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_2_24_or_later=y +CT_BINUTILS_2_23_or_later=y +CT_BINUTILS_2_22_or_later=y +CT_BINUTILS_2_21_or_later=y +CT_BINUTILS_2_20_or_later=y +CT_BINUTILS_2_19_or_later=y +CT_BINUTILS_2_18_or_later=y +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_FORCE_LD_BFD=y +CT_BINUTILS_LINKER_LD=y +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set + +# +# binutils other options +# + +# +# C-library +# +CT_LIBC="glibc" +CT_LIBC_VERSION="2.12.2" +CT_LIBC_glibc=y +# CT_LIBC_musl is not set +# CT_LIBC_uClibc is not set +CT_LIBC_avr_libc_AVAILABLE=y +CT_LIBC_glibc_AVAILABLE=y +CT_THREADS="nptl" +# CT_CC_GLIBC_SHOW_LINARO is not set +# CT_LIBC_GLIBC_V_2_22 is not set +# CT_LIBC_GLIBC_V_2_21 is not set +# CT_LIBC_GLIBC_V_2_20 is not set +# CT_LIBC_GLIBC_V_2_19 is not set +# CT_LIBC_GLIBC_V_2_18 is not set +# CT_LIBC_GLIBC_V_2_17 is not set +# CT_LIBC_GLIBC_V_2_16_0 is not set +# CT_LIBC_GLIBC_V_2_15 is not set +# CT_LIBC_GLIBC_V_2_14_1 is not set +# CT_LIBC_GLIBC_V_2_14 is not set +# CT_LIBC_GLIBC_V_2_13 is not set +CT_LIBC_GLIBC_V_2_12_2=y +# CT_LIBC_GLIBC_V_2_12_1 is not set +# CT_LIBC_GLIBC_V_2_11_1 is not set +# CT_LIBC_GLIBC_V_2_11 is not set +# CT_LIBC_GLIBC_V_2_10_1 is not set +# CT_LIBC_GLIBC_V_2_9 is not set +# CT_LIBC_GLIBC_V_2_8 is not set +CT_LIBC_mingw_AVAILABLE=y +CT_LIBC_musl_AVAILABLE=y +CT_LIBC_newlib_AVAILABLE=y +CT_LIBC_none_AVAILABLE=y +CT_LIBC_uClibc_AVAILABLE=y +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +CT_LIBC_XLDD=y + +# +# glibc other options +# +CT_LIBC_GLIBC_PORTS_EXTERNAL=y +CT_LIBC_glibc_familly=y +CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_LIBC_GLIBC_CONFIGPARMS="" +CT_LIBC_GLIBC_EXTRA_CFLAGS="" +CT_LIBC_EXTRA_CC_ARGS="" +# CT_LIBC_DISABLE_VERSIONING is not set +CT_LIBC_OLDEST_ABI="" +CT_LIBC_GLIBC_FORCE_UNWIND=y +# CT_LIBC_GLIBC_USE_PORTS is not set +CT_LIBC_ADDONS_LIST="" +# CT_LIBC_LOCALES is not set +# CT_LIBC_GLIBC_KERNEL_VERSION_NONE is not set +CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS=y +# CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_LIBC_GLIBC_MIN_KERNEL="2.6.32.68" + +# +# C compiler +# +CT_CC="gcc" +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_gcc=y +# CT_CC_GCC_SHOW_LINARO is not set +# CT_CC_GCC_V_5_2_0 is not set +CT_CC_GCC_V_4_9_3=y +# CT_CC_GCC_V_4_8_5 is not set +# CT_CC_GCC_V_4_7_4 is not set +# CT_CC_GCC_V_4_6_4 is not set +# CT_CC_GCC_V_4_5_4 is not set +# CT_CC_GCC_V_4_4_7 is not set +# CT_CC_GCC_V_4_3_6 is not set +# CT_CC_GCC_V_4_2_4 is not set +CT_CC_GCC_4_2_or_later=y +CT_CC_GCC_4_3_or_later=y +CT_CC_GCC_4_4_or_later=y +CT_CC_GCC_4_5_or_later=y +CT_CC_GCC_4_6_or_later=y +CT_CC_GCC_4_7_or_later=y +CT_CC_GCC_4_8_or_later=y +CT_CC_GCC_4_9=y +CT_CC_GCC_4_9_or_later=y +CT_CC_GCC_HAS_GRAPHITE=y +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_HAS_LTO=y +CT_CC_GCC_USE_LTO=y +CT_CC_GCC_HAS_PKGVERSION_BUGURL=y +CT_CC_GCC_HAS_BUILD_ID=y +CT_CC_GCC_HAS_LNK_HASH_STYLE=y +CT_CC_GCC_USE_GMP_MPFR=y +CT_CC_GCC_USE_MPC=y +CT_CC_GCC_HAS_LIBQUADMATH=y +CT_CC_GCC_HAS_LIBSANITIZER=y +CT_CC_GCC_VERSION="4.9.3" +# CT_CC_LANG_FORTRAN is not set +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="--with-arch=z10" +CT_CC_GCC_EXTRA_ENV_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set + +# +# Optimisation features +# + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_JAVA=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_JAVA is not set + +# +# Debug facilities +# +# CT_DEBUG_dmalloc is not set +# CT_DEBUG_duma is not set +# CT_DEBUG_gdb is not set +# CT_DEBUG_ltrace is not set +# CT_DEBUG_strace is not set + +# +# Companion libraries +# +CT_COMPLIBS_NEEDED=y +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_CLOOG_NEEDED=y +CT_MPC_NEEDED=y +CT_COMPLIBS=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_CLOOG=y +CT_MPC=y +CT_LIBICONV_V_1_14=y +CT_LIBICONV_VERSION="1.14" +CT_GETTEXT_V_0_19_6=y +CT_GETTEXT_VERSION="0.19.6" +CT_GMP_V_6_0_0=y +# CT_GMP_V_5_1_3 is not set +# CT_GMP_V_5_1_1 is not set +# CT_GMP_V_5_0_2 is not set +# CT_GMP_V_5_0_1 is not set +# CT_GMP_V_4_3_2 is not set +# CT_GMP_V_4_3_1 is not set +# CT_GMP_V_4_3_0 is not set +CT_GMP_5_0_2_or_later=y +CT_GMP_VERSION="6.0.0a" +CT_MPFR_V_3_1_3=y +# CT_MPFR_V_3_1_2 is not set +# CT_MPFR_V_3_1_0 is not set +# CT_MPFR_V_3_0_1 is not set +# CT_MPFR_V_3_0_0 is not set +# CT_MPFR_V_2_4_2 is not set +# CT_MPFR_V_2_4_1 is not set +# CT_MPFR_V_2_4_0 is not set +CT_MPFR_VERSION="3.1.3" +CT_ISL_V_0_14=y +CT_ISL_V_0_14_or_later=y +CT_ISL_V_0_12_or_later=y +CT_ISL_VERSION="0.14" +CT_CLOOG_V_0_18_4=y +# CT_CLOOG_V_0_18_1 is not set +# CT_CLOOG_V_0_18_0 is not set +CT_CLOOG_VERSION="0.18.4" +CT_CLOOG_0_18_4_or_later=y +CT_CLOOG_0_18_or_later=y +CT_MPC_V_1_0_3=y +# CT_MPC_V_1_0_2 is not set +# CT_MPC_V_1_0_1 is not set +# CT_MPC_V_1_0 is not set +# CT_MPC_V_0_9 is not set +# CT_MPC_V_0_8_2 is not set +# CT_MPC_V_0_8_1 is not set +# CT_MPC_V_0_7 is not set +CT_MPC_VERSION="1.0.3" + +# +# Companion libraries common options +# +# CT_COMPLIBS_CHECK is not set + +# +# Companion tools +# + +# +# READ HELP before you say 'Y' below !!! +# +# CT_COMP_TOOLS is not set From c051d2c8ad4b893580e891cb790aae6705ddb470 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 28 Jan 2017 21:41:35 -0800 Subject: [PATCH 74/86] Add a license to build-powerpc64le-toolchain.sh --- .../dist-powerpc64-linux/build-powerpc64le-toolchain.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh b/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh index 98fbe5045452e..8b924ca34c47c 100755 --- a/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh +++ b/src/ci/docker/dist-powerpc64-linux/build-powerpc64le-toolchain.sh @@ -1,4 +1,13 @@ #!/bin/bash +# Copyright 2017 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. set -ex From cb47d9ffc3a4fcd66e38b9065bcb9a9487dea3fc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sat, 28 Jan 2017 22:02:49 -0800 Subject: [PATCH 75/86] Fix the powerpc64 PATH --- src/ci/docker/dist-powerpc64-linux/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile index 42842d2368ac4..624763ef5de67 100644 --- a/src/ci/docker/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile @@ -68,7 +68,7 @@ RUN apt-get install -y --no-install-recommends rpm2cpio cpio COPY build-powerpc64le-toolchain.sh /tmp/ RUN ./build-powerpc64le-toolchain.sh -ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnueabihf/bin +ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin ENV \ AR_powerpc64_unknown_linux_gnu=powerpc64-unknown-linux-gnu-ar \ From 87bbb3c738e7d351d21fb19b51b2094b5afa0482 Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Sun, 29 Jan 2017 10:51:26 +0000 Subject: [PATCH 76/86] Minor grammar fix 'can not' -> 'cannot' The previous version suggested that the compiler chooses not to check, rather than being unable to check. --- src/doc/book/ffi.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book/ffi.md b/src/doc/book/ffi.md index 8ab580e6aa9fd..8d29f11aa0519 100644 --- a/src/doc/book/ffi.md +++ b/src/doc/book/ffi.md @@ -56,9 +56,9 @@ almost any function that takes a pointer argument isn't valid for all possible inputs since the pointer could be dangling, and raw pointers fall outside of Rust's safe memory model. -When declaring the argument types to a foreign function, the Rust compiler can -not check if the declaration is correct, so specifying it correctly is part of -keeping the binding correct at runtime. +When declaring the argument types to a foreign function, the Rust compiler +cannot check if the declaration is correct, so specifying it correctly is part +of keeping the binding correct at runtime. The `extern` block can be extended to cover the entire snappy API: From 149242e5190664bef3ae36e7780f33571f19c8d4 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 29 Jan 2017 20:35:11 +0900 Subject: [PATCH 77/86] Bootstrap: append libjemalloc_pic.a Fix #35349 --- src/bootstrap/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e035f8157ffde..6e077691b3a05 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -516,7 +516,7 @@ impl Config { "CFG_JEMALLOC_ROOT" if value.len() > 0 => { let target = self.target_config.entry(self.build.clone()) .or_insert(Target::default()); - target.jemalloc = Some(parse_configure_path(value)); + target.jemalloc = Some(parse_configure_path(value).join("libjemalloc_pic.a")); } "CFG_ARM_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => { let target = "arm-linux-androideabi".to_string(); From 19c9f18b2c89558300d5b71d47928878edb8bf97 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 29 Jan 2017 23:33:12 +0100 Subject: [PATCH 78/86] Add missing url in convert module --- src/libcore/convert.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 830bbc079ad1e..abd686b15e22b 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -18,25 +18,33 @@ //! support arguments of multiple types. //! //! - Impl the `As*` traits for reference-to-reference conversions -//! - Impl the `Into` trait when you want to consume the value in the conversion -//! - The `From` trait is the most flexible, useful for value _and_ reference conversions -//! - The `TryFrom` and `TryInto` traits behave like `From` and `Into`, but allow for the +//! - Impl the [`Into`] trait when you want to consume the value in the conversion +//! - The [`From`] trait is the most flexible, useful for value _and_ reference conversions +//! - The [`TryFrom`] and [`TryInto`] traits behave like [`From`] and [`Into`], but allow for the //! conversion to fail //! -//! As a library author, you should prefer implementing `From` or `TryFrom` rather than -//! `Into` or `TryInto`, as `From` and `TryFrom` provide greater flexibility and offer -//! equivalent `Into` or `TryInto` implementations for free, thanks to a blanket implementation +//! As a library author, you should prefer implementing [`From`][`From`] or +//! [`TryFrom`][`TryFrom`] rather than [`Into`][`Into`] or [`TryInto`][`TryInto`], +//! as [`From`] and [`TryFrom`] provide greater flexibility and offer +//! equivalent [`Into`] or [`TryInto`] implementations for free, thanks to a blanket implementation //! in the standard library. //! //! # Generic impl //! -//! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference -//! - `From for T` implies `Into for U` -//! - `TryFrom for T` implies `TryInto for U` -//! - `From` and `Into` are reflexive, which means that all types can `into()` +//! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference +//! - [`From`]` for T` implies [`Into`]` for U` +//! - [`TryFrom`]` for T` implies [`TryInto`]` for U` +//! - [`From`] and [`Into`] are reflexive, which means that all types can `into()` //! themselves and `from()` themselves //! //! See each trait for usage examples. +//! +//! [`Into`]: trait.Into.html +//! [`From`]: trait.From.html +//! [`TryFrom`]: trait.TryFrom.html +//! [`TryInto`]: trait.TryInto.html +//! [`AsRef`]: trait.AsRef.html +//! [`AsMut`]: trait.AsMut.html #![stable(feature = "rust1", since = "1.0.0")] From 4814fa488e44e641ff788dda9a07bbcc33a59560 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 30 Jan 2017 08:39:03 +0200 Subject: [PATCH 79/86] doc: minor Option improvements --- src/libcore/option.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 8871e1fa840ef..c4d7b2dcf96fb 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -60,7 +60,7 @@ //! the optional owned box, [`Option`]`<`[`Box`]`>`. //! //! The following example uses [`Option`] to create an optional box of -//! [`i32`]. Notice that in order to use the inner [`i32`] value first the +//! [`i32`]. Notice that in order to use the inner [`i32`] value first, the //! `check_optional` function needs to use pattern matching to //! determine whether the box has a value (i.e. it is [`Some(...)`][`Some`]) or //! not ([`None`]). @@ -74,8 +74,8 @@ //! //! fn check_optional(optional: &Option>) { //! match *optional { -//! Some(ref p) => println!("have value {}", p), -//! None => println!("have no value"), +//! Some(ref p) => println!("has value {}", p), +//! None => println!("has no value"), //! } //! } //! ``` From 45d203df302d1a4b684ffec07edc4ec7fd1fa36d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 28 Jan 2017 10:24:42 -0800 Subject: [PATCH 80/86] travis: Tweak artifact uploads * Don't upload `*.wixpdb` files by accident * Don't upload `doc` dir by accident * Fix level of indirection on Travis --- .travis.yml | 5 +++-- appveyor.yml | 1 + src/bootstrap/dist.rs | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a7dc96b34b25..5abbdbc599bd8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,11 +108,12 @@ cache: before_deploy: - mkdir -p deploy/$TRAVIS_COMMIT + - rm -rf build/dist/doc - > if [ "$TRAVIS_OS_NAME" == "osx" ]; then - cp -r build/dist deploy/$TRAVIS_COMMIT; + cp -r build/dist/* deploy/$TRAVIS_COMMIT; else - cp -r obj/build/dist deploy/$TRAVIS_COMMIT; + cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT; fi deploy: diff --git a/appveyor.yml b/appveyor.yml index 418cdcb07af4e..c617ac8a4e342 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -137,6 +137,7 @@ branches: before_deploy: - ps: | New-Item -Path deploy -ItemType directory + Remove-Item -Recurse -Force build\dist\doc Get-ChildItem -Path build\dist | Move-Item -Destination deploy Get-ChildItem -Path deploy | Foreach-Object { Push-AppveyorArtifact $_.FullName -FileName ${env:APPVEYOR_REPO_COMMIT}/$_ diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 71a5f313bbd26..5fac142f777ff 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -827,7 +827,7 @@ pub fn extended(build: &Build, stage: u32, target: &str) { cmd.arg("-nologo") .arg("-ext").arg("WixUIExtension") .arg("-ext").arg("WixUtilExtension") - .arg("-out").arg(distdir(build).join(filename)) + .arg("-out").arg(exe.join(&filename)) .arg("rust.wixobj") .arg("ui.wixobj") .arg("rustwelcomedlg.wixobj") @@ -844,6 +844,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { cmd.arg("-sice:ICE57"); build.run(&mut cmd); + + t!(fs::rename(exe.join(&filename), distdir(build).join(&filename))); } } From ffba0cea621c2609582b4e201b76b3b19860ec4f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 21 Jan 2017 17:40:31 +0300 Subject: [PATCH 81/86] Merge ty::TyBox into ty::TyAdt --- src/liballoc/boxed.rs | 1 + src/librustc/infer/freshen.rs | 1 - src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/traits/coherence.rs | 13 +--- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/select.rs | 8 +- src/librustc/ty/contents.rs | 8 +- src/librustc/ty/context.rs | 8 +- src/librustc/ty/error.rs | 1 - src/librustc/ty/fast_reject.rs | 5 -- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/item_path.rs | 3 +- src/librustc/ty/layout.rs | 77 +++++++++++-------- src/librustc/ty/mod.rs | 12 ++- src/librustc/ty/outlives.rs | 1 - src/librustc/ty/relate.rs | 6 -- src/librustc/ty/structural_impls.rs | 2 - src/librustc/ty/sty.rs | 25 +++--- src/librustc/ty/util.rs | 5 +- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 1 - src/librustc/util/ppaux.rs | 3 +- .../borrowck/mir/elaborate_drops.rs | 10 +-- src/librustc_const_eval/_match.rs | 2 - src/librustc_const_eval/pattern.rs | 2 +- src/librustc_driver/test.rs | 11 +-- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/types.rs | 5 -- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/type_check.rs | 5 +- src/librustc_trans/abi.rs | 14 ++-- src/librustc_trans/base.rs | 46 ++++++----- src/librustc_trans/collector.rs | 35 +++++---- src/librustc_trans/debuginfo/metadata.rs | 64 ++++++++------- src/librustc_trans/debuginfo/type_names.rs | 5 -- src/librustc_trans/glue.rs | 32 ++++---- src/librustc_trans/mir/analyze.rs | 2 +- src/librustc_trans/trans_item.rs | 5 -- src/librustc_trans/type_of.rs | 57 ++++++++------ src/librustc_typeck/astconv.rs | 15 +--- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 5 -- src/librustc_typeck/check/mod.rs | 3 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/coherence/builtin.rs | 2 - src/librustc_typeck/coherence/mod.rs | 4 +- src/librustc_typeck/coherence/orphan.rs | 7 -- src/librustc_typeck/variance/constraints.rs | 1 - src/librustdoc/clean/mod.rs | 31 -------- src/test/compile-fail/autoderef-full-lval.rs | 5 +- .../borrowck/borrowck-box-insensitivity.rs | 12 +-- src/test/compile-fail/cross-borrow-trait.rs | 3 +- .../compile-fail/destructure-trait-ref.rs | 3 +- src/test/compile-fail/fn-trait-formatting.rs | 9 +-- src/test/compile-fail/issue-14915.rs | 3 +- src/test/compile-fail/issue-17441.rs | 4 +- src/test/compile-fail/issue-5100.rs | 3 +- src/test/compile-fail/issue-7061.rs | 3 +- .../compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/lint-ctypes.rs | 4 +- src/test/compile-fail/map-types.rs | 2 +- .../object-does-not-impl-trait.rs | 2 +- src/test/compile-fail/occurs-check-2.rs | 2 +- src/test/compile-fail/occurs-check.rs | 2 +- .../regions-infer-paramd-indirect.rs | 4 +- src/test/compile-fail/terr-sorts.rs | 3 +- src/test/compile-fail/trivial_casts.rs | 5 +- .../type-mismatch-same-crate-name.rs | 4 +- src/test/debuginfo/type-names.rs | 12 +-- src/test/run-pass/auxiliary/issue13507.rs | 2 +- .../trait-bounds-cant-coerce.stderr | 4 +- src/test/ui/span/coerce-suggestions.stderr | 2 +- 73 files changed, 315 insertions(+), 345 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5409ade292360..d98bc1892922a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -103,6 +103,7 @@ pub struct ExchangeHeapSingleton { /// /// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] +#[fundamental] #[stable(feature = "rust1", since = "1.0.0")] pub struct Box(Unique); diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 19183892e4b0c..697a1ecadc456 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -156,7 +156,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyUint(..) | ty::TyFloat(..) | ty::TyAdt(..) | - ty::TyBox(..) | ty::TyStr | ty::TyError | ty::TyArray(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index dca85d7727a77..0e8e1921de700 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -961,7 +961,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { -> cmt<'tcx> { let ptr = match base_cmt.ty.sty { - ty::TyBox(..) => Unique, + ty::TyAdt(def, ..) if def.is_box() => Unique, ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl), ty::TyRef(r, mt) => { let bk = ty::BorrowKind::from_mutbl(mt.mutbl); diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 58cb52e897786..383fab3fcd766 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -199,7 +199,7 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt, fn uncovered_tys<'tcx>(tcx: TyCtxt, ty: Ty<'tcx>, infer_is_local: InferIsLocal) -> Vec> { - if ty_is_local_constructor(tcx, ty, infer_is_local) { + if ty_is_local_constructor(ty, infer_is_local) { vec![] } else if fundamental_ty(tcx, ty) { ty.walk_shallow() @@ -219,13 +219,13 @@ fn is_type_parameter(ty: Ty) -> bool { } fn ty_is_local(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal) -> bool { - ty_is_local_constructor(tcx, ty, infer_is_local) || + ty_is_local_constructor(ty, infer_is_local) || fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, infer_is_local)) } fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool { match ty.sty { - ty::TyBox(..) | ty::TyRef(..) => true, + ty::TyRef(..) => true, ty::TyAdt(def, _) => def.is_fundamental(), ty::TyDynamic(ref data, ..) => { data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental")) @@ -234,7 +234,7 @@ fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool { } } -fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)-> bool { +fn ty_is_local_constructor(ty: Ty, infer_is_local: InferIsLocal)-> bool { debug!("ty_is_local_constructor({:?})", ty); match ty.sty { @@ -265,11 +265,6 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)-> def.did.is_local() } - ty::TyBox(_) => { // Box - let krate = tcx.lang_items.owned_box().map(|d| d.krate); - krate == Some(LOCAL_CRATE) - } - ty::TyDynamic(ref tt, ..) => { tt.principal().map_or(false, |p| p.def_id().is_local()) } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1658efb03235a..661d47199df13 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -154,7 +154,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyStr => Some(2), ty::TyInt(..) | ty::TyUint(..) | ty::TyInfer(ty::IntVar(..)) => Some(3), ty::TyFloat(..) | ty::TyInfer(ty::FloatVar(..)) => Some(4), - ty::TyBox(..) | ty::TyRef(..) | ty::TyRawPtr(..) => Some(5), + ty::TyRef(..) | ty::TyRawPtr(..) => Some(5), ty::TyArray(..) | ty::TySlice(..) => Some(6), ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(7), ty::TyDynamic(..) => Some(8), diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 4990bb9f521d3..d51332f833d77 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1735,7 +1735,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) | ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) | - ty::TyChar | ty::TyBox(_) | ty::TyRef(..) | + ty::TyChar | ty::TyRef(..) | ty::TyArray(..) | ty::TyClosure(..) | ty::TyNever | ty::TyError => { // safe for everything @@ -1788,7 +1788,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(Vec::new())) } - ty::TyBox(_) | ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | + ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | ty::TyClosure(..) | ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { Never @@ -1865,10 +1865,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { t); } - ty::TyBox(referent_ty) => { // Box - vec![referent_ty] - } - ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) | ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => { vec![element_ty] diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index ed5b470849c41..53e8a1d0e37e5 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -191,10 +191,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> { TC::None } - ty::TyBox(typ) => { - tc_ty(tcx, typ, cache).owned_pointer() - } - ty::TyDynamic(..) => { TC::All - TC::InteriorParam } @@ -227,6 +223,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> { |ty| tc_ty(tcx, *ty, cache)) } + ty::TyAdt(def, _) if def.is_box() => { + tc_ty(tcx, ty.boxed_ty(), cache).owned_pointer() + } + ty::TyAdt(def, substs) => { let mut res = TypeContents::union(&def.variants, |v| { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 931d83f5e188a..ce4a6a3182635 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -19,6 +19,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; +use middle::lang_items; use middle::region::RegionMaps; use middle::resolve_lifetime; use middle::stability; @@ -1088,7 +1089,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { pub fn print_debug_stats(self) { sty_debug_print!( self, - TyAdt, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, + TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyDynamic, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon); println!("Substs interner: #{}", self.interners.substs.borrow().len()); @@ -1336,7 +1337,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.mk_ty(TyBox(ty)) + let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem); + let adt_def = self.lookup_adt_def(def_id); + let substs = self.mk_substs(iter::once(Kind::from(ty))); + self.mk_ty(TyAdt(adt_def, substs)) } pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 91087a3dcecd0..29d855a7fcb78 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -181,7 +181,6 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), - ty::TyBox(_) => "box".to_string(), ty::TyArray(_, n) => format!("array of {} elements", n), ty::TySlice(_) => "slice".to_string(), ty::TyRawPtr(_) => "*-ptr".to_string(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 7b4d76ad4973e..94b9abc72025f 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -11,7 +11,6 @@ use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use syntax::ast; -use middle::lang_items::OwnedBoxLangItem; use self::SimplifiedType::*; @@ -69,10 +68,6 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, // view of possibly unifying simplify_type(tcx, mt.ty, can_simplify_params) } - ty::TyBox(_) => { - // treat like we would treat `Box` - Some(AdtSimplifiedType(tcx.require_lang_item(OwnedBoxLangItem))) - } ty::TyClosure(def_id, _) => { Some(ClosureSimplifiedType(def_id)) } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index a06d3ed6cf4fb..0de77526b5a46 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -138,7 +138,7 @@ impl FlagComputation { self.add_region(r); } - &ty::TyBox(tt) | &ty::TyArray(tt, _) | &ty::TySlice(tt) => { + &ty::TyArray(tt, _) | &ty::TySlice(tt) => { self.add_ty(tt) } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index d488cd1c42711..b719911d18cf8 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -314,8 +314,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyDynamic(data, ..) => data.principal().map(|p| p.def_id()), ty::TyArray(subty, _) | - ty::TySlice(subty) | - ty::TyBox(subty) => characteristic_def_id_of_type(subty), + ty::TySlice(subty) => characteristic_def_id_of_type(subty), ty::TyRawPtr(mt) | ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index ff95554dbbfcd..78364abdaecba 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1053,6 +1053,23 @@ impl<'a, 'gcx, 'tcx> Layout { let dl = &tcx.data_layout; assert!(!ty.has_infer_types()); + let ptr_layout = |pointee: Ty<'gcx>| { + let non_zero = !ty.is_unsafe_ptr(); + let pointee = normalize_associated_type(infcx, pointee); + if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { + Ok(Scalar { value: Pointer, non_zero: non_zero }) + } else { + let unsized_part = tcx.struct_tail(pointee); + let meta = match unsized_part.sty { + ty::TySlice(_) | ty::TyStr => { + Int(dl.ptr_sized_integer()) + } + ty::TyDynamic(..) => Pointer, + _ => return Err(LayoutError::Unknown(unsized_part)) + }; + Ok(FatPointer { metadata: meta, non_zero: non_zero }) + } + }; let layout = match ty.sty { // Basic scalars. @@ -1082,24 +1099,12 @@ impl<'a, 'gcx, 'tcx> Layout { }, // Potentially-fat pointers. - ty::TyBox(pointee) | ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - let non_zero = !ty.is_unsafe_ptr(); - let pointee = normalize_associated_type(infcx, pointee); - if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { - Scalar { value: Pointer, non_zero: non_zero } - } else { - let unsized_part = tcx.struct_tail(pointee); - let meta = match unsized_part.sty { - ty::TySlice(_) | ty::TyStr => { - Int(dl.ptr_sized_integer()) - } - ty::TyDynamic(..) => Pointer, - _ => return Err(LayoutError::Unknown(unsized_part)) - }; - FatPointer { metadata: meta, non_zero: non_zero } - } + ptr_layout(pointee)? + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_layout(ty.boxed_ty())? } // Arrays and slices. @@ -1560,26 +1565,32 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> { Err(err) => err }; + let ptr_skeleton = |pointee: Ty<'gcx>| { + let non_zero = !ty.is_unsafe_ptr(); + let tail = tcx.struct_tail(pointee); + match tail.sty { + ty::TyParam(_) | ty::TyProjection(_) => { + assert!(tail.has_param_types() || tail.has_self_ty()); + Ok(SizeSkeleton::Pointer { + non_zero: non_zero, + tail: tcx.erase_regions(&tail) + }) + } + _ => { + bug!("SizeSkeleton::compute({}): layout errored ({}), yet \ + tail `{}` is not a type parameter or a projection", + ty, err, tail) + } + } + }; + match ty.sty { - ty::TyBox(pointee) | ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - let non_zero = !ty.is_unsafe_ptr(); - let tail = tcx.struct_tail(pointee); - match tail.sty { - ty::TyParam(_) | ty::TyProjection(_) => { - assert!(tail.has_param_types() || tail.has_self_ty()); - Ok(SizeSkeleton::Pointer { - non_zero: non_zero, - tail: tcx.erase_regions(&tail) - }) - } - _ => { - bug!("SizeSkeleton::compute({}): layout errored ({}), yet \ - tail `{}` is not a type parameter or a projection", - ty, err, tail) - } - } + ptr_skeleton(pointee) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_skeleton(ty.boxed_ty()) } ty::TyAdt(def, substs) => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 702f3681a020c..db21d35f990d3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1302,6 +1302,7 @@ bitflags! { const IS_SIMD = 1 << 4, const IS_FUNDAMENTAL = 1 << 5, const IS_UNION = 1 << 6, + const IS_BOX = 1 << 7, } } @@ -1376,6 +1377,9 @@ impl<'a, 'gcx, 'tcx> AdtDef { if Some(did) == tcx.lang_items.phantom_data() { flags = flags | AdtFlags::IS_PHANTOM_DATA; } + if Some(did) == tcx.lang_items.owned_box() { + flags = flags | AdtFlags::IS_BOX; + } match kind { AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM, AdtKind::Union => flags = flags | AdtFlags::IS_UNION, @@ -1468,6 +1472,12 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA) } + /// Returns true if this is Box. + #[inline] + pub fn is_box(&self) -> bool { + self.flags.get().intersects(AdtFlags::IS_BOX) + } + /// Returns whether this type has a destructor. pub fn has_dtor(&self) -> bool { self.dtor_kind().is_present() @@ -1641,7 +1651,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { -> Vec> { let result = match ty.sty { TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | + TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | TyArray(..) | TyClosure(..) | TyNever => { vec![] } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index eb384eec6a6f1..bc30f1fb71722 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -167,7 +167,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::TyFloat(..) | // OutlivesScalar ty::TyNever | // ... ty::TyAdt(..) | // OutlivesNominalType - ty::TyBox(..) | // OutlivesNominalType (ish) ty::TyAnon(..) | // OutlivesNominalType (ish) ty::TyStr | // OutlivesScalar (ish) ty::TyArray(..) | // ... diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 76c26d01ac8e2..89514085e1c78 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -418,12 +418,6 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, Ok(tcx.mk_closure_from_closure_substs(a_id, substs)) } - (&ty::TyBox(a_inner), &ty::TyBox(b_inner)) => - { - let typ = relation.relate(&a_inner, &b_inner)?; - Ok(tcx.mk_box(typ)) - } - (&ty::TyRawPtr(ref a_mt), &ty::TyRawPtr(ref b_mt)) => { let mt = relation.relate(a_mt, b_mt)?; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 06ba1b2a1fafc..05f4abad46921 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -468,7 +468,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { let sty = match self.sty { - ty::TyBox(typ) => ty::TyBox(typ.fold_with(folder)), ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)), ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz), ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)), @@ -506,7 +505,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match self.sty { - ty::TyBox(typ) => typ.visit_with(visitor), ty::TyRawPtr(ref tm) => tm.visit_with(visitor), ty::TyArray(typ, _sz) => typ.visit_with(visitor), ty::TySlice(typ) => typ.visit_with(visitor), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d6164e69ffd3a..d7686b60ae31e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -115,12 +115,6 @@ pub enum TypeVariants<'tcx> { /// definition and not a concrete use of it. TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>), - /// `Box`; this is nominally a struct in the documentation, but is - /// special-cased internally. For example, it is possible to implicitly - /// move the contents of a box out of that box, and methods of any type - /// can have type `Box`. - TyBox(Ty<'tcx>), - /// The pointee of a string slice. Written as `str`. TyStr, @@ -1139,10 +1133,18 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - pub fn is_unique(&self) -> bool { + pub fn is_box(&self) -> bool { match self.sty { - TyBox(_) => true, - _ => false + TyAdt(def, _) => def.is_box(), + _ => false, + } + } + + pub fn boxed_ty(&self) -> Ty<'tcx> { + match self.sty { + TyAdt(def, substs) if def.is_box() => + substs.types().next().expect("Box doesn't have type parameters"), + _ => bug!("`boxed_ty` is called on non-box type {:?}", self), } } @@ -1247,9 +1249,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { -> Option> { match self.sty { - TyBox(ty) => { + TyAdt(def, _) if def.is_box() => { Some(TypeAndMut { - ty: ty, + ty: self.boxed_ty(), mutbl: if pref == ty::PreferMutLvalue { hir::MutMutable } else { @@ -1349,7 +1351,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { TyInt(_) | TyUint(_) | TyFloat(_) | - TyBox(_) | TyStr | TyArray(..) | TySlice(_) | diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index c05375c47b03a..ba49aa1ef4866 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -481,7 +481,6 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyBool | TyChar | TyStr | - TyBox(_) | TySlice(_) => {} TyError | @@ -563,7 +562,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { mutbl: hir::MutImmutable, .. }) => Some(false), - TyStr | TyBox(..) | TyRef(_, TypeAndMut { + TyStr | TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) => Some(true), @@ -606,7 +605,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { // Fast-path for primitive types let result = match self.sty { TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | + TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true), TyStr | TyDynamic(..) | TySlice(_) => Some(false), diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 3fa7a803141d1..0d1dc2e4d7c21 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -83,7 +83,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => { } - ty::TyBox(ty) | ty::TyArray(ty, _) | ty::TySlice(ty) => { + ty::TyArray(ty, _) | ty::TySlice(ty) => { stack.push(ty); } ty::TyRawPtr(ref mt) | ty::TyRef(_, ref mt) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index bab9964651dca..33b70b09dcb7b 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -323,7 +323,6 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } } - ty::TyBox(_) | ty::TyRawPtr(_) => { // simple cases that are WF if their type args are WF } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 74e27f84fddc2..aa2eb2955debe 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -16,7 +16,7 @@ use ty::{TyBool, TyChar, TyAdt}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyProjection, TyAnon}; -use ty::{TyBox, TyDynamic, TyInt, TyUint, TyInfer}; +use ty::{TyDynamic, TyInt, TyUint, TyInfer}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use std::cell::Cell; @@ -708,7 +708,6 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyInt(t) => write!(f, "{}", t.ty_to_string()), TyUint(t) => write!(f, "{}", t.ty_to_string()), TyFloat(t) => write!(f, "{}", t.ty_to_string()), - TyBox(typ) => write!(f, "Box<{}>", typ), TyRawPtr(ref tm) => { write!(f, "*{} {}", match tm.mutbl { hir::MutMutable => "mut", diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 8e0d9c147824d..d555502c3ff85 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -709,9 +709,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn open_drop<'a>(&mut self, c: &DropCtxt<'a, 'tcx>) -> BasicBlock { let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx); match ty.sty { - ty::TyAdt(def, substs) => { - self.open_drop_for_adt(c, def, substs) - } ty::TyClosure(def_id, substs) => { let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx).collect(); self.open_drop_for_tuple(c, &tys) @@ -719,8 +716,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { ty::TyTuple(tys) => { self.open_drop_for_tuple(c, tys) } - ty::TyBox(ty) => { - self.open_drop_for_box(c, ty) + ty::TyAdt(def, _) if def.is_box() => { + self.open_drop_for_box(c, ty.boxed_ty()) + } + ty::TyAdt(def, substs) => { + self.open_drop_for_adt(c, def, substs) } _ => bug!("open drop from non-ADT `{:?}`", ty) } diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 1770a112cdf23..94b2ba58c9aa5 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -722,7 +722,6 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize debug!("constructor_arity({:?}, {:?})", ctor, ty); match ty.sty { ty::TyTuple(ref fs) => fs.len(), - ty::TyBox(_) => 1, ty::TySlice(..) | ty::TyArray(..) => match *ctor { Slice(length) => length, ConstantValue(_) => 0, @@ -747,7 +746,6 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, debug!("constructor_sub_pattern_tys({:?}, {:?})", ctor, ty); match ty.sty { ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(), - ty::TyBox(ty) => vec![ty], ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { Slice(length) => repeat(ty).take(length).collect(), ConstantValue(_) => vec![], diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index a3b80ebddcf00..c6272613f4d09 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -215,7 +215,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { } PatternKind::Deref { ref subpattern } => { match self.ty.sty { - ty::TyBox(_) => write!(f, "box ")?, + ty::TyAdt(def, _) if def.is_box() => write!(f, "box ")?, ty::TyRef(_, mt) => { write!(f, "&")?; if mt.mutbl == hir::MutMutable { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 59f6889ba4d94..1086d75f02cb4 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -805,10 +805,9 @@ fn walk_ty() { let uint_ty = tcx.types.usize; let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]); - let uniq_ty = tcx.mk_box(tup2_ty); - let walked: Vec<_> = uniq_ty.walk().collect(); + let walked: Vec<_> = tup2_ty.walk().collect(); assert_eq!(walked, - [uniq_ty, tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty, + [tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, uint_ty]); }) } @@ -821,12 +820,10 @@ fn walk_ty_skip_subtree() { let uint_ty = tcx.types.usize; let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]); - let uniq_ty = tcx.mk_box(tup2_ty); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. - let mut expected = vec![(uniq_ty, false), - (tup2_ty, false), + let mut expected = vec![(tup2_ty, false), (tup1_ty, false), (int_ty, false), (uint_ty, false), @@ -836,7 +833,7 @@ fn walk_ty_skip_subtree() { (uint_ty, false)]; expected.reverse(); - let mut walker = uniq_ty.walk(); + let mut walker = tup2_ty.walk(); while let Some(t) = walker.next() { debug!("walked to {:?}", t); let (expected_ty, skip) = expected.pop().unwrap(); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2892d61b8bd6f..1592d17817641 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -95,7 +95,7 @@ pub struct BoxPointers; impl BoxPointers { fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext, span: Span, ty: Ty) { for leaf_ty in ty.walk() { - if let ty::TyBox(_) = leaf_ty.sty { + if leaf_ty.is_box() { let m = format!("type uses owned (Box type) pointers: {}", ty); cx.span_lint(BOX_POINTERS, span, &m); } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 532e602226450..9669efa2d86b3 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -519,11 +519,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // Primitive types with a stable representation. ty::TyBool | ty::TyInt(..) | ty::TyUint(..) | ty::TyFloat(..) | ty::TyNever => FfiSafe, - ty::TyBox(..) => { - FfiUnsafe("found Rust type Box<_> in foreign module, \ - consider using a raw pointer instead") - } - ty::TySlice(_) => { FfiUnsafe("found Rust slice type in foreign module, \ consider using a raw pointer instead") diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index af9f7fb578138..9c1107344f241 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -350,7 +350,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { base: Lvalue::Local(index), elem: ProjectionElem::Deref }) if self.mir.local_kind(index) == LocalKind::Temp - && self.mir.local_decls[index].ty.is_unique() + && self.mir.local_decls[index].ty.is_box() && self.temp_qualif[index].map_or(false, |qualif| { qualif.intersects(Qualif::NOT_CONST) }) => { diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 0fabbe6678ad8..c9195f29f1784 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -580,9 +580,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { return; } - let arg_ty = match args[0].ty(mir, self.tcx()).sty { + let ty = args[0].ty(mir, self.tcx()); + let arg_ty = match ty.sty { ty::TyRawPtr(mt) => mt.ty, - ty::TyBox(ty) => ty, + ty::TyAdt(def, _) if def.is_box() => ty.boxed_ty(), _ => { span_mirbug!(self, term, "box_free called with bad arg ty"); return; diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 577744653f09b..d392ebaa33d42 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -429,7 +429,7 @@ impl FnType { if !type_is_fat_ptr(ccx, ret_ty) { // The `noalias` attribute on the return value is useful to a // function ptr caller. - if let ty::TyBox(_) = ret_ty.sty { + if ret_ty.is_box() { // `Box` pointer return values never alias because ownership // is transferred ret.attrs.set(ArgAttribute::NoAlias); @@ -438,12 +438,16 @@ impl FnType { // We can also mark the return value as `dereferenceable` in certain cases match ret_ty.sty { // These are not really pointers but pairs, (pointer, len) - ty::TyRef(_, ty::TypeAndMut { ty, .. }) | - ty::TyBox(ty) => { + ty::TyRef(_, ty::TypeAndMut { ty, .. }) => { let llty = type_of::sizing_type_of(ccx, ty); let llsz = llsize_of_alloc(ccx, llty); ret.attrs.set_dereferenceable(llsz); } + ty::TyAdt(def, _) if def.is_box() => { + let llty = type_of::sizing_type_of(ccx, ret_ty.boxed_ty()); + let llsz = llsize_of_alloc(ccx, llty); + ret.attrs.set_dereferenceable(llsz); + } _ => {} } } @@ -453,9 +457,9 @@ impl FnType { // Handle safe Rust thin and fat pointers. let rust_ptr_attrs = |ty: Ty<'tcx>, arg: &mut ArgType| match ty.sty { // `Box` pointer parameters never alias because ownership is transferred - ty::TyBox(inner) => { + ty::TyAdt(def, _) if def.is_box() => { arg.attrs.set(ArgAttribute::NoAlias); - Some(inner) + Some(ty.boxed_ty()) } ty::TyRef(b, mt) => { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 32fe3effcc9f8..9bd19d5bbb3e4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -227,7 +227,6 @@ pub fn unsize_thin_ptr<'a, 'tcx>( ) -> (ValueRef, ValueRef) { debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); match (&src_ty.sty, &dst_ty.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), @@ -238,6 +237,12 @@ pub fn unsize_thin_ptr<'a, 'tcx>( let ptr_ty = type_of::in_memory_type_of(bcx.ccx, b).ptr_to(); (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty()); + assert!(bcx.ccx.shared().type_is_sized(a)); + let ptr_ty = type_of::in_memory_type_of(bcx.ccx, b).ptr_to(); + (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) + } _ => bug!("unsize_thin_ptr: called on bad types"), } } @@ -249,25 +254,30 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, src_ty: Ty<'tcx>, dst: ValueRef, dst_ty: Ty<'tcx>) { + let coerce_ptr = || { + let (base, info) = if common::type_is_fat_ptr(bcx.ccx, src_ty) { + // fat-ptr to fat-ptr unsize preserves the vtable + // i.e. &'a fmt::Debug+Send => &'a fmt::Debug + // So we need to pointercast the base to ensure + // the types match up. + let (base, info) = load_fat_ptr(bcx, src, src_ty); + let llcast_ty = type_of::fat_ptr_base_ty(bcx.ccx, dst_ty); + let base = bcx.pointercast(base, llcast_ty); + (base, info) + } else { + let base = load_ty(bcx, src, src_ty); + unsize_thin_ptr(bcx, base, src_ty, dst_ty) + }; + store_fat_ptr(bcx, base, info, dst, dst_ty); + }; match (&src_ty.sty, &dst_ty.sty) { - (&ty::TyBox(..), &ty::TyBox(..)) | (&ty::TyRef(..), &ty::TyRef(..)) | (&ty::TyRef(..), &ty::TyRawPtr(..)) | (&ty::TyRawPtr(..), &ty::TyRawPtr(..)) => { - let (base, info) = if common::type_is_fat_ptr(bcx.ccx, src_ty) { - // fat-ptr to fat-ptr unsize preserves the vtable - // i.e. &'a fmt::Debug+Send => &'a fmt::Debug - // So we need to pointercast the base to ensure - // the types match up. - let (base, info) = load_fat_ptr(bcx, src, src_ty); - let llcast_ty = type_of::fat_ptr_base_ty(bcx.ccx, dst_ty); - let base = bcx.pointercast(base, llcast_ty); - (base, info) - } else { - let base = load_ty(bcx, src, src_ty); - unsize_thin_ptr(bcx, base, src_ty, dst_ty) - }; - store_fat_ptr(bcx, base, info, dst, dst_ty); + coerce_ptr() + } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + coerce_ptr() } (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => { @@ -414,7 +424,7 @@ pub fn load_ty<'a, 'tcx>(b: &Builder<'a, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> V // a char is a Unicode codepoint, and so takes values from 0 // to 0x10FFFF inclusive only. b.load_range_assert(ptr, 0, 0x10FFFF + 1, llvm::False) - } else if (t.is_region_ptr() || t.is_unique()) && !common::type_is_fat_ptr(ccx, t) { + } else if (t.is_region_ptr() || t.is_box()) && !common::type_is_fat_ptr(ccx, t) { b.load_nonnull(ptr) } else { b.load(ptr) @@ -449,7 +459,7 @@ pub fn load_fat_ptr<'a, 'tcx>( b: &Builder<'a, 'tcx>, src: ValueRef, t: Ty<'tcx> ) -> (ValueRef, ValueRef) { let ptr = get_dataptr(b, src); - let ptr = if t.is_region_ptr() || t.is_unique() { + let ptr = if t.is_region_ptr() || t.is_box() { b.load_nonnull(ptr) } else { b.load(ptr) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index fa8bad5807aaf..9766b816d9b30 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -721,14 +721,13 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, debug!("find_drop_glue_neighbors: {}", type_to_string(scx.tcx(), ty)); // Make sure the BoxFreeFn lang-item gets translated if there is a boxed value. - if let ty::TyBox(content_type) = ty.sty { + if ty.is_box() { let def_id = scx.tcx().require_lang_item(BoxFreeFnLangItem); - if should_trans_locally(scx.tcx(), def_id) { let box_free_fn_trans_item = create_fn_trans_item(scx, def_id, - scx.tcx().mk_substs(iter::once(Kind::from(content_type))), + scx.tcx().mk_substs(iter::once(Kind::from(ty.boxed_ty()))), scx.tcx().intern_substs(&[])); output.push(box_free_fn_trans_item); } @@ -790,8 +789,14 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, ty::TyDynamic(..) => { /* nothing to do */ } - ty::TyAdt(adt_def, substs) => { - for field in adt_def.all_fields() { + ty::TyAdt(def, _) if def.is_box() => { + let inner_type = glue::get_drop_glue_type(scx, ty.boxed_ty()); + if scx.type_needs_drop(inner_type) { + output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type))); + } + } + ty::TyAdt(def, substs) => { + for field in def.all_fields() { let field_type = scx.tcx().item_type(field.did); let field_type = monomorphize::apply_param_substs(scx, substs, @@ -811,7 +816,6 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, } } } - ty::TyBox(inner_type) | ty::TySlice(inner_type) | ty::TyArray(inner_type, _) => { let inner_type = glue::get_drop_glue_type(scx, inner_type); @@ -1008,21 +1012,24 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, source_ty: ty::Ty<'tcx>, target_ty: ty::Ty<'tcx>) -> (ty::Ty<'tcx>, ty::Ty<'tcx>) { + let ptr_vtable = |inner_source: ty::Ty<'tcx>, inner_target: ty::Ty<'tcx>| { + if !scx.type_is_sized(inner_source) { + (inner_source, inner_target) + } else { + scx.tcx().struct_lockstep_tails(inner_source, inner_target) + } + }; match (&source_ty.sty, &target_ty.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { - let (inner_source, inner_target) = (a, b); - - if !scx.type_is_sized(inner_source) { - (inner_source, inner_target) - } else { - scx.tcx().struct_lockstep_tails(inner_source, inner_target) - } + ptr_vtable(a, b) + } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty()) } (&ty::TyAdt(source_adt_def, source_substs), diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 0de3c13dc21a9..b7e319f2de434 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -490,6 +490,35 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug!("type_metadata: {:?}", t); let sty = &t.sty; + let ptr_metadata = |ty: Ty<'tcx>| { + match ty.sty { + ty::TySlice(typ) => { + Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)) + } + ty::TyStr => { + Ok(vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)) + } + ty::TyDynamic(..) => { + Ok(MetadataCreationResult::new( + trait_pointer_metadata(cx, ty, Some(t), unique_type_id), + false)) + } + _ => { + let pointee_metadata = type_metadata(cx, ty, usage_site_span); + + match debug_context(cx).type_map + .borrow() + .find_metadata_for_unique_id(unique_type_id) { + Some(metadata) => return Err(metadata), + None => { /* proceed normally */ } + }; + + Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), + false)) + } + } + }; + let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty { ty::TyNever | ty::TyBool | @@ -516,34 +545,17 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, trait_pointer_metadata(cx, t, None, unique_type_id), false) } - ty::TyBox(ty) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) => { - match ty.sty { - ty::TySlice(typ) => { - vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span) - } - ty::TyStr => { - vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span) - } - ty::TyDynamic(..) => { - MetadataCreationResult::new( - trait_pointer_metadata(cx, ty, Some(t), unique_type_id), - false) - } - _ => { - let pointee_metadata = type_metadata(cx, ty, usage_site_span); - - match debug_context(cx).type_map - .borrow() - .find_metadata_for_unique_id(unique_type_id) { - Some(metadata) => return metadata, - None => { /* proceed normally */ } - }; - - MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), - false) - } + match ptr_metadata(ty) { + Ok(res) => res, + Err(metadata) => return metadata, + } + } + ty::TyAdt(def, _) if def.is_box() => { + match ptr_metadata(t.boxed_ty()) { + Ok(res) => res, + Err(metadata) => return metadata, } } ty::TyFnDef(.., ref barefnty) | ty::TyFnPtr(ref barefnty) => { diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 788ce32937d84..8e11bf6b8976a 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -60,11 +60,6 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } output.push(')'); }, - ty::TyBox(inner_type) => { - output.push_str("Box<"); - push_debuginfo_type_name(cx, inner_type, true, output); - output.push('>'); - }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { output.push('*'); match mutbl { diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index b24f00ee6976d..65f3c7add4db1 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -79,16 +79,21 @@ pub fn get_drop_glue_type<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'t return scx.tcx().types.i8; } match t.sty { - ty::TyBox(typ) if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) => { - scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| { - let layout = t.layout(&infcx).unwrap(); - if layout.size(&scx.tcx().data_layout).bytes() == 0 { - // `Box` does not allocate. - scx.tcx().types.i8 - } else { - t - } - }) + ty::TyAdt(def, _) if def.is_box() => { + let typ = t.boxed_ty(); + if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) { + scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| { + let layout = t.layout(&infcx).unwrap(); + if layout.size(&scx.tcx().data_layout).bytes() == 0 { + // `Box` does not allocate. + scx.tcx().types.i8 + } else { + t + } + }) + } else { + t + } } _ => t } @@ -205,11 +210,12 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi }; let bcx = match t.sty { - ty::TyBox(content_ty) => { - // Support for TyBox is built-in and its drop glue is + ty::TyAdt(def, _) if def.is_box() => { + // Support for Box is built-in and its drop glue is // special. It may move to library and have Drop impl. As - // a safe-guard, assert TyBox not used with TyContents. + // a safe-guard, assert Box not used with TyContents. assert!(!skip_dtor); + let content_ty = t.boxed_ty(); let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) { let llbox = bcx.load(get_dataptr(&bcx, ptr.llval)); let info = bcx.load(get_meta(&bcx, ptr.llval)); diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 8df24da713588..2a1ab10d74e16 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -30,7 +30,7 @@ pub fn lvalue_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector { let ty = mircx.monomorphize(&ty); debug!("local {} has type {:?}", index, ty); if ty.is_scalar() || - ty.is_unique() || + ty.is_box() || ty.is_region_ptr() || ty.is_simd() || common::type_is_zero_size(mircx.ccx, ty) diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 43ea1e56a5a4d..d58a93e3cb71c 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -421,11 +421,6 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } output.push(')'); }, - ty::TyBox(inner_type) => { - output.push_str("Box<"); - self.push_type_name(inner_type, output); - output.push('>'); - }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { output.push('*'); match mutbl { diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 469214b466e1a..4df0e989ada99 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -38,6 +38,13 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ debug!("sizing_type_of {:?}", t); let _recursion_lock = cx.enter_type_of(t); + let ptr_sizing_ty = |ty: Ty<'tcx>| { + if cx.shared().type_is_sized(ty) { + Type::i8p(cx) + } else { + Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, ty)], false) + } + }; let llsizingty = match t.sty { _ if !cx.shared().type_is_sized(t) => { Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, t)], false) @@ -50,14 +57,12 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ ty::TyFloat(t) => Type::float_from_ty(cx, t), ty::TyNever => Type::nil(cx), - ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => { - if cx.shared().type_is_sized(ty) { - Type::i8p(cx) - } else { - Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, ty)], false) - } + ptr_sizing_ty(ty) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_sizing_ty(t.boxed_ty()) } ty::TyFnDef(..) => Type::nil(cx), @@ -131,11 +136,13 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ pub fn fat_ptr_base_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type { match ty.sty { - ty::TyBox(t) | ty::TyRef(_, ty::TypeAndMut { ty: t, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) if !ccx.shared().type_is_sized(t) => { in_memory_type_of(ccx, t).ptr_to() } + ty::TyAdt(def, _) if def.is_box() => { + in_memory_type_of(ccx, ty.boxed_ty()).ptr_to() + } _ => bug!("expected fat ptr ty but got {:?}", ty) } } @@ -214,6 +221,22 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> return llty; } + let ptr_ty = |ty: Ty<'tcx>| { + if !cx.shared().type_is_sized(ty) { + if let ty::TyStr = ty.sty { + // This means we get a nicer name in the output (str is always + // unsized). + cx.str_slice_type() + } else { + let ptr_ty = in_memory_type_of(cx, ty).ptr_to(); + let info_ty = unsized_info_ty(cx, ty); + Type::struct_(cx, &[ptr_ty, info_ty], false) + } + } else { + in_memory_type_of(cx, ty).ptr_to() + } + }; + let mut llty = match t.sty { ty::TyBool => Type::bool(cx), ty::TyChar => Type::char(cx), @@ -227,22 +250,12 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> adt::incomplete_type_of(cx, t, "closure") } - ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => { - if !cx.shared().type_is_sized(ty) { - if let ty::TyStr = ty.sty { - // This means we get a nicer name in the output (str is always - // unsized). - cx.str_slice_type() - } else { - let ptr_ty = in_memory_type_of(cx, ty).ptr_to(); - let info_ty = unsized_info_ty(cx, ty); - Type::struct_(cx, &[ptr_ty, info_ty], false) - } - } else { - in_memory_type_of(cx, ty).ptr_to() - } + ptr_ty(ty) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_ty(t.boxed_ty()) } ty::TyArray(ty, size) => { @@ -300,7 +313,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // If this was an enum or struct, fill in the type now. match t.sty { - ty::TyAdt(..) | ty::TyClosure(..) if !t.is_simd() => { + ty::TyAdt(..) | ty::TyClosure(..) if !t.is_simd() && !t.is_box() => { adt::finish_type_of(cx, t, &mut llty); } _ => () diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 56de539cbfe99..bb9a487802e7b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -670,16 +670,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } }; - let substs = self.ast_path_substs_for_ty(span, - did, - item_segment); - - // FIXME(#12938): This is a hack until we have full support for DST. - if Some(did) == self.tcx().lang_items.owned_box() { - assert_eq!(substs.types().count(), 1); - return self.tcx().mk_box(substs.type_at(0)); - } - + let substs = self.ast_path_substs_for_ty(span, did, item_segment); decl_ty.subst(self.tcx(), substs) } @@ -1674,7 +1665,7 @@ impl<'tcx> ExplicitSelf<'tcx> { fn count_modifiers(ty: Ty) -> usize { match ty.sty { ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1, - ty::TyBox(t) => count_modifiers(t) + 1, + ty::TyAdt(def, _) if def.is_box() => count_modifiers(ty.boxed_ty()) + 1, _ => 0, } } @@ -1687,7 +1678,7 @@ impl<'tcx> ExplicitSelf<'tcx> { } else { match self_arg_ty.sty { ty::TyRef(r, mt) => ExplicitSelf::ByReference(r, mt.mutbl), - ty::TyBox(_) => ExplicitSelf::ByBox, + ty::TyAdt(def, _) if def.is_box() => ExplicitSelf::ByBox, _ => ExplicitSelf::ByValue, } } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 0218f1c70ba8e..6215b4498dc68 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { tstr); } } - ty::TyBox(..) => { + ty::TyAdt(def, ..) if def.is_box() => { match fcx.tcx.sess.codemap().span_to_snippet(self.cast_span) { Ok(s) => { err.span_suggestion(self.cast_span, diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 91b772a748c72..34aa4eda772ad 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -448,7 +448,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>( Ok(()) } - ty::TyBox(ity) | ty::TyArray(ity, _) | ty::TySlice(ity) => { + ty::TyArray(ity, _) | ty::TySlice(ity) => { // single-element containers, behave like their element iterate_over_potentially_unsafe_regions_in_type( cx, context, ity, depth+1) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index e2d7d31a8a890..300caca30fec8 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -391,11 +391,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { ty::TyAdt(def, _) => { self.assemble_inherent_impl_candidates_for_type(def.did); } - ty::TyBox(_) => { - if let Some(box_did) = self.tcx.lang_items.owned_box() { - self.assemble_inherent_impl_candidates_for_type(box_did); - } - } ty::TyParam(p) => { self.assemble_inherent_candidates_from_param(self_ty, p); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c2f32c2b52bbe..c435f9341253e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3438,7 +3438,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprBox(ref subexpr) => { let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| { match ty.sty { - ty::TyBox(ty) => Expectation::rvalue_hint(self, ty), + ty::TyAdt(def, _) if def.is_box() + => Expectation::rvalue_hint(self, ty.boxed_ty()), _ => NoExpectation } }); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 7d515a36cfdff..d84e9d3fd3731 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -815,9 +815,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.type_must_outlive(infer::RelateObjectBound(cast_expr.span), from_ty, r); } - /*From:*/ (&ty::TyBox(from_referent_ty), - /*To: */ &ty::TyBox(to_referent_ty)) => { - self.walk_cast(cast_expr, from_referent_ty, to_referent_ty); + /*From:*/ (&ty::TyAdt(from_def, _), + /*To: */ &ty::TyAdt(to_def, _)) if from_def.is_box() && to_def.is_box() => { + self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty()); } _ => { } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 086484c643ad1..96875fce468d2 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -220,8 +220,6 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (mt_a.ty, mt_b.ty, unsize_trait, None) }; let (source, target, trait_def_id, kind) = match (&source.sty, &target.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) => (a, b, unsize_trait, None), - (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => { infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty)) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 5af9ea29fafa7..e9c710d2fec4c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -21,7 +21,7 @@ use rustc::ty::{Ty, TyBool, TyChar, TyError}; use rustc::ty::{TyParam, TyRawPtr}; use rustc::ty::{TyRef, TyAdt, TyDynamic, TyNever, TyTuple}; use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt}; -use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr}; +use rustc::ty::{TyUint, TyClosure, TyFnDef, TyFnPtr}; use rustc::ty::{TyProjection, TyAnon}; use CrateCtxt; use syntax_pos::Span; @@ -61,8 +61,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { TyDynamic(ref t, ..) => t.principal().map(|p| p.def_id()), - TyBox(_) => self.tcx.lang_items.owned_box(), - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyStr | TyArray(..) | TySlice(..) | TyFnDef(..) | TyFnPtr(_) | TyTuple(..) | TyParam(..) | TyError | TyNever | TyRawPtr(_) | TyRef(..) | TyProjection(..) => None, diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index a0d25abd14ce6..9ef231499df51 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -91,12 +91,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { ty::TyDynamic(ref data, ..) if data.principal().is_some() => { self.check_def_id(item, data.principal().unwrap().def_id()); } - ty::TyBox(..) => { - match self.tcx.lang_items.require_owned_box() { - Ok(trait_id) => self.check_def_id(item, trait_id), - Err(msg) => self.tcx.sess.span_fatal(item.span, &msg), - } - } ty::TyChar => { self.check_primitive_impl(def_id, self.tcx.lang_items.char_impl(), @@ -321,7 +315,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { let self_ty = trait_ref.self_ty(); let opt_self_def_id = match self_ty.sty { ty::TyAdt(self_def, _) => Some(self_def.did), - ty::TyBox(..) => self.tcx.lang_items.owned_box(), _ => None, }; diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index ba00f237684e6..40e82959336de 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -329,7 +329,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_mt(generics, mt, variance); } - ty::TyBox(typ) | ty::TyArray(typ, _) | ty::TySlice(typ) => { self.add_constraints_from_ty(generics, typ, variance); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7591475c5d3fa..cdb24a56367fc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1808,10 +1808,6 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::TyUint(uint_ty) => Primitive(uint_ty.into()), ty::TyFloat(float_ty) => Primitive(float_ty.into()), ty::TyStr => Primitive(PrimitiveType::Str), - ty::TyBox(t) => { - let box_did = cx.tcx.lang_items.owned_box(); - lang_struct(cx, box_did, t, "Box", Unique) - } ty::TySlice(ty) => Vector(box ty.clean(cx)), ty::TyArray(ty, i) => FixedVector(box ty.clean(cx), format!("{}", i)), @@ -2888,33 +2884,6 @@ impl Clean for attr::Deprecation { } } -fn lang_struct(cx: &DocContext, did: Option, - t: ty::Ty, name: &str, - fallback: fn(Box) -> Type) -> Type { - let did = match did { - Some(did) => did, - None => return fallback(box t.clean(cx)), - }; - inline::record_extern_fqn(cx, did, TypeKind::Struct); - ResolvedPath { - typarams: None, - did: did, - path: Path { - global: false, - def: Def::Err, - segments: vec![PathSegment { - name: name.to_string(), - params: PathParameters::AngleBracketed { - lifetimes: vec![], - types: vec![t.clean(cx)], - bindings: vec![] - } - }], - }, - is_generic: false, - } -} - /// An equality constraint on an associated type, e.g. `A=Bar` in `Foo` #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)] pub struct TypeBinding { diff --git a/src/test/compile-fail/autoderef-full-lval.rs b/src/test/compile-fail/autoderef-full-lval.rs index 0d666a4920038..c152fdd929682 100644 --- a/src/test/compile-fail/autoderef-full-lval.rs +++ b/src/test/compile-fail/autoderef-full-lval.rs @@ -22,13 +22,14 @@ struct fish { fn main() { let a: clam = clam{x: box 1, y: box 2}; let b: clam = clam{x: box 10, y: box 20}; - let z: isize = a.x + b.y; //~ ERROR binary operation `+` cannot be applied to type `Box` + let z: isize = a.x + b.y; + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` println!("{}", z); assert_eq!(z, 21); let forty: fish = fish{a: box 40}; let two: fish = fish{a: box 2}; let answer: isize = forty.a + two.a; - //~^ ERROR binary operation `+` cannot be applied to type `Box` + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` println!("{}", answer); assert_eq!(answer, 42); } diff --git a/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs b/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs index 530822f6c5baf..d09cb73d6702a 100644 --- a/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs +++ b/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs @@ -35,7 +35,7 @@ fn copy_after_move() { let _x = a.x; //~^ value moved here let _y = a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -44,7 +44,7 @@ fn move_after_move() { let _x = a.x; //~^ value moved here let _y = a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -53,7 +53,7 @@ fn borrow_after_move() { let _x = a.x; //~^ value moved here let _y = &a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -106,7 +106,7 @@ fn copy_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } @@ -115,7 +115,7 @@ fn move_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } @@ -124,7 +124,7 @@ fn borrow_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = &a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 672ff464718f8..f389380584b84 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -20,6 +20,5 @@ pub fn main() { let x: Box = Box::new(Foo); let _y: &Trait = x; //~ ERROR mismatched types //~| expected type `&Trait` - //~| found type `Box` - //~| expected &Trait, found box + //~| found type `std::boxed::Box` } diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index 89fb1e105900d..835ec8e4a5e7e 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -51,6 +51,5 @@ fn main() { let box box x = box 1isize as Box; //~^ ERROR mismatched types //~| expected type `T` - //~| found type `Box<_>` - //~| expected trait T, found box + //~| found type `std::boxed::Box<_>` } diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index e01a0412cef4e..6377550d3d22f 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -16,18 +16,15 @@ fn main() { let _: () = (box |_: isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box` - //~| expected (), found box + //~| found type `std::boxed::Box` let _: () = (box |_: isize, isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box` - //~| expected (), found box + //~| found type `std::boxed::Box` let _: () = (box || -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box isize>` - //~| expected (), found box + //~| found type `std::boxed::Box isize>` needs_fn(1); //~^ ERROR : std::ops::Fn<(isize,)>` diff --git a/src/test/compile-fail/issue-14915.rs b/src/test/compile-fail/issue-14915.rs index 18e4ccc331196..810d6656a8f62 100644 --- a/src/test/compile-fail/issue-14915.rs +++ b/src/test/compile-fail/issue-14915.rs @@ -13,5 +13,6 @@ fn main() { let x: Box = box 0; - println!("{}", x + 1); //~ ERROR binary operation `+` cannot be applied to type `Box` + println!("{}", x + 1); + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` } diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs index 7d300bfb14831..45ab9903532e7 100644 --- a/src/test/compile-fail/issue-17441.rs +++ b/src/test/compile-fail/issue-17441.rs @@ -13,9 +13,9 @@ fn main() { //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]` //~^^ HELP consider using an implicit coercion to `&[usize]` instead - // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. + // FIXME (#22405): Replace `std::boxed::Box::new` with `box` here when/if possible. let _bar = Box::new(1_usize) as std::fmt::Debug; - //~^ ERROR cast to unsized type: `Box` as `std::fmt::Debug` + //~^ ERROR cast to unsized type: `std::boxed::Box` as `std::fmt::Debug` //~^^ HELP try casting to a `Box` instead let _baz = 1_usize as std::fmt::Debug; diff --git a/src/test/compile-fail/issue-5100.rs b/src/test/compile-fail/issue-5100.rs index a1f5d74b30e36..9ef780aac8e27 100644 --- a/src/test/compile-fail/issue-5100.rs +++ b/src/test/compile-fail/issue-5100.rs @@ -43,8 +43,7 @@ fn main() { box (true, false) => () //~^ ERROR mismatched types //~| expected type `(bool, bool)` -//~| found type `Box<_>` -//~| expected tuple, found box +//~| found type `std::boxed::Box<_>` } match (true, false) { diff --git a/src/test/compile-fail/issue-7061.rs b/src/test/compile-fail/issue-7061.rs index da6f49f3efe91..b99f5b707ee2d 100644 --- a/src/test/compile-fail/issue-7061.rs +++ b/src/test/compile-fail/issue-7061.rs @@ -13,9 +13,8 @@ struct BarStruct; impl<'a> BarStruct { fn foo(&'a mut self) -> Box { self } //~^ ERROR mismatched types - //~| expected type `Box` + //~| expected type `std::boxed::Box` //~| found type `&'a mut BarStruct` - //~| expected box, found mutable reference } fn main() {} diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index a455a7b2d5d0f..21aefc4f9c1bc 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<{integer}>: std::marker::Copy` is not satisfied + //~^ ERROR `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/lint-ctypes.rs b/src/test/compile-fail/lint-ctypes.rs index 731c1edbfc00b..ccc25b58228bd 100644 --- a/src/test/compile-fail/lint-ctypes.rs +++ b/src/test/compile-fail/lint-ctypes.rs @@ -34,7 +34,7 @@ extern { pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without pub fn slice_type(p: &[u32]); //~ ERROR: found Rust slice type pub fn str_type(p: &str); //~ ERROR: found Rust type - pub fn box_type(p: Box); //~ ERROR found Rust type + pub fn box_type(p: Box); //~ ERROR found struct without pub fn char_type(p: char); //~ ERROR found Rust type pub fn trait_type(p: &Clone); //~ ERROR found Rust trait type pub fn tuple_type(p: (i32, i32)); //~ ERROR found Rust tuple type @@ -42,7 +42,7 @@ extern { pub fn zero_size(p: ZeroSize); //~ ERROR found zero-size struct pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust - pub fn fn_contained(p: RustBadRet); //~ ERROR: found Rust type + pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without pub fn good1(size: *const libc::c_int); pub fn good2(size: *const libc::c_uint); diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index e24441c5497d5..eaafc312379c2 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -26,5 +26,5 @@ fn main() { let x: Box> = x; // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. let y: Box> = Box::new(x); - //~^ ERROR `Box>: Map` is not satisfied + //~^ ERROR `std::boxed::Box>: Map` is not satisfied } diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs index 6fa261dea71cb..8babc734c84cc 100644 --- a/src/test/compile-fail/object-does-not-impl-trait.rs +++ b/src/test/compile-fail/object-does-not-impl-trait.rs @@ -14,5 +14,5 @@ trait Foo {} fn take_foo(f: F) {} fn take_object(f: Box) { take_foo(f); } -//~^ ERROR `Box: Foo` is not satisfied +//~^ ERROR `std::boxed::Box: Foo` is not satisfied fn main() {} diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs index 5cb60079fa4b8..a276af83dee25 100644 --- a/src/test/compile-fail/occurs-check-2.rs +++ b/src/test/compile-fail/occurs-check-2.rs @@ -17,6 +17,6 @@ fn main() { f = box g; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `Box<_>` + //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index 499124cb0573b..5b6a11e58c27c 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -15,6 +15,6 @@ fn main() { f = box f; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `Box<_>` + //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs index fad115c2aedf8..c559992c86531 100644 --- a/src/test/compile-fail/regions-infer-paramd-indirect.rs +++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs @@ -32,8 +32,8 @@ impl<'a> set_f<'a> for c<'a> { fn set_f_bad(&mut self, b: Box) { self.f = b; //~^ ERROR mismatched types - //~| expected type `Box>` - //~| found type `Box>` + //~| expected type `std::boxed::Box>` + //~| found type `std::boxed::Box>` //~| lifetime mismatch } } diff --git a/src/test/compile-fail/terr-sorts.rs b/src/test/compile-fail/terr-sorts.rs index 592d7b3929bfc..fd92a26d0fcec 100644 --- a/src/test/compile-fail/terr-sorts.rs +++ b/src/test/compile-fail/terr-sorts.rs @@ -20,8 +20,7 @@ fn want_foo(f: foo) {} fn have_bar(b: bar) { want_foo(b); //~ ERROR mismatched types //~| expected type `foo` - //~| found type `Box` - //~| expected struct `foo`, found box + //~| found type `std::boxed::Box` } fn main() {} diff --git a/src/test/compile-fail/trivial_casts.rs b/src/test/compile-fail/trivial_casts.rs index 7693d98a2f7b0..aabf0d26d5ba7 100644 --- a/src/test/compile-fail/trivial_casts.rs +++ b/src/test/compile-fail/trivial_casts.rs @@ -52,7 +52,8 @@ pub fn main() { let _: *mut [u32] = x; let x: Box<[u32; 3]> = Box::new([42, 43, 44]); - let _ = x as Box<[u32]>; //~ERROR trivial cast: `Box<[u32; 3]>` as `Box<[u32]>` + let _ = x as Box<[u32]>; + //~^ ERROR trivial cast: `std::boxed::Box<[u32; 3]>` as `std::boxed::Box<[u32]>` let x: Box<[u32; 3]> = Box::new([42, 43, 44]); let _: Box<[u32]> = x; @@ -70,7 +71,7 @@ pub fn main() { let _: *mut Foo = x; let x: Box = Box::new(Bar); - let _ = x as Box; //~ERROR trivial cast: `Box` as `Box` + let _ = x as Box; //~ERROR trivial cast: `std::boxed::Box` as `std::boxed::Box` let x: Box = Box::new(Bar); let _: Box = x; diff --git a/src/test/compile-fail/type-mismatch-same-crate-name.rs b/src/test/compile-fail/type-mismatch-same-crate-name.rs index e74acaa71b0f3..4295d08a4709c 100644 --- a/src/test/compile-fail/type-mismatch-same-crate-name.rs +++ b/src/test/compile-fail/type-mismatch-same-crate-name.rs @@ -33,7 +33,7 @@ fn main() { //~^ ERROR mismatched types //~| Perhaps two different versions of crate `crate_a1` //~| expected trait `main::a::Bar` - //~| expected type `Box` - //~| found type `Box` + //~| expected type `std::boxed::Box` + //~| found type `std::boxed::Box` } } diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 438a78743bb1e..57d40cccf2d80 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -70,12 +70,12 @@ // BOX // gdb-command:whatis box1 -// gdbg-check:type = struct (Box, i32) -// gdbr-check:type = (Box, i32) +// gdbg-check:type = struct (alloc::boxed::Box, i32) +// gdbr-check:type = (alloc::boxed::Box, i32) // gdb-command:whatis box2 -// gdbg-check:type = struct (Box>, i32) -// gdbr-check:type = (Box>, i32) +// gdbg-check:type = struct (alloc::boxed::Box>, i32) +// gdbr-check:type = (alloc::boxed::Box>, i32) // REFERENCES @@ -196,8 +196,8 @@ // gdbr-check:type = (unsafe fn(type_names::GenericStruct) -> type_names::mod1::Struct2, usize) // gdb-command:whatis extern_stdcall_fn_with_return_value -// gdbg-check:type = struct (extern "stdcall" fn(Box) -> usize, usize) -// gdbr-check:type = (extern "stdcall" fn(Box) -> usize, usize) +// gdbg-check:type = struct (extern "stdcall" fn(alloc::boxed::Box) -> usize, usize) +// gdbr-check:type = (extern "stdcall" fn(alloc::boxed::Box) -> usize, usize) // gdb-command:whatis generic_function_int // gdbg-check:type = struct (fn(isize) -> isize, usize) diff --git a/src/test/run-pass/auxiliary/issue13507.rs b/src/test/run-pass/auxiliary/issue13507.rs index ba50aed42c36f..ee7d45b77bf4d 100644 --- a/src/test/run-pass/auxiliary/issue13507.rs +++ b/src/test/run-pass/auxiliary/issue13507.rs @@ -58,7 +58,7 @@ pub mod testtypes { // Tests TySlice pub type FooSlice = [u8]; - // Tests TyBox (of u8) + // Tests Box (of u8) pub type FooBox = Box; // Tests TyRawPtr diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr index c47975b01355d..ccc9fb56772f5 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types 24 | a(x); //~ ERROR mismatched types [E0308] | ^ expected trait `Foo + std::marker::Send`, found trait `Foo` | - = note: expected type `Box` - found type `Box` + = note: expected type `std::boxed::Box` + found type `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index c32fefcd0d6a9..6a70b8ff851d7 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types | ^^^^^ cyclic type of infinite size | = note: expected type `_` - found type `Box<_>` + found type `std::boxed::Box<_>` error: aborting due to 5 previous errors From 4a4f8ff0a3eeb0855f03ad88c2f11f12761041f0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 21 Jan 2017 22:44:44 +0300 Subject: [PATCH 82/86] Implement Drop for Box --- src/liballoc/boxed.rs | 8 ++++++ src/librustc/ty/contents.rs | 27 +++---------------- src/librustc/ty/sty.rs | 3 +-- .../borrowck/mir/elaborate_drops.rs | 2 +- .../borrowck/mir/gather_moves.rs | 2 +- src/librustc_borrowck/borrowck/mir/mod.rs | 2 +- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/glue.rs | 5 ++-- 8 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d98bc1892922a..b6f490e09cddf 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -293,6 +293,14 @@ impl Box { } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<#[may_dangle] T: ?Sized> Drop for Box { + fn drop(&mut self) { + // FIXME: Do nothing, drop is currently performed by compiler. + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Default for Box { /// Creates a `Box`, with the `Default` value for T. diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index 53e8a1d0e37e5..00c6dca21b1ef 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -56,12 +56,8 @@ def_type_content_sets! { // InteriorAll = 0b00000000__00000000__1111, // Things that are owned by the value (second and third nibbles): - OwnsOwned = 0b0000_0000__0000_0001__0000, OwnsDtor = 0b0000_0000__0000_0010__0000, - OwnsAll = 0b0000_0000__1111_1111__0000, - - // Things that mean drop glue is necessary - NeedsDrop = 0b0000_0000__0000_0111__0000, + // OwnsAll = 0b0000_0000__1111_1111__0000, // All bits All = 0b1111_1111__1111_1111__1111 @@ -77,10 +73,6 @@ impl TypeContents { (self.bits & tc.bits) != 0 } - pub fn owns_owned(&self) -> bool { - self.intersects(TC::OwnsOwned) - } - pub fn interior_param(&self) -> bool { self.intersects(TC::InteriorParam) } @@ -90,12 +82,7 @@ impl TypeContents { } pub fn needs_drop(&self, _: TyCtxt) -> bool { - self.intersects(TC::NeedsDrop) - } - - /// Includes only those bits that still apply when indirected through a `Box` pointer - pub fn owned_pointer(&self) -> TypeContents { - TC::OwnsOwned | (*self & TC::OwnsAll) + self.intersects(TC::OwnsDtor) } pub fn union(v: I, mut f: F) -> TypeContents where @@ -104,10 +91,6 @@ impl TypeContents { { v.into_iter().fold(TC::None, |tc, ty| tc | f(ty)) } - - pub fn has_dtor(&self) -> bool { - self.intersects(TC::OwnsDtor) - } } impl ops::BitOr for TypeContents { @@ -223,10 +206,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> { |ty| tc_ty(tcx, *ty, cache)) } - ty::TyAdt(def, _) if def.is_box() => { - tc_ty(tcx, ty.boxed_ty(), cache).owned_pointer() - } - ty::TyAdt(def, substs) => { let mut res = TypeContents::union(&def.variants, |v| { @@ -237,7 +216,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { if def.is_union() { // unions don't have destructors regardless of the child types - res = res - TC::NeedsDrop; + res = res - TC::OwnsDtor; } if def.has_dtor() { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d7686b60ae31e..113534e4529cd 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1142,8 +1142,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn boxed_ty(&self) -> Ty<'tcx> { match self.sty { - TyAdt(def, substs) if def.is_box() => - substs.types().next().expect("Box doesn't have type parameters"), + TyAdt(def, substs) if def.is_box() => substs.type_at(0), _ => bug!("`boxed_ty` is called on non-box type {:?}", self), } } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index d555502c3ff85..9e89a3689c7ac 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -895,7 +895,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { match ty.sty { ty::TyAdt(def, _) => { - if def.has_dtor() { + if def.has_dtor() && !def.is_box() { self.tcx.sess.span_warn( c.source_info.span, &format!("dataflow bug??? moving out of type with dtor {:?}", diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 2a9acaf58b8f2..7cf6ab2999c05 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { // error: can't move out of borrowed content ty::TyRef(..) | ty::TyRawPtr(..) => return Err(MovePathError::IllegalMove), // error: can't move out of struct with destructor - ty::TyAdt(adt, _) if adt.has_dtor() => + ty::TyAdt(adt, _) if adt.has_dtor() && !adt.is_box() => return Err(MovePathError::IllegalMove), // move out of union - always move the entire union ty::TyAdt(adt, _) if adt.is_union() => diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 372eb1d5d64f0..a0c36139ddcd2 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -248,7 +248,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx lv, ty); true } - ty::TyAdt(def, _) if def.has_dtor() || def.is_union() => { + ty::TyAdt(def, _) if (def.has_dtor() && !def.is_box()) || def.is_union() => { debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => true", lv, ty); true diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 9766b816d9b30..392c270c130a8 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -740,7 +740,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, _ => None }; - if let Some(destructor_did) = destructor_did { + if let (Some(destructor_did), false) = (destructor_did, ty.is_box()) { use rustc::ty::ToPolyTraitRef; let drop_trait_def_id = scx.tcx() diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 65f3c7add4db1..350c8f950ddf4 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -211,9 +211,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi let bcx = match t.sty { ty::TyAdt(def, _) if def.is_box() => { - // Support for Box is built-in and its drop glue is - // special. It may move to library and have Drop impl. As - // a safe-guard, assert Box not used with TyContents. + // Support for Box is built-in as yet and its drop glue is special + // despite having a dummy Drop impl in the library. assert!(!skip_dtor); let content_ty = t.boxed_ty(); let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) { From a5d725cc82f0b3ca99d3d6fc157b0a28da4ddf9b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 30 Jan 2017 23:18:22 +0300 Subject: [PATCH 83/86] cleanup: Refactor away `DtorKind` --- src/librustc/ty/mod.rs | 25 +------------------------ src/librustc_trans/glue.rs | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index db21d35f990d3..5ab45e746e7f2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -9,7 +9,6 @@ // except according to those terms. pub use self::Variance::*; -pub use self::DtorKind::*; pub use self::AssociatedItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -120,21 +119,6 @@ pub struct Resolutions { pub maybe_unused_trait_imports: NodeSet, } -#[derive(Copy, Clone)] -pub enum DtorKind { - NoDtor, - TraitDtor -} - -impl DtorKind { - pub fn is_present(&self) -> bool { - match *self { - TraitDtor => true, - _ => false - } - } -} - #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum AssociatedItemContainer { TraitContainer(DefId), @@ -1480,7 +1464,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { /// Returns whether this type has a destructor. pub fn has_dtor(&self) -> bool { - self.dtor_kind().is_present() + self.destructor.get().is_some() } /// Asserts this is a struct and returns the struct's unique @@ -1543,13 +1527,6 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.destructor.set(Some(dtor)); } - pub fn dtor_kind(&self) -> DtorKind { - match self.destructor.get() { - Some(_) => TraitDtor, - None => NoDtor, - } - } - /// Returns a simpler type such that `Self: Sized` if and only /// if that type is Sized, or `TyErr` if this type is recursive. /// diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 350c8f950ddf4..1415ca6029f53 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -235,7 +235,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi bcx.call(dtor, &[ptr.llval], None); bcx } - ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => { + ty::TyAdt(def, ..) if def.has_dtor() && !skip_dtor => { let shallow_drop = def.is_union(); let tcx = bcx.tcx(); From 93e3f634b096129227c3863b76a1f303716122f4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 30 Jan 2017 23:18:29 +0300 Subject: [PATCH 84/86] Fix debuginfo scope issue with `Box` --- src/librustc_trans/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index f05d48566daae..e9468e56637d2 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -400,7 +400,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g. `<*mut T>::null`). match impl_self_ty.sty { - ty::TyAdt(..) => { + ty::TyAdt(def, ..) if !def.is_box() => { Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP)) } _ => None From d292e1229f1e7cc882e550d3ecc0e152720a0ab5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 30 Jan 2017 12:28:31 -0500 Subject: [PATCH 85/86] compiletest: Clear RUSTFLAGS env-var for run-make tests. --- src/tools/compiletest/src/runtest.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 05d6e21e9aaea..86fa5e70c9c28 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2175,6 +2175,10 @@ actual:\n\ .env("LLVM_COMPONENTS", &self.config.llvm_components) .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags); + // We don't want RUSTFLAGS set from the outside to interfere with + // compiler flags set in the test cases: + cmd.env_remove("RUSTFLAGS"); + if self.config.target.contains("msvc") { // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` // and that `lib.exe` lives next to it. From 94e9086685bf0195875037deb3a4dc634bffef60 Mon Sep 17 00:00:00 2001 From: Colm Seale Date: Sun, 22 Jan 2017 23:35:08 +0000 Subject: [PATCH 86/86] [Gate Tests] - marking feature tests Removal of the lang feature gate tests whitelist #39059 r? @est31 --- src/test/compile-fail-fulldeps/gated-macro-reexports.rs | 1 + src/test/compile-fail-fulldeps/gated-quote.rs | 2 ++ src/tools/tidy/src/features.rs | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs index b3dbcb743a135..22c92623e1c19 100644 --- a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs +++ b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs @@ -11,6 +11,7 @@ // Test that macro reexports item are gated by `macro_reexport` feature gate. // aux-build:macro_reexport_1.rs +// gate-test-macro_reexport #![crate_type = "dylib"] diff --git a/src/test/compile-fail-fulldeps/gated-quote.rs b/src/test/compile-fail-fulldeps/gated-quote.rs index dade0e946c5bf..51a9a87744a20 100644 --- a/src/test/compile-fail-fulldeps/gated-quote.rs +++ b/src/test/compile-fail-fulldeps/gated-quote.rs @@ -15,6 +15,8 @@ // FIXME the error message that is current emitted seems pretty bad. +// gate-test-quote + #![feature(rustc_private)] #![allow(dead_code, unused_imports, unused_variables)] diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 154ebd3649bcd..2c3e57c833262 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -166,8 +166,7 @@ pub fn check(path: &Path, bad: &mut bool) { // FIXME get this whitelist empty. let whitelist = vec![ - "abi_ptx", "simd", "macro_reexport", - "static_recursion", "quote", + "abi_ptx", "simd", "static_recursion", "cfg_target_has_atomic", "staged_api", "const_indexing", "unboxed_closures", "stmt_expr_attributes", "cfg_target_thread_local", "unwind_attributes",