From c440c0a0fd3c875defe5a832a212f305b355334c Mon Sep 17 00:00:00 2001 From: Albin Stjerna Date: Tue, 2 Apr 2019 15:54:31 +0200 Subject: [PATCH 01/12] update polonius-engine --- Cargo.lock | 8 ++++---- src/librustc/Cargo.toml | 2 +- src/librustc_mir/Cargo.toml | 2 +- src/librustc_mir/borrow_check/nll/mod.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c071a2e11d26..2bf8d81f1aa9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1914,7 +1914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "polonius-engine" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "datafrog 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2368,7 +2368,7 @@ dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_apfloat 0.0.0", @@ -2868,7 +2868,7 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_apfloat 0.0.0", "rustc_data_structures 0.0.0", @@ -4190,7 +4190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2490c396085801abf88df91758bad806b0890354f0875d624e62ecf0579a8145" +"checksum polonius-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b24942fee141ea45628484a453762bb7e515099c3ec05fbeb76b7bf57b1aeed" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 31e10c19c7a6..f07111ef647d 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -19,7 +19,7 @@ lazy_static = "1.0.0" num_cpus = "1.0" scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } -polonius-engine = "0.6.2" +polonius-engine = "0.7.0" rustc-rayon = "0.1.2" rustc-rayon-core = "0.1.2" rustc_apfloat = { path = "../librustc_apfloat" } diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index c32bafa99205..5de5f5e75711 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -15,7 +15,7 @@ either = "1.5.0" dot = { path = "../libgraphviz", package = "graphviz" } log = "0.4" log_settings = "0.1.1" -polonius-engine = "0.6.2" +polonius-engine = "0.7.0" rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 2d3800dd1dda..3e1b93fb4170 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -173,7 +173,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( if infcx.tcx.sess.opts.debugging_opts.polonius { let algorithm = env::var("POLONIUS_ALGORITHM") - .unwrap_or_else(|_| String::from("DatafrogOpt")); + .unwrap_or_else(|_| String::from("Hybrid")); let algorithm = Algorithm::from_str(&algorithm).unwrap(); debug!("compute_regions: using polonius algorithm {:?}", algorithm); Some(Rc::new(Output::compute( From fd4c6e903b0161cedb2297e2de25783842dffe2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 11 Apr 2019 16:15:48 -0700 Subject: [PATCH 02/12] Remove duplicated redundant spans --- src/librustc_resolve/resolve_imports.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 97b630ba5f29..2c98c66c62e3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1310,15 +1310,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if !is_redundant.is_empty() && is_redundant.present_items().all(|is_redundant| is_redundant) { + let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); + redundant_spans.dedup(); self.session.buffer_lint_with_diagnostic( UNUSED_IMPORTS, directive.id, directive.span, &format!("the item `{}` is imported redundantly", ident), - BuiltinLintDiagnostics::RedundantImport( - redundant_span.present_items().collect(), - ident, - ), + BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), ); } } From 94a5c3b2b2ea51bbe079796f24912ba4d0311e95 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Thu, 11 Apr 2019 21:21:19 -0500 Subject: [PATCH 03/12] Remove [mut] syntax in pin docs --- src/libcore/pin.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index 57bd3ed12b28..ad3e2686228c 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -158,12 +158,12 @@ //! is called *even if your type was previously pinned*! It is as if the //! compiler automatically called `get_unchecked_mut`. //! -//! This can never cause a problem in safe code because implementing a type that relies on pinning -//! requires unsafe code, but be aware that deciding to make use of pinning -//! in your type (for example by implementing some operation on `Pin<&[mut] Self>`) -//! has consequences for your `Drop` implementation as well: if an element -//! of your type could have been pinned, you must treat Drop as implicitly taking -//! `Pin<&mut Self>`. +//! This can never cause a problem in safe code because implementing a type that +//! relies on pinning requires unsafe code, but be aware that deciding to make +//! use of pinning in your type (for example by implementing some operation on +//! `Pin<&Self>` or `Pin<&mut Self>`) has consequences for your `Drop` +//! implementation as well: if an element of your type could have been pinned, +//! you must treat Drop as implicitly taking `Pin<&mut Self>`. //! //! In particular, if your type is `#[repr(packed)]`, the compiler will automatically //! move fields around to be able to drop them. As a consequence, you cannot use @@ -173,13 +173,13 @@ //! //! One interesting question arises when considering the interaction of pinning and //! the fields of a struct. When can a struct have a "pinning projection", i.e., -//! an operation with type `fn(Pin<&[mut] Struct>) -> Pin<&[mut] Field>`? +//! an operation with type `fn(Pin<&Struct>) -> Pin<&Field>`? //! In a similar vein, when can a generic wrapper type (such as `Vec`, `Box`, or `RefCell`) -//! have an operation with type `fn(Pin<&[mut] Wrapper>) -> Pin<&[mut] T>`? +//! have an operation with type `fn(Pin<&Wrapper>) -> Pin<&T>`? //! //! Having a pinning projection for some field means that pinning is "structural": //! when the wrapper is pinned, the field must be considered pinned, too. -//! After all, the pinning projection lets us get a `Pin<&[mut] Field>`. +//! After all, the pinning projection lets us get a `Pin<&Field>`. //! //! However, structural pinning comes with a few extra requirements, so not all //! wrappers can be structural and hence not all wrappers can offer pinning projections: From ac5e755164be38d6485e3ceb80d472147a0d9552 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Thu, 11 Apr 2019 23:57:29 -0500 Subject: [PATCH 04/12] Make BufWriter use get_mut instead of manipulating inner in Write implementation get_mut allows us to abstract over the implementation detail of inner being optional. --- src/libstd/io/buffered.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 3370a447fcc8..bf406bb9b0ba 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -601,7 +601,7 @@ impl Write for BufWriter { } if buf.len() >= self.buf.capacity() { self.panicked = true; - let r = self.inner.as_mut().unwrap().write(buf); + let r = self.get_mut().write(buf); self.panicked = false; r } else { @@ -616,7 +616,7 @@ impl Write for BufWriter { } if total_len >= self.buf.capacity() { self.panicked = true; - let r = self.inner.as_mut().unwrap().write_vectored(bufs); + let r = self.get_mut().write_vectored(bufs); self.panicked = false; r } else { From e9c9d1c305488eb1125d6a10367c81a5c411039c Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 12 Apr 2019 01:29:30 -0500 Subject: [PATCH 05/12] Add comment that field projectin also works with mutable fields --- src/libcore/pin.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index ad3e2686228c..e1fe0044cc48 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -171,11 +171,12 @@ //! //! # Projections and Structural Pinning //! -//! One interesting question arises when considering the interaction of pinning and -//! the fields of a struct. When can a struct have a "pinning projection", i.e., -//! an operation with type `fn(Pin<&Struct>) -> Pin<&Field>`? -//! In a similar vein, when can a generic wrapper type (such as `Vec`, `Box`, or `RefCell`) -//! have an operation with type `fn(Pin<&Wrapper>) -> Pin<&T>`? +//! One interesting question arises when considering the interaction of pinning +//! and the fields of a struct. When can a struct have a "pinning projection", +//! i.e., an operation with type `fn(Pin<&Struct>) -> Pin<&Field>`? In a +//! similar vein, when can a generic wrapper type (such as `Vec`, `Box`, +//! or `RefCell`) have an operation with type `fn(Pin<&Wrapper>) -> +//! Pin<&T>` (or similarly `fn(Pin<&mut Wrapper>) -> Pin<&mut T>`)? //! //! Having a pinning projection for some field means that pinning is "structural": //! when the wrapper is pinned, the field must be considered pinned, too. From ca5a9ce2a131b117f1d7f70163d96623ab9ca213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 12 Apr 2019 11:42:52 -0700 Subject: [PATCH 06/12] Add test and fix dedup --- src/librustc_resolve/resolve_imports.rs | 1 + src/test/ui/issues/issue-59896.rs | 10 ++++++++++ src/test/ui/issues/issue-59896.stderr | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/test/ui/issues/issue-59896.rs create mode 100644 src/test/ui/issues/issue-59896.stderr diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 2c98c66c62e3..e3909b466558 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1311,6 +1311,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { is_redundant.present_items().all(|is_redundant| is_redundant) { let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); + redundant_spans.sort(); redundant_spans.dedup(); self.session.buffer_lint_with_diagnostic( UNUSED_IMPORTS, diff --git a/src/test/ui/issues/issue-59896.rs b/src/test/ui/issues/issue-59896.rs new file mode 100644 index 000000000000..cecf2c5c22b8 --- /dev/null +++ b/src/test/ui/issues/issue-59896.rs @@ -0,0 +1,10 @@ +#![deny(unused_imports)] + +struct S; + +fn main() { + use S; //~ ERROR the item `S` is imported redundantly + + let _s = S; +} + diff --git a/src/test/ui/issues/issue-59896.stderr b/src/test/ui/issues/issue-59896.stderr new file mode 100644 index 000000000000..ef78f27fa69a --- /dev/null +++ b/src/test/ui/issues/issue-59896.stderr @@ -0,0 +1,17 @@ +error: the item `S` is imported redundantly + --> $DIR/issue-59896.rs:6:9 + | +LL | struct S; + | --------- the item `S` is already defined here +... +LL | use S; + | ^ + | +note: lint level defined here + --> $DIR/issue-59896.rs:1:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + From b754b8fb8eaa580753ea3f7bc52fa221cef2a9fe Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sat, 13 Apr 2019 15:54:57 -0500 Subject: [PATCH 07/12] Expand note on mutable references --- src/libcore/pin.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index e1fe0044cc48..d1ebe5ed72ad 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -176,7 +176,10 @@ //! i.e., an operation with type `fn(Pin<&Struct>) -> Pin<&Field>`? In a //! similar vein, when can a generic wrapper type (such as `Vec`, `Box`, //! or `RefCell`) have an operation with type `fn(Pin<&Wrapper>) -> -//! Pin<&T>` (or similarly `fn(Pin<&mut Wrapper>) -> Pin<&mut T>`)? +//! Pin<&T>`? +//! +//! Note: For the entirety of this discussion, the same applies for mutable references as it +//! does for shared references. //! //! Having a pinning projection for some field means that pinning is "structural": //! when the wrapper is pinned, the field must be considered pinned, too. From 3b99a48c4dbca21e7baa3f7747c58209359474c7 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 3 Apr 2019 09:07:45 +0200 Subject: [PATCH 08/12] HirIdify hir::Def --- src/librustc/hir/def.rs | 79 +++++++-- src/librustc/hir/lowering.rs | 154 ++++++++++++++---- src/librustc/hir/map/mod.rs | 5 +- src/librustc/hir/mod.rs | 17 +- src/librustc/middle/expr_use_visitor.rs | 6 +- src/librustc/middle/liveness.rs | 9 +- src/librustc/middle/mem_categorization.rs | 8 +- src/librustc/middle/reachable.rs | 3 +- src/librustc/mir/mod.rs | 4 +- src/librustc/query/mod.rs | 4 +- src/librustc/ty/context.rs | 12 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/print/pretty.rs | 4 +- src/librustc_metadata/cstore_impl.rs | 9 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_metadata/schema.rs | 2 +- .../borrow_check/error_reporting.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 9 +- src/librustc_resolve/build_reduced_graph.rs | 18 +- src/librustc_resolve/error_reporting.rs | 6 +- src/librustc_resolve/lib.rs | 17 +- src/librustc_resolve/macros.rs | 4 +- src/librustc_resolve/resolve_imports.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 4 +- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_typeck/check/callee.rs | 4 +- src/librustc_typeck/check/demand.rs | 4 +- src/librustc_typeck/check/method/suggest.rs | 8 +- src/librustc_typeck/check/mod.rs | 3 +- src/librustc_typeck/check/upvar.rs | 7 +- .../passes/collect_intra_doc_links.rs | 4 +- 31 files changed, 300 insertions(+), 118 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 3cc23ccdb642..7d173af31126 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -2,10 +2,12 @@ use crate::hir::def_id::DefId; use crate::util::nodemap::{NodeMap, DefIdMap}; use syntax::ast; use syntax::ext::base::MacroKind; +use syntax::ast::NodeId; use syntax_pos::Span; use rustc_macros::HashStable; use crate::hir; use crate::ty; +use std::fmt::Debug; use self::Namespace::*; @@ -43,7 +45,7 @@ pub enum NonMacroAttrKind { } #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)] -pub enum Def { +pub enum Def { // Type namespace Mod(DefId), /// `DefId` refers to the struct itself, `Def::Ctor` refers to its constructor if it exists. @@ -78,8 +80,8 @@ pub enum Def { Method(DefId), AssociatedConst(DefId), - Local(ast::NodeId), - Upvar(ast::NodeId, // `NodeId` of closed over local + Local(Id), + Upvar(Id, // `HirId` of closed over local usize, // index in the `freevars` list of the closure ast::NodeId), // expr node that creates the closure Label(ast::NodeId), @@ -108,22 +110,22 @@ pub enum Def { /// ``` #[derive(Copy, Clone, Debug)] pub struct PathResolution { - base_def: Def, + base_def: Def, unresolved_segments: usize, } impl PathResolution { - pub fn new(def: Def) -> Self { + pub fn new(def: Def) -> Self { PathResolution { base_def: def, unresolved_segments: 0 } } - pub fn with_unresolved_segments(def: Def, mut unresolved_segments: usize) -> Self { + pub fn with_unresolved_segments(def: Def, mut unresolved_segments: usize) -> Self { if def == Def::Err { unresolved_segments = 0 } PathResolution { base_def: def, unresolved_segments: unresolved_segments } } #[inline] - pub fn base_def(&self) -> Def { + pub fn base_def(&self) -> Def { self.base_def } @@ -215,18 +217,18 @@ pub type DefMap = NodeMap; /// This is the replacement export map. It maps a module to all of the exports /// within. -pub type ExportMap = DefIdMap>; +pub type ExportMap = DefIdMap>>; /// Map used to track the `use` statements within a scope, matching it with all the items in every /// namespace. pub type ImportMap = NodeMap>>; #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub struct Export { +pub struct Export { /// The name of the target. pub ident: ast::Ident, /// The definition of the target. - pub def: Def, + pub def: Def, /// The span of the target definition. pub span: Span, /// The visibility of the export. @@ -234,6 +236,17 @@ pub struct Export { pub vis: ty::Visibility, } +impl Export { + pub fn map_id(self, map: impl FnMut(Id) -> R) -> Export { + Export { + ident: self.ident, + def: self.def.map_id(map), + span: self.span, + vis: self.vis, + } + } +} + impl CtorKind { pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { match *vdata { @@ -264,9 +277,12 @@ impl NonMacroAttrKind { } } -impl Def { +impl Def { /// Return the `DefId` of this `Def` if it has an id, else panic. - pub fn def_id(&self) -> DefId { + pub fn def_id(&self) -> DefId + where + Id: Debug, + { self.opt_def_id().unwrap_or_else(|| { bug!("attempted .def_id() on invalid def: {:?}", self) }) @@ -358,4 +374,43 @@ impl Def { _ => "a", } } + + pub fn map_id(self, mut map: impl FnMut(Id) -> R) -> Def { + match self { + Def::Fn(id) => Def::Fn(id), + Def::Mod(id) => Def::Mod(id), + Def::Static(id, is_mutbl) => Def::Static(id, is_mutbl), + Def::Enum(id) => Def::Enum(id), + Def::Variant(id) => Def::Variant(id), + Def::Ctor(a, b, c) => Def::Ctor(a, b, c), + Def::Struct(id) => Def::Struct(id), + Def::Existential(id) => Def::Existential(id), + Def::TyAlias(id) => Def::TyAlias(id), + Def::TraitAlias(id) => Def::TraitAlias(id), + Def::AssociatedTy(id) => Def::AssociatedTy(id), + Def::AssociatedExistential(id) => Def::AssociatedExistential(id), + Def::SelfCtor(id) => Def::SelfCtor(id), + Def::Union(id) => Def::Union(id), + Def::Trait(id) => Def::Trait(id), + Def::ForeignTy(id) => Def::ForeignTy(id), + Def::Method(id) => Def::Method(id), + Def::Const(id) => Def::Const(id), + Def::AssociatedConst(id) => Def::AssociatedConst(id), + Def::TyParam(id) => Def::TyParam(id), + Def::ConstParam(id) => Def::ConstParam(id), + Def::PrimTy(id) => Def::PrimTy(id), + Def::Local(id) => Def::Local(map(id)), + Def::Upvar(id, index, closure) => Def::Upvar( + map(id), + index, + closure + ), + Def::Label(id) => Def::Label(id), + Def::SelfTy(a, b) => Def::SelfTy(a, b), + Def::Macro(id, macro_kind) => Def::Macro(id, macro_kind), + Def::ToolMod => Def::ToolMod, + Def::NonMacroAttr(attr_kind) => Def::NonMacroAttr(attr_kind), + Def::Err => Def::Err, + } + } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2a2555236767..a8269bb13957 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -401,6 +401,7 @@ impl<'a> LoweringContext<'a> { /// declared for every type and trait definition. struct MiscCollector<'lcx, 'interner: 'lcx> { lctx: &'lcx mut LoweringContext<'interner>, + hir_id_owner: Option, } impl MiscCollector<'_, '_> { @@ -432,9 +433,34 @@ impl<'a> LoweringContext<'a> { } } } + + fn with_hir_id_owner(&mut self, owner: Option, f: F) -> T + where + F: FnOnce(&mut Self) -> T, + { + let old = mem::replace(&mut self.hir_id_owner, owner); + let r = f(self); + self.hir_id_owner = old; + r + } } impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> { + fn visit_pat(&mut self, p: &'lcx Pat) { + match p.node { + // Doesn't generate a Hir node + PatKind::Paren(..) => {}, + _ => { + + if let Some(owner) = self.hir_id_owner { + self.lctx.lower_node_id_with_owner(p.id, owner); + } + } + }; + + visit::walk_pat(self, p) + } + fn visit_item(&mut self, item: &'lcx Item) { let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id; @@ -461,17 +487,63 @@ impl<'a> LoweringContext<'a> { } _ => {} } - visit::walk_item(self, item); + + self.with_hir_id_owner(Some(item.id), |this| { + visit::walk_item(this, item); + }); } fn visit_trait_item(&mut self, item: &'lcx TraitItem) { self.lctx.allocate_hir_id_counter(item.id); - visit::walk_trait_item(self, item); + + match item.node { + TraitItemKind::Method(_, None) => { + // Ignore patterns in trait methods without bodies + self.with_hir_id_owner(None, |this| { + visit::walk_trait_item(this, item) + }); + } + _ => self.with_hir_id_owner(Some(item.id), |this| { + visit::walk_trait_item(this, item); + }) + } } fn visit_impl_item(&mut self, item: &'lcx ImplItem) { self.lctx.allocate_hir_id_counter(item.id); - visit::walk_impl_item(self, item); + self.with_hir_id_owner(Some(item.id), |this| { + visit::walk_impl_item(this, item); + }); + } + + fn visit_foreign_item(&mut self, i: &'lcx ForeignItem) { + // Ignore patterns in foreign items + self.with_hir_id_owner(None, |this| { + visit::walk_foreign_item(this, i) + }); + } + + fn visit_ty(&mut self, t: &'lcx Ty) { + match t.node { + // Mirrors the case in visit::walk_ty + TyKind::BareFn(ref f) => { + walk_list!( + self, + visit_generic_param, + &f.generic_params + ); + // Mirrors visit::walk_fn_decl + for argument in &f.decl.inputs { + // We don't lower the ids of argument patterns + self.with_hir_id_owner(None, |this| { + this.visit_pat(&argument.pat); + }); + self.visit_ty(&argument.ty) + } + self.visit_fn_ret_ty(&f.decl.output) + } + _ => visit::walk_ty(self, t), + } } } @@ -565,7 +637,7 @@ impl<'a> LoweringContext<'a> { self.lower_node_id(CRATE_NODE_ID); debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID); - visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c); + visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c); visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c); let module = self.lower_mod(&c.module); @@ -729,7 +801,15 @@ impl<'a> LoweringContext<'a> { self.lower_node_id(self.sess.next_node_id()) } - fn expect_full_def(&mut self, id: NodeId) -> Def { + fn lower_def(&mut self, def: Def) -> Def { + def.map_id(|id| { + self.lower_node_id_generic(id, |_| { + panic!("expected node_id to be lowered already for def {:#?}", def) + }).hir_id + }) + } + + fn expect_full_def(&mut self, id: NodeId) -> Def { self.resolver.get_resolution(id).map_or(Def::Err, |pr| { if pr.unresolved_segments() != 0 { bug!("path not fully resolved: {:?}", pr); @@ -738,7 +818,7 @@ impl<'a> LoweringContext<'a> { }) } - fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator { + fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator> { self.resolver.get_import(id).present_items().map(|pr| { if pr.unresolved_segments() != 0 { bug!("path not fully resolved: {:?}", pr); @@ -1324,14 +1404,20 @@ impl<'a> LoweringContext<'a> { } return ty; } - TyKind::ImplicitSelf => hir::TyKind::Path(hir::QPath::Resolved( - None, - P(hir::Path { - def: self.expect_full_def(t.id), - segments: hir_vec![hir::PathSegment::from_ident(keywords::SelfUpper.ident())], - span: t.span, - }), - )), + TyKind::ImplicitSelf => { + let def = self.expect_full_def(t.id); + let def = self.lower_def(def); + hir::TyKind::Path(hir::QPath::Resolved( + None, + P(hir::Path { + def, + segments: hir_vec![hir::PathSegment::from_ident( + keywords::SelfUpper.ident() + )], + span: t.span, + }), + )) + }, TyKind::Array(ref ty, ref length) => { hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length)) } @@ -1755,7 +1841,7 @@ impl<'a> LoweringContext<'a> { let proj_start = p.segments.len() - resolution.unresolved_segments(); let path = P(hir::Path { - def: resolution.base_def(), + def: self.lower_def(resolution.base_def()), segments: p.segments[..proj_start] .iter() .enumerate() @@ -1931,6 +2017,7 @@ impl<'a> LoweringContext<'a> { fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path { let def = self.expect_full_def(id); + let def = self.lower_def(def); self.lower_path_extra(def, p, param_mode, None) } @@ -2042,7 +2129,7 @@ impl<'a> LoweringContext<'a> { hir::PathSegment::new( segment.ident, Some(id.hir_id), - Some(def), + Some(self.lower_def(def)), generic_args, infer_types, ) @@ -3174,7 +3261,7 @@ impl<'a> LoweringContext<'a> { let mut defs = self.expect_full_def_from_use(id); // We want to return *something* from this function, so hold onto the first item // for later. - let ret_def = defs.next().unwrap_or(Def::Err); + let ret_def = self.lower_def(defs.next().unwrap_or(Def::Err)); // Here, we are looping over namespaces, if they exist for the definition // being imported. We only handle type and value namespaces because we @@ -3192,6 +3279,7 @@ impl<'a> LoweringContext<'a> { self.with_hir_id_owner(new_node_id, |this| { let new_id = this.lower_node_id(new_node_id); + let def = this.lower_def(def); let path = this.lower_path_extra(def, &path, ParamMode::Explicit, None); let item = hir::ItemKind::Use(P(path), hir::UseKind::Single); @@ -3347,6 +3435,7 @@ impl<'a> LoweringContext<'a> { } let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); + let def = self.lower_def(def); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); hir::ItemKind::Use(path, hir::UseKind::ListStem) } @@ -3780,7 +3869,7 @@ impl<'a> LoweringContext<'a> { None, P(hir::Path { span: ident.span, - def, + def: self.lower_def(def), segments: hir_vec![hir::PathSegment::from_ident(ident)], }), )), @@ -4435,7 +4524,7 @@ impl<'a> LoweringContext<'a> { let iter = self.str_to_ident("iter"); let next_ident = self.str_to_ident("__next"); - let (next_pat, next_pat_nid) = self.pat_ident_binding_mode( + let (next_pat, next_pat_hid) = self.pat_ident_binding_mode( desugared_span, next_ident, hir::BindingAnnotation::Mutable, @@ -4444,9 +4533,9 @@ impl<'a> LoweringContext<'a> { // `::std::option::Option::Some(val) => next = val` let pat_arm = { let val_ident = self.str_to_ident("val"); - let (val_pat, val_pat_nid) = self.pat_ident(pat.span, val_ident); - let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_nid)); - let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_nid)); + let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident); + let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid)); + let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid)); let assign = P(self.expr( pat.span, hir::ExprKind::Assign(next_expr, val_expr), @@ -4497,7 +4586,7 @@ impl<'a> LoweringContext<'a> { span: head_sp, }; - let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_nid)); + let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid)); // `let mut __next` let next_let = self.stmt_let_pat( @@ -4790,6 +4879,7 @@ impl<'a> LoweringContext<'a> { self.lower_node_id(id) }; let def = self.expect_full_def(id); + let def = self.lower_def(def); hir::VisibilityKind::Restricted { path: P(self.lower_path_extra( def, @@ -4891,7 +4981,7 @@ impl<'a> LoweringContext<'a> { self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()) } - fn expr_ident(&mut self, span: Span, ident: Ident, binding: NodeId) -> hir::Expr { + fn expr_ident(&mut self, span: Span, ident: Ident, binding: hir::HirId) -> hir::Expr { self.expr_ident_with_attrs(span, ident, binding, ThinVec::new()) } @@ -4899,7 +4989,7 @@ impl<'a> LoweringContext<'a> { &mut self, span: Span, ident: Ident, - binding: NodeId, + binding: hir::HirId, attrs: ThinVec, ) -> hir::Expr { let expr_path = hir::ExprKind::Path(hir::QPath::Resolved( @@ -4994,8 +5084,8 @@ impl<'a> LoweringContext<'a> { mutbl: bool, ident: Ident, ex: P, - ) -> (hir::Stmt, NodeId) { - let (pat, pat_nid) = if mutbl { + ) -> (hir::Stmt, hir::HirId) { + let (pat, pat_hid) = if mutbl { self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable) } else { self.pat_ident(sp, ident) @@ -5003,7 +5093,7 @@ impl<'a> LoweringContext<'a> { ( self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), - pat_nid, + pat_hid, ) } @@ -5061,7 +5151,7 @@ impl<'a> LoweringContext<'a> { self.pat(span, pt) } - fn pat_ident(&mut self, span: Span, ident: Ident) -> (P, NodeId) { + fn pat_ident(&mut self, span: Span, ident: Ident) -> (P, hir::HirId) { self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated) } @@ -5070,8 +5160,8 @@ impl<'a> LoweringContext<'a> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (P, NodeId) { - let LoweredNodeId { node_id, hir_id } = self.next_id(); + ) -> (P, hir::HirId) { + let LoweredNodeId { node_id: _, hir_id } = self.next_id(); ( P(hir::Pat { @@ -5079,7 +5169,7 @@ impl<'a> LoweringContext<'a> { node: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None), span, }), - node_id + hir_id ) } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index c0579ef0f7a9..4eef2019e26f 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -393,7 +393,7 @@ impl<'hir> Map<'hir> { Node::Block(_) | Node::Crate => None, Node::Local(local) => { - Some(Def::Local(self.hir_to_node_id(local.hir_id))) + Some(Def::Local(local.hir_id)) } Node::MacroDef(macro_def) => { Some(Def::Macro(self.local_def_id_from_hir_id(macro_def.hir_id), @@ -402,8 +402,7 @@ impl<'hir> Map<'hir> { Node::GenericParam(param) => { Some(match param.kind { GenericParamKind::Lifetime { .. } => { - let node_id = self.hir_to_node_id(param.hir_id); - Def::Local(node_id) + Def::Local(param.hir_id) }, GenericParamKind::Type { .. } => Def::TyParam( self.local_def_id_from_hir_id(param.hir_id)), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 58a27d3f78ee..7ed8c08c9233 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2424,16 +2424,23 @@ impl ForeignItemKind { /// A free variable referred to in a function. #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] -pub struct Freevar { +pub struct Freevar { /// The variable being accessed free. - pub def: Def, + pub def: def::Def, // First span where it is accessed (there can be multiple). pub span: Span } -impl Freevar { - pub fn var_id(&self) -> NodeId { +impl Freevar { + pub fn map_id(self, map: impl FnMut(Id) -> R) -> Freevar { + Freevar { + def: self.def.map_id(map), + span: self.span, + } + } + + pub fn var_id(&self) -> Id { match self.def { Def::Local(id) | Def::Upvar(id, ..) => id, _ => bug!("Freevar::var_id: bad def ({:?})", self.def) @@ -2441,7 +2448,7 @@ impl Freevar { } } -pub type FreevarMap = NodeMap>; +pub type FreevarMap = NodeMap>>; pub type CaptureModeMap = NodeMap; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 4f630fe9a391..41ff9406d9df 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -863,7 +863,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // Each match binding is effectively an assignment to the // binding being produced. - let def = Def::Local(mc.tcx.hir().hir_to_node_id(canonical_id)); + let def = Def::Local(canonical_id); if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) { delegate.mutate(pat.hir_id, pat.span, binding_cmt, MutateMode::Init); } @@ -930,7 +930,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id); self.tcx().with_freevars(closure_expr.hir_id, |freevars| { for freevar in freevars { - let var_hir_id = self.tcx().hir().node_to_hir_id(freevar.var_id()); + let var_hir_id = freevar.var_id(); let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id.to_local(), @@ -967,7 +967,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_hir_id = self.tcx().hir().node_to_hir_id(upvar.var_id()); + let var_hir_id = upvar.var_id(); let var_ty = self.mc.node_ty(var_hir_id)?; self.mc.cat_def(closure_hir_id, closure_span, var_ty, upvar.def) } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f5a95d7004bf..d167b44d42f8 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -487,8 +487,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) { call_caps.extend(freevars.iter().filter_map(|fv| { if let Def::Local(rv) = fv.def { let fv_ln = ir.add_live_node(FreeVarNode(fv.span)); - let var_hid = ir.tcx.hir().node_to_hir_id(rv); - Some(CaptureInfo { ln: fv_ln, var_hid }) + Some(CaptureInfo { ln: fv_ln, var_hid: rv }) } else { None } @@ -1347,7 +1346,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn access_path(&mut self, hir_id: HirId, path: &hir::Path, succ: LiveNode, acc: u32) -> LiveNode { match path.def { - Def::Local(nid) => { + Def::Local(hid) => { + let nid = self.ir.tcx.hir().hir_to_node_id(hid); self.access_var(hir_id, nid, succ, acc, path.span) } _ => succ @@ -1539,13 +1539,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_place(&mut self, expr: &'tcx Expr) { match expr.node { hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) => { - if let Def::Local(nid) = path.def { + if let Def::Local(var_hid) = path.def { // Assignment to an immutable variable or argument: only legal // 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 ln = self.live_node(expr.hir_id, expr.span); - let var_hid = self.ir.tcx.hir().node_to_hir_id(nid); let var = self.variable(var_hid, expr.span); self.warn_about_dead_assign(expr.span, expr.hir_id, ln, var); } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1a3fef18404e..a031037b7a07 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -734,15 +734,17 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Upvar(var_id, _, fn_node_id) => { - self.cat_upvar(hir_id, span, var_id, fn_node_id) + let var_nid = self.tcx.hir().hir_to_node_id(var_id); + self.cat_upvar(hir_id, span, var_nid, fn_node_id) } Def::Local(vid) => { + let vnid = self.tcx.hir().hir_to_node_id(vid); Ok(cmt_ { hir_id, span, - cat: Categorization::Local(self.tcx.hir().node_to_hir_id(vid)), - mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vid), + cat: Categorization::Local(vid), + mutbl: MutabilityCategory::from_local(self.tcx, self.tables, vnid), ty: expr_ty, note: NoteNone }) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index b55e840596b8..92266838dd82 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -103,8 +103,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { }; match def { - Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { - let hir_id = self.tcx.hir().node_to_hir_id(node_id); + Some(Def::Local(hir_id)) | Some(Def::Upvar(hir_id, ..)) => { self.reachable_symbols.insert(hir_id); } Some(def) => { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 8424c096e88c..65501e316efc 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2455,7 +2455,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { tcx.with_freevars(hir_id, |freevars| { for (freevar, place) in freevars.iter().zip(places) { - let var_name = tcx.hir().name(freevar.var_id()); + let var_name = tcx.hir().name_by_hir_id(freevar.var_id()); struct_fmt.field(&var_name.as_str(), place); } }); @@ -2474,7 +2474,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { tcx.with_freevars(hir_id, |freevars| { for (freevar, place) in freevars.iter().zip(places) { - let var_name = tcx.hir().name(freevar.var_id()); + let var_name = tcx.hir().name_by_hir_id(freevar.var_id()); struct_fmt.field(&var_name.as_str(), place); } struct_fmt.field("$state", &places[freevars.len()]); diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d0ad2c90668a..bc9aaf870cee 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -641,7 +641,7 @@ rustc_queries! { } Other { - query module_exports(_: DefId) -> Option>> { + query module_exports(_: DefId) -> Option>>> { eval_always } } @@ -781,7 +781,7 @@ rustc_queries! { eval_always desc { "fetching what a crate is named" } } - query item_children(_: DefId) -> Lrc> {} + query item_children(_: DefId) -> Lrc>> {} query extern_mod_stmt_cnum(_: DefId) -> Option {} query get_lib_features(_: CrateNum) -> Lrc { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7dc4dee3fbf9..9bd5b2fdb961 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1024,7 +1024,7 @@ pub struct GlobalCtxt<'tcx> { Lrc>>>>, /// Export map produced by name resolution. - export_map: FxHashMap>>, + export_map: FxHashMap>>>, hir_map: hir_map::Map<'tcx>, @@ -1271,10 +1271,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { types: common_types, trait_map, export_map: resolutions.export_map.into_iter().map(|(k, v)| { - (k, Lrc::new(v)) + let exports: Vec<_> = v.into_iter().map(|e| { + e.map_id(|id| hir.node_to_hir_id(id)) + }).collect(); + (k, Lrc::new(exports)) }).collect(), freevars: resolutions.freevars.into_iter().map(|(k, v)| { - (hir.local_def_id(k), Lrc::new(v)) + let vars: Vec<_> = v.into_iter().map(|e| { + e.map_id(|id| hir.node_to_hir_id(id)) + }).collect(); + (hir.local_def_id(k), Lrc::new(vars)) }).collect(), maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7d47867cea12..d24395ac9c18 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -123,7 +123,7 @@ pub struct Resolutions { pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, - pub export_map: ExportMap, + pub export_map: ExportMap, pub glob_map: GlobMap, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index c9a4961a8e04..b31ba10d523a 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -592,7 +592,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: p!( write("{}{}:", sep, - self.tcx().hir().name(freevar.var_id())), + self.tcx().hir().name_by_hir_id(freevar.var_id())), print(upvar_ty)); sep = ", "; } @@ -635,7 +635,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: p!( write("{}{}:", sep, - self.tcx().hir().name(freevar.var_id())), + self.tcx().hir().name_by_hir_id(freevar.var_id())), print(upvar_ty)); sep = ", "; } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 995532a00cd6..e3bf09299ef0 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -11,6 +11,7 @@ use rustc::middle::cstore::{CrateStore, DepKind, use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; use rustc::hir::def; +use rustc::hir; use rustc::session::{CrateDisambiguator, Session}; use rustc::ty::{self, TyCtxt}; use rustc::ty::query::Providers; @@ -347,7 +348,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { { let visible_parent_map = &mut visible_parent_map; let mut add_child = |bfs_queue: &mut VecDeque<_>, - child: &def::Export, + child: &def::Export, parent: DefId| { if child.vis != ty::Visibility::Public { return; @@ -415,7 +416,11 @@ impl cstore::CStore { self.get_crate_data(def.krate).get_item_attrs(def.index, sess) } - pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { + pub fn item_children_untracked( + &self, + def_id: DefId, + sess: &Session + ) -> Vec> { let mut result = vec![]; self.get_crate_data(def_id.krate) .each_child_of_item(def_id.index, |child| result.push(child), sess); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f456a5c1619c..f7ea67ef3494 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -734,7 +734,7 @@ impl<'a, 'tcx> CrateMetadata { /// Iterates over each child of the given item. pub fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) - where F: FnMut(def::Export) + where F: FnMut(def::Export) { if let Some(ref proc_macros) = self.proc_macros { /* If we are loading as a proc macro, we want to return the view of this crate diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index fe2ea26c3274..504c7da7d6b9 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -423,7 +423,7 @@ impl<'a> HashStable> for RenderedConst { #[derive(RustcEncodable, RustcDecodable)] pub struct ModData { - pub reexports: LazySeq, + pub reexports: LazySeq>, } impl_stable_hash_for!(struct ModData { reexports }); diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index e6d818152f58..3ab0996d3a17 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1824,7 +1824,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { .tcx .with_freevars(hir_id, |fv| fv[field.index()]); - self.infcx.tcx.hir().name(freevar.var_id()).to_string() + self.infcx.tcx.hir().name_by_hir_id(freevar.var_id()).to_string() } _ => { // Might need a revision when the fields in trait RFC is implemented diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 91113dc2271b..2c22c5e64c4f 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -986,14 +986,13 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); match def { - Def::Local(id) => ExprKind::VarRef { id: cx.tcx.hir().node_to_hir_id(id) }, + Def::Local(id) => ExprKind::VarRef { id }, - Def::Upvar(var_id, index, closure_expr_id) => { + Def::Upvar(var_hir_id, index, closure_expr_id) => { debug!("convert_var(upvar({:?}, {:?}, {:?}))", - var_id, + var_hir_id, index, closure_expr_id); - let var_hir_id = cx.tcx.hir().node_to_hir_id(var_id); let var_ty = cx.tables().node_type(var_hir_id); // FIXME free regions in closures are not right @@ -1195,7 +1194,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, freevar: &hir::Freevar, freevar_ty: Ty<'tcx>) -> ExprRef<'tcx> { - let var_hir_id = cx.tcx.hir().node_to_hir_id(freevar.var_id()); + let var_hir_id = freevar.var_id(); let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: cx.tcx.hir().local_def_id_from_hir_id(closure_expr.hir_id).to_local(), diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 7ce264db755d..72dd043f2143 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -12,7 +12,7 @@ use crate::Namespace::{self, TypeNS, ValueNS, MacroNS}; use crate::{resolve_error, resolve_struct_error, ResolutionError}; use rustc::bug; -use rustc::hir::def::*; +use rustc::hir::def::{self, *}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::ty; use rustc::middle::cstore::CrateStore; @@ -44,6 +44,8 @@ use syntax_pos::{Span, DUMMY_SP}; use log::debug; +type Def = def::Def; + impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> { arenas.alloc_name_binding(NameBinding { @@ -641,7 +643,11 @@ impl<'a> Resolver<'a> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) { + fn build_reduced_graph_for_external_crate_def( + &mut self, + parent: Module<'a>, + child: Export, + ) { let Export { ident, def, vis, span } = child; // FIXME: We shouldn't create the gensym here, it should come from metadata, // but metadata cannot encode gensyms currently, so we create it here. @@ -684,13 +690,14 @@ impl<'a> Resolver<'a> { self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); for child in self.cstore.item_children_untracked(def_id, self.session) { - let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS }; + let def = child.def.map_id(|_| panic!("unexpected id")); + let ns = if let Def::AssociatedTy(..) = def { TypeNS } else { ValueNS }; self.define(module, child.ident, ns, - (child.def, ty::Visibility::Public, DUMMY_SP, expansion)); + (def, ty::Visibility::Public, DUMMY_SP, expansion)); if self.cstore.associated_item_cloned_untracked(child.def.def_id()) .method_has_self_argument { - self.has_self.insert(child.def.def_id()); + self.has_self.insert(def.def_id()); } } module.populated.set(true); @@ -777,6 +784,7 @@ impl<'a> Resolver<'a> { if module.populated.get() { return } let def_id = module.def_id().unwrap(); for child in self.cstore.item_children_untracked(def_id, self.session) { + let child = child.map_id(|_| panic!("unexpected id")); self.build_reduced_graph_for_external_crate_def(module, child); } module.populated.set(true) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 931bce91d7d4..9e3894dab0da 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -2,14 +2,16 @@ use std::cmp::Reverse; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use log::debug; -use rustc::hir::def::{Def, CtorKind, Namespace::*}; +use rustc::hir::def::{self, CtorKind, Namespace::*}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::session::{Session, config::nightly_options}; -use syntax::ast::{Expr, ExprKind, Ident}; +use syntax::ast::{self, Expr, ExprKind, Ident}; use syntax::ext::base::MacroKind; use syntax::symbol::{Symbol, keywords}; use syntax_pos::{BytePos, Span}; +type Def = def::Def; + use crate::macros::ParentScope; use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b34786d8f129..96aac9772979 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4,6 +4,7 @@ #![feature(label_break_value)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] +#![feature(type_alias_enum_variants)] #![recursion_limit="256"] @@ -20,7 +21,9 @@ use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str}; use rustc::middle::cstore::CrateStore; use rustc::session::Session; use rustc::lint; -use rustc::hir::def::*; +use rustc::hir::def::{ + self, PathResolution, CtorKind, CtorOf, NonMacroAttrKind, DefMap, ImportMap, ExportMap +}; use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; @@ -66,6 +69,8 @@ use error_reporting::{find_span_of_binding_until_next_binding, extend_span_to_pr use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver}; use macros::{InvocationData, LegacyBinding, ParentScope}; +type Def = def::Def; + // N.B., this module needs to be declared first so diagnostics are // registered before they are used. mod diagnostics; @@ -1563,7 +1568,7 @@ pub struct Resolver<'a> { import_map: ImportMap, pub freevars: FreevarMap, freevars_seen: NodeMap>, - pub export_map: ExportMap, + pub export_map: ExportMap, pub trait_map: TraitMap, /// A map from nodes to anonymous modules. @@ -1773,7 +1778,7 @@ impl<'a> Resolver<'a> { } }; let path = self.resolve_hir_path_cb(&path, is_value, |_, _, _| errored = true); - if errored || path.def == Def::Err { + if errored || path.def == def::Def::Err { Err(()) } else { Ok(path) @@ -1819,12 +1824,14 @@ impl<'a> Resolver<'a> { let segments: Vec<_> = segments.iter().map(|seg| { let mut hir_seg = hir::PathSegment::from_ident(seg.ident); - hir_seg.def = Some(self.def_map.get(&seg.id).map_or(Def::Err, |p| p.base_def())); + hir_seg.def = Some(self.def_map.get(&seg.id).map_or(def::Def::Err, |p| { + p.base_def().map_id(|_| panic!("unexpected node_id")) + })); hir_seg }).collect(); hir::Path { span, - def, + def: def.map_id(|_| panic!("unexpected node_id")), segments: segments.into(), } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 21ca8ea369fd..64f652d6eeba 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -8,7 +8,7 @@ use crate::build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; use crate::resolve_imports::ImportResolver; use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, DefIndex, CrateNum, DefIndexAddressSpace}; -use rustc::hir::def::{Def, NonMacroAttrKind}; +use rustc::hir::def::{self, NonMacroAttrKind}; use rustc::hir::map::{self, DefCollector}; use rustc::{ty, lint}; use rustc::{bug, span_bug}; @@ -33,6 +33,8 @@ use std::cell::Cell; use std::{mem, ptr}; use rustc_data_structures::sync::Lrc; +type Def = def::Def; + #[derive(Clone, Debug)] pub struct InvocationData<'a> { def_index: DefIndex, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 62af6e19603c..9f6395fa9071 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -21,7 +21,7 @@ use rustc::lint::builtin::{ UNUSED_IMPORTS, }; use rustc::hir::def_id::{CrateNum, DefId}; -use rustc::hir::def::*; +use rustc::hir::def::{self, PathResolution, Export}; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::FxHashSet; use rustc::{bug, span_bug}; @@ -39,6 +39,8 @@ use log::*; use std::cell::{Cell, RefCell}; use std::{mem, ptr}; +type Def = def::Def; + /// Contains data for specific types of import directives. #[derive(Clone, Debug)] pub enum ImportDirectiveSubclass<'a> { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 7d4002525942..a5ddf89d3d43 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -915,13 +915,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // process collected paths for (id, ident, immut) in collector.collected_idents { match self.save_ctxt.get_path_def(id) { - HirDef::Local(id) => { + HirDef::Local(hir_id) => { let mut value = if immut == ast::Mutability::Immutable { self.span.snippet(ident.span) } else { "".to_owned() }; - let hir_id = self.tcx.hir().node_to_hir_id(id); + let id = self.tcx.hir().hir_to_node_id(hir_id); let typ = self.save_ctxt .tables .node_type_opt(hir_id) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d6923b4490d5..ce0decaee496 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -659,7 +659,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Node::Binding(&hir::Pat { node: hir::PatKind::Binding(_, canonical_id, ..), .. - }) => HirDef::Local(self.tcx.hir().hir_to_node_id(canonical_id)), + }) => HirDef::Local(canonical_id), _ => HirDef::Err, } @@ -707,7 +707,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Some(Ref { kind: RefKind::Variable, span, - ref_id: id_from_node_id(id, self), + ref_id: id_from_node_id(self.tcx.hir().hir_to_node_id(id), self), }) } HirDef::Trait(def_id) if fn_type(path_seg) => { diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 15ae39600f6b..b8c0baff69b2 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -350,7 +350,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let def_span = match def { Def::Err => None, - Def::Local(id) | Def::Upvar(id, ..) => Some(self.tcx.hir().span(id)), + Def::Local(id) | Def::Upvar(id, ..) => { + Some(self.tcx.hir().span_by_hir_id(id)) + }, _ => def .opt_def_id() .and_then(|did| self.tcx.hir().span_if_local(did)), diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 8739147c621e..8c1f4aabb1b2 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -236,12 +236,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ) -> Option<(Span, &'static str, String)> { if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node { if let hir::def::Def::Local(id) = path.def { - let parent = self.tcx.hir().get_parent_node(id); + let parent = self.tcx.hir().get_parent_node_by_hir_id(id); if let Some(Node::Expr(hir::Expr { hir_id, node: hir::ExprKind::Closure(_, decl, ..), .. - })) = self.tcx.hir().find(parent) { + })) = self.tcx.hir().find_by_hir_id(parent) { let parent = self.tcx.hir().get_parent_node_by_hir_id(*hir_id); if let (Some(Node::Expr(hir::Expr { node: hir::ExprKind::MethodCall(path, span, expr), diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 31b7724d6381..ff889c89770a 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -249,14 +249,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ExprKind::Path(ref qpath) => { // local binding if let &QPath::Resolved(_, ref path) = &qpath { - if let hir::def::Def::Local(node_id) = path.def { - let span = tcx.hir().span(node_id); + if let hir::def::Def::Local(hir_id) = path.def { + let span = tcx.hir().span_by_hir_id(hir_id); let snippet = tcx.sess.source_map().span_to_snippet(span) .unwrap(); let filename = tcx.sess.source_map().span_to_filename(span); - let parent_node = self.tcx.hir().get( - self.tcx.hir().get_parent_node(node_id), + let parent_node = self.tcx.hir().get_by_hir_id( + self.tcx.hir().get_parent_node_by_hir_id(hir_id), ); let msg = format!( "you must specify a type for this binding, like `{}`", diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 313ed19b945d..0f076aaa2050 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5397,8 +5397,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); + Def::Local(hid) | Def::Upvar(hid, ..) => { let ty = self.local_ty(span, hid).decl_ty; let ty = self.normalize_associated_types_in(span, &ty); self.write_ty(hir_id, ty); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index a76dfdd69ba9..dc66c6c93d0e 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -126,7 +126,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for freevar in freevars { let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { - hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()), + hir_id: freevar.var_id(), }, closure_expr_id: LocalDefId::from_def_id(closure_def_id), }; @@ -250,8 +250,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { freevars .iter() .map(|freevar| { - let var_node_id = freevar.var_id(); - let var_hir_id = tcx.hir().node_to_hir_id(var_node_id); + let var_hir_id = freevar.var_id(); let freevar_ty = self.node_ty(var_hir_id); let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, @@ -261,7 +260,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!( "var_id={:?} freevar_ty={:?} capture={:?}", - var_node_id, freevar_ty, capture + var_hir_id, freevar_ty, capture ); match capture { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index dbc55b62ef84..a62b33686485 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -429,12 +429,12 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { // skip proc-macro stubs, they'll cause `get_macro` to crash } else { if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) { - return Some(def); + return Some(def.map_id(|_| panic!("unexpected id"))); } } } if let Some(def) = resolver.all_macros.get(&Symbol::intern(path_str)) { - return Some(*def); + return Some(def.map_id(|_| panic!("unexpected id"))); } None }) From b5d43fcdc9512e538c6d2070df0ad2fed35f85bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 11 Apr 2019 18:33:36 +0200 Subject: [PATCH 09/12] Update tests --- src/test/mir-opt/inline-closure-borrows-arg.rs | 2 +- src/test/mir-opt/inline-closure.rs | 2 +- src/test/mir-opt/retag.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline-closure-borrows-arg.rs index d09ddce09c54..2c30c7f36514 100644 --- a/src/test/mir-opt/inline-closure-borrows-arg.rs +++ b/src/test/mir-opt/inline-closure-borrows-arg.rs @@ -20,7 +20,7 @@ fn foo(_t: T, q: &i32) -> i32 { // ... // bb0: { // ... -// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 27 }]; +// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 29 }]; // ... // _4 = &_3; // ... diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline-closure.rs index 436a8c20e2b4..8116a445467f 100644 --- a/src/test/mir-opt/inline-closure.rs +++ b/src/test/mir-opt/inline-closure.rs @@ -16,7 +16,7 @@ fn foo(_t: T, q: i32) -> i32 { // ... // bb0: { // ... -// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 11 }]; +// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 13 }]; // ... // _4 = &_3; // ... diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index 3b333b5431c3..1f8abf10fa54 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -98,7 +98,7 @@ fn main() { // } // END rustc.main.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 70 }], _2: &i32) -> &i32 { +// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(0:7), local_id: 72 }], _2: &i32) -> &i32 { // ... // bb0: { // Retag([fn entry] _1); From 3c3a1402949b42c4470af6e0aee2b8f15bf24129 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 13 Apr 2019 12:56:07 +0300 Subject: [PATCH 10/12] Fix cross-crate visibility of fictive variant constructors --- src/librustc_metadata/decoder.rs | 11 ++++++++++- .../variants_fictive_visibility.rs | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f456a5c1619c..e2464c517ae7 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -831,7 +831,16 @@ impl<'a, 'tcx> CrateMetadata { let ctor_def_id = self.get_ctor_def_id(child_index).unwrap_or(def_id); let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Variant, ctor_kind); - let vis = self.get_visibility(ctor_def_id.index); + let mut vis = self.get_visibility(ctor_def_id.index); + // If the variant is marked as non_exhaustive then lower the visibility + // to within the crate. + let has_non_exhaustive = || { attr::contains_name( + &self.get_item_attrs(def_id.index, sess), "non_exhaustive" + )}; + if vis == ty::Visibility::Public && has_non_exhaustive() { + let crate_def_id = DefId { index: CRATE_DEF_INDEX, ..def_id }; + vis = ty::Visibility::Restricted(crate_def_id); + } callback(def::Export { def: ctor_def, ident, vis, span }); } _ => {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs new file mode 100644 index 000000000000..9057592259ba --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -0,0 +1,9 @@ +// compile-pass +// aux-build:variants.rs + +extern crate variants; + +const S: u8 = 0; +use variants::NonExhaustiveVariants::Struct as S; + +fn main() {} From dbc7042bfe690d55cbcd40e75851efd8af9bb34e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 14 Apr 2019 12:37:22 +0300 Subject: [PATCH 11/12] Address review comments --- src/librustc_metadata/decoder.rs | 18 ++++++++++-------- .../variants_fictive_visibility.rs | 3 +++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e2464c517ae7..076e6590226e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -832,14 +832,16 @@ impl<'a, 'tcx> CrateMetadata { let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::Ctor(ctor_def_id, CtorOf::Variant, ctor_kind); let mut vis = self.get_visibility(ctor_def_id.index); - // If the variant is marked as non_exhaustive then lower the visibility - // to within the crate. - let has_non_exhaustive = || { attr::contains_name( - &self.get_item_attrs(def_id.index, sess), "non_exhaustive" - )}; - if vis == ty::Visibility::Public && has_non_exhaustive() { - let crate_def_id = DefId { index: CRATE_DEF_INDEX, ..def_id }; - vis = ty::Visibility::Restricted(crate_def_id); + if ctor_def_id == def_id && vis == ty::Visibility::Public { + // For non-exhaustive variants lower the constructor visibility to + // within the crate. We only need this for fictive constructors, + // for other constructors correct visibilities + // were already encoded in metadata. + let attrs = self.get_item_attrs(def_id.index, sess); + if attr::contains_name(&attrs, "non_exhaustive") { + let crate_def_id = DefId { index: CRATE_DEF_INDEX, ..def_id }; + vis = ty::Visibility::Restricted(crate_def_id); + } } callback(def::Export { def: ctor_def, ident, vis, span }); } diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs index 9057592259ba..62f6e4463f93 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -4,6 +4,9 @@ extern crate variants; const S: u8 = 0; + +// OK, `Struct` in value namespace is crate-private, so it's filtered away +// and there's no conflict with the previously defined `const S`. use variants::NonExhaustiveVariants::Struct as S; fn main() {} From 8f3fd85da4d4a28bba6ff9d9223e578005a0704a Mon Sep 17 00:00:00 2001 From: krk Date: Sun, 14 Apr 2019 14:27:54 +0200 Subject: [PATCH 12/12] Add missing backtick to Symbol documentation. --- src/libsyntax_pos/symbol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 393f52e7de51..d2fb67f8c066 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -136,7 +136,7 @@ impl Decodable for Ident { } /// A symbol is an interned or gensymed string. The use of `newtype_index!` means -/// that `Option` only takes up 4 bytes, because `newtype_index! reserves +/// that `Option` only takes up 4 bytes, because `newtype_index!` reserves /// the last 256 values for tagging purposes. /// /// Note that `Symbol` cannot directly be a `newtype_index!` because it implements