From f85b0c456f763a70a8eae0e4a9daf6a4005ef87a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 24 Feb 2020 18:06:42 +0900 Subject: [PATCH 01/13] Remove use of `unwrap()` from save-analysis --- src/librustc_save_analysis/lib.rs | 19 +++++++++++-------- src/test/ui/assign-to-method.rs | 2 ++ src/test/ui/assign-to-method.stderr | 4 ++-- src/test/ui/issues/issue-3763.rs | 2 ++ src/test/ui/issues/issue-3763.stderr | 10 +++++----- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index b253559dd5cd5..a46be2dcd82d5 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -533,14 +533,17 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { match self.tables.expr_ty_adjusted(&hir_node).kind { ty::Adt(def, _) if !def.is_enum() => { let variant = &def.non_enum_variant(); - let index = self.tcx.find_field_index(ident, variant).unwrap(); - filter!(self.span_utils, ident.span); - let span = self.span_from_span(ident.span); - return Some(Data::RefData(Ref { - kind: RefKind::Variable, - span, - ref_id: id_from_def_id(variant.fields[index].did), - })); + if let Some(index) = self.tcx.find_field_index(ident, variant) { + filter!(self.span_utils, ident.span); + let span = self.span_from_span(ident.span); + return Some(Data::RefData(Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(variant.fields[index].did), + })); + } + + None } ty::Tuple(..) => None, _ => { diff --git a/src/test/ui/assign-to-method.rs b/src/test/ui/assign-to-method.rs index 95f066c382c8d..dec096252253a 100644 --- a/src/test/ui/assign-to-method.rs +++ b/src/test/ui/assign-to-method.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zsave-analysis + struct Cat { meows : usize, diff --git a/src/test/ui/assign-to-method.stderr b/src/test/ui/assign-to-method.stderr index feceadb67220b..b9ef49acd6da2 100644 --- a/src/test/ui/assign-to-method.stderr +++ b/src/test/ui/assign-to-method.stderr @@ -1,5 +1,5 @@ error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:20:8 + --> $DIR/assign-to-method.rs:22:8 | LL | nyan.speak = || println!("meow"); | ^^^^^ @@ -7,7 +7,7 @@ LL | nyan.speak = || println!("meow"); = help: methods are immutable and cannot be assigned to error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:21:8 + --> $DIR/assign-to-method.rs:23:8 | LL | nyan.speak += || println!("meow"); | ^^^^^ diff --git a/src/test/ui/issues/issue-3763.rs b/src/test/ui/issues/issue-3763.rs index 5d17a30ab3624..a220151c41631 100644 --- a/src/test/ui/issues/issue-3763.rs +++ b/src/test/ui/issues/issue-3763.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zsave-analysis + mod my_mod { pub struct MyStruct { priv_field: isize diff --git a/src/test/ui/issues/issue-3763.stderr b/src/test/ui/issues/issue-3763.stderr index 50169286b1ceb..3db962142b5b2 100644 --- a/src/test/ui/issues/issue-3763.stderr +++ b/src/test/ui/issues/issue-3763.stderr @@ -1,29 +1,29 @@ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:15:19 + --> $DIR/issue-3763.rs:17:19 | LL | let _woohoo = (&my_struct).priv_field; | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:18:19 + --> $DIR/issue-3763.rs:20:19 | LL | let _woohoo = (Box::new(my_struct)).priv_field; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:21:18 + --> $DIR/issue-3763.rs:23:18 | LL | (&my_struct).happyfun(); | ^^^^^^^^ error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:23:27 + --> $DIR/issue-3763.rs:25:27 | LL | (Box::new(my_struct)).happyfun(); | ^^^^^^^^ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:24:16 + --> $DIR/issue-3763.rs:26:16 | LL | let nope = my_struct.priv_field; | ^^^^^^^^^^^^^^^^^^^^ From a211a82b3c7e450edd99ff6d3cf77a0cedae0d2e Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 24 Feb 2020 23:22:46 +0900 Subject: [PATCH 02/13] Address review comment --- src/librustc_save_analysis/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index a46be2dcd82d5..22df31cc526d6 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -533,17 +533,17 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { match self.tables.expr_ty_adjusted(&hir_node).kind { ty::Adt(def, _) if !def.is_enum() => { let variant = &def.non_enum_variant(); - if let Some(index) = self.tcx.find_field_index(ident, variant) { - filter!(self.span_utils, ident.span); - let span = self.span_from_span(ident.span); - return Some(Data::RefData(Ref { - kind: RefKind::Variable, - span, - ref_id: id_from_def_id(variant.fields[index].did), - })); - } - - None + filter!(self.span_utils, ident.span); + let span = self.span_from_span(ident.span); + return Some(Data::RefData(Ref { + kind: RefKind::Variable, + span, + ref_id: self + .tcx + .find_field_index(ident, variant) + .map(|index| id_from_def_id(variant.fields[index].did)) + .unwrap_or_else(|| null_id()), + })); } ty::Tuple(..) => None, _ => { From 5307edce6faa5c675dc57a1dd3b4fdcbf1ebdc7d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 25 Feb 2020 00:21:45 +0900 Subject: [PATCH 03/13] Tweak tests --- src/test/ui/assign-to-method.rs | 24 ------------------- src/test/ui/issues/issue-3763.rs | 1 + src/test/ui/issues/issue-3763.stderr | 10 ++++---- src/test/ui/methods/assign-to-method.rs | 24 +++++++++++++++++++ .../ui/{ => methods}/assign-to-method.stderr | 12 +++++----- 5 files changed, 36 insertions(+), 35 deletions(-) delete mode 100644 src/test/ui/assign-to-method.rs create mode 100644 src/test/ui/methods/assign-to-method.rs rename src/test/ui/{ => methods}/assign-to-method.stderr (65%) diff --git a/src/test/ui/assign-to-method.rs b/src/test/ui/assign-to-method.rs deleted file mode 100644 index dec096252253a..0000000000000 --- a/src/test/ui/assign-to-method.rs +++ /dev/null @@ -1,24 +0,0 @@ -// compile-flags: -Zsave-analysis - -struct Cat { - meows : usize, - - how_hungry : isize, -} - -impl Cat { - pub fn speak(&self) { self.meows += 1; } -} - -fn cat(in_x : usize, in_y : isize) -> Cat { - Cat { - meows: in_x, - how_hungry: in_y - } -} - -fn main() { - let nyan : Cat = cat(52, 99); - nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method - nyan.speak += || println!("meow"); //~ ERROR attempted to take value of method -} diff --git a/src/test/ui/issues/issue-3763.rs b/src/test/ui/issues/issue-3763.rs index a220151c41631..3494df37fe7f1 100644 --- a/src/test/ui/issues/issue-3763.rs +++ b/src/test/ui/issues/issue-3763.rs @@ -1,4 +1,5 @@ // compile-flags: -Zsave-analysis +// Also regression test for #69416 mod my_mod { pub struct MyStruct { diff --git a/src/test/ui/issues/issue-3763.stderr b/src/test/ui/issues/issue-3763.stderr index 3db962142b5b2..873f69d390e67 100644 --- a/src/test/ui/issues/issue-3763.stderr +++ b/src/test/ui/issues/issue-3763.stderr @@ -1,29 +1,29 @@ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:17:19 + --> $DIR/issue-3763.rs:18:19 | LL | let _woohoo = (&my_struct).priv_field; | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:20:19 + --> $DIR/issue-3763.rs:21:19 | LL | let _woohoo = (Box::new(my_struct)).priv_field; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:23:18 + --> $DIR/issue-3763.rs:24:18 | LL | (&my_struct).happyfun(); | ^^^^^^^^ error[E0624]: method `happyfun` is private - --> $DIR/issue-3763.rs:25:27 + --> $DIR/issue-3763.rs:26:27 | LL | (Box::new(my_struct)).happyfun(); | ^^^^^^^^ error[E0616]: field `priv_field` of struct `my_mod::MyStruct` is private - --> $DIR/issue-3763.rs:26:16 + --> $DIR/issue-3763.rs:27:16 | LL | let nope = my_struct.priv_field; | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/methods/assign-to-method.rs b/src/test/ui/methods/assign-to-method.rs new file mode 100644 index 0000000000000..85beaee8df0a1 --- /dev/null +++ b/src/test/ui/methods/assign-to-method.rs @@ -0,0 +1,24 @@ +// compile-flags: -Zsave-analysis +// Also regression test for #69409 + +struct Cat { + meows : usize, + how_hungry : isize, +} + +impl Cat { + pub fn speak(&self) { self.meows += 1; } +} + +fn cat(in_x : usize, in_y : isize) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y + } +} + +fn main() { + let nyan : Cat = cat(52, 99); + nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method + nyan.speak += || println!("meow"); //~ ERROR attempted to take value of method +} diff --git a/src/test/ui/assign-to-method.stderr b/src/test/ui/methods/assign-to-method.stderr similarity index 65% rename from src/test/ui/assign-to-method.stderr rename to src/test/ui/methods/assign-to-method.stderr index b9ef49acd6da2..c0dd529b6818f 100644 --- a/src/test/ui/assign-to-method.stderr +++ b/src/test/ui/methods/assign-to-method.stderr @@ -1,16 +1,16 @@ error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:22:8 + --> $DIR/assign-to-method.rs:22:10 | -LL | nyan.speak = || println!("meow"); - | ^^^^^ +LL | nyan.speak = || println!("meow"); + | ^^^^^ | = help: methods are immutable and cannot be assigned to error[E0615]: attempted to take value of method `speak` on type `Cat` - --> $DIR/assign-to-method.rs:23:8 + --> $DIR/assign-to-method.rs:23:10 | -LL | nyan.speak += || println!("meow"); - | ^^^^^ +LL | nyan.speak += || println!("meow"); + | ^^^^^ | = help: methods are immutable and cannot be assigned to From f9db3c243bae6c0618f83a36520b3fa7e726d693 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 29 Feb 2020 03:22:18 +0900 Subject: [PATCH 04/13] Clean up unstable book --- .../language-features/const-in-array-repeat-expressions.md | 2 +- .../src/language-features/impl-trait-in-bindings.md | 4 ++-- src/doc/unstable-book/src/language-features/link-cfg.md | 5 +++++ src/doc/unstable-book/src/language-features/trait-alias.md | 2 +- .../src/language-features/transparent-unions.md | 2 +- .../unstable-book/src/library-features/read-initializer.md | 7 ------- .../library-features/tidy-test-never-used-anywhere-else.md | 5 +++++ 7 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/link-cfg.md delete mode 100644 src/doc/unstable-book/src/library-features/read-initializer.md create mode 100644 src/doc/unstable-book/src/library-features/tidy-test-never-used-anywhere-else.md diff --git a/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md b/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md index 09d1b19b4c3c3..940916944bdaa 100644 --- a/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md +++ b/src/doc/unstable-book/src/language-features/const-in-array-repeat-expressions.md @@ -2,7 +2,7 @@ The tracking issue for this feature is: [#49147] -[#44109]: https://github.com/rust-lang/rust/issues/49147 +[#49147]: https://github.com/rust-lang/rust/issues/49147 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md b/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md index 896465cf64978..5c6aa912c1b24 100644 --- a/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md +++ b/src/doc/unstable-book/src/language-features/impl-trait-in-bindings.md @@ -1,8 +1,8 @@ # `impl_trait_in_bindings` -The tracking issue for this feature is: [#34511] +The tracking issue for this feature is: [#63065] -[#34511]: https://github.com/rust-lang/rust/issues/34511 +[#63065]: https://github.com/rust-lang/rust/issues/63065 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/link-cfg.md b/src/doc/unstable-book/src/language-features/link-cfg.md new file mode 100644 index 0000000000000..ee0fd5bf8698c --- /dev/null +++ b/src/doc/unstable-book/src/language-features/link-cfg.md @@ -0,0 +1,5 @@ +# `link_cfg` + +This feature is internal to the Rust compiler and is not intended for general use. + +------------------------ diff --git a/src/doc/unstable-book/src/language-features/trait-alias.md b/src/doc/unstable-book/src/language-features/trait-alias.md index 4f2db040160c3..f1be053ddc42e 100644 --- a/src/doc/unstable-book/src/language-features/trait-alias.md +++ b/src/doc/unstable-book/src/language-features/trait-alias.md @@ -2,7 +2,7 @@ The tracking issue for this feature is: [#41517] -[#41417]: https://github.com/rust-lang/rust/issues/41517 +[#41517]: https://github.com/rust-lang/rust/issues/41517 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/transparent-unions.md b/src/doc/unstable-book/src/language-features/transparent-unions.md index b731c9ea6d012..9b39b8971644f 100644 --- a/src/doc/unstable-book/src/language-features/transparent-unions.md +++ b/src/doc/unstable-book/src/language-features/transparent-unions.md @@ -2,7 +2,7 @@ The tracking issue for this feature is [#60405] -[60405]: https://github.com/rust-lang/rust/issues/60405 +[#60405]: https://github.com/rust-lang/rust/issues/60405 ---- diff --git a/src/doc/unstable-book/src/library-features/read-initializer.md b/src/doc/unstable-book/src/library-features/read-initializer.md deleted file mode 100644 index 898fe58eeee53..0000000000000 --- a/src/doc/unstable-book/src/library-features/read-initializer.md +++ /dev/null @@ -1,7 +0,0 @@ -# `read_initializer` - -The tracking issue for this feature is: [#42788] - -[#0]: https://github.com/rust-lang/rust/issues/42788 - ------------------------- diff --git a/src/doc/unstable-book/src/library-features/tidy-test-never-used-anywhere-else.md b/src/doc/unstable-book/src/library-features/tidy-test-never-used-anywhere-else.md new file mode 100644 index 0000000000000..c194d79a19d3e --- /dev/null +++ b/src/doc/unstable-book/src/library-features/tidy-test-never-used-anywhere-else.md @@ -0,0 +1,5 @@ +# `tidy_test_never_used_anywhere_else` + +This feature is internal to the Rust compiler and is not intended for general use. + +------------------------ From 4c9e87e989bd15bde318e4a03836591658826445 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 29 Feb 2020 23:29:46 +0900 Subject: [PATCH 05/13] Stop generating `compiler_builtins_lib` doc --- src/tools/tidy/src/features.rs | 14 -------------- src/tools/tidy/src/unstable_book.rs | 18 ++---------------- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 12f93a87cb172..d9320e9147cff 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -63,20 +63,6 @@ pub struct CollectedFeatures { pub fn collect_lib_features(base_src_path: &Path) -> Features { let mut lib_features = Features::new(); - // This library feature is defined in the `compiler_builtins` crate, which - // has been moved out-of-tree. Now it can no longer be auto-discovered by - // `tidy`, because we need to filter out its (submodule) directory. Manually - // add it to the set of known library features so we can still generate docs. - lib_features.insert( - "compiler_builtins_lib".to_owned(), - Feature { - level: Status::Unstable, - since: None, - has_gate_test: false, - tracking_issue: None, - }, - ); - map_lib_features(base_src_path, &mut |res, _, _| { if let Ok((name, feature)) = res { lib_features.insert(name.to_owned(), feature); diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index 472d66459d724..7dfb6224d240a 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -1,4 +1,4 @@ -use crate::features::{CollectedFeatures, Feature, Features, Status}; +use crate::features::{CollectedFeatures, Features, Status}; use std::collections::BTreeSet; use std::fs; use std::path::{Path, PathBuf}; @@ -73,26 +73,12 @@ fn collect_unstable_book_lib_features_section_file_names(base_src_path: &Path) - pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) { let lang_features = features.lang; - let mut lib_features = features + let lib_features = features .lib .into_iter() .filter(|&(ref name, _)| !lang_features.contains_key(name)) .collect::(); - // This library feature is defined in the `compiler_builtins` crate, which - // has been moved out-of-tree. Now it can no longer be auto-discovered by - // `tidy`, because we need to filter out its (submodule) directory. Manually - // add it to the set of known library features so we can still generate docs. - lib_features.insert( - "compiler_builtins_lib".to_owned(), - Feature { - level: Status::Unstable, - since: None, - has_gate_test: false, - tracking_issue: None, - }, - ); - // Library features let unstable_lib_feature_names = collect_unstable_feature_names(&lib_features); let unstable_book_lib_features_section_file_names = From c55df3786a944e10615075184a507554cf7d7c39 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 1 Mar 2020 00:35:49 +0900 Subject: [PATCH 06/13] Make `rustc_attrs` tracking issue None --- src/librustc_feature/active.rs | 6 +++--- .../min_const_fn/allow_const_fn_ptr_feature_gate.stderr | 1 - src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr | 3 --- src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr | 4 ---- .../on-unimplemented/feature-gate-on-unimplemented.stderr | 1 - src/test/ui/proc-macro/expand-to-unstable-2.stderr | 1 - src/test/ui/reserved/reserved-attr-on-macro.stderr | 1 - src/test/ui/suggestions/attribute-typos.stderr | 1 - src/test/ui/tool-attributes/diagnostic_item.stderr | 1 - 9 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 0082f4f1a6e89..380dfc4a0673f 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -99,6 +99,9 @@ declare_features! ( // no-tracking-issue-start + /// Allows using `rustc_*` attributes (RFC 572). + (active, rustc_attrs, "1.0.0", None, None), + /// Allows using compiler's own crates. (active, rustc_private, "1.0.0", Some(27812), None), @@ -128,9 +131,6 @@ declare_features! ( /// Allows using `#[link_name="llvm.*"]`. (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), - /// Allows using `rustc_*` attributes (RFC 572). - (active, rustc_attrs, "1.0.0", Some(29642), None), - /// Allows using the `box $expr` syntax. (active, box_syntax, "1.0.0", Some(49733), None), diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr index c8d060f5cdcfe..7794cc7583dfc 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr @@ -4,7 +4,6 @@ error[E0658]: internal implementation detail LL | #[rustc_allow_const_fn_ptr] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr index 082d897c01dc1..82dec1fd4cf21 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs-1.stderr @@ -4,7 +4,6 @@ error[E0658]: the `#[rustc_variance]` attribute is just used for rustc unit test LL | #[rustc_variance] | ^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable @@ -13,7 +12,6 @@ error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests a LL | #[rustc_error] | ^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable @@ -22,7 +20,6 @@ error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just u LL | #[rustc_nonnull_optimization_guaranteed] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index 58f8b4e703513..1e039f17a0d11 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -4,7 +4,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[rustc::unknown] | ^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: expected attribute, found macro `rustc::unknown` @@ -19,7 +18,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[unknown::rustc] | ^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: expected attribute, found macro `unknown::rustc` @@ -34,7 +32,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[rustc_unknown] | ^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: cannot find attribute `rustc_unknown` in this scope @@ -49,7 +46,6 @@ error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests a LL | #[rustc_dummy] | ^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to 7 previous errors diff --git a/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr index 71baf92b2d409..a4b33963fb0b9 100644 --- a/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr +++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr @@ -4,7 +4,6 @@ error[E0658]: this is an internal attribute that will never be stable LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr index ff2e3af3777a1..19144b210a127 100644 --- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr +++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr @@ -4,7 +4,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[derive(Unstable)] | ^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr index 2870cb57e9caf..c387bba0a1310 100644 --- a/src/test/ui/reserved/reserved-attr-on-macro.stderr +++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr @@ -4,7 +4,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: cannot determine resolution for the macro `foo` diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr index 10a119a628c70..c7c257ba5fe53 100644 --- a/src/test/ui/suggestions/attribute-typos.stderr +++ b/src/test/ui/suggestions/attribute-typos.stderr @@ -4,7 +4,6 @@ error[E0658]: attributes starting with `rustc` are reserved for use by the `rust LL | #[rustc_err] | ^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: cannot find attribute `rustc_err` in this scope diff --git a/src/test/ui/tool-attributes/diagnostic_item.stderr b/src/test/ui/tool-attributes/diagnostic_item.stderr index d12834084e714..743e4b658c6b7 100644 --- a/src/test/ui/tool-attributes/diagnostic_item.stderr +++ b/src/test/ui/tool-attributes/diagnostic_item.stderr @@ -4,7 +4,6 @@ error[E0658]: diagnostic items compiler internal support for linting LL | #[rustc_diagnostic_item = "foomp"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #29642 for more information = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: aborting due to previous error From 2746e12948ee4d152f8d8acfb5873f970effe501 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 1 Mar 2020 03:52:45 +0100 Subject: [PATCH 07/13] check_binding_alt_eq_ty: improve precision wrt. `if let`. --- src/librustc_typeck/check/pat.rs | 12 ++++++++++-- .../or-patterns-binding-type-mismatch.stderr | 16 ++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index d5cc19f986f45..2a8be6a02445f 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -559,8 +559,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let var_ty = self.resolve_vars_with_obligations(var_ty); let msg = format!("first introduced with type `{}` here", var_ty); err.span_label(hir.span(var_id), msg); - let in_arm = hir.parent_iter(var_id).any(|(_, n)| matches!(n, hir::Node::Arm(..))); - let pre = if in_arm { "in the same arm, " } else { "" }; + let in_match = hir.parent_iter(var_id).any(|(_, n)| { + matches!( + n, + hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Match(.., hir::MatchSource::Normal), + .. + }) + ) + }); + let pre = if in_match { "in the same arm, " } else { "" }; err.note(&format!("{}a binding must have the same type in all alternatives", pre)); err.emit(); } diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr index d5e029d668d47..1dabb7c975430 100644 --- a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr +++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr @@ -101,7 +101,7 @@ LL | if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) { | | expected `usize`, found `isize` | first introduced with type `usize` here | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:38:47 @@ -112,7 +112,7 @@ LL | if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) | | expected `usize`, found `isize` | first introduced with type `usize` here | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:42:22 @@ -123,7 +123,7 @@ LL | if let (x, y) | (y, x) = (0u8, 1u16) { | | expected `u16`, found `u8` | first introduced with type `u16` here | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:42:25 @@ -134,7 +134,7 @@ LL | if let (x, y) | (y, x) = (0u8, 1u16) { | | expected `u8`, found `u16` | first introduced with type `u8` here | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:47:44 @@ -147,7 +147,7 @@ LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | = Some((0u8, Some((1u16, 2u32)))) | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:47:53 @@ -160,7 +160,7 @@ LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | = Some((0u8, Some((1u16, 2u32)))) | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:47:62 @@ -173,7 +173,7 @@ LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | = Some((0u8, Some((1u16, 2u32)))) | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:47:65 @@ -184,7 +184,7 @@ LL | if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) LL | = Some((0u8, Some((1u16, 2u32)))) | ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>` | - = note: in the same arm, a binding must have the same type in all alternatives + = note: a binding must have the same type in all alternatives error[E0308]: mismatched types --> $DIR/or-patterns-binding-type-mismatch.rs:55:39 From 8ea676eccaa3596c56b5bf665a1adb155b634ff3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 2 Mar 2020 10:00:05 -0800 Subject: [PATCH 08/13] Update books --- src/doc/embedded-book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/embedded-book b/src/doc/embedded-book index b2e1092bf67bd..b81ffb7a6f4c5 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit b2e1092bf67bd4d7686c4553f186edbb7f5f92db +Subproject commit b81ffb7a6f4c5aaed92786e770e99db116aa4ebd diff --git a/src/doc/nomicon b/src/doc/nomicon index 3e6e1001dc6e0..9f797e65e6bcc 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 3e6e1001dc6e095dbd5c88005e80969f60e384e1 +Subproject commit 9f797e65e6bcc79419975b17aff8e21c9adc039f diff --git a/src/doc/reference b/src/doc/reference index 64239df6d1735..559e09caa9661 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 64239df6d173562b9deb4f012e4c3e6e960c4754 +Subproject commit 559e09caa9661043744cf7af7bd88432d966f743 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 32facd5522ddb..db57f899ea2a5 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 32facd5522ddbbf37baf01e4e4b6562bc55c071a +Subproject commit db57f899ea2a56a544c8d280cbf033438666273d From 44c97c43b5d3df5d76381f80fb8ad0042c6ccf55 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Fri, 6 Mar 2020 14:32:54 +0100 Subject: [PATCH 09/13] Fix & test leak of some BTreeMap nodes on panic during `into_iter` --- src/liballoc/collections/btree/map.rs | 11 ++++++++++- src/liballoc/tests/btree/map.rs | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 8b9ffdfb49b46..9da324ba2d4f1 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -1477,6 +1477,14 @@ impl Drop for IntoIter { // Continue the same loop we perform below. This only runs when unwinding, so we // don't have to care about panics this time (they'll abort). while let Some(_) = self.0.next() {} + + // No need to avoid the shared root, because the tree was definitely not empty. + unsafe { + let mut node = ptr::read(&self.0.front).into_node().forget_type(); + while let Some(parent) = node.deallocate_and_ascend() { + node = parent.into_node().forget_type(); + } + } } } @@ -1491,7 +1499,8 @@ impl Drop for IntoIter { if node.is_shared_root() { return; } - + // Most of the nodes have been deallocated while traversing + // but one pile from a leaf up to the root is left standing. while let Some(parent) = node.deallocate_and_ascend() { node = parent.into_node().forget_type(); } diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index fd07a4d3926c3..d05eec19346de 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -1021,7 +1021,7 @@ fn test_split_off_large_random_sorted() { } #[test] -fn test_into_iter_drop_leak() { +fn test_into_iter_drop_leak_1() { static DROPS: AtomicU32 = AtomicU32::new(0); struct D; @@ -1045,3 +1045,27 @@ fn test_into_iter_drop_leak() { assert_eq!(DROPS.load(Ordering::SeqCst), 5); } + +#[test] +fn test_into_iter_drop_leak_2() { + let size = 12; // to obtain tree with 2 levels (having edges to leaf nodes) + static DROPS: AtomicU32 = AtomicU32::new(0); + static PANIC_POINT: AtomicU32 = AtomicU32::new(0); + + struct D; + impl Drop for D { + fn drop(&mut self) { + if DROPS.fetch_add(1, Ordering::SeqCst) == PANIC_POINT.load(Ordering::SeqCst) { + panic!("panic in `drop`"); + } + } + } + + for panic_point in vec![0, 1, size - 2, size - 1] { + DROPS.store(0, Ordering::SeqCst); + PANIC_POINT.store(panic_point, Ordering::SeqCst); + let map: BTreeMap<_, _> = (0..size).map(|i| (i, D)).collect(); + catch_unwind(move || drop(map.into_iter())).ok(); + assert_eq!(DROPS.load(Ordering::SeqCst), size); + } +} From 33ebc20513c692691216ee1924d5cd29aca6f6aa Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Fri, 28 Feb 2020 14:10:33 +0100 Subject: [PATCH 10/13] Turn trailing tokens in `assert!()` into hard errors --- src/librustc_builtin_macros/assert.rs | 12 ++++-------- src/test/ui/macros/assert-trailing-junk.rs | 6 +++--- src/test/ui/macros/assert-trailing-junk.stderr | 14 ++++---------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/librustc_builtin_macros/assert.rs b/src/librustc_builtin_macros/assert.rs index 5da4a540940c2..09ff770e87b59 100644 --- a/src/librustc_builtin_macros/assert.rs +++ b/src/librustc_builtin_macros/assert.rs @@ -80,17 +80,15 @@ fn parse_assert<'a>( // my_function(); // ); // - // Warn about semicolon and suggest removing it. Eventually, this should be turned into an - // error. + // Emit an error about semicolon and suggest removing it. if parser.token == token::Semi { - let mut err = cx.struct_span_warn(sp, "macro requires an expression as an argument"); + let mut err = cx.struct_span_err(sp, "macro requires an expression as an argument"); err.span_suggestion( parser.token.span, "try removing semicolon", String::new(), Applicability::MaybeIncorrect, ); - err.note("this is going to be an error in the future"); err.emit(); parser.bump(); @@ -101,11 +99,10 @@ fn parse_assert<'a>( // // assert!(true "error message"); // - // Parse this as an actual message, and suggest inserting a comma. Eventually, this should be - // turned into an error. + // Emit an error and suggest inserting a comma. let custom_message = if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind { - let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal"); + let mut err = cx.struct_span_err(parser.token.span, "unexpected string literal"); let comma_span = parser.prev_token.span.shrink_to_hi(); err.span_suggestion_short( comma_span, @@ -113,7 +110,6 @@ fn parse_assert<'a>( ", ".to_string(), Applicability::MaybeIncorrect, ); - err.note("this is going to be an error in the future"); err.emit(); parse_custom_message(&mut parser) diff --git a/src/test/ui/macros/assert-trailing-junk.rs b/src/test/ui/macros/assert-trailing-junk.rs index 676ae05bf0fa6..cd7faf9bf8bfb 100644 --- a/src/test/ui/macros/assert-trailing-junk.rs +++ b/src/test/ui/macros/assert-trailing-junk.rs @@ -13,12 +13,12 @@ fn main() { //~^ ERROR no rules expected assert!(true "whatever" blah); - //~^ WARN unexpected string literal + //~^ ERROR unexpected string literal //~^^ ERROR no rules expected assert!(true;); - //~^ WARN macro requires an expression + //~^ ERROR macro requires an expression assert!(false || true "error message"); - //~^ WARN unexpected string literal + //~^ ERROR unexpected string literal } diff --git a/src/test/ui/macros/assert-trailing-junk.stderr b/src/test/ui/macros/assert-trailing-junk.stderr index 4d18a531a800c..84a6768b3f453 100644 --- a/src/test/ui/macros/assert-trailing-junk.stderr +++ b/src/test/ui/macros/assert-trailing-junk.stderr @@ -18,15 +18,13 @@ LL | assert!(true, "whatever" blah); | | | help: missing comma here -warning: unexpected string literal +error: unexpected string literal --> $DIR/assert-trailing-junk.rs:15:18 | LL | assert!(true "whatever" blah); | -^^^^^^^^^^ | | | help: try adding a comma - | - = note: this is going to be an error in the future error: no rules expected the token `blah` --> $DIR/assert-trailing-junk.rs:15:29 @@ -36,25 +34,21 @@ LL | assert!(true "whatever" blah); | | | help: missing comma here -warning: macro requires an expression as an argument +error: macro requires an expression as an argument --> $DIR/assert-trailing-junk.rs:19:5 | LL | assert!(true;); | ^^^^^^^^^^^^-^^ | | | help: try removing semicolon - | - = note: this is going to be an error in the future -warning: unexpected string literal +error: unexpected string literal --> $DIR/assert-trailing-junk.rs:22:27 | LL | assert!(false || true "error message"); | -^^^^^^^^^^^^^^^ | | | help: try adding a comma - | - = note: this is going to be an error in the future -error: aborting due to 4 previous errors +error: aborting due to 7 previous errors From 1915bf122e488ce540cdb7782550e907f269b9e3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 7 Mar 2020 18:49:13 +0300 Subject: [PATCH 11/13] resolve: `ImportDirective` -> `Import` `ImportDirectiveSubclass` -> `ImportKind` `ImportKind::SingleImport` -> `ImportKind::Single` `ImportKind::GlobImport` -> `ImportKind::Glob` --- src/librustc_resolve/build_reduced_graph.rs | 38 +++--- src/librustc_resolve/check_unused.rs | 10 +- src/librustc_resolve/diagnostics.rs | 10 +- src/librustc_resolve/imports.rs | 132 +++++++++----------- src/librustc_resolve/lib.rs | 40 +++--- 5 files changed, 105 insertions(+), 125 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 43cfe05ac230e..32cf1af60ecda 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -6,8 +6,7 @@ //! Imports are also considered items and placed into modules here, but not resolved yet. use crate::def_collector::collect_definitions; -use crate::imports::ImportDirective; -use crate::imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; +use crate::imports::{Import, ImportKind}; use crate::macros::{LegacyBinding, LegacyScope}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; use crate::{CrateLint, Determinacy, PathResult, ResolutionError, VisResolutionError}; @@ -312,7 +311,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn add_import_directive( &mut self, module_path: Vec, - subclass: ImportDirectiveSubclass<'a>, + kind: ImportKind<'a>, span: Span, id: NodeId, item: &ast::Item, @@ -321,11 +320,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { vis: ty::Visibility, ) { let current_module = self.parent_scope.module; - let directive = self.r.arenas.alloc_import_directive(ImportDirective { + let directive = self.r.arenas.alloc_import_directive(Import { + kind, parent_scope: self.parent_scope, module_path, imported_module: Cell::new(None), - subclass, span, id, use_span: item.span, @@ -340,10 +339,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { debug!("add_import_directive({:?})", directive); self.r.indeterminate_imports.push(directive); - match directive.subclass { + match directive.kind { // Don't add unresolved underscore imports to modules - SingleImport { target: Ident { name: kw::Underscore, .. }, .. } => {} - SingleImport { target, type_ns_only, .. } => { + ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {} + ImportKind::Single { target, type_ns_only, .. } => { self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let key = this.new_key(target, ns); @@ -354,8 +353,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // We don't add prelude imports to the globs since they only affect lexical scopes, // which are not relevant to import resolution. - GlobImport { is_prelude: true, .. } => {} - GlobImport { .. } => current_module.globs.borrow_mut().push(directive), + ImportKind::Glob { is_prelude: true, .. } => {} + ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(directive), _ => unreachable!(), } } @@ -480,7 +479,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ); } - let subclass = SingleImport { + let kind = ImportKind::Single { source: source.ident, target: ident, source_bindings: PerNS { @@ -498,7 +497,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }; self.add_import_directive( module_path, - subclass, + kind, use_tree.span, id, item, @@ -508,13 +507,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ); } ast::UseTreeKind::Glob => { - let subclass = GlobImport { + let kind = ImportKind::Glob { is_prelude: attr::contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(ty::Visibility::Invisible), }; self.add_import_directive( prefix, - subclass, + kind, use_tree.span, id, item, @@ -637,15 +636,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let used = self.process_legacy_macro_imports(item, module); let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); - let directive = self.r.arenas.alloc_import_directive(ImportDirective { + let directive = self.r.arenas.alloc_import_directive(Import { + kind: ImportKind::ExternCrate { source: orig_name, target: ident }, root_id: item.id, id: item.id, parent_scope: self.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), - subclass: ImportDirectiveSubclass::ExternCrate { - source: orig_name, - target: ident, - }, has_attributes: !item.attrs.is_empty(), use_span_with_attributes: item.span_with_attributes(), use_span: item.span, @@ -993,12 +989,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } let macro_use_directive = |this: &Self, span| { - this.r.arenas.alloc_import_directive(ImportDirective { + this.r.arenas.alloc_import_directive(Import { + kind: ImportKind::MacroUse, root_id: item.id, id: item.id, parent_scope: this.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), - subclass: ImportDirectiveSubclass::MacroUse, use_span_with_attributes: item.span_with_attributes(), has_attributes: !item.attrs.is_empty(), use_span: item.span, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 659a54b169b39..5d45fcb39343d 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -23,7 +23,7 @@ // - `check_crate` finally emits the diagnostics based on the data generated // in the last step -use crate::imports::ImportDirectiveSubclass; +use crate::imports::ImportKind; use crate::Resolver; use rustc::{lint, ty}; @@ -224,12 +224,12 @@ fn calc_unused_spans( impl Resolver<'_> { crate fn check_unused(&mut self, krate: &ast::Crate) { for directive in self.potentially_unused_imports.iter() { - match directive.subclass { + match directive.kind { _ if directive.used.get() || directive.vis.get() == ty::Visibility::Public || directive.span.is_dummy() => { - if let ImportDirectiveSubclass::MacroUse = directive.subclass { + if let ImportKind::MacroUse = directive.kind { if !directive.span.is_dummy() { self.lint_buffer.buffer_lint( lint::builtin::MACRO_USE_EXTERN_CRATE, @@ -243,10 +243,10 @@ impl Resolver<'_> { } } } - ImportDirectiveSubclass::ExternCrate { .. } => { + ImportKind::ExternCrate { .. } => { self.maybe_unused_extern_crates.push((directive.id, directive.span)); } - ImportDirectiveSubclass::MacroUse => { + ImportKind::MacroUse => { let lint = lint::builtin::UNUSED_IMPORTS; let msg = "unused `#[macro_use]` import"; self.lint_buffer.buffer_lint(lint, directive.id, directive.span, msg); diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 18192a18cef36..52d50b950005b 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -18,7 +18,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, MultiSpan, Span}; -use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; +use crate::imports::{Import, ImportKind, ImportResolver}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1126,7 +1126,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - directive: &'b ImportDirective<'b>, + directive: &'b Import<'b>, module: ModuleOrUniformRoot<'b>, ident: Ident, ) -> Option<(Option, Vec)> { @@ -1151,10 +1151,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); - let import = match directive.subclass { - ImportDirectiveSubclass::SingleImport { source, target, .. } - if source != target => - { + let import = match directive.kind { + ImportKind::Single { source, target, .. } if source != target => { format!("{} as {}", source, target) } _ => format!("{}", ident), diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 3b018005a88d2..a43ef4ffee46f 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -1,7 +1,5 @@ //! A bunch of methods and structures more or less related to resolving imports. -use ImportDirectiveSubclass::*; - use crate::diagnostics::Suggestion; use crate::Determinacy::{self, *}; use crate::Namespace::{self, MacroNS, TypeNS}; @@ -38,8 +36,8 @@ type Res = def::Res; /// Contains data for specific types of import directives. #[derive(Clone, Debug)] -pub enum ImportDirectiveSubclass<'a> { - SingleImport { +pub enum ImportKind<'a> { + Single { /// `source` in `use prefix::source as target`. source: Ident, /// `target` in `use prefix::source as target`. @@ -53,7 +51,7 @@ pub enum ImportDirectiveSubclass<'a> { /// Did this import result from a nested import? ie. `use foo::{bar, baz};` nested: bool, }, - GlobImport { + Glob { is_prelude: bool, max_vis: Cell, // The visibility of the greatest re-export. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. @@ -67,10 +65,12 @@ pub enum ImportDirectiveSubclass<'a> { /// One import directive. #[derive(Debug, Clone)] -crate struct ImportDirective<'a> { - /// The ID of the `extern crate`, `UseTree` etc that imported this `ImportDirective`. +crate struct Import<'a> { + pub kind: ImportKind<'a>, + + /// The ID of the `extern crate`, `UseTree` etc that imported this `Import`. /// - /// In the case where the `ImportDirective` was expanded from a "nested" use tree, + /// In the case where the `Import` was expanded from a "nested" use tree, /// this id is the ID of the leaf tree. For example: /// /// ```ignore (pacify the mercilous tidy) @@ -107,22 +107,21 @@ crate struct ImportDirective<'a> { pub module_path: Vec, /// The resolution of `module_path`. pub imported_module: Cell>>, - pub subclass: ImportDirectiveSubclass<'a>, pub vis: Cell, pub used: Cell, } -impl<'a> ImportDirective<'a> { +impl<'a> Import<'a> { pub fn is_glob(&self) -> bool { - match self.subclass { - ImportDirectiveSubclass::GlobImport { .. } => true, + match self.kind { + ImportKind::Glob { .. } => true, _ => false, } } pub fn is_nested(&self) -> bool { - match self.subclass { - ImportDirectiveSubclass::SingleImport { nested, .. } => nested, + match self.kind { + ImportKind::Single { nested, .. } => nested, _ => false, } } @@ -137,7 +136,7 @@ impl<'a> ImportDirective<'a> { pub struct NameResolution<'a> { /// Single imports that may define the name in the namespace. /// Import directives are arena-allocated, so it's ok to use pointers as keys. - single_imports: FxHashSet>>, + single_imports: FxHashSet>>, /// The least shadowable known binding for this name, or None if there are no known bindings. pub binding: Option<&'a NameBinding<'a>>, shadowed_glob: Option<&'a NameBinding<'a>>, @@ -155,7 +154,7 @@ impl<'a> NameResolution<'a> { }) } - crate fn add_single_import(&mut self, directive: &'a ImportDirective<'a>) { + crate fn add_single_import(&mut self, directive: &'a Import<'a>) { self.single_imports.insert(PtrKey(directive)); } } @@ -348,8 +347,8 @@ impl<'a> Resolver<'a> { single_import.imported_module.get(), return Err((Undetermined, Weak::No)) ); - let ident = match single_import.subclass { - SingleImport { source, .. } => source, + let ident = match single_import.kind { + ImportKind::Single { source, .. } => source, _ => unreachable!(), }; match self.resolve_ident_in_module( @@ -456,7 +455,7 @@ impl<'a> Resolver<'a> { crate fn import( &self, binding: &'a NameBinding<'a>, - directive: &'a ImportDirective<'a>, + directive: &'a Import<'a>, ) -> &'a NameBinding<'a> { let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || // cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE` @@ -467,7 +466,7 @@ impl<'a> Resolver<'a> { binding.pseudo_vis() }; - if let GlobImport { ref max_vis, .. } = directive.subclass { + if let ImportKind::Glob { ref max_vis, .. } = directive.kind { if vis == directive.vis.get() || vis.is_at_least(max_vis.get(), self) { max_vis.set(vis) } @@ -596,8 +595,8 @@ impl<'a> Resolver<'a> { // Define a "dummy" resolution containing a Res::Err as a placeholder for a // failed resolution - fn import_dummy_binding(&mut self, directive: &'a ImportDirective<'a>) { - if let SingleImport { target, .. } = directive.subclass { + fn import_dummy_binding(&mut self, directive: &'a Import<'a>) { + if let ImportKind::Single { target, .. } = directive.kind { let dummy_binding = self.dummy_binding; let dummy_binding = self.import(dummy_binding, directive); self.per_ns(|this, ns| { @@ -671,7 +670,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { .chain(indeterminate_imports.into_iter().map(|i| (true, i))) { if let Some(err) = self.finalize_import(import) { - if let SingleImport { source, ref source_bindings, .. } = import.subclass { + if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { if source.name == kw::SelfLower { // Silence `unresolved import` error if E0429 is already emitted if let Err(Determined) = source_bindings.value_ns.get() { @@ -695,7 +694,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if seen_spans.insert(err.span) { let path = import_path_to_string( &import.module_path.iter().map(|seg| seg.ident).collect::>(), - &import.subclass, + &import.kind, err.span, ); errors.push((path, err)); @@ -706,7 +705,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { self.r.used_imports.insert((import.id, TypeNS)); let path = import_path_to_string( &import.module_path.iter().map(|seg| seg.ident).collect::>(), - &import.subclass, + &import.kind, import.span, ); let err = UnresolvedImportError { @@ -767,7 +766,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. - fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { + fn resolve_import(&mut self, directive: &'b Import<'b>) -> bool { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&directive.module_path), @@ -798,22 +797,22 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; directive.imported_module.set(Some(module)); - let (source, target, source_bindings, target_bindings, type_ns_only) = - match directive.subclass { - SingleImport { - source, - target, - ref source_bindings, - ref target_bindings, - type_ns_only, - .. - } => (source, target, source_bindings, target_bindings, type_ns_only), - GlobImport { .. } => { - self.resolve_glob_import(directive); - return true; - } - _ => unreachable!(), - }; + let (source, target, source_bindings, target_bindings, type_ns_only) = match directive.kind + { + ImportKind::Single { + source, + target, + ref source_bindings, + ref target_bindings, + type_ns_only, + .. + } => (source, target, source_bindings, target_bindings, type_ns_only), + ImportKind::Glob { .. } => { + self.resolve_glob_import(directive); + return true; + } + _ => unreachable!(), + }; let mut indeterminate = false; self.r.per_ns(|this, ns| { @@ -873,10 +872,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import( - &mut self, - directive: &'b ImportDirective<'b>, - ) -> Option { + fn finalize_import(&mut self, directive: &'b Import<'b>) -> Option { let orig_vis = directive.vis.replace(ty::Visibility::Invisible); let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( @@ -957,10 +953,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> { PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(), }; - let (ident, target, source_bindings, target_bindings, type_ns_only) = match directive - .subclass - { - SingleImport { + let (ident, target, source_bindings, target_bindings, type_ns_only) = match directive.kind { + ImportKind::Single { source, target, ref source_bindings, @@ -968,7 +962,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { type_ns_only, .. } => (source, target, source_bindings, target_bindings, type_ns_only), - GlobImport { is_prelude, ref max_vis } => { + ImportKind::Glob { is_prelude, ref max_vis } => { if directive.module_path.len() <= 1 { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. @@ -1272,7 +1266,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { fn check_for_redundant_imports( &mut self, ident: Ident, - directive: &'b ImportDirective<'b>, + directive: &'b Import<'b>, source_bindings: &PerNS, Determinacy>>>, target_bindings: &PerNS>>>, target: Ident, @@ -1337,7 +1331,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } - fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) { + fn resolve_glob_import(&mut self, directive: &'b Import<'b>) { let module = match directive.imported_module.get().unwrap() { ModuleOrUniformRoot::Module(module) => module, _ => { @@ -1351,7 +1345,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { return; } else if module.def_id() == directive.parent_scope.module.def_id() { return; - } else if let GlobImport { is_prelude: true, .. } = directive.subclass { + } else if let ImportKind::Glob { is_prelude: true, .. } = directive.kind { self.r.prelude = Some(module); return; } @@ -1412,11 +1406,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { && orig_binding.is_variant() && !orig_binding.vis.is_at_least(binding.vis, &*this) { - let msg = match directive.subclass { - ImportDirectiveSubclass::SingleImport { .. } => { + let msg = match directive.kind { + ImportKind::Single { .. } => { format!("variant `{}` is private and cannot be re-exported", ident) } - ImportDirectiveSubclass::GlobImport { .. } => { + ImportKind::Glob { .. } => { let msg = "enum is private and its variants \ cannot be re-exported" .to_owned(); @@ -1432,7 +1426,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } msg } - ref s => bug!("unexpected import subclass {:?}", s), + ref s => bug!("unexpected import kind {:?}", s), }; let mut err = this.session.struct_span_err(binding.span, &msg); @@ -1481,11 +1475,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } -fn import_path_to_string( - names: &[Ident], - subclass: &ImportDirectiveSubclass<'_>, - span: Span, -) -> String { +fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String { let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot); let global = !names.is_empty() && names[0].name == kw::PathRoot; if let Some(pos) = pos { @@ -1494,22 +1484,22 @@ fn import_path_to_string( } else { let names = if global { &names[1..] } else { names }; if names.is_empty() { - import_directive_subclass_to_string(subclass) + import_directive_subclass_to_string(import_kind) } else { format!( "{}::{}", names_to_string(&names.iter().map(|ident| ident.name).collect::>()), - import_directive_subclass_to_string(subclass), + import_directive_subclass_to_string(import_kind), ) } } } -fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass<'_>) -> String { - match *subclass { - SingleImport { source, .. } => source.to_string(), - GlobImport { .. } => "*".to_string(), - ExternCrate { .. } => "".to_string(), - MacroUse => "#[macro_use]".to_string(), +fn import_directive_subclass_to_string(import_kind: &ImportKind<'_>) -> String { + match import_kind { + ImportKind::Single { source, .. } => source.to_string(), + ImportKind::Glob { .. } => "*".to_string(), + ImportKind::ExternCrate { .. } => "".to_string(), + ImportKind::MacroUse => "#[macro_use]".to_string(), } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 44eba0d533d3a..2ffcf340b9a91 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -56,7 +56,7 @@ use std::{cmp, fmt, iter, ptr}; use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding}; use diagnostics::{ImportSuggestion, Suggestion}; -use imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver, NameResolution}; +use imports::{Import, ImportKind, ImportResolver, NameResolution}; use late::{HasGenericParams, PathSource, Rib, RibKind::*}; use macros::{LegacyBinding, LegacyScope}; @@ -456,8 +456,8 @@ pub struct ModuleData<'a> { no_implicit_prelude: bool, - glob_importers: RefCell>>, - globs: RefCell>>, + glob_importers: RefCell>>, + globs: RefCell>>, // Used to memoize the traits in this module for faster searches through all traits in scope. traits: RefCell)]>>>, @@ -584,7 +584,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> { enum NameBindingKind<'a> { Res(Res, /* is_macro_export */ bool), Module(Module<'a>), - Import { binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>, used: Cell }, + Import { binding: &'a NameBinding<'a>, directive: &'a Import<'a>, used: Cell }, } impl<'a> NameBindingKind<'a> { @@ -713,8 +713,7 @@ impl<'a> NameBinding<'a> { fn is_extern_crate(&self) -> bool { match self.kind { NameBindingKind::Import { - directive: - &ImportDirective { subclass: ImportDirectiveSubclass::ExternCrate { .. }, .. }, + directive: &Import { kind: ImportKind::ExternCrate { .. }, .. }, .. } => true, NameBindingKind::Module(&ModuleData { @@ -839,10 +838,10 @@ pub struct Resolver<'a> { field_names: FxHashMap>>, /// All imports known to succeed or fail. - determined_imports: Vec<&'a ImportDirective<'a>>, + determined_imports: Vec<&'a Import<'a>>, /// All non-determined imports. - indeterminate_imports: Vec<&'a ImportDirective<'a>>, + indeterminate_imports: Vec<&'a Import<'a>>, /// FIXME: Refactor things so that these fields are passed through arguments and not resolver. /// We are resolving a last import segment during import validation. @@ -947,7 +946,7 @@ pub struct Resolver<'a> { /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap, - potentially_unused_imports: Vec<&'a ImportDirective<'a>>, + potentially_unused_imports: Vec<&'a Import<'a>>, /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. @@ -971,7 +970,7 @@ pub struct ResolverArenas<'a> { modules: arena::TypedArena>, local_modules: RefCell>>, name_bindings: arena::TypedArena>, - import_directives: arena::TypedArena>, + import_directives: arena::TypedArena>, name_resolutions: arena::TypedArena>>, legacy_bindings: arena::TypedArena>, ast_paths: arena::TypedArena, @@ -991,10 +990,7 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> { self.name_bindings.alloc(name_binding) } - fn alloc_import_directive( - &'a self, - import_directive: ImportDirective<'a>, - ) -> &'a ImportDirective<'_> { + fn alloc_import_directive(&'a self, import_directive: Import<'a>) -> &'a Import<'_> { self.import_directives.alloc(import_directive) } fn alloc_name_resolution(&'a self) -> &'a RefCell> { @@ -1431,7 +1427,7 @@ impl<'a> Resolver<'a> { } #[inline] - fn add_to_glob_map(&mut self, directive: &ImportDirective<'_>, ident: Ident) { + fn add_to_glob_map(&mut self, directive: &Import<'_>, ident: Ident) { if directive.is_glob() { self.glob_map.entry(directive.id).or_default().insert(ident.name); } @@ -2261,7 +2257,7 @@ impl<'a> Resolver<'a> { if let NameBindingKind::Import { directive: d, .. } = binding.kind { // Careful: we still want to rewrite paths from // renamed extern crates. - if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass { + if let ImportKind::ExternCrate { source: None, .. } = d.kind { return; } } @@ -2639,7 +2635,7 @@ impl<'a> Resolver<'a> { &self, err: &mut DiagnosticBuilder<'_>, name: Name, - directive: &ImportDirective<'_>, + directive: &Import<'_>, binding_span: Span, ) { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { @@ -2649,11 +2645,11 @@ impl<'a> Resolver<'a> { }; let mut suggestion = None; - match directive.subclass { - ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => { + match directive.kind { + ImportKind::Single { type_ns_only: true, .. } => { suggestion = Some(format!("self as {}", suggested_name)) } - ImportDirectiveSubclass::SingleImport { source, .. } => { + ImportKind::Single { source, .. } => { if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0).map(|pos| pos as usize) { @@ -2669,7 +2665,7 @@ impl<'a> Resolver<'a> { } } } - ImportDirectiveSubclass::ExternCrate { source, target, .. } => { + ImportKind::ExternCrate { source, target, .. } => { suggestion = Some(format!( "extern crate {} as {};", source.unwrap_or(target.name), @@ -2717,7 +2713,7 @@ impl<'a> Resolver<'a> { fn add_suggestion_for_duplicate_nested_use( &self, err: &mut DiagnosticBuilder<'_>, - directive: &ImportDirective<'_>, + directive: &Import<'_>, binding_span: Span, ) { assert!(directive.is_nested()); From 66d7a88c41ebcc25e499babd103177a9d8df6cdb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 7 Mar 2020 19:02:32 +0300 Subject: [PATCH 12/13] resolve: `directive` -> `import` --- src/librustc_resolve/build_reduced_graph.rs | 51 ++-- src/librustc_resolve/check_unused.rs | 30 +- src/librustc_resolve/diagnostics.rs | 18 +- src/librustc_resolve/imports.rs | 264 +++++++++--------- src/librustc_resolve/late.rs | 8 +- src/librustc_resolve/lib.rs | 77 +++-- .../ui/rust-2018/macro-use-warned-against.rs | 2 +- .../rust-2018/macro-use-warned-against.stderr | 2 +- 8 files changed, 215 insertions(+), 237 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 32cf1af60ecda..ec5a8c4a0b896 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -307,8 +307,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }) } - // Add an import directive to the current module. - fn add_import_directive( + // Add an import to the current module. + fn add_import( &mut self, module_path: Vec, kind: ImportKind<'a>, @@ -320,7 +320,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { vis: ty::Visibility, ) { let current_module = self.parent_scope.module; - let directive = self.r.arenas.alloc_import_directive(Import { + let import = self.r.arenas.alloc_import(Import { kind, parent_scope: self.parent_scope, module_path, @@ -336,10 +336,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { used: Cell::new(false), }); - debug!("add_import_directive({:?})", directive); + debug!("add_import({:?})", import); - self.r.indeterminate_imports.push(directive); - match directive.kind { + self.r.indeterminate_imports.push(import); + match import.kind { // Don't add unresolved underscore imports to modules ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {} ImportKind::Single { target, type_ns_only, .. } => { @@ -347,14 +347,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { if !type_ns_only || ns == TypeNS { let key = this.new_key(target, ns); let mut resolution = this.resolution(current_module, key).borrow_mut(); - resolution.add_single_import(directive); + resolution.add_single_import(import); } }); } // We don't add prelude imports to the globs since they only affect lexical scopes, // which are not relevant to import resolution. ImportKind::Glob { is_prelude: true, .. } => {} - ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(directive), + ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(import), _ => unreachable!(), } } @@ -495,7 +495,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { type_ns_only, nested, }; - self.add_import_directive( + self.add_import( module_path, kind, use_tree.span, @@ -511,16 +511,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { is_prelude: attr::contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(ty::Visibility::Invisible), }; - self.add_import_directive( - prefix, - kind, - use_tree.span, - id, - item, - root_span, - item.id, - vis, - ); + self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis); } ast::UseTreeKind::Nested(ref items) => { // Ensure there is at most one `self` in the list @@ -636,7 +627,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let used = self.process_legacy_macro_imports(item, module); let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); - let directive = self.r.arenas.alloc_import_directive(Import { + let import = self.r.arenas.alloc_import(Import { kind: ImportKind::ExternCrate { source: orig_name, target: ident }, root_id: item.id, id: item.id, @@ -651,8 +642,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { vis: Cell::new(vis), used: Cell::new(used), }); - self.r.potentially_unused_imports.push(directive); - let imported_binding = self.r.import(binding, directive); + self.r.potentially_unused_imports.push(import); + let imported_binding = self.r.import(binding, import); if ptr::eq(parent, self.r.graph_root) { if let Some(entry) = self.r.extern_prelude.get(&ident.modern()) { if expansion != ExpnId::root() @@ -988,8 +979,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } } - let macro_use_directive = |this: &Self, span| { - this.r.arenas.alloc_import_directive(Import { + let macro_use_import = |this: &Self, span| { + this.r.arenas.alloc_import(Import { kind: ImportKind::MacroUse, root_id: item.id, id: item.id, @@ -1008,11 +999,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let allow_shadowing = self.parent_scope.expansion == ExpnId::root(); if let Some(span) = import_all { - let directive = macro_use_directive(self, span); - self.r.potentially_unused_imports.push(directive); + let import = macro_use_import(self, span); + self.r.potentially_unused_imports.push(import); module.for_each_child(self, |this, ident, ns, binding| { if ns == MacroNS { - let imported_binding = this.r.import(binding, directive); + let imported_binding = this.r.import(binding, import); this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing); } }); @@ -1027,9 +1018,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ident.span, ); if let Ok(binding) = result { - let directive = macro_use_directive(self, ident.span); - self.r.potentially_unused_imports.push(directive); - let imported_binding = self.r.import(binding, directive); + let import = macro_use_import(self, ident.span); + self.r.potentially_unused_imports.push(import); + let imported_binding = self.r.import(binding, import); self.legacy_import_macro( ident.name, imported_binding, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 5d45fcb39343d..722f843ab6e7e 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -3,7 +3,7 @@ // // Although this is mostly a lint pass, it lives in here because it depends on // resolve data structures and because it finalises the privacy information for -// `use` directives. +// `use` items. // // Unused trait imports can't be checked until the method resolution. We save // candidates here, and do the actual check in librustc_typeck/check_unused.rs. @@ -58,7 +58,7 @@ struct UnusedImportCheckVisitor<'a, 'b> { } impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { - // We have information about whether `use` (import) directives are actually + // We have information about whether `use` (import) items are actually // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, id: ast::NodeId) { let mut used = false; @@ -223,33 +223,33 @@ fn calc_unused_spans( impl Resolver<'_> { crate fn check_unused(&mut self, krate: &ast::Crate) { - for directive in self.potentially_unused_imports.iter() { - match directive.kind { - _ if directive.used.get() - || directive.vis.get() == ty::Visibility::Public - || directive.span.is_dummy() => + for import in self.potentially_unused_imports.iter() { + match import.kind { + _ if import.used.get() + || import.vis.get() == ty::Visibility::Public + || import.span.is_dummy() => { - if let ImportKind::MacroUse = directive.kind { - if !directive.span.is_dummy() { + if let ImportKind::MacroUse = import.kind { + if !import.span.is_dummy() { self.lint_buffer.buffer_lint( lint::builtin::MACRO_USE_EXTERN_CRATE, - directive.id, - directive.span, - "deprecated `#[macro_use]` directive used to \ + import.id, + import.span, + "deprecated `#[macro_use]` attribute used to \ import macros should be replaced at use sites \ - with a `use` statement to import the macro \ + with a `use` item to import the macro \ instead", ); } } } ImportKind::ExternCrate { .. } => { - self.maybe_unused_extern_crates.push((directive.id, directive.span)); + self.maybe_unused_extern_crates.push((import.id, import.span)); } ImportKind::MacroUse => { let lint = lint::builtin::UNUSED_IMPORTS; let msg = "unused `#[macro_use]` import"; - self.lint_buffer.buffer_lint(lint, directive.id, directive.span, msg); + self.lint_buffer.buffer_lint(lint, import.id, import.span, msg); } _ => {} } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 52d50b950005b..38efc907ff077 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1126,7 +1126,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - directive: &'b Import<'b>, + import: &'b Import<'b>, module: ModuleOrUniformRoot<'b>, ident: Ident, ) -> Option<(Option, Vec)> { @@ -1151,7 +1151,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); - let import = match directive.kind { + let import_snippet = match import.kind { ImportKind::Single { source, target, .. } if source != target => { format!("{} as {}", source, target) } @@ -1159,18 +1159,18 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; let mut corrections: Vec<(Span, String)> = Vec::new(); - if !directive.is_nested() { + if !import.is_nested() { // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove // intermediate segments. - corrections.push((directive.span, format!("{}::{}", module_name, import))); + corrections.push((import.span, format!("{}::{}", module_name, import_snippet))); } else { // Find the binding span (and any trailing commas and spaces). // ie. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( self.r.session, - directive.span, - directive.use_span, + import.span, + import.use_span, ); debug!( "check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}", @@ -1207,7 +1207,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( self.r.session, module_name, - directive.use_span, + import.use_span, ); debug!( "check_for_module_export_macro: has_nested={:?} after_crate_name={:?}", @@ -1223,11 +1223,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { start_point, if has_nested { // In this case, `start_snippet` must equal '{'. - format!("{}{}, ", start_snippet, import) + format!("{}{}, ", start_snippet, import_snippet) } else { // In this case, add a `{`, then the moved import, then whatever // was there before. - format!("{{{}, {}", import, start_snippet) + format!("{{{}, {}", import_snippet, start_snippet) }, )); } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index a43ef4ffee46f..81c1e496c9d5f 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -34,7 +34,7 @@ use std::{mem, ptr}; type Res = def::Res; -/// Contains data for specific types of import directives. +/// Contains data for specific kinds of imports. #[derive(Clone, Debug)] pub enum ImportKind<'a> { Single { @@ -63,7 +63,7 @@ pub enum ImportKind<'a> { MacroUse, } -/// One import directive. +/// One import. #[derive(Debug, Clone)] crate struct Import<'a> { pub kind: ImportKind<'a>, @@ -77,7 +77,7 @@ crate struct Import<'a> { /// use foo::bar::{a, b} /// ``` /// - /// If this is the import directive for `foo::bar::a`, we would have the ID of the `UseTree` + /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree` /// for `a` in this field. pub id: NodeId, @@ -135,7 +135,7 @@ impl<'a> Import<'a> { /// Records information about the resolution of a name in a namespace of a module. pub struct NameResolution<'a> { /// Single imports that may define the name in the namespace. - /// Import directives are arena-allocated, so it's ok to use pointers as keys. + /// Imports are arena-allocated, so it's ok to use pointers as keys. single_imports: FxHashSet>>, /// The least shadowable known binding for this name, or None if there are no known bindings. pub binding: Option<&'a NameBinding<'a>>, @@ -154,8 +154,8 @@ impl<'a> NameResolution<'a> { }) } - crate fn add_single_import(&mut self, directive: &'a Import<'a>) { - self.single_imports.insert(PtrKey(directive)); + crate fn add_single_import(&mut self, import: &'a Import<'a>) { + self.single_imports.insert(PtrKey(import)); } } @@ -450,34 +450,34 @@ impl<'a> Resolver<'a> { Err((Determined, Weak::No)) } - // Given a binding and an import directive that resolves to it, - // return the corresponding binding defined by the import directive. + // Given a binding and an import that resolves to it, + // return the corresponding binding defined by the import. crate fn import( &self, binding: &'a NameBinding<'a>, - directive: &'a Import<'a>, + import: &'a Import<'a>, ) -> &'a NameBinding<'a> { - let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || + let vis = if binding.pseudo_vis().is_at_least(import.vis.get(), self) || // cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE` - !directive.is_glob() && binding.is_extern_crate() + !import.is_glob() && binding.is_extern_crate() { - directive.vis.get() + import.vis.get() } else { binding.pseudo_vis() }; - if let ImportKind::Glob { ref max_vis, .. } = directive.kind { - if vis == directive.vis.get() || vis.is_at_least(max_vis.get(), self) { + if let ImportKind::Glob { ref max_vis, .. } = import.kind { + if vis == import.vis.get() || vis.is_at_least(max_vis.get(), self) { max_vis.set(vis) } } self.arenas.alloc_name_binding(NameBinding { - kind: NameBindingKind::Import { binding, directive, used: Cell::new(false) }, + kind: NameBindingKind::Import { binding, import, used: Cell::new(false) }, ambiguity: None, - span: directive.span, + span: import.span, vis, - expansion: directive.parent_scope.expansion, + expansion: import.parent_scope.expansion, }) } @@ -576,17 +576,17 @@ impl<'a> Resolver<'a> { }; // Define `binding` in `module`s glob importers. - for directive in module.glob_importers.borrow_mut().iter() { + for import in module.glob_importers.borrow_mut().iter() { let mut ident = key.ident; - let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) { + let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) { Some(Some(def)) => self.macro_def_scope(def), - Some(None) => directive.parent_scope.module, + Some(None) => import.parent_scope.module, None => continue, }; if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, directive); + let imported_binding = self.import(binding, import); let key = BindingKey { ident, ..key }; - let _ = self.try_define(directive.parent_scope.module, key, imported_binding); + let _ = self.try_define(import.parent_scope.module, key, imported_binding); } } @@ -595,13 +595,13 @@ impl<'a> Resolver<'a> { // Define a "dummy" resolution containing a Res::Err as a placeholder for a // failed resolution - fn import_dummy_binding(&mut self, directive: &'a Import<'a>) { - if let ImportKind::Single { target, .. } = directive.kind { + fn import_dummy_binding(&mut self, import: &'a Import<'a>) { + if let ImportKind::Single { target, .. } = import.kind { let dummy_binding = self.dummy_binding; - let dummy_binding = self.import(dummy_binding, directive); + let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { let key = this.new_key(target, ns); - let _ = this.try_define(directive.parent_scope.module, key, dummy_binding); + let _ = this.try_define(import.parent_scope.module, key, dummy_binding); // Consider erroneous imports used to avoid duplicate diagnostics. this.record_use(target, ns, dummy_binding, false); }); @@ -766,28 +766,28 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. - fn resolve_import(&mut self, directive: &'b Import<'b>) -> bool { + fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", - Segment::names_to_string(&directive.module_path), - module_to_string(directive.parent_scope.module).unwrap_or_else(|| "???".to_string()), + Segment::names_to_string(&import.module_path), + module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()), ); - let module = if let Some(module) = directive.imported_module.get() { + let module = if let Some(module) = import.imported_module.get() { module } else { // For better failure detection, pretend that the import will // not define any names while resolving its module path. - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let path_res = self.r.resolve_path( - &directive.module_path, + &import.module_path, None, - &directive.parent_scope, + &import.parent_scope, false, - directive.span, - directive.crate_lint(), + import.span, + import.crate_lint(), ); - directive.vis.set(orig_vis); + import.vis.set(orig_vis); match path_res { PathResult::Module(module) => module, @@ -796,9 +796,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } }; - directive.imported_module.set(Some(module)); - let (source, target, source_bindings, target_bindings, type_ns_only) = match directive.kind - { + import.imported_module.set(Some(module)); + let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind { ImportKind::Single { source, target, @@ -808,7 +807,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { .. } => (source, target, source_bindings, target_bindings, type_ns_only), ImportKind::Glob { .. } => { - self.resolve_glob_import(directive); + self.resolve_glob_import(import); return true; } _ => unreachable!(), @@ -820,23 +819,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if let Err(Undetermined) = source_bindings[ns].get() { // For better failure detection, pretend that the import will // not define any names while resolving its module path. - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let binding = this.resolve_ident_in_module( module, source, ns, - &directive.parent_scope, + &import.parent_scope, false, - directive.span, + import.span, ); - directive.vis.set(orig_vis); + import.vis.set(orig_vis); source_bindings[ns].set(binding); } else { return; }; - let parent = directive.parent_scope.module; + let parent = import.parent_scope.module; match source_bindings[ns].get() { Err(Undetermined) => indeterminate = true, // Don't update the resolution, because it was never added. @@ -844,20 +843,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> { Err(Determined) => { let key = this.new_key(target, ns); this.update_resolution(parent, key, |_, resolution| { - resolution.single_imports.remove(&PtrKey(directive)); + resolution.single_imports.remove(&PtrKey(import)); }); } Ok(binding) if !binding.is_importable() => { let msg = format!("`{}` is not directly importable", target); - struct_span_err!(this.session, directive.span, E0253, "{}", &msg) - .span_label(directive.span, "cannot be imported directly") + struct_span_err!(this.session, import.span, E0253, "{}", &msg) + .span_label(import.span, "cannot be imported directly") .emit(); // Do not import this illegal binding. Import a dummy binding and pretend // everything is fine - this.import_dummy_binding(directive); + this.import_dummy_binding(import); } Ok(binding) => { - let imported_binding = this.import(binding, directive); + let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); } @@ -872,35 +871,35 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import(&mut self, directive: &'b Import<'b>) -> Option { - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + fn finalize_import(&mut self, import: &'b Import<'b>) -> Option { + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( - &directive.module_path, + &import.module_path, None, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, - directive.crate_lint(), + import.span, + import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; - directive.vis.set(orig_vis); + import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics. - self.r.used_imports.insert((directive.id, TypeNS)); + self.r.used_imports.insert((import.id, TypeNS)); } let module = match path_res { PathResult::Module(module) => { // Consistency checks, analogous to `finalize_macro_resolutions`. - if let Some(initial_module) = directive.imported_module.get() { + if let Some(initial_module) = import.imported_module.get() { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { - span_bug!(directive.span, "inconsistent resolution for an import"); + span_bug!(import.span, "inconsistent resolution for an import"); } } else { if self.r.privacy_errors.is_empty() { let msg = "cannot determine resolution for the import"; let msg_note = "import resolution is stuck, try simplifying other imports"; - self.r.session.struct_span_err(directive.span, msg).note(msg_note).emit(); + self.r.session.struct_span_err(import.span, msg).note(msg_note).emit(); } } @@ -908,7 +907,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); self.r .report_error(span, ResolutionError::FailedToResolve { label, suggestion }); } @@ -916,11 +915,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); let err = match self.make_path_suggestion( span, - directive.module_path.clone(), - &directive.parent_scope, + import.module_path.clone(), + &import.parent_scope, ) { Some((suggestion, note)) => UnresolvedImportError { span, @@ -945,7 +944,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::NonModule(path_res) if path_res.base_res() == Res::Err => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); } // The error was already reported earlier. return None; @@ -953,7 +952,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(), }; - let (ident, target, source_bindings, target_bindings, type_ns_only) = match directive.kind { + let (ident, target, source_bindings, target_bindings, type_ns_only) = match import.kind { ImportKind::Single { source, target, @@ -963,24 +962,24 @@ impl<'a, 'b> ImportResolver<'a, 'b> { .. } => (source, target, source_bindings, target_bindings, type_ns_only), ImportKind::Glob { is_prelude, ref max_vis } => { - if directive.module_path.len() <= 1 { + if import.module_path.len() <= 1 { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. - let mut full_path = directive.module_path.clone(); + let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::invalid())); self.r.lint_if_path_starts_with_module( - directive.crate_lint(), + import.crate_lint(), &full_path, - directive.span, + import.span, None, ); } if let ModuleOrUniformRoot::Module(module) = module { - if module.def_id() == directive.parent_scope.module.def_id() { + if module.def_id() == import.parent_scope.module.def_id() { // Importing a module into itself is not allowed. return Some(UnresolvedImportError { - span: directive.span, + span: import.span, label: Some(String::from("cannot glob-import a module into itself")), note: Vec::new(), suggestion: None, @@ -989,15 +988,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !is_prelude && max_vis.get() != ty::Visibility::Invisible && // Allow empty globs. - !max_vis.get().is_at_least(directive.vis.get(), &*self) + !max_vis.get().is_at_least(import.vis.get(), &*self) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.r.lint_buffer.buffer_lint( - UNUSED_IMPORTS, - directive.id, - directive.span, - msg, - ); + self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg); } return None; } @@ -1007,7 +1001,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut all_ns_err = true; self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let orig_blacklisted_binding = mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get()); let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true); @@ -1015,13 +1009,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> { module, ident, ns, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, + import.span, ); this.last_import_segment = orig_last_import_segment; this.blacklisted_binding = orig_blacklisted_binding; - directive.vis.set(orig_vis); + import.vis.set(orig_vis); match binding { Ok(binding) => { @@ -1038,7 +1032,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ident, ns, target_binding, - directive.module_path.is_empty(), + import.module_path.is_empty(), ); } } @@ -1047,7 +1041,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let res = binding.res(); if let Ok(initial_res) = initial_res { if res != initial_res && this.ambiguity_errors.is_empty() { - span_bug!(directive.span, "inconsistent resolution for an import"); + span_bug!(import.span, "inconsistent resolution for an import"); } } else { if res != Res::Err @@ -1058,7 +1052,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let msg_note = "import resolution is stuck, try simplifying other imports"; this.session - .struct_span_err(directive.span, msg) + .struct_span_err(import.span, msg) .note(msg_note) .emit(); } @@ -1084,9 +1078,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { module, ident, ns, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, + import.span, ); if binding.is_ok() { all_ns_failed = false; @@ -1137,7 +1131,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }); let (suggestion, note) = - match self.check_for_module_export_macro(directive, module, ident) { + match self.check_for_module_export_macro(import, module, ident) { Some((suggestion, note)) => (suggestion.or(lev_suggestion), note), _ => (lev_suggestion, Vec::new()), }; @@ -1163,14 +1157,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; Some(UnresolvedImportError { - span: directive.span, + span: import.span, label: Some(label), note, suggestion, }) } else { // `resolve_ident_in_module` reported a privacy error. - self.r.import_dummy_binding(directive); + self.r.import_dummy_binding(import); None }; } @@ -1179,7 +1173,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut any_successful_reexport = false; self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - let vis = directive.vis.get(); + let vis = import.vis.get(); if !binding.pseudo_vis().is_at_least(vis, &*this) { reexport_error = Some((ns, binding)); } else { @@ -1200,42 +1194,42 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ); self.r.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, - directive.id, - directive.span, + import.id, + import.span, &msg, ); } else if ns == TypeNS { struct_span_err!( self.r.session, - directive.span, + import.span, E0365, "`{}` is private, and cannot be re-exported", ident ) - .span_label(directive.span, format!("re-export of private `{}`", ident)) + .span_label(import.span, format!("re-export of private `{}`", ident)) .note(&format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { let msg = format!("`{}` is private, and cannot be re-exported", ident); let note_msg = format!("consider marking `{}` as `pub` in the imported module", ident,); - struct_span_err!(self.r.session, directive.span, E0364, "{}", &msg) - .span_note(directive.span, ¬e_msg) + struct_span_err!(self.r.session, import.span, E0364, "{}", &msg) + .span_note(import.span, ¬e_msg) .emit(); } } - if directive.module_path.len() <= 1 { + if import.module_path.len() <= 1 { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. - let mut full_path = directive.module_path.clone(); + let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.lint_if_path_starts_with_module( - directive.crate_lint(), + import.crate_lint(), &full_path, - directive.span, + import.span, Some(binding), ); } @@ -1247,17 +1241,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // purposes it's good enough to just favor one over the other. self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - this.import_res_map.entry(directive.id).or_default()[ns] = Some(binding.res()); + this.import_res_map.entry(import.id).or_default()[ns] = Some(binding.res()); } }); - self.check_for_redundant_imports( - ident, - directive, - source_bindings, - target_bindings, - target, - ); + self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target); debug!("(resolving single import) successfully resolved import"); None @@ -1266,19 +1254,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> { fn check_for_redundant_imports( &mut self, ident: Ident, - directive: &'b Import<'b>, + import: &'b Import<'b>, source_bindings: &PerNS, Determinacy>>>, target_bindings: &PerNS>>>, target: Ident, ) { // Skip if the import was produced by a macro. - if directive.parent_scope.expansion != ExpnId::root() { + if import.parent_scope.expansion != ExpnId::root() { return; } // Skip if we are inside a named module (in contrast to an anonymous // module defined by a block). - if let ModuleKind::Def(..) = directive.parent_scope.module.kind { + if let ModuleKind::Def(..) = import.parent_scope.module.kind { return; } @@ -1298,10 +1286,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> { match this.early_resolve_ident_in_lexical_scope( target, ScopeSet::All(ns, false), - &directive.parent_scope, + &import.parent_scope, false, false, - directive.span, + import.span, ) { Ok(other_binding) => { is_redundant[ns] = Some( @@ -1323,35 +1311,35 @@ impl<'a, 'b> ImportResolver<'a, 'b> { redundant_spans.dedup(); self.r.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, - directive.id, - directive.span, + import.id, + import.span, &format!("the item `{}` is imported redundantly", ident), BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), ); } } - fn resolve_glob_import(&mut self, directive: &'b Import<'b>) { - let module = match directive.imported_module.get().unwrap() { + fn resolve_glob_import(&mut self, import: &'b Import<'b>) { + let module = match import.imported_module.get().unwrap() { ModuleOrUniformRoot::Module(module) => module, _ => { - self.r.session.span_err(directive.span, "cannot glob-import all possible crates"); + self.r.session.span_err(import.span, "cannot glob-import all possible crates"); return; } }; if module.is_trait() { - self.r.session.span_err(directive.span, "items in traits are not importable."); + self.r.session.span_err(import.span, "items in traits are not importable."); return; - } else if module.def_id() == directive.parent_scope.module.def_id() { + } else if module.def_id() == import.parent_scope.module.def_id() { return; - } else if let ImportKind::Glob { is_prelude: true, .. } = directive.kind { + } else if let ImportKind::Glob { is_prelude: true, .. } = import.kind { self.r.prelude = Some(module); return; } // Add to module's glob_importers - module.glob_importers.borrow_mut().push(directive); + module.glob_importers.borrow_mut().push(import); // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. @@ -1365,19 +1353,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }) .collect::>(); for (mut key, binding) in bindings { - let scope = match key.ident.span.reverse_glob_adjust(module.expansion, directive.span) { + let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) { Some(Some(def)) => self.r.macro_def_scope(def), - Some(None) => directive.parent_scope.module, + Some(None) => import.parent_scope.module, None => continue, }; if self.r.is_accessible_from(binding.pseudo_vis(), scope) { - let imported_binding = self.r.import(binding, directive); - let _ = self.r.try_define(directive.parent_scope.module, key, imported_binding); + let imported_binding = self.r.import(binding, import); + let _ = self.r.try_define(import.parent_scope.module, key, imported_binding); } } // Record the destination of this import - self.r.record_partial_res(directive.id, PartialRes::new(module.res().unwrap())); + self.r.record_partial_res(import.id, PartialRes::new(module.res().unwrap())); } // Miscellaneous post-processing, including recording re-exports, @@ -1401,12 +1389,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } - if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind { + if let NameBindingKind::Import { binding: orig_binding, import, .. } = binding.kind { if ns == TypeNS && orig_binding.is_variant() && !orig_binding.vis.is_at_least(binding.vis, &*this) { - let msg = match directive.kind { + let msg = match import.kind { ImportKind::Single { .. } => { format!("variant `{}` is private and cannot be re-exported", ident) } @@ -1430,14 +1418,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; let mut err = this.session.struct_span_err(binding.span, &msg); - let imported_module = match directive.imported_module.get() { + let imported_module = match import.imported_module.get() { Some(ModuleOrUniformRoot::Module(module)) => module, _ => bug!("module should exist"), }; let parent_module = imported_module.parent.expect("parent should exist"); let resolutions = this.resolutions(parent_module).borrow(); - let enum_path_segment_index = directive.module_path.len() - 1; - let enum_ident = directive.module_path[enum_path_segment_index].ident; + let enum_path_segment_index = import.module_path.len() - 1; + let enum_ident = import.module_path[enum_path_segment_index].ident; let key = this.new_key(enum_ident, TypeNS); let enum_resolution = resolutions.get(&key).expect("resolution should exist"); @@ -1484,18 +1472,18 @@ fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Sp } else { let names = if global { &names[1..] } else { names }; if names.is_empty() { - import_directive_subclass_to_string(import_kind) + import_kind_to_string(import_kind) } else { format!( "{}::{}", names_to_string(&names.iter().map(|ident| ident.name).collect::>()), - import_directive_subclass_to_string(import_kind), + import_kind_to_string(import_kind), ) } } } -fn import_directive_subclass_to_string(import_kind: &ImportKind<'_>) -> String { +fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String { match import_kind { ImportKind::Single { source, .. } => source.to_string(), ImportKind::Glob { .. } => "*".to_string(), diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 6b5e927214f5a..98bb98a3a8dac 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -2189,10 +2189,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { trait_name: Ident, ) -> SmallVec<[NodeId; 1]> { let mut import_ids = smallvec![]; - while let NameBindingKind::Import { directive, binding, .. } = kind { - self.r.maybe_unused_trait_imports.insert(directive.id); - self.r.add_to_glob_map(&directive, trait_name); - import_ids.push(directive.id); + while let NameBindingKind::Import { import, binding, .. } = kind { + self.r.maybe_unused_trait_imports.insert(import.id); + self.r.add_to_glob_map(&import, trait_name); + import_ids.push(import.id); kind = &binding.kind; } import_ids diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2ffcf340b9a91..492ac6ed83977 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -584,7 +584,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> { enum NameBindingKind<'a> { Res(Res, /* is_macro_export */ bool), Module(Module<'a>), - Import { binding: &'a NameBinding<'a>, directive: &'a Import<'a>, used: Cell }, + Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell }, } impl<'a> NameBindingKind<'a> { @@ -713,7 +713,7 @@ impl<'a> NameBinding<'a> { fn is_extern_crate(&self) -> bool { match self.kind { NameBindingKind::Import { - directive: &Import { kind: ImportKind::ExternCrate { .. }, .. }, + import: &Import { kind: ImportKind::ExternCrate { .. }, .. }, .. } => true, NameBindingKind::Module(&ModuleData { @@ -733,7 +733,7 @@ impl<'a> NameBinding<'a> { fn is_glob_import(&self) -> bool { match self.kind { - NameBindingKind::Import { directive, .. } => directive.is_glob(), + NameBindingKind::Import { import, .. } => import.is_glob(), _ => false, } } @@ -970,7 +970,7 @@ pub struct ResolverArenas<'a> { modules: arena::TypedArena>, local_modules: RefCell>>, name_bindings: arena::TypedArena>, - import_directives: arena::TypedArena>, + imports: arena::TypedArena>, name_resolutions: arena::TypedArena>>, legacy_bindings: arena::TypedArena>, ast_paths: arena::TypedArena, @@ -990,8 +990,8 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> { self.name_bindings.alloc(name_binding) } - fn alloc_import_directive(&'a self, import_directive: Import<'a>) -> &'a Import<'_> { - self.import_directives.alloc(import_directive) + fn alloc_import(&'a self, import: Import<'a>) -> &'a Import<'_> { + self.imports.alloc(import) } fn alloc_name_resolution(&'a self) -> &'a RefCell> { self.name_resolutions.alloc(Default::default()) @@ -1406,7 +1406,7 @@ impl<'a> Resolver<'a> { misc2: AmbiguityErrorMisc::None, }); } - if let NameBindingKind::Import { directive, binding, ref used } = used_binding.kind { + if let NameBindingKind::Import { import, binding, ref used } = used_binding.kind { // Avoid marking `extern crate` items that refer to a name from extern prelude, // but not introduce it, as used if they are accessed from lexical scope. if is_lexical_scope { @@ -1419,17 +1419,17 @@ impl<'a> Resolver<'a> { } } used.set(true); - directive.used.set(true); - self.used_imports.insert((directive.id, ns)); - self.add_to_glob_map(&directive, ident); + import.used.set(true); + self.used_imports.insert((import.id, ns)); + self.add_to_glob_map(&import, ident); self.record_use(ident, ns, binding, false); } } #[inline] - fn add_to_glob_map(&mut self, directive: &Import<'_>, ident: Ident) { - if directive.is_glob() { - self.glob_map.entry(directive.id).or_default().insert(ident.name); + fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { + if import.is_glob() { + self.glob_map.entry(import.id).or_default().insert(ident.name); } } @@ -2254,10 +2254,9 @@ impl<'a> Resolver<'a> { // `ExternCrate` (also used for `crate::...`) then no need to issue a // warning, this looks all good! if let Some(binding) = second_binding { - if let NameBindingKind::Import { directive: d, .. } = binding.kind { - // Careful: we still want to rewrite paths from - // renamed extern crates. - if let ImportKind::ExternCrate { source: None, .. } = d.kind { + if let NameBindingKind::Import { import, .. } = binding.kind { + // Careful: we still want to rewrite paths from renamed extern crates. + if let ImportKind::ExternCrate { source: None, .. } = import.kind { return; } } @@ -2560,10 +2559,10 @@ impl<'a> Resolver<'a> { // See https://github.com/rust-lang/rust/issues/32354 use NameBindingKind::Import; - let directive = match (&new_binding.kind, &old_binding.kind) { + let import = match (&new_binding.kind, &old_binding.kind) { // If there are two imports where one or both have attributes then prefer removing the // import without attributes. - (Import { directive: new, .. }, Import { directive: old, .. }) + (Import { import: new, .. }, Import { import: old, .. }) if { !new_binding.span.is_dummy() && !old_binding.span.is_dummy() @@ -2577,11 +2576,11 @@ impl<'a> Resolver<'a> { } } // Otherwise prioritize the new binding. - (Import { directive, .. }, other) if !new_binding.span.is_dummy() => { - Some((directive, new_binding.span, other.is_import())) + (Import { import, .. }, other) if !new_binding.span.is_dummy() => { + Some((import, new_binding.span, other.is_import())) } - (other, Import { directive, .. }) if !old_binding.span.is_dummy() => { - Some((directive, old_binding.span, other.is_import())) + (other, Import { import, .. }) if !old_binding.span.is_dummy() => { + Some((import, old_binding.span, other.is_import())) } _ => None, }; @@ -2598,22 +2597,22 @@ impl<'a> Resolver<'a> { && !has_dummy_span && ((new_binding.is_extern_crate() || old_binding.is_extern_crate()) || from_item); - match directive { - Some((directive, span, true)) if should_remove_import && directive.is_nested() => { - self.add_suggestion_for_duplicate_nested_use(&mut err, directive, span) + match import { + Some((import, span, true)) if should_remove_import && import.is_nested() => { + self.add_suggestion_for_duplicate_nested_use(&mut err, import, span) } - Some((directive, _, true)) if should_remove_import && !directive.is_glob() => { + Some((import, _, true)) if should_remove_import && !import.is_glob() => { // Simple case - remove the entire import. Due to the above match arm, this can // only be a single use so just remove it entirely. err.tool_only_span_suggestion( - directive.use_span_with_attributes, + import.use_span_with_attributes, "remove unnecessary import", String::new(), Applicability::MaybeIncorrect, ); } - Some((directive, span, _)) => { - self.add_suggestion_for_rename_of_use(&mut err, name, directive, span) + Some((import, span, _)) => { + self.add_suggestion_for_rename_of_use(&mut err, name, import, span) } _ => {} } @@ -2635,7 +2634,7 @@ impl<'a> Resolver<'a> { &self, err: &mut DiagnosticBuilder<'_>, name: Name, - directive: &Import<'_>, + import: &Import<'_>, binding_span: Span, ) { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { @@ -2645,7 +2644,7 @@ impl<'a> Resolver<'a> { }; let mut suggestion = None; - match directive.kind { + match import.kind { ImportKind::Single { type_ns_only: true, .. } => { suggestion = Some(format!("self as {}", suggested_name)) } @@ -2707,27 +2706,27 @@ impl<'a> Resolver<'a> { /// If the nested use contains only one import then the suggestion will remove the entire /// line. /// - /// It is expected that the directive provided is a nested import - this isn't checked by the + /// It is expected that the provided import is nested - this isn't checked by the /// function. If this invariant is not upheld, this function's behaviour will be unexpected /// as characters expected by span manipulations won't be present. fn add_suggestion_for_duplicate_nested_use( &self, err: &mut DiagnosticBuilder<'_>, - directive: &Import<'_>, + import: &Import<'_>, binding_span: Span, ) { - assert!(directive.is_nested()); + assert!(import.is_nested()); let message = "remove unnecessary import"; // Two examples will be used to illustrate the span manipulations we're doing: // // - Given `use issue_52891::{d, a, e};` where `a` is a duplicate then `binding_span` is - // `a` and `directive.use_span` is `issue_52891::{d, a, e};`. + // `a` and `import.use_span` is `issue_52891::{d, a, e};`. // - Given `use issue_52891::{d, e, a};` where `a` is a duplicate then `binding_span` is - // `a` and `directive.use_span` is `issue_52891::{d, e, a};`. + // `a` and `import.use_span` is `issue_52891::{d, e, a};`. let (found_closing_brace, span) = - find_span_of_binding_until_next_binding(self.session, binding_span, directive.use_span); + find_span_of_binding_until_next_binding(self.session, binding_span, import.use_span); // If there was a closing brace then identify the span to remove any trailing commas from // previous imports. @@ -2743,7 +2742,7 @@ impl<'a> Resolver<'a> { // Remove the entire line if we cannot extend the span back, this indicates a // `issue_52891::{self}` case. err.span_suggestion( - directive.use_span_with_attributes, + import.use_span_with_attributes, message, String::new(), Applicability::MaybeIncorrect, diff --git a/src/test/ui/rust-2018/macro-use-warned-against.rs b/src/test/ui/rust-2018/macro-use-warned-against.rs index 6cd54aa68aedd..65400163ddd86 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.rs +++ b/src/test/ui/rust-2018/macro-use-warned-against.rs @@ -4,7 +4,7 @@ #![warn(macro_use_extern_crate, unused)] -#[macro_use] //~ WARN should be replaced at use sites with a `use` statement +#[macro_use] //~ WARN should be replaced at use sites with a `use` item extern crate macro_use_warned_against; #[macro_use] //~ WARN unused `#[macro_use]` extern crate macro_use_warned_against2; diff --git a/src/test/ui/rust-2018/macro-use-warned-against.stderr b/src/test/ui/rust-2018/macro-use-warned-against.stderr index 611b9d5dac9fd..ef00b865815c0 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.stderr +++ b/src/test/ui/rust-2018/macro-use-warned-against.stderr @@ -1,4 +1,4 @@ -warning: deprecated `#[macro_use]` directive used to import macros should be replaced at use sites with a `use` statement to import the macro instead +warning: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead --> $DIR/macro-use-warned-against.rs:7:1 | LL | #[macro_use] From 2e88bec61916cdb5d24ee9c79af3f70f2d52cb5c Mon Sep 17 00:00:00 2001 From: Matthew Kuo Date: Sat, 7 Mar 2020 14:17:03 -0600 Subject: [PATCH 13/13] test(bindings_after_at): add dynamic drop tests for bindings_after_at --- src/test/ui/drop/dynamic-drop.rs | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index 451686d9ae21c..d31736f142c3f 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -3,6 +3,7 @@ #![feature(generators, generator_trait, untagged_unions)] #![feature(move_ref_pattern)] +#![feature(bindings_after_at)] #![allow(unused_assignments)] #![allow(unused_variables)] @@ -291,6 +292,44 @@ fn subslice_mixed_min_lengths(a: &Allocator, c: i32) { } } +fn bindings_after_at_dynamic_init_move(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + let _x; + + if let bar @ Some(_) = foo { + _x = bar; + } +} + +fn bindings_after_at_dynamic_init_ref(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + let _x; + + if let bar @ Some(_baz) = &foo { + _x = bar; + } +} + +fn bindings_after_at_dynamic_drop_move(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + + if let bar @ Some(_) = foo { + bar + } else { + None + }; +} + +fn bindings_after_at_dynamic_drop_ref(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + + if let bar @ Some(_baz) = &foo { + bar + } else { + &None + }; +} + fn move_ref_pattern(a: &Allocator) { let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc()); let (ref _a, ref mut _b, _c, mut _d) = tup; @@ -471,5 +510,14 @@ fn main() { run_test(|a| panic_after_init_temp(a)); run_test(|a| panic_after_init_by_loop(a)); + run_test(|a| bindings_after_at_dynamic_init_move(a, true)); + run_test(|a| bindings_after_at_dynamic_init_move(a, false)); + run_test(|a| bindings_after_at_dynamic_init_ref(a, true)); + run_test(|a| bindings_after_at_dynamic_init_ref(a, false)); + run_test(|a| bindings_after_at_dynamic_drop_move(a, true)); + run_test(|a| bindings_after_at_dynamic_drop_move(a, false)); + run_test(|a| bindings_after_at_dynamic_drop_ref(a, true)); + run_test(|a| bindings_after_at_dynamic_drop_ref(a, false)); + run_test_nopanic(|a| union1(a)); }