From cabcd99476060b4e293f3031dafe7d84a557768d Mon Sep 17 00:00:00 2001 From: BO41 Date: Wed, 2 Oct 2019 17:55:06 +0200 Subject: [PATCH 001/109] Mention keyword closing policy --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4daaa986a2dc..d796dc180324 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,6 +129,12 @@ the master branch to your feature branch. Also, please make sure that fixup commits are squashed into other related commits with meaningful commit messages. +GitHub allows [closing issues using keywords][closing-keywords]. This features +should be used to keep the issue tracker tidy. But in pull requests only. Please +do not add this to your commit message. + +[closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords + Please make sure your pull request is in compliance with Rust's style guidelines by running From 59ce359c8f5f6f9a373ca5be82a3b96527b38b9e Mon Sep 17 00:00:00 2001 From: BO41 Date: Wed, 2 Oct 2019 21:31:00 +0000 Subject: [PATCH 002/109] Fix typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d796dc180324..caf003d183af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,7 +129,7 @@ the master branch to your feature branch. Also, please make sure that fixup commits are squashed into other related commits with meaningful commit messages. -GitHub allows [closing issues using keywords][closing-keywords]. This features +GitHub allows [closing issues using keywords][closing-keywords]. This feature should be used to keep the issue tracker tidy. But in pull requests only. Please do not add this to your commit message. From 77f0aaf0d0a92feb068999d6b14f60dcf325b0c1 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Sat, 12 Oct 2019 20:53:11 +0200 Subject: [PATCH 003/109] Add more coherence tests --- .../ui/coherence/impl-foreign-for-foreign.rs | 17 +++++++++++ .../coherence/impl-foreign-for-foreign.stderr | 12 ++++++++ .../impl-foreign-for-foreign[foreign].rs | 25 ++++++++++++++++ .../impl-foreign-for-foreign[foreign].stderr | 30 +++++++++++++++++++ .../impl-foreign-for-foreign[local].rs | 16 ++++++++++ .../impl-foreign-for-fundamental[foreign].rs | 21 +++++++++++++ ...pl-foreign-for-fundamental[foreign].stderr | 21 +++++++++++++ .../impl-foreign-for-fundamental[local].rs | 17 +++++++++++ .../ui/coherence/impl-foreign-for-local.rs | 15 ++++++++++ ...reign[fundemental[foreign]]-for-foreign.rs | 26 ++++++++++++++++ ...n[fundemental[foreign]]-for-foreign.stderr | 30 +++++++++++++++++++ ...foreign[fundemental[local]]-for-foreign.rs | 18 +++++++++++ .../impl[t]-foreign-for-(local, t).rs | 17 +++++++++++ .../impl[t]-foreign-for-(local, t).stderr | 12 ++++++++ .../impl[t]-foreign-for-foreign[t].rs | 23 ++++++++++++++ .../impl[t]-foreign-for-foreign[t].stderr | 21 +++++++++++++ .../impl[t]-foreign-for-fundamental[t].rs | 17 +++++++++++ .../impl[t]-foreign-for-fundamental[t].stderr | 11 +++++++ ...eign[fundemental[local]]-for-foreign[t].rs | 17 +++++++++++ .../impl[t]-foreign[local]-for-foreign[t].rs | 17 +++++++++++ ...eign[local]-for-fundamental[foreign[t]].rs | 19 ++++++++++++ 21 files changed, 402 insertions(+) create mode 100644 src/test/ui/coherence/impl-foreign-for-foreign.rs create mode 100644 src/test/ui/coherence/impl-foreign-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs create mode 100644 src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr create mode 100644 src/test/ui/coherence/impl-foreign-for-foreign[local].rs create mode 100644 src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs create mode 100644 src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr create mode 100644 src/test/ui/coherence/impl-foreign-for-fundamental[local].rs create mode 100644 src/test/ui/coherence/impl-foreign-for-local.rs create mode 100644 src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr create mode 100644 src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr create mode 100644 src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs create mode 100644 src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.rs b/src/test/ui/coherence/impl-foreign-for-foreign.rs new file mode 100644 index 000000000000..de0b66a35eb0 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign.rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.stderr b/src/test/ui/coherence/impl-foreign-for-foreign.stderr new file mode 100644 index 000000000000..b03a75a77c34 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign.stderr @@ -0,0 +1,12 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-foreign.rs:12:1 + | +LL | impl Remote for i32 { + | ^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs new file mode 100644 index 000000000000..5146263d9911 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs @@ -0,0 +1,25 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1> for f64 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1> for f32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr new file mode 100644 index 000000000000..bfaec790b20a --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr @@ -0,0 +1,30 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-foreign[foreign].rs:12:1 + | +LL | impl Remote1> for i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-foreign[foreign].rs:16:1 + | +LL | impl Remote1> for f64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-foreign[foreign].rs:20:1 + | +LL | impl Remote1> for f32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[local].rs b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs new file mode 100644 index 000000000000..050769dcf4ce --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs @@ -0,0 +1,16 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local(Rc); + +impl Remote1> for i32 {} +impl Remote1> for f32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs new file mode 100644 index 000000000000..03b11edf98b4 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs @@ -0,0 +1,21 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Box { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote for Box> { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr new file mode 100644 index 000000000000..2ce4921cf938 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr @@ -0,0 +1,21 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-fundamental[foreign].rs:12:1 + | +LL | impl Remote for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign-for-fundamental[foreign].rs:16:1 + | +LL | impl Remote for Box> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs new file mode 100644 index 000000000000..ae03ce6a440d --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote for Box {} +impl Remote for Box> {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign-for-local.rs b/src/test/ui/coherence/impl-foreign-for-local.rs new file mode 100644 index 000000000000..c9dddeba18dc --- /dev/null +++ b/src/test/ui/coherence/impl-foreign-for-local.rs @@ -0,0 +1,15 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Local {} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs new file mode 100644 index 000000000000..06efb6c2ad75 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs @@ -0,0 +1,26 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for i32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1>> for f64 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} +impl Remote1>> for f32 { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr new file mode 100644 index 000000000000..bf2361a1718a --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr @@ -0,0 +1,30 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:13:1 + | +LL | impl Remote1> for i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:17:1 + | +LL | impl Remote1>> for f64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:21:1 + | +LL | impl Remote1>> for f32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs new file mode 100644 index 000000000000..d47e0a36a565 --- /dev/null +++ b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs @@ -0,0 +1,18 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for i32 {} +impl Remote1>> for f64 {} +impl Remote1>> for f32 {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs new file mode 100644 index 000000000000..850b6f85d0ed --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for (Local, T) { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr new file mode 100644 index 000000000000..ff0b9d6d0da9 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr @@ -0,0 +1,12 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl[t]-foreign-for-(local, t).rs:12:1 + | +LL | impl Remote for (Local, T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs new file mode 100644 index 000000000000..db7a2ae8076a --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs @@ -0,0 +1,23 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; +use std::sync::Arc; + +struct Local; + +impl Remote for Rc { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +impl Remote for Arc { + //~^ ERROR only traits defined in the current crate + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr new file mode 100644 index 000000000000..d7ffcaf76f9a --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr @@ -0,0 +1,21 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl[t]-foreign-for-foreign[t].rs:13:1 + | +LL | impl Remote for Rc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl[t]-foreign-for-foreign[t].rs:18:1 + | +LL | impl Remote for Arc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference only types defined in this crate + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs new file mode 100644 index 000000000000..4cc19e1a526c --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Box { + //~^ ERROR type parameter `T` must be used as the type parameter for + // | some local type (e.g., `MyStruct`) +} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr new file mode 100644 index 000000000000..20ce11ef9759 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr @@ -0,0 +1,11 @@ +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/impl[t]-foreign-for-fundamental[t].rs:12:1 + | +LL | impl Remote for Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs new file mode 100644 index 000000000000..914680f191ac --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for Rc {} +impl Remote1>> for Rc {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs new file mode 100644 index 000000000000..1e84ff40c622 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs @@ -0,0 +1,17 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1 for Rc {} +impl Remote1> for Rc {} + +fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs new file mode 100644 index 000000000000..ea6aa101d209 --- /dev/null +++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs @@ -0,0 +1,19 @@ +#![feature(re_rebalance_coherence)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1 for Box> {} +impl Remote1> for Box> {} +impl Remote1> for Box> {} +impl Remote1>> for Box> {} + +fn main() {} From 3a05616cb6b6df75fc54094de7f3d4b161ed8521 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 26 Sep 2019 14:44:08 -0700 Subject: [PATCH 004/109] minimize the rust-std component This splits out a rustc-dev component with the compiler crates, and keeps the status quo of default installed files on nightly. The default changing to not install compiler libraries by default is left for a future pull request. However, on stable and beta, this does remove the compiler libraries from the set of libraries installed by default, as they are never needed there (per our stability story, they "cannot" be used). --- src/bootstrap/builder.rs | 1 + src/bootstrap/dist.rs | 129 ++++++++++++++++++++------- src/tools/build-manifest/src/main.rs | 15 ++++ 3 files changed, 112 insertions(+), 33 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0caf2d9b6db5..7e3ae7f2cc90 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -443,6 +443,7 @@ impl<'a> Builder<'a> { dist::Rustc, dist::DebuggerScripts, dist::Std, + dist::RustcDev, dist::Analysis, dist::Src, dist::PlainSourceTarball, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index d9dff77a30e6..e5a43dcb29f6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -637,6 +637,28 @@ impl Step for DebuggerScripts { } } +fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { + // The only true set of target libraries came from the build triple, so + // let's reduce redundant work by only producing archives from that host. + if compiler.host != builder.config.build { + builder.info("\tskipping, not a build host"); + true + } else { + false + } +} + +/// Copy stamped files into an image's `target/lib` directory. +fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) { + let dst = image.join("lib/rustlib").join(target).join("lib"); + t!(fs::create_dir_all(&dst)); + for (path, host) in builder.read_stamp_file(stamp) { + if !host || builder.config.build == target { + builder.copy(&path, &dst.join(path.file_name().unwrap())); + } + } +} + #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct Std { pub compiler: Compiler, @@ -667,44 +689,19 @@ impl Step for Std { let target = self.target; let name = pkgname(builder, "rust-std"); - - // The only true set of target libraries came from the build triple, so - // let's reduce redundant work by only producing archives from that host. - if compiler.host != builder.config.build { - builder.info("\tskipping, not a build host"); - return distdir(builder).join(format!("{}-{}.tar.gz", name, target)); + let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target)); + if skip_host_target_lib(builder, compiler) { + return archive; } - // We want to package up as many target libraries as possible - // for the `rust-std` package, so if this is a host target we - // depend on librustc and otherwise we just depend on libtest. - if builder.hosts.iter().any(|t| t == target) { - builder.ensure(compile::Rustc { compiler, target }); - } else { - builder.ensure(compile::Std { compiler, target }); - } + builder.ensure(compile::Std { compiler, target }); let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); let _ = fs::remove_dir_all(&image); - let dst = image.join("lib/rustlib").join(target); - t!(fs::create_dir_all(&dst)); - let mut src = builder.sysroot_libdir(compiler, target).to_path_buf(); - src.pop(); // Remove the trailing /lib folder from the sysroot_libdir - builder.cp_filtered(&src, &dst, &|path| { - if let Some(name) = path.file_name().and_then(|s| s.to_str()) { - if name == builder.config.rust_codegen_backends_dir.as_str() { - return false - } - if name == "bin" { - return false - } - if name.contains("LLVM") { - return false - } - } - true - }); + let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); + let stamp = compile::libstd_stamp(builder, compiler_to_use, target); + copy_target_libs(builder, &target, &image, &stamp); let mut cmd = rust_installer(builder); cmd.arg("generate") @@ -723,7 +720,73 @@ impl Step for Std { let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); - distdir(builder).join(format!("{}-{}.tar.gz", name, target)) + archive + } +} + +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustcDev { + pub compiler: Compiler, + pub target: Interned, +} + +impl Step for RustcDev { + type Output = PathBuf; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("rustc-dev") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustcDev { + compiler: run.builder.compiler_for( + run.builder.top_stage, + run.builder.config.build, + run.target, + ), + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> PathBuf { + let compiler = self.compiler; + let target = self.target; + + let name = pkgname(builder, "rustc-dev"); + let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target)); + if skip_host_target_lib(builder, compiler) { + return archive; + } + + builder.ensure(compile::Rustc { compiler, target }); + + let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); + let _ = fs::remove_dir_all(&image); + + let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); + let stamp = compile::librustc_stamp(builder, compiler_to_use, target); + copy_target_libs(builder, &target, &image, &stamp); + + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-is-ready-to-develop.") + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(builder)) + .arg("--output-dir").arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, target)) + .arg(format!("--component-name=rustc-dev-{}", target)) + .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!("Dist rustc-dev stage{} ({} -> {})", + compiler.stage, &compiler.host, target)); + let _time = timeit(builder); + builder.run(&mut cmd); + builder.remove_dir(&image); + archive } } diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index f41e7dd17ede..97e758f9b823 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -399,6 +399,7 @@ impl Builder { fn add_packages_to(&mut self, manifest: &mut Manifest) { let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets); package("rustc", HOSTS); + package("rustc-dev", HOSTS); package("cargo", HOSTS); package("rust-mingw", MINGW); package("rust-std", TARGETS); @@ -481,6 +482,15 @@ impl Builder { components.push(host_component("rust-mingw")); } + // The compiler libraries are not stable for end users, but `rustc-dev` was only recently + // split out of `rust-std`. We'll include it by default as a transition for nightly users, + // but ship it as an optional component on the beta and stable channels. + if self.rust_release == "nightly" { + components.push(host_component("rustc-dev")); + } else { + extensions.push(host_component("rustc-dev")); + } + // Tools are always present in the manifest, // but might be marked as unavailable if they weren't built. extensions.extend(vec![ @@ -498,6 +508,11 @@ impl Builder { .filter(|&&target| target != host) .map(|target| Component::from_str("rust-std", target)) ); + extensions.extend( + HOSTS.iter() + .filter(|&&target| target != host) + .map(|target| Component::from_str("rustc-dev", target)) + ); extensions.push(Component::from_str("rust-src", "*")); // If the components/extensions don't actually exist for this From 4c906dc84ec78fad35405d5c0f2b2d58f9f26288 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 7 Oct 2019 15:49:51 -0700 Subject: [PATCH 005/109] Add rustc-dev to nightly default and complete profiles --- src/tools/build-manifest/src/main.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 97e758f9b823..c0d2deab2f8b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -427,6 +427,13 @@ impl Builder { "rls-preview", "rust-src", "llvm-tools-preview", "lldb-preview", "rust-analysis", "miri-preview" ]); + + // The compiler libraries are not stable for end users, but `rustc-dev` was only recently + // split out of `rust-std`. We'll include it by default as a transition for nightly users. + if self.rust_release == "nightly" { + self.extend_profile("default", &mut manifest.profiles, &["rustc-dev"]); + self.extend_profile("complete", &mut manifest.profiles, &["rustc-dev"]); + } } fn add_renames_to(&self, manifest: &mut Manifest) { @@ -549,6 +556,14 @@ impl Builder { dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect()); } + fn extend_profile(&mut self, + profile_name: &str, + dst: &mut BTreeMap>, + pkgs: &[&str]) { + dst.get_mut(profile_name).expect("existing profile") + .extend(pkgs.iter().map(|s| (*s).to_owned())); + } + fn package(&mut self, pkgname: &str, dst: &mut BTreeMap, From 7ccf492ae616b4d06eab283ab604938fd234415a Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Sat, 12 Oct 2019 16:01:59 +0200 Subject: [PATCH 006/109] Package non-rust objects --- src/bootstrap/check.rs | 4 +++ src/bootstrap/compile.rs | 63 ++++++++++++++++++++++++++-------------- src/bootstrap/lib.rs | 1 + 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index cadb9a7e441f..df1c72575846 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -55,6 +55,7 @@ impl Step for Std { cargo, args(builder.kind), &libstd_stamp(builder, compiler, target), + vec![], true); let libdir = builder.sysroot_libdir(compiler, target); @@ -103,6 +104,7 @@ impl Step for Rustc { cargo, args(builder.kind), &librustc_stamp(builder, compiler, target), + vec![], true); let libdir = builder.sysroot_libdir(compiler, target); @@ -155,6 +157,7 @@ impl Step for CodegenBackend { cargo, args(builder.kind), &codegen_backend_stamp(builder, compiler, target, backend), + vec![], true); } } @@ -199,6 +202,7 @@ impl Step for Rustdoc { cargo, args(builder.kind), &rustdoc_stamp(builder, compiler, target), + vec![], true); let libdir = builder.sysroot_libdir(compiler, target); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 6ea32edfb208..d48927f9bf78 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -69,7 +69,7 @@ impl Step for Std { return; } - builder.ensure(StartupObjects { compiler, target }); + let mut target_deps = builder.ensure(StartupObjects { compiler, target }); let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); if compiler_to_use != compiler { @@ -91,7 +91,7 @@ impl Step for Std { return; } - copy_third_party_objects(builder, &compiler, target); + target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter()); let mut cargo = builder.cargo(compiler, Mode::Std, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); @@ -102,6 +102,7 @@ impl Step for Std { cargo, vec![], &libstd_stamp(builder, compiler, target), + target_deps, false); builder.ensure(StdLink { @@ -113,9 +114,22 @@ impl Step for Std { } /// Copies third pary objects needed by various targets. -fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned) { +fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned) + -> Vec +{ let libdir = builder.sysroot_libdir(*compiler, target); + let mut target_deps = vec![]; + + let mut copy_and_stamp = |sourcedir: &Path, name: &str| { + let target = libdir.join(name); + builder.copy( + &sourcedir.join(name), + &target, + ); + target_deps.push(target); + }; + // Copies the crt(1,i,n).o startup objects // // Since musl supports fully static linking, we can cross link for it even @@ -123,19 +137,13 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: // files. As those shipped with glibc won't work, copy the ones provided by // musl so we have them on linux-gnu hosts. if target.contains("musl") { + let srcdir = builder.musl_root(target).unwrap().join("lib"); for &obj in &["crt1.o", "crti.o", "crtn.o"] { - builder.copy( - &builder.musl_root(target).unwrap().join("lib").join(obj), - &libdir.join(obj), - ); + copy_and_stamp(&srcdir, obj); } } else if target.ends_with("-wasi") { - for &obj in &["crt1.o"] { - builder.copy( - &builder.wasi_root(target).unwrap().join("lib/wasm32-wasi").join(obj), - &libdir.join(obj), - ); - } + let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi"); + copy_and_stamp(&srcdir, "crt1.o"); } // Copies libunwind.a compiled to be linked wit x86_64-fortanix-unknown-sgx. @@ -145,11 +153,11 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: // which is provided by std for this target. if target == "x86_64-fortanix-unknown-sgx" { let src_path_env = "X86_FORTANIX_SGX_LIBS"; - let obj = "libunwind.a"; let src = env::var(src_path_env).expect(&format!("{} not found in env", src_path_env)); - let src = Path::new(&src).join(obj); - builder.copy(&src, &libdir.join(obj)); + copy_and_stamp(Path::new(&src), "libunwind.a"); } + + target_deps } /// Configure cargo to compile the standard library, adding appropriate env vars @@ -307,7 +315,7 @@ pub struct StartupObjects { } impl Step for StartupObjects { - type Output = (); + type Output = Vec; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/rtstartup") @@ -326,13 +334,15 @@ impl Step for StartupObjects { /// They don't require any library support as they're just plain old object /// files, so we just use the nightly snapshot compiler to always build them (as /// no other compilers are guaranteed to be available). - fn run(self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) -> Vec { let for_compiler = self.compiler; let target = self.target; if !target.contains("windows-gnu") { - return + return vec![] } + let mut target_deps = vec![]; + let src_dir = &builder.src.join("src/rtstartup"); let dst_dir = &builder.native_dir(target).join("rtstartup"); let sysroot_dir = &builder.sysroot_libdir(for_compiler, target); @@ -351,7 +361,9 @@ impl Step for StartupObjects { .arg(src_file)); } - builder.copy(dst_file, &sysroot_dir.join(file.to_string() + ".o")); + let target = sysroot_dir.join(file.to_string() + ".o"); + builder.copy(dst_file, &target); + target_deps.push(target); } for obj in ["crt2.o", "dllcrt2.o"].iter() { @@ -359,8 +371,12 @@ impl Step for StartupObjects { builder.cc(target), target, obj); - builder.copy(&src, &sysroot_dir.join(obj)); + let target = sysroot_dir.join(obj); + builder.copy(&src, &target); + target_deps.push(target); } + + target_deps } } @@ -438,6 +454,7 @@ impl Step for Rustc { cargo, vec![], &librustc_stamp(builder, compiler, target), + vec![], false); builder.ensure(RustcLink { @@ -586,7 +603,7 @@ impl Step for CodegenBackend { let tmp_stamp = out_dir.join(".tmp.stamp"); - let files = run_cargo(builder, cargo, vec![], &tmp_stamp, false); + let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false); if builder.config.dry_run { return; } @@ -954,6 +971,7 @@ pub fn run_cargo(builder: &Builder<'_>, cargo: Cargo, tail_args: Vec, stamp: &Path, + additional_target_deps: Vec, is_check: bool) -> Vec { @@ -1070,6 +1088,7 @@ pub fn run_cargo(builder: &Builder<'_>, deps.push((path_to_add.into(), false)); } + deps.extend(additional_target_deps.into_iter().map(|d| (d, false))); deps.sort(); let mut new_contents = Vec::new(); for (dep, proc_macro) in deps.iter() { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 9203a558f646..ad0bdd0f425f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1144,6 +1144,7 @@ impl Build { pub fn copy(&self, src: &Path, dst: &Path) { if self.config.dry_run { return; } self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst)); + if src == dst { return; } let _ = fs::remove_file(&dst); let metadata = t!(src.symlink_metadata()); if metadata.file_type().is_symlink() { From b9bca1800219b908049a5cfb7cafc0322439f9a8 Mon Sep 17 00:00:00 2001 From: Lucas Henry Date: Thu, 17 Oct 2019 19:15:42 +0200 Subject: [PATCH 007/109] Replaced warn attibute by deny --- .../lint/unused_parens_json_suggestion.fixed | 5 +- .../ui/lint/unused_parens_json_suggestion.rs | 5 +- .../lint/unused_parens_json_suggestion.stderr | 50 +++++++++++-------- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/test/ui/lint/unused_parens_json_suggestion.fixed b/src/test/ui/lint/unused_parens_json_suggestion.fixed index 427407119102..7a2d9ecdc362 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_json_suggestion.fixed @@ -1,5 +1,4 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// build-pass (FIXME(62277): could be check-pass?) // run-rustfix // The output for humans should just highlight the whole span without showing @@ -8,13 +7,13 @@ // stripping away any starting or ending parenthesis characters—hence this // test of the JSON error format. -#![warn(unused_parens)] +#![deny(unused_parens)] #![allow(unreachable_code)] fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = 1 / (2 + 3); + let _a = 1 / (2 + 3); //~ERROR unused parentheses wrap expression f(); } diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index 87192503986c..bfc649ad99c9 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -1,5 +1,4 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// build-pass (FIXME(62277): could be check-pass?) // run-rustfix // The output for humans should just highlight the whole span without showing @@ -8,13 +7,13 @@ // stripping away any starting or ending parenthesis characters—hence this // test of the JSON error format. -#![warn(unused_parens)] +#![deny(unused_parens)] #![allow(unreachable_code)] fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = (1 / (2 + 3)); + let _a = (1 / (2 + 3)); //~ERROR unused parentheses wrap expression f(); } diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 256c7555c908..54baade36e6a 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -4,20 +4,20 @@ "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 654, - "byte_end": 667, - "line_start": 17, - "line_end": 17, + "byte_start": 603, + "byte_end": 616, + "line_start": 16, + "line_end": 16, "column_start": 14, "column_end": 27, "is_primary": true, "text": [ { - "text": " let _a = (1 / (2 + 3));", + "text": " let _a = (1 / (2 + 3)); "highlight_start": 14, "highlight_end": 27 } @@ -36,16 +36,16 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 472, - "byte_end": 485, - "line_start": 11, - "line_end": 11, + "byte_start": 421, + "byte_end": 434, + "line_start": 10, + "line_end": 10, "column_start": 9, "column_end": 22, "is_primary": true, "text": [ { - "text": "#![warn(unused_parens)]", + "text": "#![deny(unused_parens)]", "highlight_start": 9, "highlight_end": 22 } @@ -66,16 +66,16 @@ "spans": [ { "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 654, - "byte_end": 667, - "line_start": 17, - "line_end": 17, + "byte_start": 603, + "byte_end": 616, + "line_start": 16, + "line_end": 16, "column_start": 14, "column_end": 27, "is_primary": true, "text": [ { - "text": " let _a = (1 / (2 + 3));", + "text": " let _a = (1 / (2 + 3)); "highlight_start": 14, "highlight_end": 27 } @@ -90,17 +90,27 @@ "rendered": null } ], - "rendered": "warning: unnecessary parentheses around assigned value - --> $DIR/unused_parens_json_suggestion.rs:17:14 + "rendered": "error: unnecessary parentheses around assigned value + --> $DIR/unused_parens_json_suggestion.rs:16:14 | LL | let _a = (1 / (2 + 3)); | ^^^^^^^^^^^^^ help: remove these parentheses | note: lint level defined here - --> $DIR/unused_parens_json_suggestion.rs:11:9 + --> $DIR/unused_parens_json_suggestion.rs:10:9 | -LL | #![warn(unused_parens)] +LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ " } +{ + "message": "aborting due to previous error", + "code": null, + "level": "error", + "spans": [], + "children": [], + "rendered": "error: aborting due to previous error + +" +} From 43b5dcaabb527126830f721318037bb270e21d4a Mon Sep 17 00:00:00 2001 From: Lucas Henry Date: Thu, 17 Oct 2019 19:27:55 +0200 Subject: [PATCH 008/109] Replaced warn attribute by deny --- .../lint/unused_parens_json_suggestion.fixed | 2 +- .../ui/lint/unused_parens_json_suggestion.rs | 2 +- ...unused_parens_remove_json_suggestion.fixed | 19 +- .../unused_parens_remove_json_suggestion.rs | 19 +- ...nused_parens_remove_json_suggestion.stderr | 254 +++++++++--------- 5 files changed, 152 insertions(+), 144 deletions(-) diff --git a/src/test/ui/lint/unused_parens_json_suggestion.fixed b/src/test/ui/lint/unused_parens_json_suggestion.fixed index 7a2d9ecdc362..5408a7cab7fa 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_json_suggestion.fixed @@ -13,7 +13,7 @@ fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = 1 / (2 + 3); //~ERROR unused parentheses wrap expression + let _a = 1 / (2 + 3); //~ERROR f(); } diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index bfc649ad99c9..ca421523ccd3 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -13,7 +13,7 @@ fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = (1 / (2 + 3)); //~ERROR unused parentheses wrap expression + let _a = (1 / (2 + 3)); //~ERROR f(); } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed index 2459eb1ac5cb..d63abfc8e50d 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed @@ -1,5 +1,4 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// build-pass // run-rustfix // The output for humans should just highlight the whole span without showing @@ -8,14 +7,14 @@ // stripping away any starting or ending parenthesis characters—hence this // test of the JSON error format. -#![warn(unused_parens)] +#![deny(unused_parens)] #![allow(unreachable_code)] fn main() { let _b = false; - if _b { + if _b { //~ ERROR println!("hello"); } @@ -26,29 +25,29 @@ fn main() { fn f() -> bool { let c = false; - if c { + if c { //~ ERROR println!("next"); } - if c { + if c { //~ ERROR println!("prev"); } while false && true { - if c { + if c { //~ ERROR println!("norm"); } } - while true && false { - for _ in 0 .. 3 { + while true && false { //~ ERROR + for _ in 0 .. 3 { //~ ERROR println!("e~") } } - for _ in 0 .. 3 { - while true && false { + for _ in 0 .. 3 { //~ ERROR + while true && false { //~ ERROR println!("e~") } } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs index 0e9869b67d59..1af352df78d7 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs @@ -1,5 +1,4 @@ // compile-flags: --error-format pretty-json -Zunstable-options -// build-pass // run-rustfix // The output for humans should just highlight the whole span without showing @@ -8,14 +7,14 @@ // stripping away any starting or ending parenthesis characters—hence this // test of the JSON error format. -#![warn(unused_parens)] +#![deny(unused_parens)] #![allow(unreachable_code)] fn main() { let _b = false; - if (_b) { + if (_b) { //~ ERROR println!("hello"); } @@ -26,29 +25,29 @@ fn main() { fn f() -> bool { let c = false; - if(c) { + if(c) { //~ ERROR println!("next"); } - if (c){ + if (c){ //~ ERROR println!("prev"); } while (false && true){ - if (c) { + if (c) { //~ ERROR println!("norm"); } } - while(true && false) { - for _ in (0 .. 3){ + while(true && false) { //~ ERROR + for _ in (0 .. 3){ //~ ERROR println!("e~") } } - for _ in (0 .. 3) { - while (true && false) { + for _ in (0 .. 3) { //~ ERROR + while (true && false) { //~ ERROR println!("e~") } } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr index b4eab200dd01..3665d94cca20 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -4,20 +4,20 @@ "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 521, - "byte_end": 525, - "line_start": 18, - "line_end": 18, + "byte_start": 507, + "byte_end": 511, + "line_start": 17, + "line_end": 17, "column_start": 8, "column_end": 12, "is_primary": true, "text": [ { - "text": " if (_b) {", + "text": " if (_b) { "highlight_start": 8, "highlight_end": 12 } @@ -36,16 +36,16 @@ "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 435, - "byte_end": 448, - "line_start": 11, - "line_end": 11, + "byte_start": 421, + "byte_end": 434, + "line_start": 10, + "line_end": 10, "column_start": 9, "column_end": 22, "is_primary": true, "text": [ { - "text": "#![warn(unused_parens)]", + "text": "#![deny(unused_parens)]", "highlight_start": 9, "highlight_end": 22 } @@ -66,16 +66,16 @@ "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 521, - "byte_end": 525, - "line_start": 18, - "line_end": 18, + "byte_start": 507, + "byte_end": 511, + "line_start": 17, + "line_end": 17, "column_start": 8, "column_end": 12, "is_primary": true, "text": [ { - "text": " if (_b) {", + "text": " if (_b) { "highlight_start": 8, "highlight_end": 12 } @@ -90,16 +90,16 @@ "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `if` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:18:8 + "rendered": "error: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:17:8 | LL | if (_b) { | ^^^^ help: remove these parentheses | note: lint level defined here - --> $DIR/unused_parens_remove_json_suggestion.rs:11:9 + --> $DIR/unused_parens_remove_json_suggestion.rs:10:9 | -LL | #![warn(unused_parens)] +LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ " @@ -110,20 +110,20 @@ LL | #![warn(unused_parens)] "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 618, - "byte_end": 621, - "line_start": 29, - "line_end": 29, + "byte_start": 614, + "byte_end": 617, + "line_start": 28, + "line_end": 28, "column_start": 7, "column_end": 10, "is_primary": true, "text": [ { - "text": " if(c) {", + "text": " if(c) { "highlight_start": 7, "highlight_end": 10 } @@ -142,16 +142,16 @@ LL | #![warn(unused_parens)] "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 618, - "byte_end": 621, - "line_start": 29, - "line_end": 29, + "byte_start": 614, + "byte_end": 617, + "line_start": 28, + "line_end": 28, "column_start": 7, "column_end": 10, "is_primary": true, "text": [ { - "text": " if(c) {", + "text": " if(c) { "highlight_start": 7, "highlight_end": 10 } @@ -166,8 +166,8 @@ LL | #![warn(unused_parens)] "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `if` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:29:7 + "rendered": "error: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:28:7 | LL | if(c) { | ^^^ help: remove these parentheses @@ -180,20 +180,20 @@ LL | if(c) { "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 664, - "byte_end": 667, - "line_start": 33, - "line_end": 33, + "byte_start": 670, + "byte_end": 673, + "line_start": 32, + "line_end": 32, "column_start": 8, "column_end": 11, "is_primary": true, "text": [ { - "text": " if (c){", + "text": " if (c){ "highlight_start": 8, "highlight_end": 11 } @@ -212,16 +212,16 @@ LL | if(c) { "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 664, - "byte_end": 667, - "line_start": 33, - "line_end": 33, + "byte_start": 670, + "byte_end": 673, + "line_start": 32, + "line_end": 32, "column_start": 8, "column_end": 11, "is_primary": true, "text": [ { - "text": " if (c){", + "text": " if (c){ "highlight_start": 8, "highlight_end": 11 } @@ -236,8 +236,8 @@ LL | if(c) { "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `if` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:33:8 + "rendered": "error: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:32:8 | LL | if (c){ | ^^^ help: remove these parentheses @@ -250,14 +250,14 @@ LL | if (c){ "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 712, - "byte_end": 727, - "line_start": 37, - "line_end": 37, + "byte_start": 728, + "byte_end": 743, + "line_start": 36, + "line_end": 36, "column_start": 11, "column_end": 26, "is_primary": true, @@ -282,10 +282,10 @@ LL | if (c){ "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 712, - "byte_end": 727, - "line_start": 37, - "line_end": 37, + "byte_start": 728, + "byte_end": 743, + "line_start": 36, + "line_end": 36, "column_start": 11, "column_end": 26, "is_primary": true, @@ -306,8 +306,8 @@ LL | if (c){ "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `while` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:37:11 + "rendered": "error: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:36:11 | LL | while (false && true){ | ^^^^^^^^^^^^^^^ help: remove these parentheses @@ -320,20 +320,20 @@ LL | while (false && true){ "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 740, - "byte_end": 743, - "line_start": 38, - "line_end": 38, + "byte_start": 756, + "byte_end": 759, + "line_start": 37, + "line_end": 37, "column_start": 12, "column_end": 15, "is_primary": true, "text": [ { - "text": " if (c) {", + "text": " if (c) { "highlight_start": 12, "highlight_end": 15 } @@ -352,16 +352,16 @@ LL | while (false && true){ "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 740, - "byte_end": 743, - "line_start": 38, - "line_end": 38, + "byte_start": 756, + "byte_end": 759, + "line_start": 37, + "line_end": 37, "column_start": 12, "column_end": 15, "is_primary": true, "text": [ { - "text": " if (c) {", + "text": " if (c) { "highlight_start": 12, "highlight_end": 15 } @@ -376,8 +376,8 @@ LL | while (false && true){ "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `if` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:38:12 + "rendered": "error: unnecessary parentheses around `if` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:37:12 | LL | if (c) { | ^^^ help: remove these parentheses @@ -390,20 +390,20 @@ LL | if (c) { "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 803, - "byte_end": 818, - "line_start": 44, - "line_end": 44, + "byte_start": 829, + "byte_end": 844, + "line_start": 43, + "line_end": 43, "column_start": 10, "column_end": 25, "is_primary": true, "text": [ { - "text": " while(true && false) {", + "text": " while(true && false) { "highlight_start": 10, "highlight_end": 25 } @@ -422,16 +422,16 @@ LL | if (c) { "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 803, - "byte_end": 818, - "line_start": 44, - "line_end": 44, + "byte_start": 829, + "byte_end": 844, + "line_start": 43, + "line_end": 43, "column_start": 10, "column_end": 25, "is_primary": true, "text": [ { - "text": " while(true && false) {", + "text": " while(true && false) { "highlight_start": 10, "highlight_end": 25 } @@ -446,8 +446,8 @@ LL | if (c) { "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `while` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:44:10 + "rendered": "error: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:43:10 | LL | while(true && false) { | ^^^^^^^^^^^^^^^ help: remove these parentheses @@ -460,20 +460,20 @@ LL | while(true && false) { "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 838, - "byte_end": 846, - "line_start": 45, - "line_end": 45, + "byte_start": 874, + "byte_end": 882, + "line_start": 44, + "line_end": 44, "column_start": 18, "column_end": 26, "is_primary": true, "text": [ { - "text": " for _ in (0 .. 3){", + "text": " for _ in (0 .. 3){ "highlight_start": 18, "highlight_end": 26 } @@ -492,16 +492,16 @@ LL | while(true && false) { "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 838, - "byte_end": 846, - "line_start": 45, - "line_end": 45, + "byte_start": 874, + "byte_end": 882, + "line_start": 44, + "line_end": 44, "column_start": 18, "column_end": 26, "is_primary": true, "text": [ { - "text": " for _ in (0 .. 3){", + "text": " for _ in (0 .. 3){ "highlight_start": 18, "highlight_end": 26 } @@ -516,8 +516,8 @@ LL | while(true && false) { "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `for` head expression - --> $DIR/unused_parens_remove_json_suggestion.rs:45:18 + "rendered": "error: unnecessary parentheses around `for` head expression + --> $DIR/unused_parens_remove_json_suggestion.rs:44:18 | LL | for _ in (0 .. 3){ | ^^^^^^^^ help: remove these parentheses @@ -530,20 +530,20 @@ LL | for _ in (0 .. 3){ "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 905, - "byte_end": 913, - "line_start": 50, - "line_end": 50, + "byte_start": 951, + "byte_end": 959, + "line_start": 49, + "line_end": 49, "column_start": 14, "column_end": 22, "is_primary": true, "text": [ { - "text": " for _ in (0 .. 3) {", + "text": " for _ in (0 .. 3) { "highlight_start": 14, "highlight_end": 22 } @@ -562,16 +562,16 @@ LL | for _ in (0 .. 3){ "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 905, - "byte_end": 913, - "line_start": 50, - "line_end": 50, + "byte_start": 951, + "byte_end": 959, + "line_start": 49, + "line_end": 49, "column_start": 14, "column_end": 22, "is_primary": true, "text": [ { - "text": " for _ in (0 .. 3) {", + "text": " for _ in (0 .. 3) { "highlight_start": 14, "highlight_end": 22 } @@ -586,8 +586,8 @@ LL | for _ in (0 .. 3){ "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `for` head expression - --> $DIR/unused_parens_remove_json_suggestion.rs:50:14 + "rendered": "error: unnecessary parentheses around `for` head expression + --> $DIR/unused_parens_remove_json_suggestion.rs:49:14 | LL | for _ in (0 .. 3) { | ^^^^^^^^ help: remove these parentheses @@ -600,20 +600,20 @@ LL | for _ in (0 .. 3) { "code": "unused_parens", "explanation": null }, - "level": "warning", + "level": "error", "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 930, - "byte_end": 945, - "line_start": 51, - "line_end": 51, + "byte_start": 986, + "byte_end": 1001, + "line_start": 50, + "line_end": 50, "column_start": 15, "column_end": 30, "is_primary": true, "text": [ { - "text": " while (true && false) {", + "text": " while (true && false) { "highlight_start": 15, "highlight_end": 30 } @@ -632,16 +632,16 @@ LL | for _ in (0 .. 3) { "spans": [ { "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 930, - "byte_end": 945, - "line_start": 51, - "line_end": 51, + "byte_start": 986, + "byte_end": 1001, + "line_start": 50, + "line_end": 50, "column_start": 15, "column_end": 30, "is_primary": true, "text": [ { - "text": " while (true && false) {", + "text": " while (true && false) { "highlight_start": 15, "highlight_end": 30 } @@ -656,11 +656,21 @@ LL | for _ in (0 .. 3) { "rendered": null } ], - "rendered": "warning: unnecessary parentheses around `while` condition - --> $DIR/unused_parens_remove_json_suggestion.rs:51:15 + "rendered": "error: unnecessary parentheses around `while` condition + --> $DIR/unused_parens_remove_json_suggestion.rs:50:15 | LL | while (true && false) { | ^^^^^^^^^^^^^^^ help: remove these parentheses " } +{ + "message": "aborting due to 9 previous errors", + "code": null, + "level": "error", + "spans": [], + "children": [], + "rendered": "error: aborting due to 9 previous errors + +" +} From 46a44668b2e9a25b0e6fe8c805a76325a3c49810 Mon Sep 17 00:00:00 2001 From: Lucas Henry Date: Thu, 17 Oct 2019 19:31:37 +0200 Subject: [PATCH 009/109] Replaced pretty-json error-format with only json --- ...unused_parens_remove_json_suggestion.fixed | 2 +- .../unused_parens_remove_json_suggestion.rs | 2 +- ...nused_parens_remove_json_suggestion.stderr | 644 +----------------- 3 files changed, 22 insertions(+), 626 deletions(-) diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed index d63abfc8e50d..4497a159f64d 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed @@ -1,4 +1,4 @@ -// compile-flags: --error-format pretty-json -Zunstable-options +// compile-flags: --error-format json -Zunstable-options // run-rustfix // The output for humans should just highlight the whole span without showing diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs index 1af352df78d7..22539b34bce1 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs @@ -1,4 +1,4 @@ -// compile-flags: --error-format pretty-json -Zunstable-options +// compile-flags: --error-format json -Zunstable-options // run-rustfix // The output for humans should just highlight the whole span without showing diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr index 3665d94cca20..6901ac09f991 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -1,96 +1,4 @@ -{ - "message": "unnecessary parentheses around `if` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 507, - "byte_end": 511, - "line_start": 17, - "line_end": 17, - "column_start": 8, - "column_end": 12, - "is_primary": true, - "text": [ - { - "text": " if (_b) { - "highlight_start": 8, - "highlight_end": 12 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "lint level defined here", - "code": null, - "level": "note", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 421, - "byte_end": 434, - "line_start": 10, - "line_end": 10, - "column_start": 9, - "column_end": 22, - "is_primary": true, - "text": [ - { - "text": "#![deny(unused_parens)]", - "highlight_start": 9, - "highlight_end": 22 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [], - "rendered": null - }, - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 507, - "byte_end": 511, - "line_start": 17, - "line_end": 17, - "column_start": 8, - "column_end": 12, - "is_primary": true, - "text": [ - { - "text": " if (_b) { - "highlight_start": 8, - "highlight_end": 12 - } - ], - "label": null, - "suggested_replacement": "_b", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `if` condition +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":504,"line_start":17,"line_end":17,"column_start":8,"column_end":12,"is_primary":true,"text":[{"text":" if (_b) { --> $DIR/unused_parens_remove_json_suggestion.rs:17:8 | LL | if (_b) { @@ -102,575 +10,63 @@ note: lint level defined here LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ -" -} -{ - "message": "unnecessary parentheses around `if` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 614, - "byte_end": 617, - "line_start": 28, - "line_end": 28, - "column_start": 7, - "column_end": 10, - "is_primary": true, - "text": [ - { - "text": " if(c) { - "highlight_start": 7, - "highlight_end": 10 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 614, - "byte_end": 617, - "line_start": 28, - "line_end": 28, - "column_start": 7, - "column_end": 10, - "is_primary": true, - "text": [ - { - "text": " if(c) { - "highlight_start": 7, - "highlight_end": 10 - } - ], - "label": null, - "suggested_replacement": " c", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `if` condition +"} +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":607,"byte_end":610,"line_start":28,"line_end":28,"column_start":7,"column_end":10,"is_primary":true,"text":[{"text":" if(c) { --> $DIR/unused_parens_remove_json_suggestion.rs:28:7 | LL | if(c) { | ^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `if` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 670, - "byte_end": 673, - "line_start": 32, - "line_end": 32, - "column_start": 8, - "column_end": 11, - "is_primary": true, - "text": [ - { - "text": " if (c){ - "highlight_start": 8, - "highlight_end": 11 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 670, - "byte_end": 673, - "line_start": 32, - "line_end": 32, - "column_start": 8, - "column_end": 11, - "is_primary": true, - "text": [ - { - "text": " if (c){ - "highlight_start": 8, - "highlight_end": 11 - } - ], - "label": null, - "suggested_replacement": "c ", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `if` condition +"} +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":663,"byte_end":666,"line_start":32,"line_end":32,"column_start":8,"column_end":11,"is_primary":true,"text":[{"text":" if (c){ --> $DIR/unused_parens_remove_json_suggestion.rs:32:8 | LL | if (c){ | ^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `while` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 728, - "byte_end": 743, - "line_start": 36, - "line_end": 36, - "column_start": 11, - "column_end": 26, - "is_primary": true, - "text": [ - { - "text": " while (false && true){", - "highlight_start": 11, - "highlight_end": 26 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 728, - "byte_end": 743, - "line_start": 36, - "line_end": 36, - "column_start": 11, - "column_end": 26, - "is_primary": true, - "text": [ - { - "text": " while (false && true){", - "highlight_start": 11, - "highlight_end": 26 - } - ], - "label": null, - "suggested_replacement": "false && true ", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `while` condition +"} +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":721,"byte_end":736,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":721,"byte_end":736,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":"false && true ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition --> $DIR/unused_parens_remove_json_suggestion.rs:36:11 | LL | while (false && true){ | ^^^^^^^^^^^^^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `if` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 756, - "byte_end": 759, - "line_start": 37, - "line_end": 37, - "column_start": 12, - "column_end": 15, - "is_primary": true, - "text": [ - { - "text": " if (c) { - "highlight_start": 12, - "highlight_end": 15 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 756, - "byte_end": 759, - "line_start": 37, - "line_end": 37, - "column_start": 12, - "column_end": 15, - "is_primary": true, - "text": [ - { - "text": " if (c) { - "highlight_start": 12, - "highlight_end": 15 - } - ], - "label": null, - "suggested_replacement": "c", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `if` condition +"} +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":749,"byte_end":752,"line_start":37,"line_end":37,"column_start":12,"column_end":15,"is_primary":true,"text":[{"text":" if (c) { --> $DIR/unused_parens_remove_json_suggestion.rs:37:12 | LL | if (c) { | ^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `while` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 829, - "byte_end": 844, - "line_start": 43, - "line_end": 43, - "column_start": 10, - "column_end": 25, - "is_primary": true, - "text": [ - { - "text": " while(true && false) { - "highlight_start": 10, - "highlight_end": 25 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 829, - "byte_end": 844, - "line_start": 43, - "line_end": 43, - "column_start": 10, - "column_end": 25, - "is_primary": true, - "text": [ - { - "text": " while(true && false) { - "highlight_start": 10, - "highlight_end": 25 - } - ], - "label": null, - "suggested_replacement": " true && false", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `while` condition +"} +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":837,"line_start":43,"line_end":43,"column_start":10,"column_end":25,"is_primary":true,"text":[{"text":" while(true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:43:10 | LL | while(true && false) { | ^^^^^^^^^^^^^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `for` head expression", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 874, - "byte_end": 882, - "line_start": 44, - "line_end": 44, - "column_start": 18, - "column_end": 26, - "is_primary": true, - "text": [ - { - "text": " for _ in (0 .. 3){ - "highlight_start": 18, - "highlight_end": 26 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 874, - "byte_end": 882, - "line_start": 44, - "line_end": 44, - "column_start": 18, - "column_end": 26, - "is_primary": true, - "text": [ - { - "text": " for _ in (0 .. 3){ - "highlight_start": 18, - "highlight_end": 26 - } - ], - "label": null, - "suggested_replacement": "0 .. 3 ", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `for` head expression +"} +{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":867,"byte_end":875,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ --> $DIR/unused_parens_remove_json_suggestion.rs:44:18 | LL | for _ in (0 .. 3){ | ^^^^^^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `for` head expression", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 951, - "byte_end": 959, - "line_start": 49, - "line_end": 49, - "column_start": 14, - "column_end": 22, - "is_primary": true, - "text": [ - { - "text": " for _ in (0 .. 3) { - "highlight_start": 14, - "highlight_end": 22 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 951, - "byte_end": 959, - "line_start": 49, - "line_end": 49, - "column_start": 14, - "column_end": 22, - "is_primary": true, - "text": [ - { - "text": " for _ in (0 .. 3) { - "highlight_start": 14, - "highlight_end": 22 - } - ], - "label": null, - "suggested_replacement": "0 .. 3", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `for` head expression +"} +{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":944,"byte_end":952,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { --> $DIR/unused_parens_remove_json_suggestion.rs:49:14 | LL | for _ in (0 .. 3) { | ^^^^^^^^ help: remove these parentheses -" -} -{ - "message": "unnecessary parentheses around `while` condition", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 986, - "byte_end": 1001, - "line_start": 50, - "line_end": 50, - "column_start": 15, - "column_end": 30, - "is_primary": true, - "text": [ - { - "text": " while (true && false) { - "highlight_start": 15, - "highlight_end": 30 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_remove_json_suggestion.rs", - "byte_start": 986, - "byte_end": 1001, - "line_start": 50, - "line_end": 50, - "column_start": 15, - "column_end": 30, - "is_primary": true, - "text": [ - { - "text": " while (true && false) { - "highlight_start": 15, - "highlight_end": 30 - } - ], - "label": null, - "suggested_replacement": "true && false", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around `while` condition +"} +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":979,"byte_end":994,"line_start":50,"line_end":50,"column_start":15,"column_end":30,"is_primary":true,"text":[{"text":" while (true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:50:15 | LL | while (true && false) { | ^^^^^^^^^^^^^^^ help: remove these parentheses -" -} -{ - "message": "aborting due to 9 previous errors", - "code": null, - "level": "error", - "spans": [], - "children": [], - "rendered": "error: aborting due to 9 previous errors +"} +{"message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors -" -} +"} From a1387e352f36ae6cd80ee25e01a4a6de2aedef45 Mon Sep 17 00:00:00 2001 From: Lucas Henry Date: Thu, 17 Oct 2019 19:32:04 +0200 Subject: [PATCH 010/109] Replaced pretty-json error-format with only json --- .../lint/unused_parens_json_suggestion.fixed | 2 +- .../ui/lint/unused_parens_json_suggestion.rs | 2 +- .../lint/unused_parens_json_suggestion.stderr | 108 +----------------- 3 files changed, 6 insertions(+), 106 deletions(-) diff --git a/src/test/ui/lint/unused_parens_json_suggestion.fixed b/src/test/ui/lint/unused_parens_json_suggestion.fixed index 5408a7cab7fa..757ad933a1f7 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_json_suggestion.fixed @@ -1,4 +1,4 @@ -// compile-flags: --error-format pretty-json -Zunstable-options +// compile-flags: --error-format json -Zunstable-options // run-rustfix // The output for humans should just highlight the whole span without showing diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index ca421523ccd3..173cd5554502 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -1,4 +1,4 @@ -// compile-flags: --error-format pretty-json -Zunstable-options +// compile-flags: --error-format json -Zunstable-options // run-rustfix // The output for humans should just highlight the whole span without showing diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 54baade36e6a..c503c100808d 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -1,96 +1,4 @@ -{ - "message": "unnecessary parentheses around assigned value", - "code": { - "code": "unused_parens", - "explanation": null - }, - "level": "error", - "spans": [ - { - "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 603, - "byte_end": 616, - "line_start": 16, - "line_end": 16, - "column_start": 14, - "column_end": 27, - "is_primary": true, - "text": [ - { - "text": " let _a = (1 / (2 + 3)); - "highlight_start": 14, - "highlight_end": 27 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [ - { - "message": "lint level defined here", - "code": null, - "level": "note", - "spans": [ - { - "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 421, - "byte_end": 434, - "line_start": 10, - "line_end": 10, - "column_start": 9, - "column_end": 22, - "is_primary": true, - "text": [ - { - "text": "#![deny(unused_parens)]", - "highlight_start": 9, - "highlight_end": 22 - } - ], - "label": null, - "suggested_replacement": null, - "suggestion_applicability": null, - "expansion": null - } - ], - "children": [], - "rendered": null - }, - { - "message": "remove these parentheses", - "code": null, - "level": "help", - "spans": [ - { - "file_name": "$DIR/unused_parens_json_suggestion.rs", - "byte_start": 603, - "byte_end": 616, - "line_start": 16, - "line_end": 16, - "column_start": 14, - "column_end": 27, - "is_primary": true, - "text": [ - { - "text": " let _a = (1 / (2 + 3)); - "highlight_start": 14, - "highlight_end": 27 - } - ], - "label": null, - "suggested_replacement": "1 / (2 + 3)", - "suggestion_applicability": "MachineApplicable", - "expansion": null - } - ], - "children": [], - "rendered": null - } - ], - "rendered": "error: unnecessary parentheses around assigned value +{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":609,"line_start":16,"line_end":16,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3)); --> $DIR/unused_parens_json_suggestion.rs:16:14 | LL | let _a = (1 / (2 + 3)); @@ -102,15 +10,7 @@ note: lint level defined here LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ -" -} -{ - "message": "aborting due to previous error", - "code": null, - "level": "error", - "spans": [], - "children": [], - "rendered": "error: aborting due to previous error +"} +{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error -" -} +"} From 47a443c50dbeee88cadc78e5c938f3e6d04d6f6b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:13:02 -0400 Subject: [PATCH 011/109] Duplicate lint specifications are always bug! Replace early_error and sess.err with bug!, in all cases. If the compiler we're running with, including plugins, is registering something twice, that's a (compiler/plugin) programmer error -- we should not try to be nice at the cost of developer ergononomics (hiding the stacktrace of the second registration is bad). This also is basically a static bug in ~all cases so it should not be a detriment to users, including with plugins. --- src/librustc/lint/context.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index fa73a3c6c462..002c3f662351 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -218,16 +218,7 @@ impl LintStore { let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { - let msg = format!("duplicate specification of lint {}", lint.name_lower()); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint {}", lint.name_lower()) } } } @@ -300,16 +291,7 @@ impl LintStore { } if !new { - let msg = format!("duplicate specification of lint group {}", name); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint group {}", name); } } From 577d442fe8337338b873d3df1ab5132de6a1af83 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:26:11 -0400 Subject: [PATCH 012/109] De-propagate optional session from lint registration This is straight up removing dead code, but is a separate commit from the previous to avoid conflating clean up and important changes. --- src/librustc/lint/context.rs | 17 ++++--------- src/librustc_interface/passes.rs | 6 ++--- src/librustc_interface/util.rs | 5 ++-- src/librustc_lint/lib.rs | 42 +++++++++++++------------------- 4 files changed, 28 insertions(+), 42 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 002c3f662351..dc16de822ebc 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -26,7 +26,7 @@ use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; -use crate::session::{config, early_error, Session}; +use crate::session::Session; use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::util::nodemap::FxHashMap; @@ -169,11 +169,10 @@ impl LintStore { } pub fn register_early_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -181,24 +180,22 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -210,7 +207,6 @@ impl LintStore { // Helper method for register_early/late_pass fn push_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, pass: &Box

) { for lint in pass.get_lints() { @@ -224,14 +220,13 @@ impl LintStore { } pub fn register_future_incompatible(&mut self, - sess: Option<&Session>, lints: Vec) { for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, edition.lint_name(), None, lints) + self.register_group(false, edition.lint_name(), None, lints) } } @@ -242,7 +237,6 @@ impl LintStore { } self.register_group( - sess, false, "future_incompatible", None, @@ -268,7 +262,6 @@ impl LintStore { pub fn register_group( &mut self, - sess: Option<&Session>, from_plugin: bool, name: &'static str, deprecated_name: Option<&'static str>, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 89de5714695d..280ac45803b7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,14 +299,14 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, false, pass); + ls.register_early_pass(true, false, pass); } for pass in late_lint_passes { - ls.register_late_pass(Some(sess), true, false, false, pass); + ls.register_late_pass(true, false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(Some(sess), true, name, deprecated_name, to); + ls.register_group(true, name, deprecated_name, to); } *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 0c272f0c4563..005f1a44acd6 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -108,9 +108,10 @@ pub fn create_session( let codegen_backend = get_codegen_backend(&sess); - rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); + rustc_lint::register_builtins(&mut sess.lint_store.get_mut(), + sess.opts.debugging_opts.no_interleave_lints); if sess.unstable_options() { - rustc_lint::register_internals(&mut sess.lint_store.borrow_mut(), Some(&sess)); + rustc_lint::register_internals(&mut sess.lint_store.get_mut()); } let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0e054013cd77..5c70e9f8a1a3 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,7 +41,6 @@ use rustc::lint::builtin::{ PRIVATE_DOC_TESTS, parser::ILL_FORMED_ATTRIBUTE_INPUT, }; -use rustc::session; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::ty::query::Providers; @@ -51,7 +50,6 @@ use syntax::ast; use syntax::edition::Edition; use syntax_pos::Span; -use session::Session; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -198,16 +196,16 @@ late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLint /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { +pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { - ($sess:ident, $name:expr, $($lint:ident),*) => ( - store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]); + ($name:expr, $($lint:ident),*) => ( + store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); ) } macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(sess, false, false, $($args,)* box $constructor); + store.$method(false, false, $($args,)* box $constructor); ) } @@ -219,35 +217,32 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { ) } - if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) { + if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); late_lint_passes!(register_passes, [register_late_pass, [false]]); late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - sess, false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - sess, false, true, true, box BuiltinCombinedModuleLateLintPass::new() + false, true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - sess, false, true, false, box BuiltinCombinedLateLintPass::new() + false, true, false, box BuiltinCombinedLateLintPass::new() ); } - add_lint_group!(sess, - "nonstandard_style", + add_lint_group!("nonstandard_style", NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS); - add_lint_group!(sess, - "unused", + add_lint_group!("unused", UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, @@ -267,8 +262,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_LABELS, UNUSED_PARENS); - add_lint_group!(sess, - "rust_2018_idioms", + add_lint_group!("rust_2018_idioms", BARE_TRAIT_OBJECTS, UNUSED_EXTERN_CRATES, ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, @@ -284,8 +278,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // MACRO_USE_EXTERN_CRATE, ); - add_lint_group!(sess, - "rustdoc", + add_lint_group!("rustdoc", INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); @@ -298,7 +291,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // and include the full URL, sort items in ascending order of issue numbers. // - Later, change lint to error // - Eventually, remove lint - store.register_future_incompatible(sess, vec![ + store.register_future_incompatible(vec![ FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", @@ -498,12 +491,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } -pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { - store.register_early_pass(sess, false, false, box DefaultHashTypes::new()); - store.register_early_pass(sess, false, false, box LintPassImpl); - store.register_late_pass(sess, false, false, false, box TyTyKind); +pub fn register_internals(store: &mut lint::LintStore) { + store.register_early_pass(false, false, box DefaultHashTypes::new()); + store.register_early_pass(false, false, box LintPassImpl); + store.register_late_pass(false, false, false, box TyTyKind); store.register_group( - sess, false, "rustc::internal", None, From 2121b04751702359f3bf03847040a9907ec2f66f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 24 Sep 2019 18:24:45 -0400 Subject: [PATCH 013/109] Handle lints, not passes in push_lints This extracts the call to get_lints() to callers. --- src/librustc/lint/context.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index dc16de822ebc..c21c45b759c6 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -172,7 +172,7 @@ impl LintStore { from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -184,7 +184,7 @@ impl LintStore { register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } @@ -195,7 +195,7 @@ impl LintStore { register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,10 +206,8 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_pass(&mut self, - from_plugin: bool, - pass: &Box

) { - for lint in pass.get_lints() { + fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + for lint in lints { self.lints.push((lint, from_plugin)); let id = LintId::of(lint); From 748eccd48828e430b906ffa6bd3f6abdcc766dc9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:52:53 -0400 Subject: [PATCH 014/109] Lints being from a plugin is dependent on the lint, not the registration --- src/librustc/lint/context.rs | 17 +++++++---------- src/librustc/lint/mod.rs | 5 +++++ src/librustc_driver/lib.rs | 5 ++--- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 15 +++++++-------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c21c45b759c6..37f577da8bba 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -50,7 +50,7 @@ use syntax_pos::{MultiSpan, Span, symbol::Symbol}; pub struct LintStore { /// Registered lints. The bool is true if the lint was /// added by a plugin. - lints: Vec<(&'static Lint, bool)>, + lints: Vec<&'static Lint>, /// Trait objects for each lint pass. /// This is only `None` while performing a lint pass. @@ -152,7 +152,7 @@ impl LintStore { } } - pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] { + pub fn get_lints<'t>(&'t self) -> &'t [&'static Lint] { &self.lints } @@ -169,10 +169,9 @@ impl LintStore { } pub fn register_early_pass(&mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -180,22 +179,20 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,9 +203,9 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + fn push_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { - self.lints.push((lint, from_plugin)); + self.lints.push(lint); let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7443cca822a9..455dc06a1efb 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -76,6 +76,8 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + + pub is_plugin: bool, } impl Lint { @@ -117,6 +119,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: false, }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, @@ -128,6 +131,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)), report_in_external_macro: false, + is_plugin: false, }; ); } @@ -156,6 +160,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: true, }; ); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f33cb4e215d3..5af1e8faccc8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -835,8 +835,7 @@ Available lint options: "); - fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { - let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); + fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> { // The sort doesn't case-fold but it's doubtful we care. lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name)); lints @@ -852,7 +851,7 @@ Available lint options: let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints() .iter() .cloned() - .partition(|&(_, p)| p); + .partition(|&lint| lint.is_plugin); let plugin = sort_lints(sess, plugin); let builtin = sort_lints(sess, builtin); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 280ac45803b7..2684650c3a97 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(true, false, pass); + ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(true, false, false, pass); + ls.register_late_pass(false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5c70e9f8a1a3..2c39ba024513 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, false, $($args,)* box $constructor); + store.$method(false, $($args,)* box $constructor); ) } @@ -224,16 +224,15 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - false, true, true, box BuiltinCombinedModuleLateLintPass::new() + true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - false, true, false, box BuiltinCombinedLateLintPass::new() + true, false, box BuiltinCombinedLateLintPass::new() ); } @@ -492,9 +491,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, false, box DefaultHashTypes::new()); - store.register_early_pass(false, false, box LintPassImpl); - store.register_late_pass(false, false, false, box TyTyKind); + store.register_early_pass(false, box DefaultHashTypes::new()); + store.register_early_pass(false, box LintPassImpl); + store.register_late_pass(false, false, box TyTyKind); store.register_group( false, "rustc::internal", From b060f3b84d98a0288cf51a6ab82be61e8f047c31 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:59:12 -0400 Subject: [PATCH 015/109] Split module and crate late pass registration --- src/librustc/lint/context.rs | 18 +++++++++--------- src/librustc_interface/passes.rs | 2 +- src/librustc_lint/lib.rs | 19 ++++++------------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 37f577da8bba..c65acd98385f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -188,17 +188,17 @@ impl LintStore { } } - pub fn register_late_pass(&mut self, - register_only: bool, - per_module: bool, - pass: LateLintPassObject) { + pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { self.push_lints(&pass.get_lints()); if !register_only { - if per_module { - self.late_module_passes.push(pass); - } else { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + self.late_passes.lock().as_mut().unwrap().push(pass); + } + } + + pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { + self.push_lints(&pass.get_lints()); + if !register_only { + self.late_module_passes.push(pass); } } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2684650c3a97..544dd26d0152 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -302,7 +302,7 @@ pub fn register_plugins<'a>( ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(false, false, pass); + ls.register_late_pass(false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2c39ba024513..5b190740c101 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -220,20 +220,13 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, [false]]); - late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); + late_lint_passes!(register_passes, [register_late_pass, []]); + late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); } else { - store.register_pre_expansion_pass( - true, - box BuiltinCombinedPreExpansionLintPass::new() - ); + store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_pass( - true, true, box BuiltinCombinedModuleLateLintPass::new() - ); - store.register_late_pass( - true, false, box BuiltinCombinedLateLintPass::new() - ); + store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); + store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); } add_lint_group!("nonstandard_style", @@ -493,7 +486,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_early_pass(false, box DefaultHashTypes::new()); store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, false, box TyTyKind); + store.register_late_pass(false, box TyTyKind); store.register_group( false, "rustc::internal", From e1079c82be514c6a9423acefd4457a7a08c0091c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:21:50 -0400 Subject: [PATCH 016/109] Split out just registration to separate function --- src/librustc/lint/context.rs | 40 +++++++++++--------------------- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 30 ++++++++++++------------ 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c65acd98385f..ff0b5a9e25b7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,42 +168,28 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - register_only: bool, - pass: EarlyLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.early_passes.as_mut().unwrap().push(pass); - } + pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.early_passes.as_mut().unwrap().push(pass); } - pub fn register_pre_expansion_pass( - &mut self, - register_only: bool, - pass: EarlyLintPassObject, - ) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.pre_expansion_passes.as_mut().unwrap().push(pass); - } + pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.pre_expansion_passes.as_mut().unwrap().push(pass); } - pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + pub fn register_late_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_passes.lock().as_mut().unwrap().push(pass); } - pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_module_passes.push(pass); - } + pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass - fn push_lints(&mut self, lints: &[&'static Lint]) { + pub fn register_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { self.lints.push(lint); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 544dd26d0152..4e879e508ab4 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(false, pass); + ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_late_pass(false, pass); + ls.register_late_pass(pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5b190740c101..49ab34b830a9 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,29 +204,29 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, $($args,)* box $constructor); + ($method:ident, $constructor:expr) => ( + store.$method(box $constructor); ) } macro_rules! register_passes { - ([$method:ident, $args:tt], [$($passes:ident: $constructor:expr,)*]) => ( + ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor, $args); + register_pass!($method, $constructor); )* ) } if no_interleave_lints { - pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); - early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, []]); - late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); + pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass); + early_lint_passes!(register_passes, register_early_pass); + late_lint_passes!(register_passes, register_late_pass); + late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); - store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); - store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); } add_lint_group!("nonstandard_style", @@ -484,9 +484,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, box DefaultHashTypes::new()); - store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, box TyTyKind); + store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(box LintPassImpl); + store.register_late_pass(box TyTyKind); store.register_group( false, "rustc::internal", From 68c07db80a90fd0fc3be03474555dc685864bcb6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:36:44 -0400 Subject: [PATCH 017/109] No longer implicitly register lints when registering passes This is in preparation for on-demand constructing passes --- src/librustc/lint/context.rs | 4 ---- src/librustc_interface/passes.rs | 2 ++ src/librustc_lint/lib.rs | 7 ++++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ff0b5a9e25b7..e04845d278a5 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -169,22 +169,18 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.early_passes.as_mut().unwrap().push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.pre_expansion_passes.as_mut().unwrap().push(pass); } pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_passes.lock().as_mut().unwrap().push(pass); } pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_module_passes.push(pass); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 4e879e508ab4..951b0970754a 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,9 +299,11 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 49ab34b830a9..3bb7de8b7f61 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr) => ( - store.$method(box $constructor); + let obj = box $constructor; + store.register_lints(&obj.get_lints()); + store.$method(obj); ) } @@ -484,8 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { + store.register_lints(&DefaultHashTypes::new().get_lints()); store.register_early_pass(box DefaultHashTypes::new()); + store.register_lints(&LintPassImpl.get_lints()); store.register_early_pass(box LintPassImpl); + store.register_lints(&TyTyKind.get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, From 7fef39791a093681c59f08181f96a0a2d63ab981 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:04:05 -0400 Subject: [PATCH 018/109] Make get_lints be a static function This moves from calling get_lints on instantiated pass objects to the raw object --- src/librustc/lint/context.rs | 10 +----- src/librustc/lint/mod.rs | 36 ++++++++----------- src/librustc_interface/passes.rs | 4 +-- src/librustc_lint/lib.rs | 20 +++++------ src/librustc_plugin/registry.rs | 9 +++++ src/librustdoc/core.rs | 7 ++-- .../lint_pass_impl_without_macro.rs | 10 +----- .../lint_pass_impl_without_macro.stderr | 3 +- 8 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e04845d278a5..373ee2568a47 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -1307,10 +1307,6 @@ impl LintPass for LateLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_late_lint_pass_impl_methods { @@ -1477,10 +1473,6 @@ impl LintPass for EarlyLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_early_lint_pass_impl_methods { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 455dc06a1efb..1b34808ef30a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -178,14 +178,6 @@ pub type LintArray = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; - - /// Gets descriptions of the lints this `LintPass` object can emit. - /// - /// N.B., there is no enforcement that the object only emits lints it registered. - /// And some `rustc` internal `LintPass`es register lints to be emitted by other - /// parts of the compiler. If you want enforced access restrictions for your - /// `Lint`, make it a private `static` item in its own module. - fn get_lints(&self) -> LintArray; } /// Implements `LintPass for $name` with the given list of `Lint` statics. @@ -194,7 +186,9 @@ macro_rules! impl_lint_pass { ($name:ident => [$($lint:expr),* $(,)?]) => { impl LintPass for $name { fn name(&self) -> &'static str { stringify!($name) } - fn get_lints(&self) -> LintArray { $crate::lint_array!($($lint),*) } + } + impl $name { + pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) } } }; } @@ -332,6 +326,12 @@ macro_rules! declare_combined_late_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name { @@ -342,12 +342,6 @@ macro_rules! declare_combined_late_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } @@ -459,6 +453,12 @@ macro_rules! declare_combined_early_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl EarlyLintPass for $name { @@ -469,12 +469,6 @@ macro_rules! declare_combined_early_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 951b0970754a..fdea437d37fb 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -291,6 +291,7 @@ pub fn register_plugins<'a>( syntax_exts, early_lint_passes, late_lint_passes, + lints, lint_groups, llvm_passes, attributes, @@ -298,12 +299,11 @@ pub fn register_plugins<'a>( } = registry; let mut ls = sess.lint_store.borrow_mut(); + ls.register_lints(&lints); for pass in early_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3bb7de8b7f61..752396188afd 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,9 +204,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr) => ( + ($method:ident, $ty:ident, $constructor:expr) => ( let obj = box $constructor; - store.register_lints(&obj.get_lints()); + store.register_lints(&$ty::get_lints()); store.$method(obj); ) } @@ -214,7 +214,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_passes { ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor); + register_pass!($method, $passes, $constructor); )* ) } @@ -225,10 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_passes!(register_passes, register_late_pass); late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::get_lints()); } add_lint_group!("nonstandard_style", @@ -486,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_lints(&DefaultHashTypes::new().get_lints()); + store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(box DefaultHashTypes::new()); - store.register_lints(&LintPassImpl.get_lints()); + store.register_lints(&LintPassImpl::get_lints()); store.register_early_pass(box LintPassImpl); - store.register_lints(&TyTyKind.get_lints()); + store.register_lints(&TyTyKind::get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index b826dd911983..a8076b57c86a 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -41,6 +41,9 @@ pub struct Registry<'a> { #[doc(hidden)] pub late_lint_passes: Vec, + #[doc(hidden)] + pub lints: Vec<&'static Lint>, + #[doc(hidden)] pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, @@ -59,6 +62,7 @@ impl<'a> Registry<'a> { args_hidden: None, krate_span, syntax_exts: vec![], + lints: vec![], early_lint_passes: vec![], late_lint_passes: vec![], lint_groups: FxHashMap::default(), @@ -99,6 +103,11 @@ impl<'a> Registry<'a> { self.register_syntax_extension(Symbol::intern(name), ext); } + /// Register a compiler lint pass. + pub fn register_lints(&mut self, lints: &[&'static Lint]) { + self.lints.extend(lints); + } + /// Register a compiler lint pass. pub fn register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject) { self.early_lint_passes.push(lint_pass); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 00265caa965e..2a468d679a88 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,7 +5,7 @@ use rustc::hir::HirId; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{Ty, TyCtxt}; -use rustc::lint::{self, LintPass}; +use rustc::lint; use rustc::session::config::ErrorOutputType; use rustc::session::DiagnosticOutput; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -273,10 +273,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints - .get_lints() + lint::builtin::HardwiredLints::get_lints() .into_iter() - .chain(rustc_lint::SoftLints.get_lints().into_iter()) + .chain(rustc_lint::SoftLints::get_lints().into_iter()) }; let lint_opts = lints().filter_map(|lint| { diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index 48dd5b122b5a..0bfb32c6dc43 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc; use rustc::lint::{LintArray, LintPass}; -use rustc::{declare_lint, declare_lint_pass, impl_lint_pass, lint_array}; +use rustc::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { pub TEST_LINT, @@ -17,10 +17,6 @@ declare_lint! { struct Foo; impl LintPass for Foo { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Foo" } @@ -31,10 +27,6 @@ macro_rules! custom_lint_pass_macro { struct Custom; impl LintPass for Custom { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Custom" } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b439ae2cd148..b7cff343395e 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)] = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:33:14 + --> $DIR/lint_pass_impl_without_macro.rs:29:14 | LL | impl LintPass for Custom { | ^^^^^^^^ @@ -23,4 +23,3 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors - From 24545128ebf7e19536e1384f64b89a18742471b0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:10:41 -0400 Subject: [PATCH 019/109] Take lint passes as constructor functions --- src/librustc/lint/context.rs | 16 ++++++++-------- src/librustc_lint/lib.rs | 9 ++++----- src/librustc_plugin/registry.rs | 8 ++++---- src/test/ui-fulldeps/auxiliary/lint-for-crate.rs | 3 ++- .../lint_pass_impl_without_macro.stderr | 1 + 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 373ee2568a47..73d8bb11b719 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,20 +168,20 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push(pass); + pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.early_passes.as_mut().unwrap().push((pass)()); } - pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push(pass); + pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.pre_expansion_passes.as_mut().unwrap().push((pass)()); } - pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push(pass); + pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_passes.lock().as_mut().unwrap().push((pass)()); } - pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_module_passes.push((pass)()); } // Helper method for register_early/late_pass diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 752396188afd..0026c2317d15 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,9 +205,8 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $ty:ident, $constructor:expr) => ( - let obj = box $constructor; store.register_lints(&$ty::get_lints()); - store.$method(obj); + store.$method(|| box $constructor); ) } @@ -487,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); - store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); - store.register_early_pass(box LintPassImpl); + store.register_early_pass(|| box LintPassImpl); store.register_lints(&TyTyKind::get_lints()); - store.register_late_pass(box TyTyKind); + store.register_late_pass(|| box TyTyKind); store.register_group( false, "rustc::internal", diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index a8076b57c86a..44318bf06aaa 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -36,10 +36,10 @@ pub struct Registry<'a> { pub syntax_exts: Vec, #[doc(hidden)] - pub early_lint_passes: Vec, + pub early_lint_passes: Vec EarlyLintPassObject>, #[doc(hidden)] - pub late_lint_passes: Vec, + pub late_lint_passes: Vec LateLintPassObject>, #[doc(hidden)] pub lints: Vec<&'static Lint>, @@ -109,12 +109,12 @@ impl<'a> Registry<'a> { } /// Register a compiler lint pass. - pub fn register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject) { + pub fn register_early_lint_pass(&mut self, lint_pass: fn() -> EarlyLintPassObject) { self.early_lint_passes.push(lint_pass); } /// Register a compiler lint pass. - pub fn register_late_lint_pass(&mut self, lint_pass: LateLintPassObject) { + pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) { self.late_lint_passes.push(lint_pass); } /// Register a lint group. diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 000e10392e82..ba5b5d1906ae 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -32,5 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); + reg.register_lint(&[&CRATE_NOT_OKAY]); + reg.register_late_lint_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b7cff343395e..0dbdf4f5aa9e 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -23,3 +23,4 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors + From aa4ee2cc0f722467da4c4b0d19ad365a4be1e5d5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:23:16 -0400 Subject: [PATCH 020/109] Move to storing constructor functions inside LintStore This stops storing the pass objects and instead stores constructor functions. The primary effect is that LintStore no longer has any interior mutability. --- src/librustc/lint/context.rs | 56 +++++++++++++++++------------------- src/librustc/lint/mod.rs | 3 -- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 73d8bb11b719..6e67c0315cf2 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::edition; @@ -52,12 +52,17 @@ pub struct LintStore { /// added by a plugin. lints: Vec<&'static Lint>, - /// Trait objects for each lint pass. - /// This is only `None` while performing a lint pass. - pre_expansion_passes: Option>, - early_passes: Option>, - late_passes: Lock>>, - late_module_passes: Vec, + /// Constructor functions for each variety of lint pass. + /// + /// These should only be called once, but since we want to avoid locks or + /// interior mutability, we don't enforce this (and lints should, in theory, + /// be compatible with being constructed more than once, though not + /// necessarily in a sane manner. This is safe though.) + pre_expansion_passes: Vec EarlyLintPassObject>, + early_passes: Vec EarlyLintPassObject>, + late_passes: Vec LateLintPassObject>, + /// This is unique in that we construct them per-module, so not once. + late_module_passes: Vec LateLintPassObject>, /// Lints indexed by name. by_name: FxHashMap, @@ -142,9 +147,9 @@ impl LintStore { pub fn new() -> LintStore { LintStore { lints: vec![], - pre_expansion_passes: Some(vec![]), - early_passes: Some(vec![]), - late_passes: Lock::new(Some(vec![])), + pre_expansion_passes: vec![], + early_passes: vec![], + late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), future_incompatible: Default::default(), @@ -169,19 +174,19 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push((pass)()); + self.early_passes.push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push((pass)()); + self.pre_expansion_passes.push(pass); } pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push((pass)()); + self.late_passes.push(pass); } pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push((pass)()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass @@ -1374,7 +1379,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] }); @@ -1415,7 +1420,8 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap(); + let mut passes = tcx.sess.lint_store.borrow() + .late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { if !passes.is_empty() { @@ -1431,7 +1437,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b } let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); for pass in &mut passes { time(tcx.sess, &format!("running late module lint: {}", pass.name()), || { @@ -1439,9 +1445,6 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } } - - // Put the passes back in the session. - *tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes); } /// Performs lint checking on a crate. @@ -1525,14 +1528,14 @@ pub fn check_ast_crate( pre_expansion: bool, builtin_lints: T, ) { - let (mut passes, mut buffered) = if pre_expansion { + let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(), + sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow_mut().early_passes.take().unwrap(), + sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; @@ -1561,13 +1564,6 @@ pub fn check_ast_crate( } } - // Put the lint store levels and passes back in the session. - if pre_expansion { - sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes); - } else { - sess.lint_store.borrow_mut().early_passes = Some(passes); - } - // All of the buffered lints should have been emitted at this point. // If not, that means that we somehow buffered a lint for a node id // that was not lint-checked (perhaps it doesn't exist?). This is a bug. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 1b34808ef30a..63c4013e1d31 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -286,9 +286,6 @@ macro_rules! expand_lint_pass_methods { macro_rules! declare_late_lint_pass { ([], [$hir:tt], [$($methods:tt)*]) => ( pub trait LateLintPass<'a, $hir>: LintPass { - fn fresh_late_pass(&self) -> LateLintPassObject { - panic!() - } expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]); } ) From c1abc30660c0c0b081a42d0a476d81ba04e6d16b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 18:47:08 -0400 Subject: [PATCH 021/109] Make declare_lint take any amount of boolean fields --- src/librustc/lint/builtin.rs | 8 ++++---- src/librustc/lint/mod.rs | 23 +++++++++++++++++------ src/librustc_lint/builtin.rs | 4 ++-- src/librustc_lint/unused.rs | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 983e3a9922ec..29cc326fab64 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -22,7 +22,7 @@ declare_lint! { pub CONST_ERR, Deny, "constant evaluation detected erroneous expression", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -71,7 +71,7 @@ declare_lint! { pub UNREACHABLE_CODE, Warn, "detects unreachable code paths", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -211,7 +211,7 @@ declare_lint! { pub DEPRECATED, Warn, "detects use of deprecated items", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -381,7 +381,7 @@ declare_lint! { pub DEPRECATED_IN_FUTURE, Allow, "detects use of items that will be deprecated in a future version", - report_in_external_macro: true + report_in_external_macro } declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 63c4013e1d31..76e6a28008a3 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -81,6 +81,17 @@ pub struct Lint { } impl Lint { + pub const fn default_fields_for_macro() -> Self { + Lint { + name: "", + default_level: Level::Forbid, + desc: "", + edition_lint_opts: None, + is_plugin: false, + report_in_external_macro: false, + } + } + /// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`. pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self { match lint_id { @@ -107,19 +118,19 @@ impl Lint { #[macro_export] macro_rules! declare_lint { ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, false} + declare_lint!( + $vis $NAME, $Level, $desc, + ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, report_in_external_macro: $rep: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, $rep} - ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $external: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, edition_lint_opts: None, - report_in_external_macro: $external, is_plugin: false, + $($v: true,)* + ..$crate::lint::Lint::default_fields_for_macro() }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 9a16d0a0715f..2997e1d2ca94 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -280,7 +280,7 @@ declare_lint! { pub MISSING_DOCS, Allow, "detects missing documentation for public members", - report_in_external_macro: true + report_in_external_macro } pub struct MissingDoc { @@ -1374,7 +1374,7 @@ declare_lint! { UNNAMEABLE_TEST_ITEMS, Warn, "detects an item that cannot be named being marked as `#[test_case]`", - report_in_external_macro: true + report_in_external_macro } pub struct UnnameableTestItems { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 3b3995832cb4..2ff8147149bb 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -25,7 +25,7 @@ declare_lint! { pub UNUSED_MUST_USE, Warn, "unused result of a type flagged as `#[must_use]`", - report_in_external_macro: true + report_in_external_macro } declare_lint! { From 7abb1fafcec155c4b596147fda4aff5a5cda62f3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:49:21 -0400 Subject: [PATCH 022/109] Remove side table of future incompatibility info Moves this information to a direct field of Lint, which is where it belongs. --- src/librustc/lint/builtin.rs | 161 +++++++++++++++++++++++++++++------ src/librustc/lint/context.rs | 63 +++++--------- src/librustc/lint/mod.rs | 20 ++++- src/librustc_lint/builtin.rs | 13 ++- src/librustc_lint/lib.rs | 157 ---------------------------------- 5 files changed, 183 insertions(+), 231 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 29cc326fab64..4c1093e00cee 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,11 +4,12 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo}; use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; +use syntax::edition::Edition; use syntax::source_map::Span; use syntax::symbol::Symbol; @@ -125,7 +126,11 @@ declare_lint! { declare_lint! { pub PRIVATE_IN_PUBLIC, Warn, - "detect private items in public interfaces not caught by the old implementation" + "detect private items in public interfaces not caught by the old implementation", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { @@ -137,13 +142,21 @@ declare_lint! { declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, - "detect public re-exports of private extern crates" + "detect public re-exports of private extern crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { pub INVALID_TYPE_PARAM_DEFAULT, Deny, - "type parameter default erroneously allowed in invalid location" + "type parameter default erroneously allowed in invalid location", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36887 ", + edition: None, + }; } declare_lint! { @@ -155,56 +168,92 @@ declare_lint! { declare_lint! { pub SAFE_EXTERN_STATICS, Deny, - "safe access to extern statics was erroneously allowed" + "safe access to extern statics was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36247 ", + edition: None, + }; } declare_lint! { pub SAFE_PACKED_BORROWS, Warn, - "safe borrows of fields of packed structs were was erroneously allowed" + "safe borrows of fields of packed structs were was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46043 ", + edition: None, + }; } declare_lint! { pub PATTERNS_IN_FNS_WITHOUT_BODY, Warn, - "patterns in functions without body were erroneously allowed" + "patterns in functions without body were erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35203 ", + edition: None, + }; } declare_lint! { pub LEGACY_DIRECTORY_OWNERSHIP, Deny, "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \ - not named `mod.rs`" + not named `mod.rs`", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #37872 ", + edition: None, + }; } declare_lint! { pub LEGACY_CONSTRUCTOR_VISIBILITY, Deny, - "detects use of struct constructors that would be invisible with new visibility rules" + "detects use of struct constructors that would be invisible with new visibility rules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #39207 ", + edition: None, + }; } declare_lint! { pub MISSING_FRAGMENT_SPECIFIER, Deny, - "detects missing fragment specifiers in unused `macro_rules!` patterns" + "detects missing fragment specifiers in unused `macro_rules!` patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #40107 ", + edition: None, + }; } declare_lint! { pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, Deny, - "detects parenthesized generic parameters in type and module names" + "detects parenthesized generic parameters in type and module names", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42238 ", + edition: None, + }; } declare_lint! { pub LATE_BOUND_LIFETIME_ARGUMENTS, Warn, - "detects generic lifetime arguments in path segments with late bound lifetime parameters" + "detects generic lifetime arguments in path segments with late bound lifetime parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42868 ", + edition: None, + }; } declare_lint! { pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, - "trait-object types were treated as different depending on marker-trait order" + "trait-object types were treated as different depending on marker-trait order", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #56484 ", + edition: None, + }; } declare_lint! { @@ -247,7 +296,11 @@ declare_lint! { declare_lint! { pub TYVAR_BEHIND_RAW_POINTER, Warn, - "raw pointer to an inference variable" + "raw pointer to an inference variable", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46906 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -266,19 +319,33 @@ declare_lint! { pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, Allow, "fully qualified paths that start with a module name \ - instead of `crate`, `self`, or an extern crate name" + instead of `crate`, `self`, or an extern crate name", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #53130 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, Warn, - "floating-point literals cannot be used in patterns" + "floating-point literals cannot be used in patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41620 ", + edition: None, + }; } declare_lint! { pub UNSTABLE_NAME_COLLISIONS, Warn, - "detects name collision with an existing but unstable method" + "detects name collision with an existing but unstable method", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #48919 ", + edition: None, + // Note: this item represents future incompatibility of all unstable functions in the + // standard library, and thus should never be removed or changed to an error. + }; } declare_lint! { @@ -296,7 +363,11 @@ declare_lint! { declare_lint! { pub DUPLICATE_MACRO_EXPORTS, Deny, - "detects duplicate macro exports" + "detects duplicate macro exports", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35896 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -320,13 +391,21 @@ declare_lint! { declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, - "checks the object safety of where clauses" + "checks the object safety of where clauses", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #51443 ", + edition: None, + }; } declare_lint! { pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, Warn, - "detects proc macro derives using inaccessible names from parent modules" + "detects proc macro derives using inaccessible names from parent modules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #50504 ", + edition: None, + }; } declare_lint! { @@ -340,7 +419,11 @@ declare_lint! { pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, Deny, "macro-expanded `macro_export` macros from the current crate \ - cannot be referred to by absolute paths" + cannot be referred to by absolute paths", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #52234 ", + edition: None, + }; } declare_lint! { @@ -353,7 +436,11 @@ declare_lint! { pub INDIRECT_STRUCTURAL_MATCH, // defaulting to allow until rust-lang/rust#62614 is fixed. Allow, - "pattern with const indirectly referencing non-`#[structural_match]` type" + "pattern with const indirectly referencing non-`#[structural_match]` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #62411 ", + edition: None, + }; } /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. @@ -361,7 +448,11 @@ pub mod parser { declare_lint! { pub ILL_FORMED_ATTRIBUTE_INPUT, Warn, - "ill-formed attribute inputs that were previously accepted and used in practice" + "ill-formed attribute inputs that were previously accepted and used in practice", + @future_incompatible = super::FutureIncompatibleInfo { + reference: "issue #57571 ", + edition: None, + }; } declare_lint! { @@ -387,25 +478,41 @@ declare_lint! { declare_lint! { pub AMBIGUOUS_ASSOCIATED_ITEMS, Deny, - "ambiguous associated items" + "ambiguous associated items", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #57644 ", + edition: None, + }; } declare_lint! { pub NESTED_IMPL_TRAIT, Warn, - "nested occurrence of `impl Trait` type" + "nested occurrence of `impl Trait` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59014 ", + edition: None, + }; } declare_lint! { pub MUTABLE_BORROW_RESERVATION_CONFLICT, Warn, - "reservation of a two-phased borrow conflicts with other shared borrows" + "reservation of a two-phased borrow conflicts with other shared borrows", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59159 ", + edition: None, + }; } declare_lint! { pub SOFT_UNSTABLE, Deny, - "a feature gate that doesn't break dependent crates" + "a feature gate that doesn't break dependent crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #64266 ", + edition: None, + }; } declare_lint_pass! { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6e67c0315cf2..97b9f21163db 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer, FutureIncompatibleInfo}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -38,7 +38,6 @@ use std::default::Default as StdDefault; use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; -use syntax::edition; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; use syntax_pos::{MultiSpan, Span, symbol::Symbol}; @@ -69,10 +68,6 @@ pub struct LintStore { /// Map of registered lint groups to what lints they expand to. lint_groups: FxHashMap<&'static str, LintGroup>, - - /// Extra info for future incompatibility lints, describing the - /// issue or RFC that caused the incompatibility. - future_incompatible: FxHashMap, } /// Lints that are buffered up early on in the `Session` before the @@ -86,18 +81,6 @@ pub struct BufferedEarlyLint { pub diagnostic: BuiltinLintDiagnostics, } -/// Extra information for a future incompatibility lint. See the call -/// to `register_future_incompatible` in `librustc_lint/lib.rs` for -/// guidelines. -pub struct FutureIncompatibleInfo { - pub id: LintId, - /// e.g., a URL for an issue/PR/RFC or error code - pub reference: &'static str, - /// If this is an edition fixing lint, the edition in which - /// this lint becomes obsolete - pub edition: Option, -} - /// The target of the `by_name` map, which accounts for renaming/deprecation. enum TargetLint { /// A direct lint target @@ -152,7 +135,6 @@ impl LintStore { late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), - future_incompatible: Default::default(), lint_groups: Default::default(), } } @@ -198,36 +180,31 @@ impl LintStore { if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { bug!("duplicate specification of lint {}", lint.name_lower()) } - } - } - pub fn register_future_incompatible(&mut self, - lints: Vec) { + if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible { + if let Some(edition) = edition { + self.lint_groups.entry(edition.lint_name()) + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); + } - for edition in edition::ALL_EDITIONS { - let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) - .collect::>(); - if !lints.is_empty() { - self.register_group(false, edition.lint_name(), None, lints) + self.lint_groups.entry("future_incompatible") + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); } } - - let mut future_incompatible = Vec::with_capacity(lints.len()); - for lint in lints { - future_incompatible.push(lint.id); - self.future_incompatible.insert(lint.id, lint); - } - - self.register_group( - false, - "future_incompatible", - None, - future_incompatible, - ); } - pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> { - self.future_incompatible.get(&id) + pub fn future_incompatible(&self, id: LintId) -> Option { + id.lint.future_incompatible } pub fn register_group_alias( diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 76e6a28008a3..ba7ec0ed6e48 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -45,7 +45,7 @@ use syntax_pos::Span; pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore, check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult, - FutureIncompatibleInfo, BufferedEarlyLint,}; + BufferedEarlyLint,}; /// Specification of a single lint. #[derive(Copy, Clone, Debug)] @@ -77,9 +77,21 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + pub future_incompatible: Option, + pub is_plugin: bool, } +/// Extra information for a future incompatibility lint. +#[derive(Copy, Clone, Debug)] +pub struct FutureIncompatibleInfo { + /// e.g., a URL for an issue/PR/RFC or error code + pub reference: &'static str, + /// If this is an edition fixing lint, the edition in which + /// this lint becomes obsolete + pub edition: Option, +} + impl Lint { pub const fn default_fields_for_macro() -> Self { Lint { @@ -89,6 +101,7 @@ impl Lint { edition_lint_opts: None, is_plugin: false, report_in_external_macro: false, + future_incompatible: None, } } @@ -122,7 +135,8 @@ macro_rules! declare_lint { $vis $NAME, $Level, $desc, ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, + $(@future_incompatible = $fi:expr;)? $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, @@ -130,6 +144,7 @@ macro_rules! declare_lint { edition_lint_opts: None, is_plugin: false, $($v: true,)* + $(future_incompatible: Some($fi),)* ..$crate::lint::Lint::default_fields_for_macro() }; ); @@ -171,6 +186,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + future_incompatible: None, is_plugin: true, }; ); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2997e1d2ca94..bce04471cec4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -27,6 +27,7 @@ use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx}; use rustc::{lint, util}; +use rustc::lint::FutureIncompatibleInfo; use hir::Node; use util::nodemap::HirIdSet; use lint::{LateContext, LintContext, LintArray}; @@ -601,7 +602,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { declare_lint! { pub ANONYMOUS_PARAMETERS, Allow, - "detects anonymous parameters" + "detects anonymous parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41686 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( @@ -1423,7 +1428,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { declare_lint! { pub KEYWORD_IDENTS, Allow, - "detects edition keywords being used as an identifier" + "detects edition keywords being used as an identifier", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #49716 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0026c2317d15..c83074c95ca0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -33,13 +33,11 @@ use rustc::lint; use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, - ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, - parser::ILL_FORMED_ATTRIBUTE_INPUT, }; use rustc::hir; use rustc::hir::def_id::DefId; @@ -47,11 +45,9 @@ use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use syntax::ast; -use syntax::edition::Edition; use syntax_pos::Span; use lint::LintId; -use lint::FutureIncompatibleInfo; use redundant_semicolon::*; use nonstandard_style::*; @@ -276,159 +272,6 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); - // Guidelines for creating a future incompatibility lint: - // - // - Create a lint defaulting to warn as normal, with ideally the same error - // message you would normally give - // - Add a suitable reference, typically an RFC or tracking issue. Go ahead - // and include the full URL, sort items in ascending order of issue numbers. - // - Later, change lint to error - // - Eventually, remove lint - store.register_future_incompatible(vec![ - FutureIncompatibleInfo { - id: LintId::of(PRIVATE_IN_PUBLIC), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), - reference: "issue #35203 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(DUPLICATE_MACRO_EXPORTS), - reference: "issue #35896 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(KEYWORD_IDENTS), - reference: "issue #49716 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_EXTERN_STATICS), - reference: "issue #36247 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), - reference: "issue #36887 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), - reference: "issue #37872 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), - reference: "issue #39207 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MISSING_FRAGMENT_SPECIFIER), - reference: "issue #40107 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), - reference: "issue #41620 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ANONYMOUS_PARAMETERS), - reference: "issue #41686 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), - reference: "issue #42238 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), - reference: "issue #42868 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_PACKED_BORROWS), - reference: "issue #46043 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS), - reference: "issue #56484 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(TYVAR_BEHIND_RAW_POINTER), - reference: "issue #46906 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(UNSTABLE_NAME_COLLISIONS), - reference: "issue #48919 ", - edition: None, - // Note: this item represents future incompatibility of all unstable functions in the - // standard library, and thus should never be removed or changed to an error. - }, - FutureIncompatibleInfo { - id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE), - reference: "issue #53130 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY), - reference: "issue #51443 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK), - reference: "issue #50504 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS), - reference: "issue #52234 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILL_FORMED_ATTRIBUTE_INPUT), - reference: "issue #57571 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS), - reference: "issue #57644 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(NESTED_IMPL_TRAIT), - reference: "issue #59014 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT), - reference: "issue #59159 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INDIRECT_STRUCTURAL_MATCH), - reference: "issue #62411 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SOFT_UNSTABLE), - reference: "issue #64266 ", - edition: None, - }, - ]); - // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths"); From c4475c753b252060dbc76a73b83159484992bf06 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:51:18 -0400 Subject: [PATCH 023/109] Access future incompatibility information directly Avoid querying LintStore when not necessary --- src/librustc/lint/context.rs | 4 ---- src/librustc/lint/mod.rs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 97b9f21163db..4146606d443e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -203,10 +203,6 @@ impl LintStore { } } - pub fn future_incompatible(&self, id: LintId) -> Option { - id.lint.future_incompatible - } - pub fn register_group_alias( &mut self, lint_name: &'static str, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ba7ec0ed6e48..e3219b717905 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -672,9 +672,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, }; // Check for future incompatibility lints and issue a stronger warning. - let lints = sess.lint_store.borrow(); let lint_id = LintId::of(lint); - let future_incompatible = lints.future_incompatible(lint_id); + let future_incompatible = lint.future_incompatible; // If this code originates in a foreign macro, aka something that this crate // did not itself author, then it's likely that there's nothing this crate From da56d1d20113355047f5e6e3d5686ea1c7589d99 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 08:46:11 -0400 Subject: [PATCH 024/109] Remove all borrows of lint store from Session from librustc Access through tcx is fine -- by that point, the lint store is frozen, but direct access through Session will go away in future commits, as lint store is still mutable in early stages of Session, and will be removed completely. --- src/librustc/lint/context.rs | 21 +++++++++++++-------- src/librustc/lint/levels.rs | 16 +++++++--------- src/librustc/lint/mod.rs | 15 +++++++++------ src/librustc_interface/passes.rs | 9 ++++++++- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4146606d443e..515d4d3cd727 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -480,7 +480,7 @@ pub struct EarlyContext<'a> { builder: LintLevelsBuilder<'a>, /// The store of registered lints and the lint levels. - lint_store: ReadGuard<'a, LintStore>, + lint_store: &'a LintStore, buffered: LintBuffer, } @@ -569,14 +569,15 @@ pub trait LintContext: Sized { impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, + lint_store: &'a LintStore, krate: &'a ast::Crate, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { sess, krate, - lint_store: sess.lint_store.borrow(), - builder: LintLevelSets::builder(sess), + lint_store, + builder: LintLevelSets::builder(sess, lint_store), buffered, } } @@ -611,7 +612,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { f: F) where F: FnOnce(&mut Self) { - let push = self.context.builder.push(attrs); + let push = self.context.builder.push(attrs, &self.context.lint_store); self.check_id(id); self.enter_attrs(attrs); f(self); @@ -1473,12 +1474,13 @@ early_lint_methods!(early_lint_pass_impl, []); fn early_lint_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pass: T, buffered: LintBuffer, ) -> LintBuffer { let mut cx = EarlyContextAndPass { - context: EarlyContext::new(sess, krate, buffered), + context: EarlyContext::new(sess, lint_store, krate, buffered), pass, }; @@ -1497,28 +1499,30 @@ fn early_lint_crate( pub fn check_ast_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pre_expansion: bool, builtin_lints: T, ) { let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), + lint_store.pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), + lint_store.early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; if !sess.opts.debugging_opts.no_interleave_lints { - buffered = early_lint_crate(sess, krate, builtin_lints, buffered); + buffered = early_lint_crate(sess, lint_store, krate, builtin_lints, buffered); if !passes.is_empty() { buffered = early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: &mut passes[..] }, buffered, @@ -1529,6 +1533,7 @@ pub fn check_ast_crate( buffered = time(sess, &format!("running lint: {}", pass.name()), || { early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: slice::from_mut(pass) }, buffered, diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 60b1b192d10d..36c7c5b20fde 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -3,7 +3,7 @@ use std::cmp; use crate::hir::HirId; use crate::ich::StableHashingContext; use crate::lint::builtin; -use crate::lint::context::CheckLintNameResult; +use crate::lint::context::{LintStore, CheckLintNameResult}; use crate::lint::{self, Lint, LintId, Level, LintSource}; use crate::session::Session; use crate::util::nodemap::FxHashMap; @@ -35,21 +35,20 @@ enum LintSet { } impl LintLevelSets { - pub fn new(sess: &Session) -> LintLevelSets { + pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets { let mut me = LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid, }; - me.process_command_line(sess); + me.process_command_line(sess, lint_store); return me } - pub fn builder(sess: &Session) -> LintLevelsBuilder<'_> { - LintLevelsBuilder::new(sess, LintLevelSets::new(sess)) + pub fn builder<'a>(sess: &'a Session, store: &LintStore) -> LintLevelsBuilder<'a> { + LintLevelsBuilder::new(sess, LintLevelSets::new(sess, store)) } - fn process_command_line(&mut self, sess: &Session) { - let store = sess.lint_store.borrow(); + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { let mut specs = FxHashMap::default(); self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); @@ -186,9 +185,8 @@ impl<'a> LintLevelsBuilder<'a> { /// #[allow] /// /// Don't forget to call `pop`! - pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { + pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { let mut specs = FxHashMap::default(); - let store = self.sess.lint_store.borrow(); let sess = self.sess; let bad_attr = |span| { struct_span_err!(sess, span, E0452, "malformed lint attribute input") diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index e3219b717905..ea06884d2c42 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -777,13 +777,15 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); + let store = tcx.sess.lint_store.borrow(); let mut builder = LintLevelMapBuilder { - levels: LintLevelSets::builder(tcx.sess), + levels: LintLevelSets::builder(tcx.sess, &store), tcx: tcx, + store: &*store, }; let krate = tcx.hir().krate(); - let push = builder.levels.push(&krate.attrs); + let push = builder.levels.push(&krate.attrs, &store); builder.levels.register_id(hir::CRATE_HIR_ID); for macro_def in &krate.exported_macros { builder.levels.register_id(macro_def.hir_id); @@ -794,19 +796,20 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { tcx.arena.alloc(builder.levels.build_map()) } -struct LintLevelMapBuilder<'tcx> { +struct LintLevelMapBuilder<'a, 'tcx> { levels: levels::LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, + store: &'a LintStore, } -impl LintLevelMapBuilder<'tcx> { +impl LintLevelMapBuilder<'_, '_> { fn with_lint_attrs(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F) where F: FnOnce(&mut Self) { - let push = self.levels.push(attrs); + let push = self.levels.push(attrs, self.store); if push.changed { self.levels.register_id(id); } @@ -815,7 +818,7 @@ impl LintLevelMapBuilder<'tcx> { } } -impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { +impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> { intravisit::NestedVisitorMap::All(&self.tcx.hir()) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index fdea437d37fb..2fd7b2507a78 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -329,6 +329,7 @@ fn configure_and_expand_inner<'a>( time(sess, "pre-AST-expansion lint checks", || { lint::check_ast_crate( sess, + &*sess.lint_store.borrow(), &krate, true, rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); @@ -556,7 +557,13 @@ pub fn lower_to_hir( }); time(sess, "early lint checks", || { - lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new()) + lint::check_ast_crate( + sess, + &*sess.lint_store.borrow(), + &krate, + false, + rustc_lint::BuiltinCombinedEarlyLintPass::new(), + ) }); // Discard hygiene data, which isn't required after lowering to HIR. From dab3bd6cda23064e6726bd046c903096ef03cbd0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 09:53:13 -0400 Subject: [PATCH 025/109] Create lint store during plugin registration Remove lint store from Session --- Cargo.lock | 1 + src/librustc/lint/context.rs | 16 +++++----- src/librustc/lint/mod.rs | 4 +-- src/librustc/session/mod.rs | 11 +++---- src/librustc/ty/context.rs | 4 +++ src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/lib.rs | 18 +++++++---- src/librustc_interface/passes.rs | 38 ++++++++++------------- src/librustc_interface/queries.rs | 21 +++++++++---- src/librustc_interface/util.rs | 7 ----- src/librustc_lint/lib.rs | 15 ++++++++-- src/librustc_plugin/registry.rs | 50 ++++--------------------------- 12 files changed, 83 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5a7521abde1..04181e197258 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3483,6 +3483,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_interface", + "rustc_lint", "rustc_metadata", "rustc_mir", "rustc_plugin", diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 515d4d3cd727..8208cc26ed30 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -452,7 +452,7 @@ pub struct LateContext<'a, 'tcx> { pub access_levels: &'a AccessLevels, /// The store of registered lints and the lint levels. - lint_store: ReadGuard<'a, LintStore>, + lint_store: &'tcx LintStore, last_node_with_lint_attrs: hir::HirId, @@ -1320,7 +1320,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: tcx.sess.lint_store.borrow(), + lint_store: &tcx.lint_store, last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(), generics: None, only_module: true, @@ -1352,7 +1352,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); - let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes + let mut passes: Vec<_> = tcx.lint_store.late_module_passes .iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { @@ -1370,7 +1370,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: tcx.sess.lint_store.borrow(), + lint_store: &tcx.lint_store, last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, only_module: false, @@ -1394,7 +1394,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.sess.lint_store.borrow() + let mut passes = tcx.lint_store .late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { @@ -1410,7 +1410,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } - let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes + let mut passes: Vec<_> = tcx.lint_store.late_module_passes .iter().map(|pass| (pass)()).collect(); for pass in &mut passes { @@ -1571,7 +1571,7 @@ impl Decodable for LintId { fn decode(d: &mut D) -> Result { let s = d.read_str()?; ty::tls::with(|tcx| { - match tcx.sess.lint_store.borrow().find_lints(&s) { + match tcx.lint_store.find_lints(&s) { Ok(ids) => { if ids.len() != 0 { panic!("invalid lint-id `{}`", s); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ea06884d2c42..3c35bdae66e9 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -777,11 +777,11 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); - let store = tcx.sess.lint_store.borrow(); + let store = &tcx.lint_store; let mut builder = LintLevelMapBuilder { levels: LintLevelSets::builder(tcx.sess, &store), tcx: tcx, - store: &*store, + store: store, }; let krate = tcx.hir().krate(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b65bf2230b39..bd2460cfab11 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported}; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ - self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering, + self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering, Ordering::SeqCst, }; @@ -77,9 +77,11 @@ pub struct Session { /// if the value stored here has been affected by path remapping. pub working_dir: (PathBuf, bool), - // FIXME: `lint_store` and `buffered_lints` are not thread-safe, - // but are only used in a single thread. - pub lint_store: RwLock, + /// This is intended to be used from a single thread. + /// + /// FIXME: there was a previous comment about this not being thread safe, + /// but it's not clear how or why that's the case. The LintBuffer itself is certainly thread + /// safe at least from a "Rust safety" standpoint. pub buffered_lints: Lock>, /// Set of `(DiagnosticId, Option, message)` tuples tracking @@ -1213,7 +1215,6 @@ fn build_session_( sysroot, local_crate_source_file, working_dir, - lint_store: RwLock::new(lint::LintStore::new()), buffered_lints: Lock::new(Some(Default::default())), one_time_diagnostics: Default::default(), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 256194cfb00e..a70ff37b7a04 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1035,6 +1035,8 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, + pub lint_store: Lrc, + pub dep_graph: DepGraph, pub prof: SelfProfilerRef, @@ -1199,6 +1201,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, + lint_store: Lrc, cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, @@ -1268,6 +1271,7 @@ impl<'tcx> TyCtxt<'tcx> { GlobalCtxt { sess: s, + lint_store, cstore, arena: WorkerLocal::new(|_| Arena::default()), interners, diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index aa74966d0ab4..a9e4e6db1c75 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -16,6 +16,7 @@ log = "0.4" env_logger = { version = "0.7", default-features = false } rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } +rustc_lint = { path = "../librustc_lint" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5af1e8faccc8..8793b7f5130a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -202,9 +202,13 @@ pub fn run_compiler( interface::run_compiler(config, |compiler| { let sopts = &compiler.session().opts; if sopts.describe_lints { + let lint_store = rustc_lint::new_lint_store( + sopts.debugging_opts.no_interleave_lints, + compiler.session().unstable_options(), + ); describe_lints( compiler.session(), - &*compiler.session().lint_store.borrow(), + &lint_store, false ); return; @@ -321,12 +325,14 @@ pub fn run_compiler( return sess.compile_status(); } - compiler.register_plugins()?; + { + let (_, _, lint_store) = &*compiler.register_plugins()?.peek(); - // Lint plugins are registered; now we can process command line flags. - if sess.opts.describe_lints { - describe_lints(&sess, &sess.lint_store.borrow(), true); - return sess.compile_status(); + // Lint plugins are registered; now we can process command line flags. + if sess.opts.describe_lints { + describe_lints(&sess, &lint_store, true); + return sess.compile_status(); + } } compiler.expansion()?; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2fd7b2507a78..f9efd00f6983 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -117,6 +117,7 @@ declare_box_region_type!( /// Returns `None` if we're aborting after handling -W help. pub fn configure_and_expand( sess: Lrc, + lint_store: Lrc, cstore: Lrc, krate: ast::Crate, crate_name: &str, @@ -134,6 +135,7 @@ pub fn configure_and_expand( let resolver_arenas = Resolver::arenas(); let res = configure_and_expand_inner( sess, + &lint_store, &*cstore, krate, &crate_name, @@ -227,7 +229,7 @@ pub fn register_plugins<'a>( cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, -) -> Result<(ast::Crate, PluginInfo)> { +) -> Result<(ast::Crate, PluginInfo, Lrc)> { krate = time(sess, "attributes injection", || { syntax_ext::cmdline_attrs::inject( krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr @@ -278,7 +280,12 @@ pub fn register_plugins<'a>( ) }); - let mut registry = Registry::new(sess, krate.span); + let mut lint_store = rustc_lint::new_lint_store( + sess.opts.debugging_opts.no_interleave_lints, + sess.unstable_options(), + ); + + let mut registry = Registry::new(sess, &mut lint_store, krate.span); time(sess, "plugin registration", || { for registrar in registrars { @@ -289,36 +296,20 @@ pub fn register_plugins<'a>( let Registry { syntax_exts, - early_lint_passes, - late_lint_passes, - lints, - lint_groups, llvm_passes, attributes, .. } = registry; - let mut ls = sess.lint_store.borrow_mut(); - ls.register_lints(&lints); - for pass in early_lint_passes { - ls.register_early_pass(pass); - } - for pass in late_lint_passes { - ls.register_late_pass(pass); - } - - for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(true, name, deprecated_name, to); - } - *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; *sess.plugin_attributes.borrow_mut() = attributes; - Ok((krate, PluginInfo { syntax_exts })) + Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store))) } fn configure_and_expand_inner<'a>( sess: &'a Session, + lint_store: &'a lint::LintStore, cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, @@ -329,7 +320,7 @@ fn configure_and_expand_inner<'a>( time(sess, "pre-AST-expansion lint checks", || { lint::check_ast_crate( sess, - &*sess.lint_store.borrow(), + lint_store, &krate, true, rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); @@ -539,6 +530,7 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir( sess: &Session, + lint_store: &lint::LintStore, cstore: &CStore, resolver: &mut Resolver<'_>, dep_graph: &DepGraph, @@ -559,7 +551,7 @@ pub fn lower_to_hir( time(sess, "early lint checks", || { lint::check_ast_crate( sess, - &*sess.lint_store.borrow(), + lint_store, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new(), @@ -826,6 +818,7 @@ impl BoxedGlobalCtxt { pub fn create_global_ctxt( compiler: &Compiler, + lint_store: Lrc, mut hir_forest: hir::map::Forest, defs: hir::map::Definitions, resolutions: Resolutions, @@ -863,6 +856,7 @@ pub fn create_global_ctxt( let gcx = TyCtxt::create_global_ctxt( sess, + lint_store, cstore, local_providers, extern_providers, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index cd72dc9453c7..bb1221ead98b 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,9 +2,11 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; +use rustc_data_structures::sync::Lrc; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; +use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; @@ -74,8 +76,8 @@ pub(crate) struct Queries { dep_graph_future: Query>, parse: Query, crate_name: Query, - register_plugins: Query<(ast::Crate, PluginInfo)>, - expansion: Query<(ast::Crate, Steal>>)>, + register_plugins: Query<(ast::Crate, PluginInfo, Lrc)>, + expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, lower_to_hir: Query<(Steal, ExpansionResult)>, prepare_outputs: Query, @@ -106,7 +108,7 @@ impl Compiler { }) } - pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> { + pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc)>> { self.queries.register_plugins.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); @@ -148,17 +150,20 @@ impl Compiler { pub fn expansion( &self - ) -> Result<&Query<(ast::Crate, Steal>>)>> { + ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { self.queries.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); - let (krate, plugin_info) = self.register_plugins()?.take(); + let (krate, plugin_info, lint_store) = self.register_plugins()?.take(); passes::configure_and_expand( self.sess.clone(), + lint_store.clone(), self.cstore().clone(), krate, &crate_name, plugin_info, - ).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver))))) + ).map(|(krate, resolver)| { + (krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store) + }) }) } @@ -185,9 +190,11 @@ impl Compiler { let peeked = expansion_result.peek(); let krate = &peeked.0; let resolver = peeked.1.steal(); + let lint_store = &peeked.2; let hir = Steal::new(resolver.borrow_mut().access(|resolver| { passes::lower_to_hir( self.session(), + lint_store, self.cstore(), resolver, &*self.dep_graph()?.peek(), @@ -212,11 +219,13 @@ impl Compiler { self.queries.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); + let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?; let hir = hir.peek(); let (ref hir_forest, ref expansion) = *hir; Ok(passes::create_global_ctxt( self, + lint_store, hir_forest.steal(), expansion.defs.steal(), expansion.resolutions.steal(), diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 005f1a44acd6..8f11dc937272 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -13,7 +13,6 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_errors::registry::Registry; -use rustc_lint; use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_mir; use rustc_passes; @@ -108,12 +107,6 @@ pub fn create_session( let codegen_backend = get_codegen_backend(&sess); - rustc_lint::register_builtins(&mut sess.lint_store.get_mut(), - sess.opts.debugging_opts.no_interleave_lints); - if sess.unstable_options() { - rustc_lint::register_internals(&mut sess.lint_store.get_mut()); - } - let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); add_configuration(&mut cfg, &sess, &*codegen_backend); sess.parse_sess.config = cfg; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c83074c95ca0..3c2396f6cdb0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -189,10 +189,21 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]) late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]); +pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore { + let mut lint_store = lint::LintStore::new(); + + register_builtins(&mut lint_store, no_interleave_lints); + if internal_lints { + register_internals(&mut lint_store); + } + + lint_store +} + /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { +fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { ($name:expr, $($lint:ident),*) => ( store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); @@ -327,7 +338,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } -pub fn register_internals(store: &mut lint::LintStore) { +fn register_internals(store: &mut lint::LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 44318bf06aaa..223956a4f5e3 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -1,8 +1,7 @@ //! Used by plugin crates to tell `rustc` about the plugins they provide. -use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint}; +use rustc::lint::LintStore; use rustc::session::Session; -use rustc::util::nodemap::FxHashMap; use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension}; use syntax_expand::base::MacroExpanderFn; @@ -26,6 +25,8 @@ pub struct Registry<'a> { /// from the plugin registrar. pub sess: &'a Session, + pub lint_store: &'a mut LintStore, + #[doc(hidden)] pub args_hidden: Option>, @@ -35,18 +36,6 @@ pub struct Registry<'a> { #[doc(hidden)] pub syntax_exts: Vec, - #[doc(hidden)] - pub early_lint_passes: Vec EarlyLintPassObject>, - - #[doc(hidden)] - pub late_lint_passes: Vec LateLintPassObject>, - - #[doc(hidden)] - pub lints: Vec<&'static Lint>, - - #[doc(hidden)] - pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, - #[doc(hidden)] pub llvm_passes: Vec, @@ -56,16 +45,13 @@ pub struct Registry<'a> { impl<'a> Registry<'a> { #[doc(hidden)] - pub fn new(sess: &'a Session, krate_span: Span) -> Registry<'a> { + pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> { Registry { sess, + lint_store, args_hidden: None, krate_span, syntax_exts: vec![], - lints: vec![], - early_lint_passes: vec![], - late_lint_passes: vec![], - lint_groups: FxHashMap::default(), llvm_passes: vec![], attributes: vec![], } @@ -103,32 +89,6 @@ impl<'a> Registry<'a> { self.register_syntax_extension(Symbol::intern(name), ext); } - /// Register a compiler lint pass. - pub fn register_lints(&mut self, lints: &[&'static Lint]) { - self.lints.extend(lints); - } - - /// Register a compiler lint pass. - pub fn register_early_lint_pass(&mut self, lint_pass: fn() -> EarlyLintPassObject) { - self.early_lint_passes.push(lint_pass); - } - - /// Register a compiler lint pass. - pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) { - self.late_lint_passes.push(lint_pass); - } - /// Register a lint group. - pub fn register_lint_group( - &mut self, - name: &'static str, - deprecated_name: Option<&'static str>, - to: Vec<&'static Lint> - ) { - self.lint_groups.insert(name, - (to.into_iter().map(|x| LintId::of(x)).collect(), - deprecated_name)); - } - /// Register an LLVM pass. /// /// Registration with LLVM itself is handled through static C++ objects with From b761367d52b30c86a7d404a64a3b2dd854cd7418 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 15:41:17 -0400 Subject: [PATCH 026/109] Fix test fallout --- .../auxiliary/issue-40001-plugin.rs | 7 +++--- .../auxiliary/lint-for-crate-rpass.rs | 24 +++++++++---------- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 6 ++--- .../auxiliary/lint-group-plugin-test.rs | 8 ++++--- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 6 ++--- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 8 ++++--- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index bb0ebf693d0b..6b914f501ca7 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -15,15 +15,14 @@ use syntax::symbol::Symbol; use rustc::hir; use rustc::hir::intravisit; -use rustc::hir::map as hir_map; use hir::Node; use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use rustc::ty; -use syntax::{ast, source_map}; +use syntax::source_map; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box MissingWhitelistedAttrPass); + reg.lint_store.register_lints(&[&MISSING_WHITELISTED_ATTR]); + reg.lint_store.register_late_pass(|| box MissingWhitelistedAttrPass); reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 17386d7e1aa5..6874c921c1cc 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -7,24 +7,20 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; use syntax::symbol::Symbol; macro_rules! fake_lint_pass { - ($struct:ident, $lints:expr, $($attr:expr),*) => { + ($struct:ident, $($attr:expr),*) => { struct $struct; impl LintPass for $struct { fn name(&self) -> &'static str { stringify!($struct) } - - fn get_lints(&self) -> LintArray { - $lints - } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { @@ -49,25 +45,29 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); fake_lint_pass! { PassOkay, - lint_array!(CRATE_NOT_OKAY), // Single lint Symbol::intern("rustc_crate_okay") } fake_lint_pass! { PassRedBlue, - lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") } fake_lint_pass! { PassGreyGreen, - lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") } #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box PassOkay); - reg.register_late_lint_pass(box PassRedBlue); - reg.register_late_lint_pass(box PassGreyGreen); + reg.lint_store.register_lints(&[ + &CRATE_NOT_OKAY, + &CRATE_NOT_RED, + &CRATE_NOT_BLUE, + &CRATE_NOT_GREY, + &CRATE_NOT_GREEN, + ]); + reg.lint_store.register_late_pass(|| box PassOkay); + reg.lint_store.register_late_pass(|| box PassRedBlue); + reg.lint_store.register_late_pass(|| box PassGreyGreen); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index ba5b5d1906ae..1cd3e7b28dba 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -7,7 +7,7 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; @@ -32,6 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint(&[&CRATE_NOT_OKAY]); - reg.register_late_lint_pass(|| box Pass); + reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]); + reg.lint_store.register_late_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index a377b07bd3dd..cb793b434988 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -9,7 +9,7 @@ extern crate rustc; extern crate rustc_driver; use rustc::hir; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray, LintId}; use rustc_driver::plugin::Registry; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -30,6 +30,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); - reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]); + reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]); + reg.lint_store.register_late_pass(|| box Pass); + reg.lint_store.register_group(true, "lint_me", None, + vec![LintId::of(&TEST_LINT), LintId::of(&PLEASE_LINT)]); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 02675191f785..40c37eb570e2 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -10,8 +10,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, - EarlyLintPassObject, LintArray}; +use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray}; use rustc_driver::plugin::Registry; use syntax::ast; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -28,5 +27,6 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass as EarlyLintPassObject); + reg.lint_store.register_lints(&[&TEST_LINT]); + reg.lint_store.register_early_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 40f8d490ac87..67135d595f44 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -8,7 +8,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId}; use rustc_driver::plugin::Registry; use syntax::ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); @@ -40,6 +40,8 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass); - reg.register_lint_group("clippy::group", Some("clippy_group"), vec![TEST_LINT, TEST_GROUP]); + reg.lint_store.register_lints(&[&TEST_RUSTC_TOOL_LINT, &TEST_LINT, &TEST_GROUP]); + reg.lint_store.register_early_pass(|| box Pass); + reg.lint_store.register_group(true, "clippy::group", Some("clippy_group"), + vec![LintId::of(&TEST_LINT), LintId::of(&TEST_GROUP)]); } From 6be0a7081a9aafc4e0b39cae266fbed5eabd8993 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 10 Oct 2019 19:33:00 -0400 Subject: [PATCH 027/109] Update API to be more compatible with plugin needs Move to using Box ...> so that we can let plugins register state. This also adds a callback that'll get called from plugin registration so that Clippy and other tools can register lints without using the plugin API. The plugin API still works, but this new API is more compatible with drivers other than rustc. --- src/librustc/lint/context.rs | 30 +++++++++++-------- src/librustc_driver/lib.rs | 3 ++ src/librustc_interface/interface.rs | 4 +++ src/librustc_interface/passes.rs | 3 ++ src/librustc_interface/queries.rs | 7 +++++ src/librustdoc/core.rs | 1 + src/librustdoc/test.rs | 1 + src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 8208cc26ed30..2a0cdba50cb5 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -57,11 +57,11 @@ pub struct LintStore { /// interior mutability, we don't enforce this (and lints should, in theory, /// be compatible with being constructed more than once, though not /// necessarily in a sane manner. This is safe though.) - pre_expansion_passes: Vec EarlyLintPassObject>, - early_passes: Vec EarlyLintPassObject>, - late_passes: Vec LateLintPassObject>, + pre_expansion_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + early_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + late_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// This is unique in that we construct them per-module, so not once. - late_module_passes: Vec LateLintPassObject>, + late_module_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// Lints indexed by name. by_name: FxHashMap, @@ -155,20 +155,24 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.push(pass); + pub fn register_early_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.push(pass); + pub fn register_pre_expansion_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.push(pass); + pub fn register_late_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_module_passes.push(Box::new(pass)); } // Helper method for register_early/late_pass diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8793b7f5130a..2cf1552ed968 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation { @@ -182,6 +183,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); config @@ -259,6 +261,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index b26bd75c974c..34ec3c862a3e 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -34,6 +34,7 @@ pub struct Compiler { pub(crate) queries: Queries, pub(crate) cstore: Lrc, pub(crate) crate_name: Option, + pub(crate) register_lints: Option>, } impl Compiler { @@ -80,6 +81,8 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + + pub register_lints: Option>, } pub fn run_compiler_in_existing_thread_pool(config: Config, f: F) -> R @@ -108,6 +111,7 @@ where output_file: config.output_file, queries: Default::default(), crate_name: config.crate_name, + register_lints: config.register_lints, }; let _sess_abort_error = OnDrop(|| { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index f9efd00f6983..2044b73db8aa 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -227,6 +227,7 @@ pub struct PluginInfo { pub fn register_plugins<'a>( sess: &'a Session, cstore: &'a CStore, + register_lints: impl Fn(&Session, &mut lint::LintStore), mut krate: ast::Crate, crate_name: &str, ) -> Result<(ast::Crate, PluginInfo, Lrc)> { @@ -285,6 +286,8 @@ pub fn register_plugins<'a>( sess.unstable_options(), ); + (register_lints)(&sess, &mut lint_store); + let mut registry = Registry::new(sess, &mut lint_store, krate.span); time(sess, "plugin registration", || { diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index bb1221ead98b..84648ca8326f 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -6,6 +6,8 @@ use rustc_data_structures::sync::Lrc; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; +use rustc::lint; +use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; @@ -113,9 +115,14 @@ impl Compiler { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); + let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), self.cstore(), + self.register_lints + .as_ref() + .map(|p| &**p) + .unwrap_or_else(|| empty), krate, &crate_name, ); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2a468d679a88..be6404b86976 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,6 +338,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt stderr: None, crate_name, lint_caps, + register_lints: None, }; interface::run_compiler_in_existing_thread_pool(config, |compiler| { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0be6340df96e..03e37967c4b5 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -77,6 +77,7 @@ pub fn run(options: Options) -> i32 { stderr: None, crate_name: options.crate_name.clone(), lint_caps: Default::default(), + register_lints: None, }; let mut test_args = options.test_args.clone(); diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index e290f7fa6b13..9582137eae91 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -59,6 +59,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; interface::run_compiler(config, |compiler| { From 0585475efdd1cac3a1143f4a349f3de057635efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 17 Oct 2019 13:16:24 -0700 Subject: [PATCH 028/109] Avoid ICE when checking `Destination` of `break` inside a closure --- src/librustc_typeck/check/expr.rs | 14 ++++++++++++-- src/librustc_typeck/check/mod.rs | 12 +++++++++--- src/test/ui/break-outside-loop.rs | 8 ++++++++ src/test/ui/break-outside-loop.stderr | 10 +++++++++- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index ad46a443b8ff..a8ec2c393a59 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -566,7 +566,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the `enclosing_loops` field and let's coerce the // type of `expr_opt` into what is expected. let mut enclosing_breakables = self.enclosing_breakables.borrow_mut(); - let ctxt = enclosing_breakables.find_breakable(target_id); + let ctxt = match enclosing_breakables.opt_find_breakable(target_id) { + Some(ctxt) => ctxt, + None => { // Avoid ICE when `break` is inside a closure (#65383). + self.tcx.sess.delay_span_bug( + expr.span, + "break was outside loop, but no error was emitted", + ); + return tcx.types.err; + } + }; + if let Some(ref mut coerce) = ctxt.coerce { if let Some(ref e) = expr_opt { coerce.coerce(self, &cause, e, e_ty); @@ -592,7 +602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // If `ctxt.coerce` is `None`, we can just ignore - // the type of the expresison. This is because + // the type of the expression. This is because // either this was a break *without* a value, in // which case it is always a legal type (`()`), or // else an error would have been flagged by the diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7475b9cc3b32..6943e261209a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -536,10 +536,16 @@ pub struct EnclosingBreakables<'tcx> { impl<'tcx> EnclosingBreakables<'tcx> { fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> { - let ix = *self.by_id.get(&target_id).unwrap_or_else(|| { + self.opt_find_breakable(target_id).unwrap_or_else(|| { bug!("could not find enclosing breakable with id {}", target_id); - }); - &mut self.stack[ix] + }) + } + + fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> { + match self.by_id.get(&target_id) { + Some(ix) => Some(&mut self.stack[*ix]), + None => None, + } } } diff --git a/src/test/ui/break-outside-loop.rs b/src/test/ui/break-outside-loop.rs index c424c25c646b..a6f9d0423d08 100644 --- a/src/test/ui/break-outside-loop.rs +++ b/src/test/ui/break-outside-loop.rs @@ -22,4 +22,12 @@ fn main() { let rs: Foo = Foo{t: pth}; let unconstrained = break; //~ ERROR: `break` outside of a loop + + // This used to ICE because `target_id` passed to `check_expr_break` would be the closure and + // not the `loop`, which failed in the call to `find_breakable`. (#65383) + 'lab: loop { + || { + break 'lab; //~ ERROR `break` inside of a closure + }; + } } diff --git a/src/test/ui/break-outside-loop.stderr b/src/test/ui/break-outside-loop.stderr index 8b686356055a..8e300fd848da 100644 --- a/src/test/ui/break-outside-loop.stderr +++ b/src/test/ui/break-outside-loop.stderr @@ -33,7 +33,15 @@ error[E0268]: `break` outside of a loop LL | let unconstrained = break; | ^^^^^ cannot `break` outside of a loop -error: aborting due to 5 previous errors +error[E0267]: `break` inside of a closure + --> $DIR/break-outside-loop.rs:30:13 + | +LL | || { + | -- enclosing closure +LL | break 'lab; + | ^^^^^^^^^^ cannot `break` inside of a closure + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0267, E0268. For more information about an error, try `rustc --explain E0267`. From 95d98af806f78d9cbe3975b633d5341394a155ad Mon Sep 17 00:00:00 2001 From: Lucas Henry Date: Fri, 18 Oct 2019 13:21:39 +0200 Subject: [PATCH 029/109] Added text after error messages --- .../ui/lint/unused_parens_json_suggestion.fixed | 2 +- .../ui/lint/unused_parens_json_suggestion.rs | 2 +- .../unused_parens_remove_json_suggestion.fixed | 16 ++++++++-------- .../lint/unused_parens_remove_json_suggestion.rs | 16 ++++++++-------- .../unused_parens_remove_json_suggestion.stderr | 16 ++++++++-------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/test/ui/lint/unused_parens_json_suggestion.fixed b/src/test/ui/lint/unused_parens_json_suggestion.fixed index 757ad933a1f7..15ee19755bff 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_json_suggestion.fixed @@ -13,7 +13,7 @@ fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = 1 / (2 + 3); //~ERROR + let _a = 1 / (2 + 3); //~ERROR unnecessary parentheses f(); } diff --git a/src/test/ui/lint/unused_parens_json_suggestion.rs b/src/test/ui/lint/unused_parens_json_suggestion.rs index 173cd5554502..d72df21e09ae 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_json_suggestion.rs @@ -13,7 +13,7 @@ fn main() { // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not // the malformed `1 / (2 + 3` - let _a = (1 / (2 + 3)); //~ERROR + let _a = (1 / (2 + 3)); //~ERROR unnecessary parentheses f(); } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed index 4497a159f64d..1d891d328dd5 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.fixed @@ -14,7 +14,7 @@ fn main() { let _b = false; - if _b { //~ ERROR + if _b { //~ ERROR unnecessary parentheses println!("hello"); } @@ -25,29 +25,29 @@ fn main() { fn f() -> bool { let c = false; - if c { //~ ERROR + if c { //~ ERROR unnecessary parentheses println!("next"); } - if c { //~ ERROR + if c { //~ ERROR unnecessary parentheses println!("prev"); } while false && true { - if c { //~ ERROR + if c { //~ ERROR unnecessary parentheses println!("norm"); } } - while true && false { //~ ERROR - for _ in 0 .. 3 { //~ ERROR + while true && false { //~ ERROR unnecessary parentheses + for _ in 0 .. 3 { //~ ERROR unnecessary parentheses println!("e~") } } - for _ in 0 .. 3 { //~ ERROR - while true && false { //~ ERROR + for _ in 0 .. 3 { //~ ERROR unnecessary parentheses + while true && false { //~ ERROR unnecessary parentheses println!("e~") } } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs index 22539b34bce1..494cd1845063 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.rs +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.rs @@ -14,7 +14,7 @@ fn main() { let _b = false; - if (_b) { //~ ERROR + if (_b) { //~ ERROR unnecessary parentheses println!("hello"); } @@ -25,29 +25,29 @@ fn main() { fn f() -> bool { let c = false; - if(c) { //~ ERROR + if(c) { //~ ERROR unnecessary parentheses println!("next"); } - if (c){ //~ ERROR + if (c){ //~ ERROR unnecessary parentheses println!("prev"); } while (false && true){ - if (c) { //~ ERROR + if (c) { //~ ERROR unnecessary parentheses println!("norm"); } } - while(true && false) { //~ ERROR - for _ in (0 .. 3){ //~ ERROR + while(true && false) { //~ ERROR unnecessary parentheses + for _ in (0 .. 3){ //~ ERROR unnecessary parentheses println!("e~") } } - for _ in (0 .. 3) { //~ ERROR - while (true && false) { //~ ERROR + for _ in (0 .. 3) { //~ ERROR unnecessary parentheses + while (true && false) { //~ ERROR unnecessary parentheses println!("e~") } } diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr index 6901ac09f991..873f105435e0 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -11,56 +11,56 @@ LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":607,"byte_end":610,"line_start":28,"line_end":28,"column_start":7,"column_end":10,"is_primary":true,"text":[{"text":" if(c) { +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":634,"line_start":28,"line_end":28,"column_start":7,"column_end":10,"is_primary":true,"text":[{"text":" if(c) { --> $DIR/unused_parens_remove_json_suggestion.rs:28:7 | LL | if(c) { | ^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":663,"byte_end":666,"line_start":32,"line_end":32,"column_start":8,"column_end":11,"is_primary":true,"text":[{"text":" if (c){ +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":714,"line_start":32,"line_end":32,"column_start":8,"column_end":11,"is_primary":true,"text":[{"text":" if (c){ --> $DIR/unused_parens_remove_json_suggestion.rs:32:8 | LL | if (c){ | ^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":721,"byte_end":736,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":721,"byte_end":736,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":"false && true ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":"false && true ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition --> $DIR/unused_parens_remove_json_suggestion.rs:36:11 | LL | while (false && true){ | ^^^^^^^^^^^^^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":749,"byte_end":752,"line_start":37,"line_end":37,"column_start":12,"column_end":15,"is_primary":true,"text":[{"text":" if (c) { +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":824,"line_start":37,"line_end":37,"column_start":12,"column_end":15,"is_primary":true,"text":[{"text":" if (c) { --> $DIR/unused_parens_remove_json_suggestion.rs:37:12 | LL | if (c) { | ^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":822,"byte_end":837,"line_start":43,"line_end":43,"column_start":10,"column_end":25,"is_primary":true,"text":[{"text":" while(true && false) { +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":933,"line_start":43,"line_end":43,"column_start":10,"column_end":25,"is_primary":true,"text":[{"text":" while(true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:43:10 | LL | while(true && false) { | ^^^^^^^^^^^^^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":867,"byte_end":875,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ +{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":995,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ --> $DIR/unused_parens_remove_json_suggestion.rs:44:18 | LL | for _ in (0 .. 3){ | ^^^^^^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":944,"byte_end":952,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { +{"message":"unnecessary parentheses around `for` head expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1096,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { --> $DIR/unused_parens_remove_json_suggestion.rs:49:14 | LL | for _ in (0 .. 3) { | ^^^^^^^^ help: remove these parentheses "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":979,"byte_end":994,"line_start":50,"line_end":50,"column_start":15,"column_end":30,"is_primary":true,"text":[{"text":" while (true && false) { +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1162,"line_start":50,"line_end":50,"column_start":15,"column_end":30,"is_primary":true,"text":[{"text":" while (true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:50:15 | LL | while (true && false) { From 1c85b45117ad2cb7979f8f6580be965227f9241f Mon Sep 17 00:00:00 2001 From: BO41 Date: Fri, 18 Oct 2019 16:55:08 +0000 Subject: [PATCH 030/109] Apply suggested wording to better describe the situation --- CONTRIBUTING.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index caf003d183af..add4338771e4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,8 +130,10 @@ Also, please make sure that fixup commits are squashed into other related commits with meaningful commit messages. GitHub allows [closing issues using keywords][closing-keywords]. This feature -should be used to keep the issue tracker tidy. But in pull requests only. Please -do not add this to your commit message. +should be used to keep the issue tracker tidy. However, it is generally preferred +to put the "closes #123" text in the PR description rather than the issue commit; +particularly during rebasing, citing the issue number in the commit can "spam" +the issue in question. [closing-keywords]: https://help.github.com/en/articles/closing-issues-using-keywords From 7e17ea37b72efd42153604a28977a8482ceef6f8 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Sat, 19 Oct 2019 16:02:21 +0200 Subject: [PATCH 031/109] Fix test paths --- .../coherence/impl[t]-foreign-for-(local, t).rs | 17 ----------------- .../impl[t]-foreign-for-(local, t).stderr | 12 ------------ 2 files changed, 29 deletions(-) delete mode 100644 src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs delete mode 100644 src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr diff --git a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs deleted file mode 100644 index 850b6f85d0ed..000000000000 --- a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(re_rebalance_coherence)] - -// compile-flags:--crate-name=test -// aux-build:coherence_lib.rs - -extern crate coherence_lib as lib; -use lib::*; -use std::rc::Rc; - -struct Local; - -impl Remote for (Local, T) { - //~^ ERROR only traits defined in the current crate - // | can be implemented for arbitrary types [E0117] -} - -fn main() {} diff --git a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr b/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr deleted file mode 100644 index ff0b9d6d0da9..000000000000 --- a/src/test/ui/coherence/impl[t]-foreign-for-(local, t).stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/impl[t]-foreign-for-(local, t).rs:12:1 - | -LL | impl Remote for (Local, T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate - | - = note: the impl does not reference only types defined in this crate - = note: define and implement a trait or new type instead - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0117`. From 1e2b711d308be714e6211c125b1a33ac1247f866 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sun, 20 Oct 2019 06:31:27 +0000 Subject: [PATCH 032/109] fix WASI sleep impl --- src/libstd/sys/wasi/thread.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs index 28a504f19797..6ce41420284e 100644 --- a/src/libstd/sys/wasi/thread.rs +++ b/src/libstd/sys/wasi/thread.rs @@ -31,10 +31,10 @@ impl Thread { let nanos = dur.as_nanos(); assert!(nanos <= u64::max_value() as u128); - const CLOCK_ID: wasi::Userdata = 0x0123_45678; + const USERDATA: wasi::Userdata = 0x0123_45678; let clock = wasi::raw::__wasi_subscription_u_clock_t { - identifier: CLOCK_ID, + identifier: 0, clock_id: wasi::CLOCK_MONOTONIC, timeout: nanos as u64, precision: 0, @@ -42,7 +42,7 @@ impl Thread { }; let in_ = [wasi::Subscription { - userdata: 0, + userdata: USERDATA, type_: wasi::EVENTTYPE_CLOCK, u: wasi::raw::__wasi_subscription_u { clock: clock }, }]; @@ -53,7 +53,7 @@ impl Thread { }; match (res, event) { (Ok(1), wasi::Event { - userdata: CLOCK_ID, + userdata: USERDATA, error: 0, type_: wasi::EVENTTYPE_CLOCK, .. From 429f91c9e68d6c15f7a6cedb3c8e9e300fa71da1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 19 Oct 2019 11:21:52 +0200 Subject: [PATCH 033/109] Add long error explanation for E0588 --- src/librustc_typeck/error_codes.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index ef08e8d4f0b7..892919cbf207 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -3891,6 +3891,33 @@ details. [issue #33685]: https://github.com/rust-lang/rust/issues/33685 "##, +E0588: r##" +A type with `packed` representation hint has a field with `align` +representation hint. + +Erroneous code example: + +```compile_fail,E0588 +#[repr(align(16))] +struct Aligned(i32); + +#[repr(packed)] // error! +struct Packed(Aligned); +``` + +Just like you can't have both `align` and `packed` representation hints on a +same type, a `packed` type can't contain another type with the `align` +representation hint. However, you can do the opposite: + +``` +#[repr(packed)] +struct Packed(i32); + +#[repr(align(16))] // ok! +struct Aligned(Packed); +``` +"##, + E0592: r##" This error occurs when you defined methods or associated functions with same name. @@ -5043,7 +5070,6 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC. // E0564, // only named lifetimes are allowed in `impl Trait`, // but `{}` was found in the type `{}` E0587, // type has conflicting packed and align representation hints - E0588, // packed type cannot transitively contain a `[repr(align)]` type // E0611, // merged into E0616 // E0612, // merged into E0609 // E0613, // Removed (merged with E0609) From 2541d49601ad4fd311d28d9ae7a7ce947879d839 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 19 Oct 2019 11:22:17 +0200 Subject: [PATCH 034/109] Update ui tests --- src/test/ui/repr/repr-packed-contains-align.stderr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/repr/repr-packed-contains-align.stderr b/src/test/ui/repr/repr-packed-contains-align.stderr index 219516d8abc4..df001d6b5f2a 100644 --- a/src/test/ui/repr/repr-packed-contains-align.stderr +++ b/src/test/ui/repr/repr-packed-contains-align.stderr @@ -56,3 +56,4 @@ LL | | } error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0588`. From c290293cf291951825b10830df4bce3bc03aabef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Oct 2019 10:33:16 +1100 Subject: [PATCH 035/109] Derive `Rustc{En,De}codable` for `TokenStream`. `TokenStream` used to be a complex type, but it is now just a newtype around a `Lrc>`. Currently it uses custom encoding that discards the `IsJoint` and custom decoding that adds `NonJoint` back in for every token tree. This requires building intermediate `Vec`s. This commit makes `TokenStream` derive `Rustc{En,De}codable`. This simplifies the code, and avoids the creation of the intermediate vectors, saving up to 3% on various benchmarks. It also changes the AST JSON output in one test. --- src/libsyntax/tokenstream.rs | 17 ++--------------- src/test/ui/ast-json/ast-json-output.stdout | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index ac155556cdae..0559f224f1f4 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -19,7 +19,6 @@ use syntax_pos::{BytePos, Span, DUMMY_SP}; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; use rustc_data_structures::sync::Lrc; -use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use smallvec::{SmallVec, smallvec}; use std::{iter, mem}; @@ -136,7 +135,7 @@ impl TokenTree { /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s /// instead of a representation of the abstract syntax tree. /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, RustcEncodable, RustcDecodable)] pub struct TokenStream(pub Lrc>); pub type TreeAndJoint = (TokenTree, IsJoint); @@ -145,7 +144,7 @@ pub type TreeAndJoint = (TokenTree, IsJoint); #[cfg(target_arch = "x86_64")] static_assert_size!(TokenStream, 8); -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)] pub enum IsJoint { Joint, NonJoint @@ -460,18 +459,6 @@ impl Cursor { } } -impl Encodable for TokenStream { - fn encode(&self, encoder: &mut E) -> Result<(), E::Error> { - self.trees().collect::>().encode(encoder) - } -} - -impl Decodable for TokenStream { - fn decode(decoder: &mut D) -> Result { - Vec::::decode(decoder).map(|vec| vec.into_iter().collect()) - } -} - #[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] pub struct DelimSpan { pub open: Span, diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout index 563885133a4c..64c9f6931158 100644 --- a/src/test/ui/ast-json/ast-json-output.stdout +++ b/src/test/ui/ast-json/ast-json-output.stdout @@ -1 +1 @@ -{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"kind":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]}]}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}} +{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"kind":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}} From 02edd14cde7d07a303ed2e7d2b233890f02033c1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Oct 2019 13:22:50 +1100 Subject: [PATCH 036/109] Convert some `InternedString`s to `Symbols`. This avoids the needs for various conversions, and makes the code slightly faster, because `Symbol` comparisons and hashing is faster. --- src/librustc/hir/mod.rs | 6 ++-- src/librustc/infer/mod.rs | 4 +-- src/librustc/infer/type_variable.rs | 4 +-- src/librustc/infer/unify_key.rs | 4 +-- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/object_safety.rs | 4 +-- src/librustc/traits/on_unimplemented.rs | 4 +-- src/librustc/traits/structural_impls.rs | 10 +++---- src/librustc/ty/context.rs | 8 +++--- src/librustc/ty/mod.rs | 4 +-- src/librustc/ty/print/pretty.rs | 28 +++++++++---------- src/librustc/ty/sty.rs | 18 ++++++------ .../debuginfo/metadata.rs | 4 +-- src/librustc_codegen_llvm/debuginfo/mod.rs | 4 +-- .../error_reporting/region_name.rs | 14 +++++----- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_typeck/astconv.rs | 6 ++-- src/librustc_typeck/check/intrinsic.rs | 6 ++-- src/librustc_typeck/collect.rs | 18 ++++++------ src/librustdoc/clean/mod.rs | 2 +- 21 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 568e051aaf08..cd111ab9f949 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -19,7 +19,7 @@ use crate::ty::query::Providers; use crate::util::nodemap::{NodeMap, FxHashSet}; use errors::FatalError; -use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan}; +use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax::source_map::Spanned; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect}; use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy}; @@ -628,9 +628,9 @@ impl Generics { own_counts } - pub fn get_named(&self, name: InternedString) -> Option<&GenericParam> { + pub fn get_named(&self, name: Symbol) -> Option<&GenericParam> { for param in &self.params { - if name == param.name.ident().as_interned_str() { + if name == param.name.ident().name { return Some(param); } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index af74d1357243..61e49d32fcdd 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -32,7 +32,7 @@ use std::cell::{Cell, Ref, RefCell, RefMut}; use std::collections::BTreeMap; use std::fmt; use syntax::ast; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use syntax_pos::Span; use self::combine::CombineFields; @@ -392,7 +392,7 @@ pub enum RegionVariableOrigin { Coercion(Span), /// Region variables created as the values for early-bound regions - EarlyBoundRegion(Span, InternedString), + EarlyBoundRegion(Span, Symbol), /// Region variables created for bound regions /// in a function or method that is called diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index ce1b54bb1c81..f79a30c7ae8f 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -1,4 +1,4 @@ -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use syntax_pos::Span; use crate::ty::{self, Ty, TyVid}; @@ -49,7 +49,7 @@ pub enum TypeVariableOriginKind { MiscVariable, NormalizeProjectionType, TypeInference, - TypeParameterDefinition(InternedString), + TypeParameterDefinition(Symbol), /// One of the upvars or closure kind parameters in a `ClosureSubsts` /// (before it has been determined). diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index 846611db0542..b0b6d971c608 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -3,7 +3,7 @@ use crate::mir::interpret::ConstValue; use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable}; use rustc_data_structures::unify::InPlace; use syntax_pos::{Span, DUMMY_SP}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use std::cmp; use std::marker::PhantomData; @@ -90,7 +90,7 @@ pub struct ConstVariableOrigin { pub enum ConstVariableOriginKind { MiscVariable, ConstInference, - ConstParameterDefinition(InternedString), + ConstParameterDefinition(Symbol), SubstitutionPlaceholder, } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index daa4a215a238..ae604b9eb13a 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -406,7 +406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }, GenericParamDefKind::Lifetime => continue, }; - let name = param.name.as_symbol(); + let name = param.name; flags.push((name, Some(value))); } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index e0ef179911b6..e42c3a63541c 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -19,7 +19,7 @@ use crate::ty::subst::{Subst, InternalSubsts}; use std::borrow::Cow; use std::iter::{self}; use syntax::ast::{self}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -560,7 +560,7 @@ impl<'tcx> TyCtxt<'tcx> { // are implemented let unsized_self_ty: Ty<'tcx> = self.mk_ty_param( ::std::u32::MAX, - InternedString::intern("RustaceansAreAwesome"), + Symbol::intern("RustaceansAreAwesome"), ); // `Receiver[Self => U]` diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 5a988d9509e8..c1c814f9b037 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -250,7 +250,7 @@ impl<'tcx> OnUnimplementedFormatString { Position::ArgumentNamed(s) if s == sym::from_desugaring => (), // So is `{A}` if A is a type parameter Position::ArgumentNamed(s) => match generics.params.iter().find(|param| { - param.name.as_symbol() == s + param.name == s }) { Some(_) => (), None => { @@ -289,7 +289,7 @@ impl<'tcx> OnUnimplementedFormatString { }, GenericParamDefKind::Lifetime => return None }; - let name = param.name.as_symbol(); + let name = param.name; Some((name, value)) }).collect::>(); let empty_string = String::new(); diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index dab62a6bcb5b..2a53dcab8a9f 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -4,7 +4,7 @@ use crate::traits; use crate::traits::project::Normalized; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::{self, Lift, Ty, TyCtxt}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use std::fmt; use std::rc::Rc; @@ -261,11 +261,11 @@ impl fmt::Display for traits::QuantifierKind { /// for debug output in tests anyway. struct BoundNamesCollector { // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. - regions: BTreeSet, + regions: BTreeSet, // Sort by `BoundVar` index, so usually this should be equivalent to the order given // by the list of type parameters. - types: BTreeMap, + types: BTreeMap, binder_index: ty::DebruijnIndex, } @@ -319,7 +319,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { match bound_ty.kind { ty::BoundTyKind::Param(name) => name, ty::BoundTyKind::Anon => - InternedString::intern(&format!("^{}", bound_ty.var.as_u32()), + Symbol::intern(&format!("^{}", bound_ty.var.as_u32()), ), } ); @@ -340,7 +340,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { } ty::BoundRegion::BrAnon(var) => { - self.regions.insert(InternedString::intern(&format!("'^{}", var))); + self.regions.insert(Symbol::intern(&format!("'^{}", var))); } _ => (), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 665d4c2d0696..d34e8d687208 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -72,7 +72,7 @@ use syntax::ast; use syntax::attr; use syntax::source_map::MultiSpan; use syntax::feature_gate; -use syntax::symbol::{Symbol, InternedString, kw, sym}; +use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::Span; pub struct AllArenas { @@ -949,7 +949,7 @@ impl<'tcx> CommonTypes<'tcx> { f64: mk(Float(ast::FloatTy::F64)), self_param: mk(ty::Param(ty::ParamTy { index: 0, - name: kw::SelfUpper.as_interned_str(), + name: kw::SelfUpper, })), trait_object_dummy_self: mk(Infer(ty::FreshTy(0))), @@ -2552,7 +2552,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_ty_param(self, index: u32, name: InternedString) -> Ty<'tcx> { + pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> { self.mk_ty(Param(ParamTy { index, name: name })) } @@ -2560,7 +2560,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_const_param( self, index: u32, - name: InternedString, + name: Symbol, ty: Ty<'tcx> ) -> &'tcx Const<'tcx> { self.mk_const(ty::Const { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d46ab3769ad5..9703ed838532 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -849,7 +849,7 @@ impl ty::EarlyBoundRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). pub fn has_name(&self) -> bool { - self.name != kw::UnderscoreLifetime.as_interned_str() + self.name != kw::UnderscoreLifetime } } @@ -866,7 +866,7 @@ pub enum GenericParamDefKind { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct GenericParamDef { - pub name: InternedString, + pub name: Symbol, pub def_id: DefId, pub index: u32, diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 363109a0582d..f1042813e5ea 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -14,7 +14,7 @@ use rustc_apfloat::Float; use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr::{SignedInt, UnsignedInt}; -use syntax::symbol::{kw, InternedString}; +use syntax::symbol::{kw, Symbol}; use std::cell::Cell; use std::fmt::{self, Write as _}; @@ -992,7 +992,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> { empty_path: bool, in_value: bool, - used_region_names: FxHashSet, + used_region_names: FxHashSet, region_index: usize, binder_depth: usize, @@ -1332,16 +1332,16 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { match *region { ty::ReEarlyBound(ref data) => { - data.name.as_symbol() != kw::Invalid && - data.name.as_symbol() != kw::UnderscoreLifetime + data.name != kw::Invalid && + data.name != kw::UnderscoreLifetime } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name.as_symbol() != kw::Invalid && - name.as_symbol() != kw::UnderscoreLifetime { + if name != kw::Invalid && + name != kw::UnderscoreLifetime { return true; } } @@ -1397,7 +1397,7 @@ impl FmtPrinter<'_, '_, F> { // `explain_region()` or `note_and_explain_region()`. match *region { ty::ReEarlyBound(ref data) => { - if data.name.as_symbol() != kw::Invalid { + if data.name != kw::Invalid { p!(write("{}", data.name)); return Ok(self); } @@ -1406,8 +1406,8 @@ impl FmtPrinter<'_, '_, F> { ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name.as_symbol() != kw::Invalid && - name.as_symbol() != kw::UnderscoreLifetime { + if name != kw::Invalid && + name != kw::UnderscoreLifetime { p!(write("{}", name)); return Ok(self); } @@ -1474,11 +1474,11 @@ impl FmtPrinter<'_, 'tcx, F> { where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { - fn name_by_region_index(index: usize) -> InternedString { + fn name_by_region_index(index: usize) -> Symbol { match index { - 0 => InternedString::intern("'r"), - 1 => InternedString::intern("'s"), - i => InternedString::intern(&format!("'t{}", i-2)), + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), } } @@ -1541,7 +1541,7 @@ impl FmtPrinter<'_, 'tcx, F> { where T: TypeFoldable<'tcx> { - struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); + struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 4af73fa389a7..f4de0cd7b6b1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -24,7 +24,7 @@ use std::marker::PhantomData; use std::ops::Range; use rustc_target::spec::abi; use syntax::ast::{self, Ident}; -use syntax::symbol::{kw, InternedString}; +use syntax::symbol::{kw, Symbol}; use self::InferTy::*; use self::TyKind::*; @@ -55,7 +55,7 @@ pub enum BoundRegion { /// /// The `DefId` is needed to distinguish free regions in /// the event of shadowing. - BrNamed(DefId, InternedString), + BrNamed(DefId, Symbol), /// Anonymous region for the implicit env pointer parameter /// to a closure @@ -1123,16 +1123,16 @@ pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder>>; Hash, RustcEncodable, RustcDecodable, HashStable)] pub struct ParamTy { pub index: u32, - pub name: InternedString, + pub name: Symbol, } impl<'tcx> ParamTy { - pub fn new(index: u32, name: InternedString) -> ParamTy { + pub fn new(index: u32, name: Symbol) -> ParamTy { ParamTy { index, name: name } } pub fn for_self() -> ParamTy { - ParamTy::new(0, kw::SelfUpper.as_interned_str()) + ParamTy::new(0, kw::SelfUpper) } pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { @@ -1148,11 +1148,11 @@ impl<'tcx> ParamTy { Eq, PartialEq, Ord, PartialOrd, HashStable)] pub struct ParamConst { pub index: u32, - pub name: InternedString, + pub name: Symbol, } impl<'tcx> ParamConst { - pub fn new(index: u32, name: InternedString) -> ParamConst { + pub fn new(index: u32, name: Symbol) -> ParamConst { ParamConst { index, name } } @@ -1325,7 +1325,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {} pub struct EarlyBoundRegion { pub def_id: DefId, pub index: u32, - pub name: InternedString, + pub name: Symbol, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] @@ -1389,7 +1389,7 @@ pub struct BoundTy { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum BoundTyKind { Anon, - Param(InternedString), + Param(Symbol), } impl_stable_hash_for!(struct BoundTy { var, kind }); diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 438a660b8a86..d0bfbe051483 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -46,7 +46,7 @@ use std::iter; use std::ptr; use std::path::{Path, PathBuf}; use syntax::ast; -use syntax::symbol::{Interner, InternedString}; +use syntax::symbol::{Interner, Symbol}; use syntax_pos::{self, Span, FileName}; impl PartialEq for llvm::Metadata { @@ -2127,7 +2127,7 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&' fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) - -> Vec { + -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_parameter_names(cx, cx.tcx.generics_of(def_id)) }); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 6e4ed42c45e9..5b59f4c28de2 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -36,7 +36,7 @@ use std::ffi::{CStr, CString}; use syntax_pos::{self, Span, Pos}; use syntax::ast; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc_codegen_ssa::traits::*; @@ -490,7 +490,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) - -> Vec { + -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_parameter_names(cx, cx.tcx.generics_of(def_id)) }); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 6fb976e0d84b..d6e84940291a 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -18,14 +18,14 @@ use rustc::ty::print::RegionHighlightMode; use rustc_errors::DiagnosticBuilder; use syntax::symbol::kw; use rustc_data_structures::fx::FxHashMap; -use syntax_pos::{Span, symbol::InternedString}; +use syntax_pos::{Span, symbol::Symbol}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. #[derive(Debug, Clone)] crate struct RegionName { /// The name of the region (interned). - crate name: InternedString, + crate name: Symbol, /// Where the region comes from. crate source: RegionNameSource, } @@ -109,7 +109,7 @@ impl RegionName { } #[allow(dead_code)] - crate fn name(&self) -> InternedString { + crate fn name(&self) -> Symbol { self.name } @@ -273,7 +273,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } ty::ReStatic => Some(RegionName { - name: kw::StaticLifetime.as_interned_str(), + name: kw::StaticLifetime, source: RegionNameSource::Static }), @@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, tcx: TyCtxt<'tcx>, error_region: &RegionKind, - name: InternedString, + name: Symbol, ) -> Span { let scope = error_region.free_region_binding_scope(tcx); let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); @@ -837,10 +837,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Creates a synthetic region named `'1`, incrementing the counter. - fn synthesize_region_name(&self, renctx: &mut RegionErrorNamingCtx) -> InternedString { + fn synthesize_region_name(&self, renctx: &mut RegionErrorNamingCtx) -> Symbol { let c = renctx.counter; renctx.counter += 1; - InternedString::intern(&format!("'{:?}", c)) + Symbol::intern(&format!("'{:?}", c)) } } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 5f6951856434..b39aa483a6a6 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -790,7 +790,7 @@ fn for_each_late_bound_region_defined_on<'tcx>( owner: fn_def_id.index, local_id: *late_bound, }; - let name = tcx.hir().name(hir_id).as_interned_str(); + let name = tcx.hir().name(hir_id); let region_def_id = tcx.hir().local_def_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e6f7a042f1c2..7bb96661bb74 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -908,7 +908,7 @@ fn convert_path_expr<'a, 'tcx>( let generics = cx.tcx.generics_of(item_def_id); let local_def_id = cx.tcx.hir().local_def_id(hir_id); let index = generics.param_def_id_to_index[&local_def_id]; - let name = cx.tcx.hir().name(hir_id).as_interned_str(); + let name = cx.tcx.hir().name(hir_id); let val = ConstValue::Param(ty::ParamConst::new(index, name)); ExprKind::Literal { literal: cx.tcx.mk_const( diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7e0a9bc4011c..f2502ab3648f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -131,7 +131,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { let tcx = self.tcx(); let lifetime_name = |def_id| { - tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap()).as_interned_str() + tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap()) }; let r = match tcx.named_region(lifetime.hir_id) { @@ -2023,7 +2023,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let item_def_id = tcx.hir().local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - tcx.mk_ty_param(index, tcx.hir().name(hir_id).as_interned_str()) + tcx.mk_ty_param(index, tcx.hir().name(hir_id)) } Res::SelfTy(Some(_), None) => { // `Self` in trait or type alias. @@ -2204,7 +2204,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let item_def_id = tcx.hir().local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)]; - let name = tcx.hir().name(hir_id).as_interned_str(); + let name = tcx.hir().name(hir_id); const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index aeb2c40e2ef8..72a0fe887b96 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -7,7 +7,7 @@ use rustc::ty::subst::Subst; use crate::require_same_types; use rustc_target::spec::abi::Abi; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::hir; @@ -80,7 +80,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs, /// and in libcore/intrinsics.rs pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { - let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n))); + let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); let name = it.ident.as_str(); let mk_va_list_ty = |mutbl| { @@ -387,7 +387,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { /// Type-check `extern "platform-intrinsic" { ... }` functions. pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { let param = |n| { - let name = InternedString::intern(&format!("P{}", n)); + let name = Symbol::intern(&format!("P{}", n)); tcx.mk_ty_param(n, name) }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1749fd1075e0..d4c64512f984 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -36,7 +36,7 @@ use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used}; use syntax::feature_gate; -use syntax::symbol::{InternedString, kw, Symbol, sym}; +use syntax::symbol::{kw, Symbol, sym}; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::def::{CtorKind, Res, DefKind}; @@ -265,7 +265,7 @@ fn type_param_predicates( let param_owner_def_id = tcx.hir().local_def_id(param_owner); let generics = tcx.generics_of(param_owner_def_id); let index = generics.param_def_id_to_index[&def_id]; - let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str()); + let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id)); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner_def_id { @@ -961,7 +961,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { opt_self = Some(ty::GenericParamDef { index: 0, - name: kw::SelfUpper.as_interned_str(), + name: kw::SelfUpper, def_id: tcx.hir().local_def_id(param_id), pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -1006,7 +1006,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { early_lifetimes .enumerate() .map(|(i, param)| ty::GenericParamDef { - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, index: own_start + i as u32, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, @@ -1060,7 +1060,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { let param_def = ty::GenericParamDef { index: type_start + i as u32, - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind, @@ -1090,7 +1090,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { .enumerate() .map(|(i, &arg)| ty::GenericParamDef { index: type_start + i as u32, - name: InternedString::intern(arg), + name: Symbol::intern(arg), def_id, pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -1105,7 +1105,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { params.extend(upvars.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| { ty::GenericParamDef { index: type_start + i, - name: InternedString::intern(""), + name: Symbol::intern(""), def_id, pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -2198,7 +2198,7 @@ fn explicit_predicates_of( let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: tcx.hir().local_def_id(param.hir_id), index, - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, })); index += 1; @@ -2221,7 +2221,7 @@ fn explicit_predicates_of( // type parameter (e.g., ``). for param in &ast_generics.params { if let GenericParamKind::Type { .. } = param.kind { - let name = param.name.ident().as_interned_str(); + let name = param.name.ident().name; let param_ty = ty::ParamTy::new(index, name).to_ty(tcx); index += 1; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c355f661410e..3f8fca53cd42 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1682,7 +1682,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime => None, ty::GenericParamDefKind::Type { synthetic, .. } => { - if param.name.as_symbol() == kw::SelfUpper { + if param.name == kw::SelfUpper { assert_eq!(param.index, 0); return None; } From c325553a30ec0de8e156c28533e55ddee71013f0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Oct 2019 15:01:51 +1100 Subject: [PATCH 037/109] Convert `InternedString`s to `Symbols` in `UnsafetyViolation`. --- src/librustc/mir/mod.rs | 6 ++--- src/librustc_mir/transform/check_unsafety.rs | 27 ++++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9ac1465cb0ba..b0830fb72eb0 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -37,7 +37,7 @@ use std::slice; use std::vec::IntoIter; use std::{iter, mem, option, u32}; use syntax::ast::Name; -use syntax::symbol::{InternedString, Symbol}; +use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; pub use crate::mir::interpret::AssertMessage; @@ -2736,8 +2736,8 @@ pub enum UnsafetyViolationKind { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)] pub struct UnsafetyViolation { pub source_info: SourceInfo, - pub description: InternedString, - pub details: InternedString, + pub description: Symbol, + pub details: Symbol, pub kind: UnsafetyViolationKind, } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 70855d70228b..3ff36e01275b 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -12,7 +12,7 @@ use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSA use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext}; -use syntax::symbol::{InternedString, sym}; +use syntax::symbol::{Symbol, sym}; use std::ops::Bound; @@ -167,9 +167,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { (CastTy::FnPtr, CastTy::Int(_)) => { self.register_violations(&[UnsafetyViolation { source_info: self.source_info, - description: InternedString::intern("cast of pointer to int"), - details: InternedString::intern( - "casting pointers to integers in constants"), + description: Symbol::intern("cast of pointer to int"), + details: Symbol::intern("casting pointers to integers in constants"), kind: UnsafetyViolationKind::General, }], &[]); }, @@ -185,8 +184,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind { self.register_violations(&[UnsafetyViolation { source_info: self.source_info, - description: InternedString::intern("pointer operation"), - details: InternedString::intern("operations on pointers in constants"), + description: Symbol::intern("pointer operation"), + details: Symbol::intern("operations on pointers in constants"), kind: UnsafetyViolationKind::General, }], &[]); } @@ -219,8 +218,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_scope_local_data[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern("use of extern static"), - details: InternedString::intern( + description: Symbol::intern("use of extern static"), + details: Symbol::intern( "extern statics are not controlled by the Rust type system: \ invalid data, aliasing violations or data races will cause \ undefined behavior"), @@ -240,8 +239,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_scope_local_data[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern("borrow of packed field"), - details: InternedString::intern( + description: Symbol::intern("borrow of packed field"), + details: Symbol::intern( "fields of packed structs might be misaligned: dereferencing a \ misaligned pointer or even just creating a misaligned reference \ is undefined behavior"), @@ -334,8 +333,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { let source_info = self.source_info; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern(description), - details: InternedString::intern(details), + description: Symbol::intern(description), + details: Symbol::intern(details), kind, }], &[]); } @@ -438,8 +437,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { let source_info = self.source_info; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern(description), - details: InternedString::intern(details), + description: Symbol::intern(description), + details: Symbol::intern(details), kind: UnsafetyViolationKind::GeneralAndConstFn, }], &[]); } From 78c342730840248a98d81f7cc10b06c69831751b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 20 Oct 2019 09:59:26 +1100 Subject: [PATCH 038/109] Remove unnecessary `impl Clean for InternedString`. --- src/librustdoc/clean/mod.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3f8fca53cd42..b84540d899ee 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -31,7 +31,6 @@ use syntax::attr; use syntax_expand::base::MacroKind; use syntax::source_map::DUMMY_SP; use syntax::symbol::{Symbol, kw, sym}; -use syntax::symbol::InternedString; use syntax_pos::{self, Pos, FileName}; use std::collections::hash_map::Entry; @@ -3701,13 +3700,6 @@ impl Clean for ast::Name { } } -impl Clean for InternedString { - #[inline] - fn clean(&self, _: &DocContext<'_>) -> String { - self.to_string() - } -} - #[derive(Clone, Debug)] pub struct Typedef { pub type_: Type, From ddc1c279753897021ae81c6c75f04f510b11740d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Sep 2019 13:57:43 +1000 Subject: [PATCH 039/109] Eliminate `intersect_opt`. Its fourth argument is always `Some(pred)`, so the pattern matching is unnecessary. This commit inlines and removes it. --- .../graph/dominators/mod.rs | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 29a8a98d229c..444463c08e55 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -17,7 +17,7 @@ pub fn dominators(graph: &G) -> Dominators { dominators_given_rpo(graph, &rpo) } -pub fn dominators_given_rpo( +fn dominators_given_rpo( graph: &G, rpo: &[G::Node], ) -> Dominators { @@ -43,14 +43,12 @@ pub fn dominators_given_rpo( let mut new_idom = None; for pred in graph.predecessors(node) { if immediate_dominators[pred].is_some() { - // (*) // (*) dominators for `pred` have been calculated - new_idom = intersect_opt( - &post_order_rank, - &immediate_dominators, - new_idom, - Some(pred), - ); + new_idom = Some(if let Some(new_idom) = new_idom { + intersect(&post_order_rank, &immediate_dominators, new_idom, pred) + } else { + pred + }); } } @@ -67,19 +65,6 @@ pub fn dominators_given_rpo( } } -fn intersect_opt( - post_order_rank: &IndexVec, - immediate_dominators: &IndexVec>, - node1: Option, - node2: Option, -) -> Option { - match (node1, node2) { - (None, None) => None, - (Some(n), None) | (None, Some(n)) => Some(n), - (Some(n1), Some(n2)) => Some(intersect(post_order_rank, immediate_dominators, n1, n2)), - } -} - fn intersect( post_order_rank: &IndexVec, immediate_dominators: &IndexVec>, From b8214e9b44a5796749a70d7806e575412333e27c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 14:25:08 +1100 Subject: [PATCH 040/109] Convert fields within `DefPathData` from `InternedString` to `Symbol`. It's a full conversion, except in `DefKey::compute_stable_hash()` where a `Symbol` now is converted to an `InternedString` before being hashed. This was necessary to avoid test failures. --- src/librustc/hir/lowering.rs | 8 ++-- src/librustc/hir/map/def_collector.rs | 29 ++++++------ src/librustc/hir/map/definitions.rs | 44 +++++++++---------- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/lint/context.rs | 2 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/print/obsolete.rs | 4 +- src/librustc/ty/print/pretty.rs | 6 +-- .../debuginfo/namespace.rs | 2 +- .../debuginfo/type_names.rs | 2 +- .../symbol_names/legacy.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 9 ++-- .../interpret/intrinsics/type_name.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- src/librustc_resolve/build_reduced_graph.rs | 4 +- 16 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d5287fd415b7..7971c33426b2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -792,15 +792,15 @@ impl<'a> LoweringContext<'a> { // really show up for end-user. let (str_name, kind) = match hir_name { ParamName::Plain(ident) => ( - ident.as_interned_str(), + ident.name, hir::LifetimeParamKind::InBand, ), ParamName::Fresh(_) => ( - kw::UnderscoreLifetime.as_interned_str(), + kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided, ), ParamName::Error => ( - kw::UnderscoreLifetime.as_interned_str(), + kw::UnderscoreLifetime, hir::LifetimeParamKind::Error, ), }; @@ -1590,7 +1590,7 @@ impl<'a> LoweringContext<'a> { self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, - DefPathData::LifetimeNs(name.ident().as_interned_str()), + DefPathData::LifetimeNs(name.ident().name), ExpnId::root(), lifetime.span); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 9be339be7034..7c8fdcc8b12e 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -57,7 +57,7 @@ impl<'a> DefCollector<'a> { // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. - let fn_def_data = DefPathData::ValueNs(name.as_interned_str()); + let fn_def_data = DefPathData::ValueNs(name); let fn_def = self.create_def(id, fn_def_data, span); return self.with_parent(fn_def, |this| { this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); @@ -83,8 +83,7 @@ impl<'a> DefCollector<'a> { .unwrap_or_else(|| { let node_id = NodeId::placeholder_from_expn_id(self.expansion); sym::integer(self.definitions.placeholder_field_indices[&node_id]) - }) - .as_interned_str(); + }); let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); self.with_parent(def, |this| visit::walk_struct_field(this, field)); } @@ -109,7 +108,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | - ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.as_interned_str()), + ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), ItemKind::Fn( ref decl, ref header, @@ -127,8 +126,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ) } ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => - DefPathData::ValueNs(i.ident.as_interned_str()), - ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()), + DefPathData::ValueNs(i.ident.name), + ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name), ItemKind::Mac(..) => return self.visit_macro_invoc(i.id), ItemKind::GlobalAsm(..) => DefPathData::Misc, ItemKind::Use(..) => { @@ -162,7 +161,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } let def = self.create_def(foreign_item.id, - DefPathData::ValueNs(foreign_item.ident.as_interned_str()), + DefPathData::ValueNs(foreign_item.ident.name), foreign_item.span); self.with_parent(def, |this| { @@ -175,7 +174,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { return self.visit_macro_invoc(v.id); } let def = self.create_def(v.id, - DefPathData::TypeNs(v.ident.as_interned_str()), + DefPathData::TypeNs(v.ident.name), v.span); self.with_parent(def, |this| { if let Some(ctor_hir_id) = v.data.ctor_id() { @@ -202,7 +201,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { self.visit_macro_invoc(param.id); return; } - let name = param.ident.as_interned_str(); + let name = param.ident.name; let def_path_data = match param.kind { GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name), GenericParamKind::Type { .. } => DefPathData::TypeNs(name), @@ -216,9 +215,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_trait_item(&mut self, ti: &'a TraitItem) { let def_data = match ti.kind { TraitItemKind::Method(..) | TraitItemKind::Const(..) => - DefPathData::ValueNs(ti.ident.as_interned_str()), + DefPathData::ValueNs(ti.ident.name), TraitItemKind::Type(..) => { - DefPathData::TypeNs(ti.ident.as_interned_str()) + DefPathData::TypeNs(ti.ident.name) }, TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id), }; @@ -243,12 +242,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { body, ) } - ImplItemKind::Method(..) | ImplItemKind::Const(..) => - DefPathData::ValueNs(ii.ident.as_interned_str()), + ImplItemKind::Method(..) | + ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name), ImplItemKind::TyAlias(..) | - ImplItemKind::OpaqueTy(..) => { - DefPathData::TypeNs(ii.ident.as_interned_str()) - }, + ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name), ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id), }; diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index d2732c92d268..893b295c60a2 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -18,7 +18,7 @@ use std::fmt::Write; use std::hash::Hash; use syntax::ast; use syntax_expand::hygiene::ExpnId; -use syntax::symbol::{Symbol, sym, InternedString}; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, DUMMY_SP}; /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa. @@ -136,7 +136,9 @@ impl DefKey { ::std::mem::discriminant(data).hash(&mut hasher); if let Some(name) = data.get_opt_name() { - name.hash(&mut hasher); + // Get a stable hash by considering the symbol chars rather than + // the symbol index. + name.as_str().hash(&mut hasher); } disambiguator.hash(&mut hasher); @@ -218,7 +220,7 @@ impl DefPath { for component in &self.data { write!(s, "::{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -238,11 +240,11 @@ impl DefPath { for component in &self.data { if component.disambiguator == 0 { - write!(s, "::{}", component.data.as_interned_str()).unwrap(); + write!(s, "::{}", component.data.as_symbol()).unwrap(); } else { write!(s, "{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -262,11 +264,11 @@ impl DefPath { opt_delimiter.map(|d| s.push(d)); opt_delimiter = Some('-'); if component.disambiguator == 0 { - write!(s, "{}", component.data.as_interned_str()).unwrap(); + write!(s, "{}", component.data.as_symbol()).unwrap(); } else { write!(s, "{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -290,13 +292,13 @@ pub enum DefPathData { /// An impl. Impl, /// Something in the type namespace. - TypeNs(InternedString), + TypeNs(Symbol), /// Something in the value namespace. - ValueNs(InternedString), + ValueNs(Symbol), /// Something in the macro namespace. - MacroNs(InternedString), + MacroNs(Symbol), /// Something in the lifetime namespace. - LifetimeNs(InternedString), + LifetimeNs(Symbol), /// A closure expression. ClosureExpr, @@ -311,7 +313,7 @@ pub enum DefPathData { /// Identifies a piece of crate metadata that is global to a whole crate /// (as opposed to just one item). `GlobalMetaData` components are only /// supposed to show up right below the crate root. - GlobalMetaData(InternedString), + GlobalMetaData(Symbol), } #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, @@ -545,7 +547,7 @@ impl Definitions { } impl DefPathData { - pub fn get_opt_name(&self) -> Option { + pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { TypeNs(name) | @@ -564,15 +566,15 @@ impl DefPathData { } } - pub fn as_interned_str(&self) -> InternedString { + pub fn as_symbol(&self) -> Symbol { use self::DefPathData::*; - let s = match *self { + match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | GlobalMetaData(name) => { - return name + name } // Note that this does not show up in user print-outs. CrateRoot => sym::double_braced_crate, @@ -582,13 +584,11 @@ impl DefPathData { Ctor => sym::double_braced_constructor, AnonConst => sym::double_braced_constant, ImplTrait => sym::double_braced_opaque, - }; - - s.as_interned_str() + } } pub fn to_string(&self) -> String { - self.as_interned_str().to_string() + self.as_symbol().to_string() } } @@ -611,7 +611,7 @@ macro_rules! define_global_metadata_kind { definitions.create_def_with_parent( CRATE_DEF_INDEX, ast::DUMMY_NODE_ID, - DefPathData::GlobalMetaData(instance.name().as_interned_str()), + DefPathData::GlobalMetaData(instance.name()), ExpnId::root(), DUMMY_SP ); @@ -625,7 +625,7 @@ macro_rules! define_global_metadata_kind { let def_key = DefKey { parent: Some(CRATE_DEF_INDEX), disambiguated_data: DisambiguatedDefPathData { - data: DefPathData::GlobalMetaData(self.name().as_interned_str()), + data: DefPathData::GlobalMetaData(self.name()), disambiguator: 0, } }; diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f6068855e630..7e1dcdfe18f9 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -542,7 +542,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let mut path = print_prefix(self)?; - path.push(disambiguated_data.data.as_interned_str().to_string()); + path.push(disambiguated_data.data.as_symbol().to_string()); Ok(path) } fn path_generic_args( diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index fa73a3c6c462..1b38c908917b 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -875,7 +875,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { _ => {} } - path.push(disambiguated_data.data.as_interned_str().as_symbol()); + path.push(disambiguated_data.data.as_symbol()); Ok(path) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9703ed838532..f52d1bc5ffab 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3019,7 +3019,7 @@ impl<'tcx> TyCtxt<'tcx> { }), _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); - }).as_symbol(), + }), } } } diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index df39d0ccc9ee..e72916de6a9c 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -218,9 +218,9 @@ impl DefPathBasedNames<'tcx> { // foo::bar::ItemName:: for part in self.tcx.def_path(def_id).data { if self.omit_disambiguators { - write!(output, "{}::", part.data.as_interned_str()).unwrap(); + write!(output, "{}::", part.data.as_symbol()).unwrap(); } else { - write!(output, "{}[{}]::", part.data.as_interned_str(), part.disambiguator) + write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator) .unwrap(); } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index f1042813e5ea..8a98a5d83615 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -384,7 +384,7 @@ pub trait PrettyPrinter<'tcx>: let reexport = self.tcx().item_children(visible_parent) .iter() .find(|child| child.res.def_id() == def_id) - .map(|child| child.ident.as_interned_str()); + .map(|child| child.ident.name); if let Some(reexport) = reexport { *name = reexport; } @@ -392,7 +392,7 @@ pub trait PrettyPrinter<'tcx>: // Re-exported `extern crate` (#43189). DefPathData::CrateRoot => { data = DefPathData::TypeNs( - self.tcx().original_crate_name(def_id.krate).as_interned_str(), + self.tcx().original_crate_name(def_id.krate), ); } _ => {} @@ -1222,7 +1222,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { // FIXME(eddyb) `name` should never be empty, but it // currently is for `extern { ... }` "foreign modules". - let name = disambiguated_data.data.as_interned_str().as_str(); + let name = disambiguated_data.data.as_symbol().as_str(); if !name.is_empty() { if !self.empty_path { write!(self, "::")?; diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index 889984749fdf..628d1372b570 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -35,7 +35,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { let namespace_name = match def_key.disambiguated_data.data { DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(), - data => data.as_interned_str().as_str() + data => data.as_symbol().as_str() }; let namespace_name = SmallCStr::new(&namespace_name); diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index d875c60959cb..166a74fe4879 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -221,7 +221,7 @@ pub fn push_debuginfo_type_name<'tcx>( output.push_str(&tcx.crate_name(def_id.krate).as_str()); for path_element in tcx.def_path(def_id).data { output.push_str("::"); - output.push_str(&path_element.data.as_interned_str().as_str()); + output.push_str(&path_element.data.as_symbol().as_str()); } } else { output.push_str(&tcx.item_name(def_id).as_str()); diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index cf575c54293c..601a33a66bb3 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -335,7 +335,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { self.path.finalize_pending_component(); } - self.write_str(&disambiguated_data.data.as_interned_str().as_str())?; + self.write_str(&disambiguated_data.data.as_symbol().as_str())?; Ok(self) } fn path_generic_args( diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4cd1ff7b4a4f..6aba66a79ab3 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -460,7 +460,7 @@ impl cstore::CStore { LoadedMacro::MacroDef(ast::Item { // FIXME: cross-crate hygiene - ident: ast::Ident::with_dummy_span(name.as_symbol()), + ident: ast::Ident::with_dummy_span(name), id: ast::DUMMY_NODE_ID, span: local_span, attrs: attrs.iter().cloned().collect(), diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b8b003024402..c9851694d446 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -35,7 +35,7 @@ use syntax::ast::{self, Ident}; use syntax::source_map::{self, respan, Spanned}; use syntax::symbol::{Symbol, sym}; use syntax_expand::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension}; -use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}}; +use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP}; use log::debug; use proc_macro::bridge::client::ProcMacro; use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro}; @@ -514,7 +514,6 @@ impl<'a, 'tcx> CrateMetadata { .data .get_opt_name() .expect("no name in item_name") - .as_symbol() } else { Symbol::intern(self.raw_proc_macro(item_index).name()) } @@ -864,7 +863,7 @@ impl<'a, 'tcx> CrateMetadata { let span = self.get_span(child_index, sess); if let (Some(kind), Some(name)) = (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) { - let ident = Ident::from_interned_str(name); + let ident = Ident::with_dummy_span(name); let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); @@ -987,7 +986,7 @@ impl<'a, 'tcx> CrateMetadata { }; ty::AssocItem { - ident: Ident::from_interned_str(name), + ident: Ident::with_dummy_span(name), kind, vis: self.get_visibility(id), defaultness: container.defaultness(), @@ -1262,7 +1261,7 @@ impl<'a, 'tcx> CrateMetadata { let mut key = self.def_path_table.def_key(index); if self.is_proc_macro(index) { let name = self.raw_proc_macro(index).name(); - key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name)); + key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name)); } key } diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index f9200f8c1c04..f1f9fac08ca3 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -148,7 +148,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { self.path.push_str("::"); - self.path.push_str(&disambiguated_data.data.as_interned_str().as_str()); + self.path.push_str(&disambiguated_data.data.as_symbol().as_str()); Ok(self) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index b9d38028b72a..b09f9e9e536a 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -762,7 +762,7 @@ fn compute_codegen_unit_name( let components = def_path .data .iter() - .map(|part| part.data.as_interned_str()); + .map(|part| part.data.as_symbol()); let volatile_suffix = if volatile { Some("volatile") diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e261d3af61ff..6444a82fd737 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -110,14 +110,14 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate).as_interned_str(), None) + (self.cstore.crate_name_untracked(def_id.krate), None) } else { let def_key = self.cstore.def_key(def_id); (def_key.disambiguated_data.data.get_opt_name().unwrap(), Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) }; - let kind = ModuleKind::Def(DefKind::Mod, def_id, name.as_symbol()); + let kind = ModuleKind::Def(DefKind::Mod, def_id, name); let module = self.arenas.alloc_module(ModuleData::new( parent, kind, def_id, ExpnId::root(), DUMMY_SP )); From dddacf1eb3efb3c2111b27456be43c21e4497ffd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 15:53:37 +1100 Subject: [PATCH 041/109] Change `SymbolName::name` from `InternedString` to `Symbol`. This requires changing the `PartialOrd`/`Ord` implementations to look at the chars rather than the symbol index. --- src/librustc/mir/mono.rs | 4 ++-- src/librustc/ty/mod.rs | 21 ++++++++++++++++---- src/librustc/ty/query/values.rs | 4 ++-- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 23 ++++++++++------------ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 265ac975ed7a..1f52672199ca 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,6 @@ use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use crate::hir::HirId; -use syntax::symbol::InternedString; +use syntax::symbol::{InternedString, Symbol}; use syntax::attr::InlineAttr; use syntax::source_map::Span; use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; @@ -80,7 +80,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(hir_id) => { let def_id = tcx.hir().local_def_id(hir_id); SymbolName { - name: InternedString::intern(&format!("global_asm_{:?}", def_id)) + name: Symbol::intern(&format!("global_asm_{:?}", def_id)) } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f52d1bc5ffab..f72a221fe396 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -46,7 +46,7 @@ use std::ops::Range; use syntax::ast::{self, Name, Ident, NodeId}; use syntax::attr; use syntax_expand::hygiene::ExpnId; -use syntax::symbol::{kw, sym, Symbol, InternedString}; +use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; use smallvec; @@ -3429,11 +3429,11 @@ pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub struct SymbolName { // FIXME: we don't rely on interning or equality here - better have // this be a `&'tcx str`. - pub name: InternedString + pub name: Symbol } impl_stable_hash_for!(struct self::SymbolName { @@ -3443,11 +3443,24 @@ impl_stable_hash_for!(struct self::SymbolName { impl SymbolName { pub fn new(name: &str) -> SymbolName { SymbolName { - name: InternedString::intern(name) + name: Symbol::intern(name) } } } +impl PartialOrd for SymbolName { + fn partial_cmp(&self, other: &SymbolName) -> Option { + self.name.as_str().partial_cmp(&other.name.as_str()) + } +} + +/// Ordering must use the chars to ensure reproducible builds. +impl Ord for SymbolName { + fn cmp(&self, other: &SymbolName) -> Ordering { + self.name.as_str().cmp(&other.name.as_str()) + } +} + impl fmt::Display for SymbolName { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.name, fmt) diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index 0149f7571647..f0d1639f72f5 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -1,7 +1,7 @@ use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint}; use crate::ty::util::NeedsDrop; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; pub(super) trait Value<'tcx>: Sized { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self; @@ -22,7 +22,7 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> { impl<'tcx> Value<'tcx> for ty::SymbolName { fn from_cycle_error(_: TyCtxt<'tcx>) -> Self { - ty::SymbolName { name: InternedString::intern("") } + ty::SymbolName { name: Symbol::intern("") } } } diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index d4df5b4a804e..fd7054a5a0ad 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> { def_id); let ty = instance.ty(self.tcx); - let sym = self.tcx.symbol_name(instance).name.as_symbol(); + let sym = self.tcx.symbol_name(instance).name; debug!("get_static: sym={} instance={:?}", sym, instance); diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 7ccd024769f7..c52c6cfa83c9 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -95,7 +95,7 @@ use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, Instance}; use rustc::mir::mono::{MonoItem, InstantiationMode}; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use log::debug; @@ -112,7 +112,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { +fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { let def_id = instance.def_id(); let substs = instance.substs; @@ -123,13 +123,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { if def_id.is_local() { if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return - InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)); + return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)); } if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return - InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)); + return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)); } } @@ -146,23 +144,22 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { let attrs = tcx.codegen_fn_attrs(def_id); if is_foreign { if let Some(name) = attrs.link_name { - return name.as_interned_str(); + return name; } // Don't mangle foreign items. - return tcx.item_name(def_id).as_interned_str(); + return tcx.item_name(def_id); } - if let Some(name) = &attrs.export_name { + if let Some(name) = attrs.export_name { // Use provided name - return name.as_interned_str(); + return name; } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id).as_interned_str(); + return tcx.item_name(def_id); } - let is_generic = substs.non_erasable_generics().next().is_some(); let avoid_cross_crate_conflicts = // If this is an instance of a generic function, we also hash in @@ -222,5 +219,5 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate), }; - InternedString::intern(&mangled) + Symbol::intern(&mangled) } From 2da7a9c0d943e694eef17c0b47e87cbcde03a957 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 17:14:03 +1100 Subject: [PATCH 042/109] Use `Symbol` for codegen unit names. This is a straightforward replacement except for two places where we have to convert to `LocalInternedString` to get a stable sort. --- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/mir/mono.rs | 20 +++++----- src/librustc/query/mod.rs | 4 +- src/librustc/ty/query/keys.rs | 4 +- src/librustc/ty/query/mod.rs | 1 - src/librustc_codegen_llvm/base.rs | 6 +-- src/librustc_codegen_llvm/lib.rs | 3 +- src/librustc_codegen_ssa/base.rs | 4 +- src/librustc_codegen_ssa/traits/backend.rs | 4 +- .../assert_module_sources.rs | 8 ++-- src/librustc_mir/monomorphize/partitioning.rs | 39 +++++++++---------- 11 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 0686bec0621f..dea8d70aaf4e 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -59,7 +59,7 @@ use crate::ich::{Fingerprint, StableHashingContext}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::fmt; use std::hash::Hash; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use crate::traits; use crate::traits::query::{ CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, @@ -426,7 +426,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [anon] TraitSelect, - [] CompileCodegenUnit(InternedString), + [] CompileCodegenUnit(Symbol), [eval_always] Analysis(CrateNum), ]); diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 1f52672199ca..9be741a16560 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,6 @@ use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use crate::hir::HirId; -use syntax::symbol::{InternedString, Symbol}; +use syntax::symbol::Symbol; use syntax::attr::InlineAttr; use syntax::source_map::Span; use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; @@ -246,7 +246,7 @@ pub struct CodegenUnit<'tcx> { /// name be unique amongst **all** crates. Therefore, it should /// contain something unique to this crate (e.g., a module path) /// as well as the crate name and disambiguator. - name: InternedString, + name: Symbol, items: FxHashMap, (Linkage, Visibility)>, size_estimate: Option, } @@ -294,7 +294,7 @@ impl_stable_hash_for!(enum self::Visibility { }); impl<'tcx> CodegenUnit<'tcx> { - pub fn new(name: InternedString) -> CodegenUnit<'tcx> { + pub fn new(name: Symbol) -> CodegenUnit<'tcx> { CodegenUnit { name: name, items: Default::default(), @@ -302,11 +302,11 @@ impl<'tcx> CodegenUnit<'tcx> { } } - pub fn name(&self) -> &InternedString { - &self.name + pub fn name(&self) -> Symbol { + self.name } - pub fn set_name(&mut self, name: InternedString) { + pub fn set_name(&mut self, name: Symbol) { self.name = name; } @@ -474,7 +474,7 @@ impl CodegenUnitNameBuilder<'tcx> { cnum: CrateNum, components: I, special_suffix: Option) - -> InternedString + -> Symbol where I: IntoIterator, C: fmt::Display, S: fmt::Display, @@ -487,7 +487,7 @@ impl CodegenUnitNameBuilder<'tcx> { cgu_name } else { let cgu_name = &cgu_name.as_str()[..]; - InternedString::intern(&CodegenUnit::mangle_name(cgu_name)) + Symbol::intern(&CodegenUnit::mangle_name(cgu_name)) } } @@ -497,7 +497,7 @@ impl CodegenUnitNameBuilder<'tcx> { cnum: CrateNum, components: I, special_suffix: Option) - -> InternedString + -> Symbol where I: IntoIterator, C: fmt::Display, S: fmt::Display, @@ -543,6 +543,6 @@ impl CodegenUnitNameBuilder<'tcx> { write!(cgu_name, ".{}", special_suffix).unwrap(); } - InternedString::intern(&cgu_name[..]) + Symbol::intern(&cgu_name[..]) } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 2c407a24493f..fdca6d0e17a1 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -15,7 +15,7 @@ use crate::traits::query::{ }; use std::borrow::Cow; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method @@ -924,7 +924,7 @@ rustc_queries! { desc { "collect_and_partition_mono_items" } } query is_codegened_item(_: DefId) -> bool {} - query codegen_unit(_: InternedString) -> Arc> { + query codegen_unit(_: Symbol) -> Arc> { no_force desc { "codegen_unit" } } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 30a3e53dddfb..0c48ae971786 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -11,7 +11,7 @@ use crate::mir; use std::fmt::Debug; use std::hash::Hash; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; /// The `Key` trait controls what types can legally be used as the key /// for a query. @@ -190,7 +190,7 @@ impl<'tcx> Key for traits::Environment<'tcx> { } } -impl Key for InternedString { +impl Key for Symbol { fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 4279ca8c3daf..9b15ad560b5d 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -55,7 +55,6 @@ use std::ops::Deref; use std::sync::Arc; use std::any::type_name; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::symbol::InternedString; use syntax::attr; use syntax::ast; use syntax::feature_gate; diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index bd7d0d4017dc..edd34b52eade 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -36,7 +36,7 @@ use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm; use std::ffi::CString; use std::time::Instant; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use rustc::hir::CodegenFnAttrs; use crate::value::Value; @@ -105,7 +105,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { pub fn compile_codegen_unit( tcx: TyCtxt<'tcx>, - cgu_name: InternedString, + cgu_name: Symbol, tx_to_llvm_workers: &std::sync::mpsc::Sender>, ) { let prof_timer = tcx.prof.generic_activity("codegen_module"); @@ -131,7 +131,7 @@ pub fn compile_codegen_unit( fn module_codegen( tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 9b55bef0c514..8c1797cfb7de 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -50,7 +50,6 @@ use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; use syntax_expand::allocator::AllocatorKind; -use syntax_pos::symbol::InternedString; pub use llvm_util::target_features; use std::any::Any; use std::sync::Arc; @@ -123,7 +122,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend { } fn compile_codegen_unit( &self, tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, tx: &std::sync::mpsc::Sender>, ) { base::compile_codegen_unit(tcx, cgu_name, tx); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index f4f3dd4d2d29..516fd5049f26 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -515,7 +515,7 @@ pub fn codegen_crate( // unnecessarily. if tcx.dep_graph.is_fully_enabled() { for cgu in &codegen_units { - tcx.codegen_unit(cgu.name().clone()); + tcx.codegen_unit(cgu.name()); } } @@ -603,7 +603,7 @@ pub fn codegen_crate( match cgu_reuse { CguReuse::No => { let start_time = Instant::now(); - backend.compile_codegen_unit(tcx, *cgu.name(), &ongoing_codegen.coordinator_send); + backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send); total_codegen_time += start_time.elapsed(); false } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 7cae3e9ade59..1fff740d7403 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -10,7 +10,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::sync::Arc; use std::sync::mpsc; use syntax_expand::allocator::AllocatorKind; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; pub trait BackendTypes { type Value: CodegenObject; @@ -50,7 +50,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se fn compile_codegen_unit( &self, tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, tx_to_llvm_workers: &mpsc::Sender>, ); // If find_features is true this won't access `sess.crate_types` by assuming diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index e08eeaf85758..ca035d0cdcb1 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -27,7 +27,7 @@ use rustc::mir::mono::CodegenUnitNameBuilder; use rustc::ty::TyCtxt; use std::collections::BTreeSet; use syntax::ast; -use syntax::symbol::{InternedString, Symbol, sym}; +use syntax::symbol::{Symbol, sym}; use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED, ATTR_EXPECTED_CGU_REUSE}; @@ -45,8 +45,8 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { .collect_and_partition_mono_items(LOCAL_CRATE) .1 .iter() - .map(|cgu| *cgu.name()) - .collect::>(); + .map(|cgu| cgu.name()) + .collect::>(); let ams = AssertModuleSource { tcx, @@ -61,7 +61,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { struct AssertModuleSource<'tcx> { tcx: TyCtxt<'tcx>, - available_cgus: BTreeSet, + available_cgus: BTreeSet, } impl AssertModuleSource<'tcx> { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index b09f9e9e536a..42f08771f866 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -96,7 +96,7 @@ use std::collections::hash_map::Entry; use std::cmp; use std::sync::Arc; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def::DefKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; @@ -121,7 +121,7 @@ pub enum PartitioningStrategy { } // Anything we can't find a proper codegen unit for goes into this. -fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> InternedString { +fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol { name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu")) } @@ -185,9 +185,7 @@ where internalization_candidates: _, } = post_inlining; - result.sort_by(|cgu1, cgu2| { - cgu1.name().cmp(cgu2.name()) - }); + result.sort_by_cached_key(|cgu| cgu.name().as_str()); result } @@ -203,7 +201,7 @@ struct PreInliningPartitioning<'tcx> { /// to keep track of that. #[derive(Clone, PartialEq, Eq, Debug)] enum MonoItemPlacement { - SingleCgu { cgu_name: InternedString }, + SingleCgu { cgu_name: Symbol }, MultipleCgus, } @@ -251,8 +249,8 @@ where None => fallback_cgu_name(cgu_name_builder), }; - let codegen_unit = codegen_units.entry(codegen_unit_name.clone()) - .or_insert_with(|| CodegenUnit::new(codegen_unit_name.clone())); + let codegen_unit = codegen_units.entry(codegen_unit_name) + .or_insert_with(|| CodegenUnit::new(codegen_unit_name)); let mut can_be_internalized = true; let (linkage, visibility) = mono_item_linkage_and_visibility( @@ -273,8 +271,7 @@ where // crate with just types (for example), we could wind up with no CGU. if codegen_units.is_empty() { let codegen_unit_name = fallback_cgu_name(cgu_name_builder); - codegen_units.insert(codegen_unit_name.clone(), - CodegenUnit::new(codegen_unit_name.clone())); + codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name)); } PreInliningPartitioning { @@ -492,7 +489,7 @@ fn merge_codegen_units<'tcx>( // smallest into each other) we're sure to start off with a deterministic // order (sorted by name). This'll mean that if two cgus have the same size // the stable sort below will keep everything nice and deterministic. - codegen_units.sort_by_key(|cgu| *cgu.name()); + codegen_units.sort_by_cached_key(|cgu| cgu.name().as_str()); // Merge the two smallest codegen units until the target size is reached. while codegen_units.len() > target_cgu_count { @@ -537,7 +534,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< follow_inlining(*root, inlining_map, &mut reachable); } - let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name().clone()); + let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name()); // Add all monomorphizations that are not already there. for mono_item in reachable { @@ -564,8 +561,8 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< Entry::Occupied(e) => { let placement = e.into_mut(); debug_assert!(match *placement { - MonoItemPlacement::SingleCgu { ref cgu_name } => { - *cgu_name != *new_codegen_unit.name() + MonoItemPlacement::SingleCgu { cgu_name } => { + cgu_name != new_codegen_unit.name() } MonoItemPlacement::MultipleCgus => true, }); @@ -573,7 +570,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< } Entry::Vacant(e) => { e.insert(MonoItemPlacement::SingleCgu { - cgu_name: new_codegen_unit.name().clone() + cgu_name: new_codegen_unit.name() }); } } @@ -638,7 +635,7 @@ fn internalize_symbols<'tcx>( // accessed from outside its defining codegen unit. for cgu in &mut partitioning.codegen_units { let home_cgu = MonoItemPlacement::SingleCgu { - cgu_name: cgu.name().clone() + cgu_name: cgu.name() }; for (accessee, linkage_and_visibility) in cgu.items_mut() { @@ -717,7 +714,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( } } -type CguNameCache = FxHashMap<(DefId, bool), InternedString>; +type CguNameCache = FxHashMap<(DefId, bool), Symbol>; fn compute_codegen_unit_name( tcx: TyCtxt<'_>, @@ -725,7 +722,7 @@ fn compute_codegen_unit_name( def_id: DefId, volatile: bool, cache: &mut CguNameCache, -) -> InternedString { +) -> Symbol { // Find the innermost module that is not nested within a function. let mut current_def_id = def_id; let mut cgu_def_id = None; @@ -777,7 +774,7 @@ fn compute_codegen_unit_name( fn numbered_codegen_unit_name( name_builder: &mut CodegenUnitNameBuilder<'_>, index: usize, -) -> InternedString { +) -> Symbol { name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index)) } @@ -929,7 +926,7 @@ fn collect_and_partition_mono_items( for (&mono_item, &linkage) in cgu.items() { item_to_cgus.entry(mono_item) .or_default() - .push((cgu.name().clone(), linkage)); + .push((cgu.name(), linkage)); } } @@ -991,7 +988,7 @@ pub fn provide(providers: &mut Providers<'_>) { providers.codegen_unit = |tcx, name| { let (_, all) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); all.iter() - .find(|cgu| *cgu.name() == name) + .find(|cgu| cgu.name() == name) .cloned() .unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name)) }; From 08e2f05549de74022f2e596251ed88e784514640 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 18:25:03 +1100 Subject: [PATCH 043/109] Remove `InternedString`. By using `LocalInternedString` instead for the few remaining uses. --- src/librustc/hir/map/collector.rs | 4 +- src/librustc/ich/impls_syntax.rs | 19 ++--- src/libsyntax_pos/symbol.rs | 120 ++---------------------------- src/tools/linkchecker/main.rs | 1 - 4 files changed, 17 insertions(+), 127 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 1a970c7a2c1e..307dbe7dab08 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -186,13 +186,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }); let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| { - let name = cstore.crate_name_untracked(cnum).as_interned_str(); + let name = cstore.crate_name_untracked(cnum); let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint(); let hash = cstore.crate_hash_untracked(cnum); (name, disambiguator, hash) }).collect(); - upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name, dis)); + upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis)); // We hash the final, remapped names of all local source files so we // don't have to include the path prefix remapping commandline args. diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index defc3fb25bc5..dc1f6fd3131b 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -9,7 +9,7 @@ use std::mem; use syntax::ast; use syntax::feature_gate; use syntax::parse::token; -use syntax::symbol::InternedString; +use syntax::symbol::LocalInternedString; use syntax::tokenstream; use syntax_pos::SourceFile; @@ -18,20 +18,21 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; -impl<'a> HashStable> for InternedString { +impl<'a> HashStable> for LocalInternedString { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.with(|s| s.hash_stable(hcx, hasher)) + let str = self as &str; + str.hash_stable(hcx, hasher) } } -impl<'a> ToStableHashKey> for InternedString { - type KeyType = InternedString; +impl<'a> ToStableHashKey> for LocalInternedString { + type KeyType = LocalInternedString; #[inline] fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) - -> InternedString { + -> LocalInternedString { self.clone() } } @@ -44,13 +45,13 @@ impl<'a> HashStable> for ast::Name { } impl<'a> ToStableHashKey> for ast::Name { - type KeyType = InternedString; + type KeyType = LocalInternedString; #[inline] fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) - -> InternedString { - self.as_interned_str() + -> LocalInternedString { + self.as_str() } } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index fa9567fb62c0..4b947c5b857c 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -9,7 +9,7 @@ use rustc_macros::symbols; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; -use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; +use std::cmp::{PartialEq, PartialOrd, Ord}; use std::fmt; use std::hash::{Hash, Hasher}; use std::str; @@ -766,11 +766,6 @@ impl Ident { Ident::with_dummy_span(kw::Invalid) } - /// Maps an interned string to an identifier with an empty syntax context. - pub fn from_interned_str(string: InternedString) -> Ident { - Ident::with_dummy_span(string.as_symbol()) - } - /// Maps a string to an identifier with a dummy span. pub fn from_str(string: &str) -> Ident { Ident::with_dummy_span(Symbol::intern(string)) @@ -813,11 +808,6 @@ impl Ident { pub fn as_str(self) -> LocalInternedString { self.name.as_str() } - - /// Convert the name to an `InternedString`. - pub fn as_interned_str(self) -> InternedString { - self.name.as_interned_str() - } } impl PartialEq for Ident { @@ -903,15 +893,6 @@ impl Symbol { }) } - /// Access two symbols' chars. This is a slowish operation because it - /// requires locking the symbol interner, but it is faster than calling - /// `with()` twice. - fn with2 R, R>(self, other: Symbol, f: F) -> R { - with_interner(|interner| { - f(interner.get(self), interner.get(other)) - }) - } - /// Convert to a `LocalInternedString`. This is a slowish operation because /// it requires locking the symbol interner. pub fn as_str(self) -> LocalInternedString { @@ -922,11 +903,6 @@ impl Symbol { }) } - /// Convert to an `InternedString`. - pub fn as_interned_str(self) -> InternedString { - InternedString { symbol: self } - } - pub fn as_u32(self) -> u32 { self.0.as_u32() } @@ -1105,9 +1081,9 @@ fn with_interner T>(f: F) -> T { GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock())) } -/// An alternative to `Symbol` and `InternedString`, useful when the chars -/// within the symbol need to be accessed. It deliberately has limited -/// functionality and should only be used for temporary values. +/// An alternative to `Symbol`, useful when the chars within the symbol need to +/// be accessed. It deliberately has limited functionality and should only be +/// used for temporary values. /// /// Because the interner outlives any thread which uses this type, we can /// safely treat `string` which points to interner data, as an immortal string, @@ -1116,7 +1092,7 @@ fn with_interner T>(f: F) -> T { // FIXME: ensure that the interner outlives any thread which uses // `LocalInternedString`, by creating a new thread right after constructing the // interner. -#[derive(Eq, PartialOrd, Ord)] +#[derive(Clone, Eq, PartialOrd, Ord)] pub struct LocalInternedString { string: &'static str, } @@ -1157,89 +1133,3 @@ impl fmt::Display for LocalInternedString { fmt::Display::fmt(self.string, f) } } - -/// An alternative to `Symbol` that is focused on string contents. -/// -/// Its implementations of `Hash`, `PartialOrd` and `Ord` work with the -/// string chars rather than the symbol integer. This is useful when hash -/// stability is required across compile sessions, or a guaranteed sort -/// ordering is required. -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct InternedString { - symbol: Symbol, -} - -impl InternedString { - /// Maps a string to its interned representation. - pub fn intern(string: &str) -> Self { - InternedString { - symbol: Symbol::intern(string) - } - } - - pub fn with R, R>(self, f: F) -> R { - self.symbol.with(f) - } - - fn with2 R, R>(self, other: &InternedString, f: F) -> R { - self.symbol.with2(other.symbol, f) - } - - pub fn as_symbol(self) -> Symbol { - self.symbol - } - - /// Convert to a `LocalInternedString`. This is a slowish operation because it - /// requires locking the symbol interner. - pub fn as_str(self) -> LocalInternedString { - self.symbol.as_str() - } -} - -impl Hash for InternedString { - fn hash(&self, state: &mut H) { - self.with(|str| str.hash(state)) - } -} - -impl PartialOrd for InternedString { - fn partial_cmp(&self, other: &InternedString) -> Option { - if self.symbol == other.symbol { - return Some(Ordering::Equal); - } - self.with2(other, |self_str, other_str| self_str.partial_cmp(other_str)) - } -} - -impl Ord for InternedString { - fn cmp(&self, other: &InternedString) -> Ordering { - if self.symbol == other.symbol { - return Ordering::Equal; - } - self.with2(other, |self_str, other_str| self_str.cmp(other_str)) - } -} - -impl fmt::Debug for InternedString { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Debug::fmt(&str, f)) - } -} - -impl fmt::Display for InternedString { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Display::fmt(&str, f)) - } -} - -impl Decodable for InternedString { - fn decode(d: &mut D) -> Result { - Ok(InternedString::intern(&d.read_str()?)) - } -} - -impl Encodable for InternedString { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.with(|string| s.emit_str(string)) - } -} diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index e8a7252cb767..79c98b780eb6 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -126,7 +126,6 @@ fn check(cache: &mut Cache, // FIXME(#32129) if file.ends_with("std/string/struct.String.html") || file.ends_with("interpret/struct.ImmTy.html") || - file.ends_with("symbol/struct.InternedString.html") || file.ends_with("ast/struct.ThinVec.html") || file.ends_with("util/struct.ThinVec.html") || file.ends_with("layout/struct.TyLayout.html") || From 87744841c81377b1f195ff171fb23c9ae3d40303 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 21 Oct 2019 11:36:52 +0200 Subject: [PATCH 044/109] Add option to disable keyboard shortcuts in docs --- src/librustdoc/html/render.rs | 1 + src/librustdoc/html/static/main.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 72a72e892814..414c3137376a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1241,6 +1241,7 @@ fn settings(root_path: &str, suffix: &str) -> String { ("go-to-only-result", "Directly go to item in search if there is only one result", false), ("line-numbers", "Show line numbers on code examples", false), + ("disable-shortcuts", "Disable keyboard shortcuts", false), ]; format!( "

\ diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 17a940cc4c9f..f0104c9156de 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -79,6 +79,7 @@ function getSearchElement() { "derive", "traitalias"]; + var disableShortcuts = getCurrentValue("rustdoc-disable-shortcuts") !== "true"; var search_input = getSearchInput(); // On the search screen, so you remain on the last tab you opened. @@ -294,7 +295,7 @@ function getSearchElement() { function handleShortcut(ev) { // Don't interfere with browser shortcuts - if (ev.ctrlKey || ev.altKey || ev.metaKey) { + if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts === true) { return; } From cde60e82a079f0d900b35d5f41101111bbe56d7b Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 08:48:01 +0900 Subject: [PATCH 045/109] Add long error explanation for E0728 --- src/librustc/error_codes.rs | 73 ++++++++++++++++++- .../incorrect-syntax-suggestions.stderr | 3 +- .../ui/async-await/issues/issue-51719.stderr | 1 + .../ui/async-await/issues/issue-51751.stderr | 1 + .../async-await/issues/issue-62009-1.stderr | 3 +- .../async-await/issues/issue-62009-2.stderr | 1 + .../issues/non-async-enclosing-span.stderr | 1 + 7 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 3d501cacf6f4..bc66beab8626 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2045,8 +2045,8 @@ so that a generator can then be constructed: async fn bar() -> () {} async fn foo() { - bar::().await; - // ^^^^^^^^ specify type explicitly + bar::().await; + // ^^^^^^^^ specify type explicitly } ``` "##, @@ -2126,6 +2126,74 @@ static X: u32 = 42; ``` "##, +E0728: r##" +`await` has been used outside `async` function or block. + +Erroneous code examples: + +```edition2018,compile_fail,E0728 +# use std::pin::Pin; +# use std::future::Future; +# use std::task::{Context, Poll}; + +# struct WakeOnceThenComplete(bool); + +# fn wake_and_yield_once() -> WakeOnceThenComplete { +# WakeOnceThenComplete(false) +# } + +# impl Future for WakeOnceThenComplete { +# type Output = (); +# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { +# if self.0 { +# Poll::Ready(()) +# } else { +# cx.waker().wake_by_ref(); +# self.0 = true; +# Poll::Pending +# } +# } +# } + +fn foo() { + wake_and_yield_once().await // `await` is used outside `async` context +} +``` + +`await` is used to suspend the current computation until the given +future is ready to produce a value. So it is legal only within +an async context, like an `async fn` or an `async` block. + +```edition2018 +# use std::pin::Pin; +# use std::future::Future; +# use std::task::{Context, Poll}; + +# struct WakeOnceThenComplete(bool); + +# fn wake_and_yield_once() -> WakeOnceThenComplete { +# WakeOnceThenComplete(false) +# } + +# impl Future for WakeOnceThenComplete { +# type Output = (); +# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { +# if self.0 { +# Poll::Ready(()) +# } else { +# cx.waker().wake_by_ref(); +# self.0 = true; +# Poll::Pending +# } +# } +# } + +async fn foo() { + wake_and_yield_once().await // `await` is used within `async` context +} +``` +"##, + E0734: r##" A stability attribute has been used outside of the standard library. @@ -2218,6 +2286,5 @@ See [RFC 2091] for details on this and other limitations. // E0702, // replaced with a generic attribute input check E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported - E0728, // `await` must be in an `async` function or block E0739, // invalid track_caller application/syntax } diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index 7caa9f26bc2f..4b5e2d59e38c 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -244,4 +244,5 @@ LL | let _ = await bar()?; error: aborting due to 35 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0728. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issues/issue-51719.stderr b/src/test/ui/async-await/issues/issue-51719.stderr index 6c3c8889da7c..5b9adb253d96 100644 --- a/src/test/ui/async-await/issues/issue-51719.stderr +++ b/src/test/ui/async-await/issues/issue-51719.stderr @@ -8,3 +8,4 @@ LL | let _gen = || foo().await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0728`. diff --git a/src/test/ui/async-await/issues/issue-51751.stderr b/src/test/ui/async-await/issues/issue-51751.stderr index e50c78534f85..f120bd119c54 100644 --- a/src/test/ui/async-await/issues/issue-51751.stderr +++ b/src/test/ui/async-await/issues/issue-51751.stderr @@ -9,3 +9,4 @@ LL | let finished = result.await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0728`. diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr index f63eaa4c48a9..538430290d29 100644 --- a/src/test/ui/async-await/issues/issue-62009-1.stderr +++ b/src/test/ui/async-await/issues/issue-62009-1.stderr @@ -40,4 +40,5 @@ LL | F: Future error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0728. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issues/issue-62009-2.stderr b/src/test/ui/async-await/issues/issue-62009-2.stderr index 79b6803263ee..47b74b5574fe 100644 --- a/src/test/ui/async-await/issues/issue-62009-2.stderr +++ b/src/test/ui/async-await/issues/issue-62009-2.stderr @@ -8,3 +8,4 @@ LL | (async || 2333)().await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0728`. diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr index 49ebf414c550..f826a86f0898 100644 --- a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr +++ b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr @@ -9,3 +9,4 @@ LL | let y = do_the_thing().await; error: aborting due to previous error +For more information about this error, try `rustc --explain E0728`. From 4fcc784c9ad6748ab9a5754e75c38281d4e7a249 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 09:00:01 +0900 Subject: [PATCH 046/109] Apply suggestions --- src/librustc/error_codes.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index bc66beab8626..4ee3445235ee 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2135,13 +2135,13 @@ Erroneous code examples: # use std::pin::Pin; # use std::future::Future; # use std::task::{Context, Poll}; - +# # struct WakeOnceThenComplete(bool); - +# # fn wake_and_yield_once() -> WakeOnceThenComplete { # WakeOnceThenComplete(false) # } - +# # impl Future for WakeOnceThenComplete { # type Output = (); # fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { @@ -2154,7 +2154,7 @@ Erroneous code examples: # } # } # } - +# fn foo() { wake_and_yield_once().await // `await` is used outside `async` context } @@ -2168,13 +2168,13 @@ an async context, like an `async fn` or an `async` block. # use std::pin::Pin; # use std::future::Future; # use std::task::{Context, Poll}; - +# # struct WakeOnceThenComplete(bool); - +# # fn wake_and_yield_once() -> WakeOnceThenComplete { # WakeOnceThenComplete(false) # } - +# # impl Future for WakeOnceThenComplete { # type Output = (); # fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { @@ -2187,9 +2187,16 @@ an async context, like an `async fn` or an `async` block. # } # } # } - +# async fn foo() { - wake_and_yield_once().await // `await` is used within `async` context + wake_and_yield_once().await // `await` is used within `async` function +} + +fn bar(x: u8) -> impl Future { + async move { + wake_and_yield_once().await; // `await` is used within `async` block + x + } } ``` "##, From 3f1af9056d8b2bf7b90a657503cd03f8c0c2b538 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 21 Oct 2019 17:29:40 -0700 Subject: [PATCH 047/109] Code cleanups following up on #65576. This makes a few code cleanups to follow up on the review comments in https://github.com/rust-lang/rust/pull/65576. --- src/librustc_codegen_ssa/base.rs | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index f4f3dd4d2d29..e8ffe868231a 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -406,6 +406,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' rust_main_def_id: DefId, use_start_lang_item: bool, ) { + // The entry function is either `int main(void)` or `int main(int argc, char **argv)`, + // depending on whether the target needs `argc` and `argv` to be passed in. let llfty = if cx.sess().target.target.options.main_needs_argc_argv { cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int()) } else { @@ -440,19 +442,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' bx.insert_reference_to_gdb_debug_scripts_section_global(); - let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv { - // Params from native main() used as args for rust start function - let param_argc = bx.get_param(0); - let param_argv = bx.get_param(1); - let arg_argc = bx.intcast(param_argc, cx.type_isize(), true); - let arg_argv = param_argv; - (arg_argc, arg_argv) - } else { - // The Rust start function doesn't need argc and argv, so just pass zeros. - let arg_argc = bx.const_int(cx.type_int(), 0); - let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p())); - (arg_argc, arg_argv) - }; + let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx); let (start_fn, args) = if use_start_lang_item { let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None); @@ -477,6 +467,27 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' } } +/// Obtain the `argc` and `argv` values to pass to the rust start function. +fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( + cx: &'a Bx::CodegenCx, + bx: &mut Bx +) -> (Bx::Value, Bx::Value) +{ + if cx.sess().target.target.options.main_needs_argc_argv { + // Params from native `main()` used as args for rust start function + let param_argc = bx.get_param(0); + let param_argv = bx.get_param(1); + let arg_argc = bx.intcast(param_argc, cx.type_isize(), true); + let arg_argv = param_argv; + (arg_argc, arg_argv) + } else { + // The Rust start function doesn't need `argc` and `argv`, so just pass zeros. + let arg_argc = bx.const_int(cx.type_int(), 0); + let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p())); + (arg_argc, arg_argv) + } +} + pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; pub fn codegen_crate( From 40f92b3b0595984f40aafd70ec4a5b9a3bdde47a Mon Sep 17 00:00:00 2001 From: yjhmelody <465402634@qq.com> Date: Tue, 22 Oct 2019 12:25:14 +0800 Subject: [PATCH 048/109] refactor maybe_append --- src/libsyntax/parse/parser.rs | 7 ------- src/libsyntax/parse/parser/item.rs | 10 ++++++++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9cb410a8ae31..d4d2f42446be 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -86,13 +86,6 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { } } -fn maybe_append(mut lhs: Vec, mut rhs: Option>) -> Vec { - if let Some(ref mut rhs) = rhs { - lhs.append(rhs); - } - lhs -} - #[derive(Debug, Clone, Copy, PartialEq)] enum PrevTokenKind { DocComment, diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 0acfd1450d81..73bd80e2a21f 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -10,7 +10,6 @@ use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField}; use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param}; use crate::parse::token; -use crate::parse::parser::maybe_append; use crate::tokenstream::{TokenTree, TokenStream}; use crate::symbol::{kw, sym}; use crate::source_map::{self, respan, Span}; @@ -416,10 +415,17 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Option>> { let (ident, item, extra_attrs) = info; let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); + let attrs = Self::maybe_append(attrs, extra_attrs); Ok(Some(self.mk_item(span, ident, item, vis, attrs))) } + fn maybe_append(mut lhs: Vec, mut rhs: Option>) -> Vec { + if let Some(ref mut rhs) = rhs { + lhs.append(rhs); + } + lhs + } + /// This is the fall-through for parsing items. fn parse_macro_use_or_failure( &mut self, From a239c8dfb29c20f29fc3b30959f654d41fb0dd7f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 17:00:47 +0900 Subject: [PATCH 049/109] Add test for issue-41366 --- src/test/ui/closures/issue-41366.rs | 13 +++++++++++++ src/test/ui/closures/issue-41366.stderr | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/test/ui/closures/issue-41366.rs create mode 100644 src/test/ui/closures/issue-41366.stderr diff --git a/src/test/ui/closures/issue-41366.rs b/src/test/ui/closures/issue-41366.rs new file mode 100644 index 000000000000..5cae0e76d1ac --- /dev/null +++ b/src/test/ui/closures/issue-41366.rs @@ -0,0 +1,13 @@ +trait T<'x> { + type V; +} + +impl<'g> T<'g> for u32 { + type V = u16; +} + +fn main() { + (&|_|()) as &dyn for<'x> Fn(>::V); + //~^ ERROR: type mismatch in closure arguments + //~| ERROR: type mismatch resolving +} diff --git a/src/test/ui/closures/issue-41366.stderr b/src/test/ui/closures/issue-41366.stderr new file mode 100644 index 000000000000..91d26efbc4f3 --- /dev/null +++ b/src/test/ui/closures/issue-41366.stderr @@ -0,0 +1,22 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-41366.rs:10:5 + | +LL | (&|_|()) as &dyn for<'x> Fn(>::V); + | ^^-----^ + | | | + | | found signature of `fn(_) -> _` + | expected signature of `for<'x> fn(>::V) -> _` + | + = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(>::V)` + +error[E0271]: type mismatch resolving `for<'x> <[closure@$DIR/issue-41366.rs:10:7: 10:12] as std::ops::FnOnce<(>::V,)>>::Output == ()` + --> $DIR/issue-41366.rs:10:5 + | +LL | (&|_|()) as &dyn for<'x> Fn(>::V); + | ^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime + | + = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(>::V)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. From dd0f98bc3ebc08cd0bcff7e682b9aff9038921cd Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 17:01:06 +0900 Subject: [PATCH 050/109] Add test for issue-51431 --- src/test/ui/asm/issue-51431.rs | 10 ++++++++++ src/test/ui/asm/issue-51431.stderr | 8 ++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/asm/issue-51431.rs create mode 100644 src/test/ui/asm/issue-51431.stderr diff --git a/src/test/ui/asm/issue-51431.rs b/src/test/ui/asm/issue-51431.rs new file mode 100644 index 000000000000..d29c31fafc28 --- /dev/null +++ b/src/test/ui/asm/issue-51431.rs @@ -0,0 +1,10 @@ +// ignore-emscripten no asm! support + +#![feature(asm)] + +fn main() { + unsafe { + asm! {"mov $0,$1"::"0"("bx"),"1"(0x00)} + //~^ ERROR: invalid value for constraint in inline assembly + } +} diff --git a/src/test/ui/asm/issue-51431.stderr b/src/test/ui/asm/issue-51431.stderr new file mode 100644 index 000000000000..132eea126d64 --- /dev/null +++ b/src/test/ui/asm/issue-51431.stderr @@ -0,0 +1,8 @@ +error[E0669]: invalid value for constraint in inline assembly + --> $DIR/issue-51431.rs:7:32 + | +LL | asm! {"mov $0,$1"::"0"("bx"),"1"(0x00)} + | ^^^^ + +error: aborting due to previous error + From 93fab980e3b6e02deeecf5168cd0f3745c698660 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 17:01:32 +0900 Subject: [PATCH 051/109] Add test for issue-52437 --- src/test/ui/closures/issue-52437.rs | 5 +++++ src/test/ui/closures/issue-52437.stderr | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/ui/closures/issue-52437.rs create mode 100644 src/test/ui/closures/issue-52437.stderr diff --git a/src/test/ui/closures/issue-52437.rs b/src/test/ui/closures/issue-52437.rs new file mode 100644 index 000000000000..6ac5380a5aa2 --- /dev/null +++ b/src/test/ui/closures/issue-52437.rs @@ -0,0 +1,5 @@ +fn main() { + [(); &(&'static: loop { |x| {}; }) as *const _ as usize] + //~^ ERROR: invalid label name `'static` + //~| ERROR: type annotations needed +} diff --git a/src/test/ui/closures/issue-52437.stderr b/src/test/ui/closures/issue-52437.stderr new file mode 100644 index 000000000000..e76f942e9ba5 --- /dev/null +++ b/src/test/ui/closures/issue-52437.stderr @@ -0,0 +1,15 @@ +error: invalid label name `'static` + --> $DIR/issue-52437.rs:2:13 + | +LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] + | ^^^^^^^ + +error[E0282]: type annotations needed + --> $DIR/issue-52437.rs:2:30 + | +LL | [(); &(&'static: loop { |x| {}; }) as *const _ as usize] + | ^ consider giving this closure parameter a type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. From 768965a2a65277a59bf6fb8d37ee5fbcfa57dc8c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Oct 2019 10:15:56 +0200 Subject: [PATCH 052/109] bring back some Debug instances for Miri --- src/librustc_mir/interpret/eval_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 2ab7c41bb787..0ff350f0bab2 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> { pub extra: Extra, } -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Debug)] pub enum StackPopCleanup { /// Jump to the next block in the caller, or cause UB if None (that's a function /// that may never return). Also store layout of return place so @@ -113,7 +113,7 @@ pub struct LocalState<'tcx, Tag=(), Id=AllocId> { } /// Current value of a local variable -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, Debug)] pub enum LocalValue { /// This local is not currently alive, and cannot be used at all. Dead, From fc5b48514ef6cc74a81686e71b7efe3659fcadb5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Oct 2019 10:18:38 +0200 Subject: [PATCH 053/109] add comments --- src/librustc_mir/interpret/eval_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 0ff350f0bab2..d929e958f05d 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -91,7 +91,7 @@ pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> { pub extra: Extra, } -#[derive(Clone, Eq, PartialEq, Debug)] +#[derive(Clone, Eq, PartialEq, Debug)] // Miri debug-prints these pub enum StackPopCleanup { /// Jump to the next block in the caller, or cause UB if None (that's a function /// that may never return). Also store layout of return place so @@ -113,7 +113,7 @@ pub struct LocalState<'tcx, Tag=(), Id=AllocId> { } /// Current value of a local variable -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] // Miri debug-prints these pub enum LocalValue { /// This local is not currently alive, and cannot be used at all. Dead, From ed965f1b6a299b729efad94836ff7498093f3236 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 22 Oct 2019 11:52:05 +0200 Subject: [PATCH 054/109] Update E0659 error code long explanation to 2018 edition --- src/librustc_resolve/error_codes.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index 8ccb27078d56..a7a3d71b5395 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1822,7 +1822,7 @@ An item usage is ambiguous. Erroneous code example: -```compile_fail,E0659 +```compile_fail,edition2018,E0659 pub mod moon { pub fn foo() {} } @@ -1832,12 +1832,12 @@ pub mod earth { } mod collider { - pub use moon::*; - pub use earth::*; + pub use crate::moon::*; + pub use crate::earth::*; } fn main() { - collider::foo(); // ERROR: `foo` is ambiguous + crate::collider::foo(); // ERROR: `foo` is ambiguous } ``` @@ -1849,7 +1849,7 @@ functions collide. To solve this error, the best solution is generally to keep the path before the item when using it. Example: -``` +```edition2018 pub mod moon { pub fn foo() {} } @@ -1859,13 +1859,13 @@ pub mod earth { } mod collider { - pub use moon; - pub use earth; + pub use crate::moon; + pub use crate::earth; } fn main() { - collider::moon::foo(); // ok! - collider::earth::foo(); // ok! + crate::collider::moon::foo(); // ok! + crate::collider::earth::foo(); // ok! } ``` "##, From 7a85c430fb978717ee1433cf5bee756f40544e74 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 17:01:49 +0900 Subject: [PATCH 055/109] Add test for issue-63496 --- src/test/ui/associated-const/issue-63496.rs | 9 ++++++++ .../ui/associated-const/issue-63496.stderr | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/associated-const/issue-63496.rs create mode 100644 src/test/ui/associated-const/issue-63496.stderr diff --git a/src/test/ui/associated-const/issue-63496.rs b/src/test/ui/associated-const/issue-63496.rs new file mode 100644 index 000000000000..311c48b5e48c --- /dev/null +++ b/src/test/ui/associated-const/issue-63496.rs @@ -0,0 +1,9 @@ +trait A { + const C: usize; + + fn f() -> ([u8; A::C], [u8; A::C]); + //~^ ERROR: type annotations needed: cannot resolve + //~| ERROR: type annotations needed: cannot resolve +} + +fn main() {} diff --git a/src/test/ui/associated-const/issue-63496.stderr b/src/test/ui/associated-const/issue-63496.stderr new file mode 100644 index 000000000000..70bb12de1fb7 --- /dev/null +++ b/src/test/ui/associated-const/issue-63496.stderr @@ -0,0 +1,21 @@ +error[E0283]: type annotations needed: cannot resolve `_: A` + --> $DIR/issue-63496.rs:4:21 + | +LL | const C: usize; + | --------------- required by `A::C` +LL | +LL | fn f() -> ([u8; A::C], [u8; A::C]); + | ^^^^ + +error[E0283]: type annotations needed: cannot resolve `_: A` + --> $DIR/issue-63496.rs:4:33 + | +LL | const C: usize; + | --------------- required by `A::C` +LL | +LL | fn f() -> ([u8; A::C], [u8; A::C]); + | ^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0283`. From 07f2f054ec5395536a0daddcb442c4a135fd8927 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Tue, 22 Oct 2019 12:07:07 +0200 Subject: [PATCH 056/109] Update error_codes.rs --- src/librustc_typeck/error_codes.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 892919cbf207..9e3235636534 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -194,7 +194,7 @@ a guard. ```compile_fail,E0029 let string = "salutations !"; -// The ordering relation for strings can't be evaluated at compile time, +// The ordering relation for strings cannot be evaluated at compile time, // so this doesn't work: match string { "hello" ..= "world" => {} @@ -348,7 +348,7 @@ fn main() { "##, E0044: r##" -You can't use type or const parameters on foreign items. +You cannot use type or const parameters on foreign items. Example of erroneous code: ```compile_fail,E0044 @@ -788,7 +788,7 @@ fn some_other_func() {} fn some_function() { SOME_CONST = 14; // error : a constant value cannot be changed! 1 = 3; // error : 1 isn't a valid place! - some_other_func() = 4; // error : we can't assign value to a function! + some_other_func() = 4; // error : we cannot assign value to a function! SomeStruct.x = 12; // error : SomeStruct a structure name but it is used // like a variable! } @@ -3905,8 +3905,8 @@ struct Aligned(i32); struct Packed(Aligned); ``` -Just like you can't have both `align` and `packed` representation hints on a -same type, a `packed` type can't contain another type with the `align` +Just like you cannot have both `align` and `packed` representation hints on a +same type, a `packed` type cannot contain another type with the `align` representation hint. However, you can do the opposite: ``` @@ -4326,7 +4326,7 @@ extern { unsafe { printf(::std::ptr::null(), 0f32); - // error: can't pass an `f32` to variadic function, cast to `c_double` + // error: cannot pass an `f32` to variadic function, cast to `c_double` } ``` @@ -5023,7 +5023,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC. // E0174, // E0182, // merged into E0229 E0183, -// E0187, // can't infer the kind of the closure +// E0187, // cannot infer the kind of the closure // E0188, // can not cast an immutable reference to a mutable pointer // E0189, // deprecated: can only cast a boxed pointer to a boxed object // E0190, // deprecated: can only cast a &-pointer to an &-object From 74db3e8a9e31adf0ed7b3e9f4e1093e6b6a40fc4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Oct 2019 21:22:41 +0300 Subject: [PATCH 057/109] rustc_metadata: use a table for super_predicates. --- src/librustc_metadata/decoder.rs | 14 ++++---------- src/librustc_metadata/encoder.rs | 23 +++++++++++++++-------- src/librustc_metadata/schema.rs | 13 ++++--------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b8b003024402..1ec7702af79d 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -448,7 +448,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Mod(_) => DefKind::Mod, EntryKind::Variant(_) => DefKind::Variant, EntryKind::Trait(_) => DefKind::Trait, - EntryKind::TraitAlias(_) => DefKind::TraitAlias, + EntryKind::TraitAlias => DefKind::TraitAlias, EntryKind::Enum(..) => DefKind::Enum, EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang), EntryKind::ForeignType => DefKind::ForeignTy, @@ -575,7 +575,7 @@ impl<'a, 'tcx> CrateMetadata { data.is_marker, self.def_path_table.def_path_hash(item_id)) }, - EntryKind::TraitAlias(_) => { + EntryKind::TraitAlias => { ty::TraitDef::new(self.local_def_id(item_id), hir::Unsafety::Normal, false, @@ -680,13 +680,7 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'tcx>, ) -> ty::GenericPredicates<'tcx> { - let super_predicates = match self.kind(item_id) { - EntryKind::Trait(data) => data.decode(self).super_predicates, - EntryKind::TraitAlias(data) => data.decode(self).super_predicates, - _ => bug!("def-index does not refer to trait or trait alias"), - }; - - super_predicates.decode((self, tcx)) + self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx)) } crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics { @@ -1118,7 +1112,7 @@ impl<'a, 'tcx> CrateMetadata { def_key.parent.and_then(|parent_index| { match self.kind(parent_index) { EntryKind::Trait(_) | - EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)), + EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), _ => None, } }) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6ae8c2fc6c69..79a7caa292b0 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -76,6 +76,7 @@ struct PerDefTables<'tcx> { generics: PerDefTable>, predicates: PerDefTable>>, predicates_defined_on: PerDefTable>>, + super_predicates: PerDefTable>>, mir: PerDefTable>>, promoted_mir: PerDefTable>>>, @@ -513,6 +514,7 @@ impl<'tcx> EncodeContext<'tcx> { generics: self.per_def.generics.encode(&mut self.opaque), predicates: self.per_def.predicates.encode(&mut self.opaque), predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque), + super_predicates: self.per_def.super_predicates.encode(&mut self.opaque), mir: self.per_def.mir.encode(&mut self.opaque), promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque), @@ -835,6 +837,11 @@ impl EncodeContext<'tcx> { self.tcx.predicates_defined_on(def_id)) } + fn encode_super_predicates(&mut self, def_id: DefId) { + debug!("EncodeContext::encode_super_predicates({:?})", def_id); + record!(self.per_def.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id)); + } + fn encode_info_for_trait_item(&mut self, def_id: DefId) { debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id); let tcx = self.tcx; @@ -1166,18 +1173,11 @@ impl EncodeContext<'tcx> { paren_sugar: trait_def.paren_sugar, has_auto_impl: self.tcx.trait_is_auto(def_id), is_marker: trait_def.is_marker, - super_predicates: self.lazy(tcx.super_predicates_of(def_id)), }; EntryKind::Trait(self.lazy(data)) } - hir::ItemKind::TraitAlias(..) => { - let data = TraitAliasData { - super_predicates: self.lazy(tcx.super_predicates_of(def_id)), - }; - - EntryKind::TraitAlias(self.lazy(data)) - } + hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias, hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), }); @@ -1269,6 +1269,13 @@ impl EncodeContext<'tcx> { } _ => {} // not *wrong* for other kinds of items, but not needed } + match item.kind { + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => { + self.encode_super_predicates(def_id); + } + _ => {} + } let mir = match item.kind { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 96f35783278f..b681078ee0d5 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -243,6 +243,7 @@ crate struct LazyPerDefTables<'tcx> { pub generics: Lazy!(PerDefTable>), pub predicates: Lazy!(PerDefTable)>), pub predicates_defined_on: Lazy!(PerDefTable)>), + pub super_predicates: Lazy!(PerDefTable)>), pub mir: Lazy!(PerDefTable)>), pub promoted_mir: Lazy!(PerDefTable>)>), @@ -273,13 +274,13 @@ crate enum EntryKind<'tcx> { MacroDef(Lazy), Closure(Lazy!(ClosureData<'tcx>)), Generator(Lazy!(GeneratorData<'tcx>)), - Trait(Lazy!(TraitData<'tcx>)), + Trait(Lazy), Impl(Lazy!(ImplData<'tcx>)), Method(Lazy!(MethodData<'tcx>)), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, ConstQualif, Lazy), - TraitAlias(Lazy!(TraitAliasData<'tcx>)), + TraitAlias, } /// Additional data for EntryKind::Const and EntryKind::AssocConst @@ -324,17 +325,11 @@ crate struct VariantData<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -crate struct TraitData<'tcx> { +crate struct TraitData { pub unsafety: hir::Unsafety, pub paren_sugar: bool, pub has_auto_impl: bool, pub is_marker: bool, - pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>), -} - -#[derive(RustcEncodable, RustcDecodable)] -crate struct TraitAliasData<'tcx> { - pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>), } #[derive(RustcEncodable, RustcDecodable)] From 66a025378025742a2a867287c4683e1209d15f65 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 22 Oct 2019 12:53:46 +0200 Subject: [PATCH 058/109] self-profiling: Remove module names from some event-ids in codegen backend. --- src/librustc_codegen_ssa/back/write.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 8bc815f2c622..762b50f1659c 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -259,7 +259,7 @@ fn generate_lto_work( needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule, WorkProduct)> ) -> Vec<(WorkItem, u64)> { - let _prof_timer = cgcx.prof.generic_activity("codegen_run_lto"); + let _prof_timer = cgcx.prof.generic_activity("codegen_generate_lto_work"); let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); @@ -674,11 +674,11 @@ impl WorkItem { } } - pub fn name(&self) -> String { + fn profiling_event_id(&self) -> &'static str { match *self { - WorkItem::Optimize(ref m) => format!("optimize: {}", m.name), - WorkItem::CopyPostLtoArtifacts(ref m) => format!("copy post LTO artifacts: {}", m.name), - WorkItem::LTO(ref m) => format!("lto: {}", m.name()), + WorkItem::Optimize(_) => "codegen_module_optimize", + WorkItem::CopyPostLtoArtifacts(_) => "codegen_copy_artifacts_from_incr_cache", + WorkItem::LTO(_) => "codegen_module_perform_lto", } } } @@ -1587,7 +1587,7 @@ fn spawn_work( // as a diagnostic was already sent off to the main thread - just // surface that there was an error in this worker. bomb.result = { - let _prof_timer = cgcx.prof.generic_activity(&work.name()); + let _prof_timer = cgcx.prof.generic_activity(work.profiling_event_id()); execute_work_item(&cgcx, work).ok() }; }); From 7a80a11a83f1b00e750f3d1c235b67ef8ab70c29 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Oct 2019 22:15:14 +0300 Subject: [PATCH 059/109] rustc_metadata: use a table for fn_sig. --- src/librustc_metadata/decoder.rs | 13 ++------ src/librustc_metadata/encoder.rs | 53 +++++++++++++++----------------- src/librustc_metadata/schema.rs | 32 ++++++++----------- 3 files changed, 38 insertions(+), 60 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1ec7702af79d..9c7b721fb7f6 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -458,7 +458,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Impl(_) | EntryKind::Field | EntryKind::Generator(_) | - EntryKind::Closure(_) => return None, + EntryKind::Closure => return None, }) } } @@ -1239,16 +1239,7 @@ impl<'a, 'tcx> CrateMetadata { } crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { - let sig = match self.kind(id) { - EntryKind::Fn(data) | - EntryKind::ForeignFn(data) => data.decode(self).sig, - EntryKind::Method(data) => data.decode(self).fn_data.sig, - EntryKind::Variant(data) | - EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(), - EntryKind::Closure(data) => data.decode(self).sig, - _ => bug!(), - }; - sig.decode((self, tcx)) + self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx)) } #[inline] diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 79a7caa292b0..e3ad1c5e197b 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -71,6 +71,7 @@ struct PerDefTables<'tcx> { deprecation: PerDefTable>, ty: PerDefTable>>, + fn_sig: PerDefTable>>, inherent_impls: PerDefTable>, variances: PerDefTable>, generics: PerDefTable>, @@ -509,6 +510,7 @@ impl<'tcx> EncodeContext<'tcx> { deprecation: self.per_def.deprecation.encode(&mut self.opaque), ty: self.per_def.ty.encode(&mut self.opaque), + fn_sig: self.per_def.fn_sig.encode(&mut self.opaque), inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), variances: self.per_def.variances.encode(&mut self.opaque), generics: self.per_def.generics.encode(&mut self.opaque), @@ -637,13 +639,7 @@ impl EncodeContext<'tcx> { let data = VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, - // FIXME(eddyb) deduplicate these with `encode_enum_variant_ctor`. ctor: variant.ctor_def_id.map(|did| did.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - variant.ctor_def_id.map(|ctor_def_id| self.lazy(&tcx.fn_sig(ctor_def_id))) - } else { - None - }, }; let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap(); @@ -662,6 +658,11 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. + if let Some(ctor_def_id) = variant.ctor_def_id { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); + } + // FIXME(eddyb) is this ever used? self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -681,15 +682,11 @@ impl EncodeContext<'tcx> { let def_id = variant.ctor_def_id.unwrap(); debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id); + // FIXME(eddyb) encode only the `CtorKind` for constructors. let data = VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(tcx.fn_sig(def_id))) - } else { - None - } }; // Variant constructors have the same visibility as the parent enums, unless marked as @@ -708,6 +705,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -782,11 +780,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(tcx.fn_sig(def_id))) - } else { - None - } }; let struct_id = tcx.hir().as_local_hir_id(adt_def_id).unwrap(); @@ -813,6 +806,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -881,7 +875,6 @@ impl EncodeContext<'tcx> { asyncness: m_sig.header.asyncness, constness: hir::Constness::NotConst, param_names, - sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() @@ -913,6 +906,7 @@ impl EncodeContext<'tcx> { ty::AssocKind::OpaqueTy => unreachable!(), } if trait_item.kind == ty::AssocKind::Method { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -959,7 +953,6 @@ impl EncodeContext<'tcx> { asyncness: sig.header.asyncness, constness: sig.header.constness, param_names: self.encode_fn_param_names_for_body(body), - sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() @@ -980,6 +973,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if impl_item.kind == ty::AssocKind::Method { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -1088,7 +1082,6 @@ impl EncodeContext<'tcx> { asyncness: header.asyncness, constness: header.constness, param_names: self.encode_fn_param_names_for_body(body), - sig: self.lazy(tcx.fn_sig(def_id)), }; EntryKind::Fn(self.lazy(data)) @@ -1116,7 +1109,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor, - ctor_sig: None, }), adt_def.repr) } hir::ItemKind::Union(..) => { @@ -1127,7 +1119,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: None, - ctor_sig: None, }), adt_def.repr) } hir::ItemKind::Impl(_, _, defaultness, ..) => { @@ -1232,6 +1223,9 @@ impl EncodeContext<'tcx> { hir::ItemKind::Impl(..) => self.encode_item_type(def_id), _ => {} } + if let hir::ItemKind::Fn(..) = item.kind { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + } self.encode_inherent_implementations(def_id); match item.kind { hir::ItemKind::Enum(..) | @@ -1328,10 +1322,12 @@ impl EncodeContext<'tcx> { fn encode_info_for_closure(&mut self, def_id: DefId) { debug!("EncodeContext::encode_info_for_closure({:?})", def_id); - let tables = self.tcx.typeck_tables_of(def_id); + // NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic, + // including on the signature, which is inferred in `typeck_tables_of. let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap(); + let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id); - record!(self.per_def.kind[def_id] <- match tables.node_type(hir_id).kind { + record!(self.per_def.kind[def_id] <- match ty.kind { ty::Generator(def_id, ..) => { let layout = self.tcx.generator_layout(def_id); let data = GeneratorData { @@ -1340,11 +1336,7 @@ impl EncodeContext<'tcx> { EntryKind::Generator(self.lazy(data)) } - ty::Closure(def_id, substs) => { - let sig = substs.as_closure().sig(def_id, self.tcx); - let data = ClosureData { sig: self.lazy(sig) }; - EntryKind::Closure(self.lazy(data)) - } + ty::Closure(..) => EntryKind::Closure, _ => bug!("closure that is neither generator nor closure"), }); @@ -1352,6 +1344,9 @@ impl EncodeContext<'tcx> { record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); self.encode_item_type(def_id); + if let ty::Closure(def_id, substs) = ty.kind { + record!(self.per_def.fn_sig[def_id] <- substs.as_closure().sig(def_id, self.tcx)); + } self.encode_generics(def_id); self.encode_optimized_mir(def_id); self.encode_promoted_mir(def_id); @@ -1560,7 +1555,6 @@ impl EncodeContext<'tcx> { asyncness: hir::IsAsync::NotAsync, constness: hir::Constness::NotConst, param_names: self.encode_fn_param_names(names), - sig: self.lazy(tcx.fn_sig(def_id)), }; EntryKind::ForeignFn(self.lazy(data)) } @@ -1576,6 +1570,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if let hir::ForeignItemKind::Fn(..) = nitem.kind { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index b681078ee0d5..03754c92252a 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -238,6 +238,7 @@ crate struct LazyPerDefTables<'tcx> { pub deprecation: Lazy!(PerDefTable>), pub ty: Lazy!(PerDefTable)>), + pub fn_sig: Lazy!(PerDefTable)>), pub inherent_impls: Lazy!(PerDefTable>), pub variances: Lazy!(PerDefTable>), pub generics: Lazy!(PerDefTable>), @@ -265,18 +266,18 @@ crate enum EntryKind<'tcx> { OpaqueTy, Enum(ReprOptions), Field, - Variant(Lazy!(VariantData<'tcx>)), - Struct(Lazy!(VariantData<'tcx>), ReprOptions), - Union(Lazy!(VariantData<'tcx>), ReprOptions), - Fn(Lazy!(FnData<'tcx>)), - ForeignFn(Lazy!(FnData<'tcx>)), + Variant(Lazy), + Struct(Lazy, ReprOptions), + Union(Lazy, ReprOptions), + Fn(Lazy), + ForeignFn(Lazy), Mod(Lazy), MacroDef(Lazy), - Closure(Lazy!(ClosureData<'tcx>)), + Closure, Generator(Lazy!(GeneratorData<'tcx>)), Trait(Lazy), Impl(Lazy!(ImplData<'tcx>)), - Method(Lazy!(MethodData<'tcx>)), + Method(Lazy), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, ConstQualif, Lazy), @@ -306,22 +307,18 @@ crate struct MacroDef { } #[derive(RustcEncodable, RustcDecodable)] -crate struct FnData<'tcx> { +crate struct FnData { pub asyncness: hir::IsAsync, pub constness: hir::Constness, pub param_names: Lazy<[ast::Name]>, - pub sig: Lazy!(ty::PolyFnSig<'tcx>), } #[derive(RustcEncodable, RustcDecodable)] -crate struct VariantData<'tcx> { +crate struct VariantData { pub ctor_kind: CtorKind, pub discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. pub ctor: Option, - /// If this is a tuple struct or variant - /// ctor, this is its "function" signature. - pub ctor_sig: Option)>, } #[derive(RustcEncodable, RustcDecodable)] @@ -383,17 +380,12 @@ impl AssocContainer { } #[derive(RustcEncodable, RustcDecodable)] -crate struct MethodData<'tcx> { - pub fn_data: FnData<'tcx>, +crate struct MethodData { + pub fn_data: FnData, pub container: AssocContainer, pub has_self: bool, } -#[derive(RustcEncodable, RustcDecodable)] -crate struct ClosureData<'tcx> { - pub sig: Lazy!(ty::PolyFnSig<'tcx>), -} - #[derive(RustcEncodable, RustcDecodable)] crate struct GeneratorData<'tcx> { pub layout: mir::GeneratorLayout<'tcx>, From 371cc39b256d0fa5ec0da3193e0ec6f9377bd903 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 19 Oct 2019 01:10:58 +0300 Subject: [PATCH 060/109] rustc_metadata: use a table for impl_trait_ref. --- src/librustc_metadata/decoder.rs | 4 ++-- src/librustc_metadata/encoder.rs | 8 +++++++- src/librustc_metadata/schema.rs | 7 ++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 9c7b721fb7f6..1333e3fb3ce3 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -711,7 +711,7 @@ impl<'a, 'tcx> CrateMetadata { } } - fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> { + fn get_impl_data(&self, id: DefIndex) -> ImplData { match self.kind(id) { EntryKind::Impl(data) => data.decode(self), _ => bug!(), @@ -738,7 +738,7 @@ impl<'a, 'tcx> CrateMetadata { } crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option> { - self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx))) + self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx))) } /// Iterates over all the stability attributes in the given crate. diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e3ad1c5e197b..0dc9f91ae00e 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -72,6 +72,7 @@ struct PerDefTables<'tcx> { ty: PerDefTable>>, fn_sig: PerDefTable>>, + impl_trait_ref: PerDefTable>>, inherent_impls: PerDefTable>, variances: PerDefTable>, generics: PerDefTable>, @@ -511,6 +512,7 @@ impl<'tcx> EncodeContext<'tcx> { ty: self.per_def.ty.encode(&mut self.opaque), fn_sig: self.per_def.fn_sig.encode(&mut self.opaque), + impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque), inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), variances: self.per_def.variances.encode(&mut self.opaque), generics: self.per_def.generics.encode(&mut self.opaque), @@ -1152,7 +1154,6 @@ impl EncodeContext<'tcx> { defaultness, parent_impl: parent, coerce_unsized_info, - trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)), }; EntryKind::Impl(self.lazy(data)) @@ -1226,6 +1227,11 @@ impl EncodeContext<'tcx> { if let hir::ItemKind::Fn(..) = item.kind { record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); } + if let hir::ItemKind::Impl(..) = item.kind { + if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { + record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); + } + } self.encode_inherent_implementations(def_id); match item.kind { hir::ItemKind::Enum(..) | diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 03754c92252a..ad39aa34fd5c 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -239,6 +239,7 @@ crate struct LazyPerDefTables<'tcx> { pub ty: Lazy!(PerDefTable)>), pub fn_sig: Lazy!(PerDefTable)>), + pub impl_trait_ref: Lazy!(PerDefTable)>), pub inherent_impls: Lazy!(PerDefTable>), pub variances: Lazy!(PerDefTable>), pub generics: Lazy!(PerDefTable>), @@ -276,7 +277,7 @@ crate enum EntryKind<'tcx> { Closure, Generator(Lazy!(GeneratorData<'tcx>)), Trait(Lazy), - Impl(Lazy!(ImplData<'tcx>)), + Impl(Lazy), Method(Lazy), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), @@ -330,14 +331,14 @@ crate struct TraitData { } #[derive(RustcEncodable, RustcDecodable)] -crate struct ImplData<'tcx> { +crate struct ImplData { pub polarity: ty::ImplPolarity, pub defaultness: hir::Defaultness, pub parent_impl: Option, /// This is `Some` only for impls of `CoerceUnsized`. + // FIXME(eddyb) perhaps compute this on the fly if cheap enough? pub coerce_unsized_info: Option, - pub trait_ref: Option)>, } From 600607f45a400e5930126b5ef1dc05f5644e95c3 Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 20 Oct 2019 17:16:58 +0100 Subject: [PATCH 061/109] Move `search_for_adt_without_structural_match` to `ty/mod` --- src/librustc/ty/mod.rs | 117 ++++++++++++++++++++++++- src/librustc_mir/hair/pattern/mod.rs | 122 +-------------------------- 2 files changed, 116 insertions(+), 123 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d377b7328e80..77d8141c9688 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -4,7 +4,7 @@ pub use self::Variance::*; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; -pub use self::fold::TypeFoldable; +pub use self::fold::{TypeFoldable, TypeVisitor}; use crate::hir::{map as hir_map, GlobMap, TraitMap}; use crate::hir::Node; @@ -50,7 +50,7 @@ use syntax::symbol::{kw, sym, Symbol, InternedString}; use syntax_pos::Span; use smallvec; -use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use rustc_index::vec::{Idx, IndexVec}; @@ -3393,6 +3393,119 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { fn_like.asyncness() } +/// This method traverses the structure of `ty`, trying to find an +/// instance of an ADT (i.e. struct or enum) that was declared without +/// the `#[structural_match]` attribute. +/// +/// The "structure of a type" includes all components that would be +/// considered when doing a pattern match on a constant of that +/// type. +/// +/// * This means this method descends into fields of structs/enums, +/// and also descends into the inner type `T` of `&T` and `&mut T` +/// +/// * The traversal doesn't dereference unsafe pointers (`*const T`, +/// `*mut T`), and it does not visit the type arguments of an +/// instantiated generic like `PhantomData`. +/// +/// The reason we do this search is Rust currently require all ADTs +/// reachable from a constant's type to be annotated with +/// `#[structural_match]`, an attribute which essentially says that +/// the implementation of `PartialEq::eq` behaves *equivalently* to a +/// comparison against the unfolded structure. +/// +/// For more background on why Rust has this requirement, and issues +/// that arose when the requirement was not enforced completely, see +/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. +pub fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>) + -> Option<&'tcx AdtDef> +{ + let mut search = Search { tcx, found: None, seen: FxHashSet::default() }; + ty.visit_with(&mut search); + return search.found; + + struct Search<'tcx> { + tcx: TyCtxt<'tcx>, + + // records the first ADT we find without `#[structural_match` + found: Option<&'tcx AdtDef>, + + // tracks ADT's previously encountered during search, so that + // we will not recur on them again. + seen: FxHashSet, + } + + impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + debug!("Search visiting ty: {:?}", ty); + + let (adt_def, substs) = match ty.kind { + ty::Adt(adt_def, substs) => (adt_def, substs), + ty::RawPtr(..) => { + // `#[structural_match]` ignores substructure of + // `*const _`/`*mut _`, so skip super_visit_with + // + // (But still tell caller to continue search.) + return false; + } + ty::FnDef(..) | ty::FnPtr(..) => { + // types of formals and return in `fn(_) -> _` are also irrelevant + // + // (But still tell caller to continue search.) + return false; + } + ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) + => { + // rust-lang/rust#62336: ignore type of contents + // for empty array. + return false; + } + _ => { + ty.super_visit_with(self); + return false; + } + }; + + if !self.tcx.has_attr(adt_def.did, sym::structural_match) { + self.found = Some(&adt_def); + debug!("Search found adt_def: {:?}", adt_def); + return true // Halt visiting! + } + + if !self.seen.insert(adt_def.did) { + debug!("Search already seen adt_def: {:?}", adt_def); + // let caller continue its search + return false; + } + + // `#[structural_match]` does not care about the + // instantiation of the generics in an ADT (it + // instead looks directly at its fields outside + // this match), so we skip super_visit_with. + // + // (Must not recur on substs for `PhantomData` cf + // rust-lang/rust#55028 and rust-lang/rust#55837; but also + // want to skip substs when only uses of generic are + // behind unsafe pointers `*const T`/`*mut T`.) + + // even though we skip super_visit_with, we must recur on + // fields of ADT. + let tcx = self.tcx; + for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) { + if field_ty.visit_with(self) { + // found an ADT without `#[structural_match]`; halt visiting! + assert!(self.found.is_some()); + return true; + } + } + + // Even though we do not want to recur on substs, we do + // want our caller to continue its own search. + false + } + } +} pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 58480912929b..d99688122185 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -25,7 +25,6 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::ptr::P; use rustc_index::vec::Idx; -use rustc_data_structures::fx::FxHashSet; use std::cmp::Ordering; use std::fmt; @@ -1000,7 +999,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if self.include_lint_checks && !saw_error { // If we were able to successfully convert the const to some pat, double-check // that the type of the const obeys `#[structural_match]` constraint. - if let Some(adt_def) = search_for_adt_without_structural_match(self.tcx, cv.ty) { + if let Some(adt_def) = ty::search_for_adt_without_structural_match(self.tcx, cv.ty) { let path = self.tcx.def_path_str(adt_def.did); let msg = format!( @@ -1169,125 +1168,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } } -/// This method traverses the structure of `ty`, trying to find an -/// instance of an ADT (i.e. struct or enum) that was declared without -/// the `#[structural_match]` attribute. -/// -/// The "structure of a type" includes all components that would be -/// considered when doing a pattern match on a constant of that -/// type. -/// -/// * This means this method descends into fields of structs/enums, -/// and also descends into the inner type `T` of `&T` and `&mut T` -/// -/// * The traversal doesn't dereference unsafe pointers (`*const T`, -/// `*mut T`), and it does not visit the type arguments of an -/// instantiated generic like `PhantomData`. -/// -/// The reason we do this search is Rust currently require all ADT's -/// reachable from a constant's type to be annotated with -/// `#[structural_match]`, an attribute which essentially says that -/// the implementation of `PartialEq::eq` behaves *equivalently* to a -/// comparison against the unfolded structure. -/// -/// For more background on why Rust has this requirement, and issues -/// that arose when the requirement was not enforced completely, see -/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. -fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>) - -> Option<&'tcx AdtDef> -{ - // Import here (not mod level), because `TypeFoldable::fold_with` - // conflicts with `PatternFoldable::fold_with` - use crate::rustc::ty::fold::TypeVisitor; - use crate::rustc::ty::TypeFoldable; - - let mut search = Search { tcx, found: None, seen: FxHashSet::default() }; - ty.visit_with(&mut search); - return search.found; - - struct Search<'tcx> { - tcx: TyCtxt<'tcx>, - - // records the first ADT we find without `#[structural_match` - found: Option<&'tcx AdtDef>, - - // tracks ADT's previously encountered during search, so that - // we will not recur on them again. - seen: FxHashSet, - } - - impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { - fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { - debug!("Search visiting ty: {:?}", ty); - - let (adt_def, substs) = match ty.kind { - ty::Adt(adt_def, substs) => (adt_def, substs), - ty::RawPtr(..) => { - // `#[structural_match]` ignores substructure of - // `*const _`/`*mut _`, so skip super_visit_with - // - // (But still tell caller to continue search.) - return false; - } - ty::FnDef(..) | ty::FnPtr(..) => { - // types of formals and return in `fn(_) -> _` are also irrelevant - // - // (But still tell caller to continue search.) - return false; - } - ty::Array(_, n) if n.try_eval_usize(self.tcx, ty::ParamEnv::reveal_all()) == Some(0) - => { - // rust-lang/rust#62336: ignore type of contents - // for empty array. - return false; - } - _ => { - ty.super_visit_with(self); - return false; - } - }; - - if !self.tcx.has_attr(adt_def.did, sym::structural_match) { - self.found = Some(&adt_def); - debug!("Search found adt_def: {:?}", adt_def); - return true // Halt visiting! - } - - if !self.seen.insert(adt_def.did) { - debug!("Search already seen adt_def: {:?}", adt_def); - // let caller continue its search - return false; - } - - // `#[structural_match]` does not care about the - // instantiation of the generics in an ADT (it - // instead looks directly at its fields outside - // this match), so we skip super_visit_with. - // - // (Must not recur on substs for `PhantomData` cf - // rust-lang/rust#55028 and rust-lang/rust#55837; but also - // want to skip substs when only uses of generic are - // behind unsafe pointers `*const T`/`*mut T`.) - - // even though we skip super_visit_with, we must recur on - // fields of ADT. - let tcx = self.tcx; - for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) { - if field_ty.visit_with(self) { - // found an ADT without `#[structural_match]`; halt visiting! - assert!(self.found.is_some()); - return true; - } - } - - // Even though we do not want to recur on substs, we do - // want our caller to continue its own search. - false - } - } -} - impl UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx From bbd53deaeb79e78162524e18ca29211745e2d18e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 20 Oct 2019 17:17:12 +0100 Subject: [PATCH 062/109] Forbid non-`structural_match` types in const generics --- src/librustc_typeck/collect.rs | 11 +++++++++ src/librustc_typeck/error_codes.rs | 24 +++++++++++++++++++ .../forbid-non-structural_match-types.rs | 13 ++++++++++ .../forbid-non-structural_match-types.stderr | 17 +++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 src/test/ui/const-generics/forbid-non-structural_match-types.rs create mode 100644 src/test/ui/const-generics/forbid-non-structural_match-types.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1749fd1075e0..d6162c0bc0e9 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1532,6 +1532,17 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option { diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index 3ecbf620cbc7..5d1afcaef914 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4978,6 +4978,30 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC. [RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md "##, +E0739: r##" +Only `structural_match` types (that is, types that derive `PartialEq` and `Eq`) +may be used as the types of const generic parameters. + +```compile_fail,E0739 +#![feature(const_generics)] + +struct A; + +struct B; // error! +``` + +To fix this example, we derive `PartialEq` and `Eq`. + +``` +#![feature(const_generics)] + +#[derive(PartialEq, Eq)] +struct A; + +struct B; // ok! +``` +"##, + ; // E0035, merged into E0087/E0089 // E0036, merged into E0087/E0089 diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.rs b/src/test/ui/const-generics/forbid-non-structural_match-types.rs new file mode 100644 index 000000000000..7bc4f3986eb7 --- /dev/null +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.rs @@ -0,0 +1,13 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +#[derive(PartialEq, Eq)] +struct A; + +struct B; // ok + +struct C; + +struct D; //~ ERROR the types of const generic parameters must derive + +fn main() {} diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr new file mode 100644 index 000000000000..9ab6c69521be --- /dev/null +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr @@ -0,0 +1,17 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/forbid-non-structural_match-types.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + +error[E0739]: the types of const generic parameters must derive `PartialEq` and `Eq` + --> $DIR/forbid-non-structural_match-types.rs:11:19 + | +LL | struct D; + | ^ `C` doesn't derive both `PartialEq` and `Eq` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0739`. From 133cd2cfaf244c130e2e0d681090ca117bcba94e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 20 Oct 2019 18:17:42 +0100 Subject: [PATCH 063/109] Search for generic parameters when finding non-`structural_match` types --- src/librustc/ty/mod.rs | 32 ++++++++++++------- src/librustc_mir/hair/pattern/mod.rs | 24 ++++++++------ src/librustc_typeck/collect.rs | 4 +-- src/librustc_typeck/error_codes.rs | 4 +-- .../forbid-non-structural_match-types.stderr | 4 +-- 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 77d8141c9688..6c512a0238ee 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3393,9 +3393,15 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { fn_like.asyncness() } +pub enum NonStructuralMatchTy<'tcx> { + Adt(&'tcx AdtDef), + Param, +} + /// This method traverses the structure of `ty`, trying to find an /// instance of an ADT (i.e. struct or enum) that was declared without -/// the `#[structural_match]` attribute. +/// the `#[structural_match]` attribute, or a generic type parameter +/// (which cannot be determined to be `structural_match`). /// /// The "structure of a type" includes all components that would be /// considered when doing a pattern match on a constant of that @@ -3417,10 +3423,10 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { /// For more background on why Rust has this requirement, and issues /// that arose when the requirement was not enforced completely, see /// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. -pub fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>) - -> Option<&'tcx AdtDef> -{ +pub fn search_for_structural_match_violation<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> Option> { let mut search = Search { tcx, found: None, seen: FxHashSet::default() }; ty.visit_with(&mut search); return search.found; @@ -3428,11 +3434,11 @@ pub fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, struct Search<'tcx> { tcx: TyCtxt<'tcx>, - // records the first ADT we find without `#[structural_match` - found: Option<&'tcx AdtDef>, + // Records the first ADT or type parameter we find without `#[structural_match`. + found: Option>, - // tracks ADT's previously encountered during search, so that - // we will not recur on them again. + // Tracks ADTs previously encountered during search, so that + // we will not recurse on them again. seen: FxHashSet, } @@ -3442,6 +3448,10 @@ pub fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, let (adt_def, substs) = match ty.kind { ty::Adt(adt_def, substs) => (adt_def, substs), + ty::Param(_) => { + self.found = Some(NonStructuralMatchTy::Param); + return true; // Stop visiting. + } ty::RawPtr(..) => { // `#[structural_match]` ignores substructure of // `*const _`/`*mut _`, so skip super_visit_with @@ -3468,9 +3478,9 @@ pub fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>, }; if !self.tcx.has_attr(adt_def.did, sym::structural_match) { - self.found = Some(&adt_def); + self.found = Some(NonStructuralMatchTy::Adt(&adt_def)); debug!("Search found adt_def: {:?}", adt_def); - return true // Halt visiting! + return true; // Stop visiting. } if !self.seen.insert(adt_def.did) { diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index d99688122185..98e286e61e94 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -999,15 +999,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if self.include_lint_checks && !saw_error { // If we were able to successfully convert the const to some pat, double-check // that the type of the const obeys `#[structural_match]` constraint. - if let Some(adt_def) = ty::search_for_adt_without_structural_match(self.tcx, cv.ty) { - - let path = self.tcx.def_path_str(adt_def.did); - let msg = format!( - "to use a constant of type `{}` in a pattern, \ - `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - path, - path, - ); + if let Some(non_sm_ty) = ty::search_for_structural_match_violation(self.tcx, cv.ty) { + let msg = match non_sm_ty { + ty::NonStructuralMatchTy::Adt(adt_def) => { + let path = self.tcx.def_path_str(adt_def.did); + format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + path, + path, + ) + } + ty::NonStructuralMatchTy::Param => { + bug!("use of constant whose type is a parameter inside a pattern"); + } + }; // before issuing lint, double-check there even *is* a // semantic PartialEq for us to dispatch to. diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d6162c0bc0e9..08fb5ae1676e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1532,11 +1532,11 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option $DIR/forbid-non-structural_match-types.rs:11:19 | LL | struct D; @@ -14,4 +14,4 @@ LL | struct D; error: aborting due to previous error -For more information about this error, try `rustc --explain E0739`. +For more information about this error, try `rustc --explain E0740`. From f0e6cd9f89d3cdb11f417707690679fc334dfe0a Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 20 Oct 2019 18:18:24 +0100 Subject: [PATCH 064/109] Remove "type parameter depends on const parameter" error from resolution --- src/librustc_resolve/diagnostics.rs | 10 -------- src/librustc_resolve/error_codes.rs | 7 +++--- src/librustc_resolve/late.rs | 23 +------------------ src/librustc_resolve/lib.rs | 15 ++---------- ...aram-type-depends-on-type-param-ungated.rs | 2 +- ...-type-depends-on-type-param-ungated.stderr | 14 +++++------ .../const-param-type-depends-on-type-param.rs | 3 +-- ...st-param-type-depends-on-type-param.stderr | 19 ++++----------- 8 files changed, 21 insertions(+), 72 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 5647d5b2794a..7634093fbefb 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -367,16 +367,6 @@ impl<'a> Resolver<'a> { span, "`Self` in type parameter default".to_string()); err } - ResolutionError::ConstParamDependentOnTypeParam => { - let mut err = struct_span_err!( - self.session, - span, - E0671, - "const parameters cannot depend on type parameters" - ); - err.span_label(span, format!("const parameter depends on type parameter")); - err - } } } diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index b82cba8c83dc..49f8e82a2d1b 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1880,13 +1880,14 @@ fn main() { "##, E0671: r##" +#### Note: this error code is no longer emitted by the compiler. + Const parameters cannot depend on type parameters. The following is therefore invalid: -```compile_fail,E0671 +```compile_fail,E0740 #![feature(const_generics)] -fn const_id() -> T { // error: const parameter - // depends on type parameter +fn const_id() -> T { // error N } ``` diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 73a282b1a0ec..136ab1f0444f 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -111,9 +111,6 @@ crate enum RibKind<'a> { /// from the default of a type parameter because they're not declared /// before said type parameter. Also see the `visit_generics` override. ForwardTyParamBanRibKind, - - /// We forbid the use of type parameters as the types of const parameters. - TyParamAsConstParamTy, } impl RibKind<'_> { @@ -128,8 +125,7 @@ impl RibKind<'_> { | MacroDefinition(_) => false, AssocItemRibKind | ItemRibKind(_) - | ForwardTyParamBanRibKind - | TyParamAsConstParamTy => true, + | ForwardTyParamBanRibKind => true, } } } @@ -483,18 +479,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { default_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err); } - // We also ban access to type parameters for use as the types of const parameters. - let mut const_ty_param_ban_rib = Rib::new(TyParamAsConstParamTy); - const_ty_param_ban_rib.bindings.extend(generics.params.iter() - .filter(|param| { - if let GenericParamKind::Type { .. } = param.kind { - true - } else { - false - } - }) - .map(|param| (Ident::with_dummy_span(param.ident.name), Res::Err))); - for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => self.visit_generic_param(param), @@ -513,15 +497,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name)); } GenericParamKind::Const { ref ty } => { - self.ribs[TypeNS].push(const_ty_param_ban_rib); - for bound in ¶m.bounds { self.visit_param_bound(bound); } - self.visit_ty(ty); - - const_ty_param_ban_rib = self.ribs[TypeNS].pop().unwrap(); } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 17d8f0f211a9..1cc21a54e3cf 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -215,8 +215,6 @@ enum ResolutionError<'a> { ForwardDeclaredTyParam, // FIXME(const_generics:defaults) /// Error E0735: type parameters with a default cannot use `Self` SelfInTyParamDefault, - /// Error E0671: const parameter cannot depend on type parameter. - ConstParamDependentOnTypeParam, } // A minimal representation of a path segment. We use this in resolve because @@ -2169,15 +2167,6 @@ impl<'a> Resolver<'a> { return Res::Err; } - // An invalid use of a type parameter as the type of a const parameter. - if let TyParamAsConstParamTy = all_ribs[rib_index].kind { - if record_used { - self.report_error(span, ResolutionError::ConstParamDependentOnTypeParam); - } - assert_eq!(res, Res::Err); - return Res::Err; - } - match res { Res::Local(_) => { use ResolutionError::*; @@ -2186,7 +2175,7 @@ impl<'a> Resolver<'a> { for rib in ribs { match rib.kind { NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) | - ForwardTyParamBanRibKind | TyParamAsConstParamTy => { + ForwardTyParamBanRibKind => { // Nothing to do. Continue. } ItemRibKind(_) | FnItemRibKind | AssocItemRibKind => { @@ -2220,7 +2209,7 @@ impl<'a> Resolver<'a> { let has_generic_params = match rib.kind { NormalRibKind | AssocItemRibKind | ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind | - ConstantItemRibKind | TyParamAsConstParamTy => { + ConstantItemRibKind => { // Nothing to do. Continue. continue; } diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs index af5e8f49754e..78bd549ba791 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; struct B(PhantomData<[T; N]>); //~ ERROR const generics are unstable -//~^ ERROR const parameters cannot depend on type parameters +//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index c659074a091c..ba6f53e56840 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -1,9 +1,3 @@ -error[E0671]: const parameters cannot depend on type parameters - --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 - | -LL | struct B(PhantomData<[T; N]>); - | ^ const parameter depends on type parameter - error[E0658]: const generics are unstable --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19 | @@ -13,7 +7,13 @@ LL | struct B(PhantomData<[T; N]>); = note: for more information, see https://github.com/rust-lang/rust/issues/44580 = help: add `#![feature(const_generics)]` to the crate attributes to enable +error[E0740]: the types of const generic parameters must derive `PartialEq` and `Eq` + --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 + | +LL | struct B(PhantomData<[T; N]>); + | ^ `T` doesn't derive both `PartialEq` and `Eq` + error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0671. +Some errors have detailed explanations: E0658, E0740. For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs index 28e0d6c2bb7e..b76209571b05 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs @@ -7,7 +7,6 @@ // details. pub struct Dependent([(); X]); -//~^ ERROR const parameters cannot depend on type parameters -//~^^ ERROR parameter `T` is never used +//~^ ERROR the types of const generic parameters must derive `PartialEq` and `Eq` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index db14f9c9bf69..c86a09bef0b8 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -1,9 +1,3 @@ -error[E0671]: const parameters cannot depend on type parameters - --> $DIR/const-param-type-depends-on-type-param.rs:9:34 - | -LL | pub struct Dependent([(); X]); - | ^ const parameter depends on type parameter - warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/const-param-type-depends-on-type-param.rs:1:12 | @@ -12,15 +6,12 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0392]: parameter `T` is never used - --> $DIR/const-param-type-depends-on-type-param.rs:9:22 +error[E0740]: the types of const generic parameters must derive `PartialEq` and `Eq` + --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | LL | pub struct Dependent([(); X]); - | ^ unused parameter - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData` + | ^ `T` doesn't derive both `PartialEq` and `Eq` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0392, E0671. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0740`. From 9f788f3a2b7626318d0bdedca38986fc283f481f Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 21 Oct 2019 16:54:33 +0100 Subject: [PATCH 065/109] Fix rustdoc const generics test --- src/test/rustdoc/const-generics/const-impl.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/rustdoc/const-generics/const-impl.rs b/src/test/rustdoc/const-generics/const-impl.rs index 85ee6d3376b2..2d506787b3b8 100644 --- a/src/test/rustdoc/const-generics/const-impl.rs +++ b/src/test/rustdoc/const-generics/const-impl.rs @@ -4,6 +4,7 @@ #![crate_name = "foo"] +#[derive(PartialEq, Eq)] pub enum Order { Sorted, Unsorted, From 7f13a4a80a67ecc4fd0521e867eeb91b657f2fa0 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 22 Oct 2019 12:00:54 +0100 Subject: [PATCH 066/109] Remove FIXME --- src/librustc/ty/relate.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 41f34703622e..1da65f4b51d3 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -557,10 +557,9 @@ pub fn super_relate_consts>( x.val }; - // Currently, the values that can be unified are those that - // implement both `PartialEq` and `Eq`, corresponding to - // `structural_match` types. - // FIXME(const_generics): check for `structural_match` synthetic attribute. + // Currently, the values that can be unified are primitive types, + // and those that derive both `PartialEq` and `Eq`, corresponding + // to `structural_match` types. let new_const_val = match (eagerly_eval(a), eagerly_eval(b)) { (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => { // The caller should handle these cases! From 2dda8ad98a8d5089335b2d09307f1bfd085499f9 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 22 Oct 2019 12:28:23 +0100 Subject: [PATCH 067/109] Use E0741 for structural match error --- src/librustc_resolve/error_codes.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/error_codes.rs | 4 ++-- .../const-param-type-depends-on-type-param-ungated.stderr | 4 ++-- .../const-param-type-depends-on-type-param.stderr | 4 ++-- .../const-generics/forbid-non-structural_match-types.stderr | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index 49f8e82a2d1b..df22085c38c7 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1884,7 +1884,7 @@ E0671: r##" Const parameters cannot depend on type parameters. The following is therefore invalid: -```compile_fail,E0740 +```compile_fail,E0741 #![feature(const_generics)] fn const_id() -> T { // error diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 08fb5ae1676e..f40667652cac 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1536,7 +1536,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option(PhantomData<[T; N]>); = note: for more information, see https://github.com/rust-lang/rust/issues/44580 = help: add `#![feature(const_generics)]` to the crate attributes to enable -error[E0740]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 | LL | struct B(PhantomData<[T; N]>); @@ -15,5 +15,5 @@ LL | struct B(PhantomData<[T; N]>); error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0740. +Some errors have detailed explanations: E0658, E0741. For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index c86a09bef0b8..c9d6db7e2c22 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -6,7 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0740]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | LL | pub struct Dependent([(); X]); @@ -14,4 +14,4 @@ LL | pub struct Dependent([(); X]); error: aborting due to previous error -For more information about this error, try `rustc --explain E0740`. +For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr index c870d9b1db48..0fd9e0599e80 100644 --- a/src/test/ui/const-generics/forbid-non-structural_match-types.stderr +++ b/src/test/ui/const-generics/forbid-non-structural_match-types.stderr @@ -6,7 +6,7 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0740]: the types of const generic parameters must derive `PartialEq` and `Eq` +error[E0741]: the types of const generic parameters must derive `PartialEq` and `Eq` --> $DIR/forbid-non-structural_match-types.rs:11:19 | LL | struct D; @@ -14,4 +14,4 @@ LL | struct D; error: aborting due to previous error -For more information about this error, try `rustc --explain E0740`. +For more information about this error, try `rustc --explain E0741`. From a1f65895a071885141061590e24022eacec6e858 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 22 Oct 2019 21:10:51 +0900 Subject: [PATCH 068/109] Add link to async/await --- src/librustc/error_codes.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 4ee3445235ee..122ae4a6cf66 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2127,7 +2127,7 @@ static X: u32 = 42; "##, E0728: r##" -`await` has been used outside `async` function or block. +[`await`] has been used outside [`async`] function or block. Erroneous code examples: @@ -2160,9 +2160,9 @@ fn foo() { } ``` -`await` is used to suspend the current computation until the given +[`await`] is used to suspend the current computation until the given future is ready to produce a value. So it is legal only within -an async context, like an `async fn` or an `async` block. +an [`async`] context, like an `async fn` or an `async` block. ```edition2018 # use std::pin::Pin; @@ -2199,6 +2199,9 @@ fn bar(x: u8) -> impl Future { } } ``` + +[`async`]: https://doc.rust-lang.org/std/keyword.async.html +[`await`]: https://doc.rust-lang.org/std/keyword.await.html "##, E0734: r##" From 9220558c246d6d1610e7a9b20bd031559b868236 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 22 Oct 2019 14:00:19 +0100 Subject: [PATCH 069/109] Fix an issue with const inference variables sticking around under Chalk + NLL --- src/librustc/infer/combine.rs | 14 ++++------ src/librustc/infer/nll_relate/mod.rs | 41 ++++++++++++++++------------ 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index f06dbc72cd96..2e724ac56eee 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -602,19 +602,15 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be == - match c { - ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => { + match c.val { + ConstValue::Infer(InferConst::Var(vid)) => { let mut variable_table = self.infcx.const_unification_table.borrow_mut(); - match variable_table.probe_value(*vid).val.known() { - Some(u) => { - self.relate(&u, &u) - } + match variable_table.probe_value(vid).val.known() { + Some(u) => self.relate(&u, &u), None => Ok(c), } } - _ => { - relate::super_relate_consts(self, c, c) - } + _ => relate::super_relate_consts(self, c, c), } } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index 64ef0421808f..8d59f455cbb8 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -27,7 +27,7 @@ use crate::ty::error::TypeError; use crate::ty::fold::{TypeFoldable, TypeVisitor}; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::subst::GenericArg; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, InferConst}; use crate::mir::interpret::ConstValue; use rustc_data_structures::fx::FxHashMap; use std::fmt::Debug; @@ -616,15 +616,20 @@ where fn consts( &mut self, a: &'tcx ty::Const<'tcx>, - b: &'tcx ty::Const<'tcx>, + mut b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - if let ty::Const { val: ConstValue::Bound(..), .. } = a { - // FIXME(const_generics): I'm unsure how this branch should actually be handled, - // so this is probably not correct. - self.infcx.super_combine_consts(self, a, b) - } else { - debug!("consts(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance); - relate::super_relate_consts(self, a, b) + let a = self.infcx.shallow_resolve(a); + + if !D::forbid_inference_vars() { + b = self.infcx.shallow_resolve(b); + } + + match b.val { + ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { + // Forbid inference variables in the RHS. + bug!("unexpected inference var {:?}", b) + } + _ => self.infcx.super_combine_consts(self, a, b) } } @@ -991,15 +996,15 @@ where a: &'tcx ty::Const<'tcx>, _: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - debug!("TypeGeneralizer::consts(a={:?})", a); - - if let ty::Const { val: ConstValue::Bound(..), .. } = a { - bug!( - "unexpected inference variable encountered in NLL generalization: {:?}", - a - ); - } else { - relate::super_relate_consts(self, a, a) + match a.val { + ConstValue::Infer(InferConst::Var(vid)) => { + let mut variable_table = self.infcx.const_unification_table.borrow_mut(); + match variable_table.probe_value(vid).val.known() { + Some(u) => self.relate(&u, &u), + None => Ok(a), + } + } + _ => relate::super_relate_consts(self, a, a), } } From 51c687446d65fe271972f6371639334bb10da6db Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 22 Oct 2019 14:07:20 +0100 Subject: [PATCH 070/109] Add regression test for #65675 --- src/test/ui/const-generics/issues/issue-65675.rs | 10 ++++++++++ src/test/ui/const-generics/issues/issue-65675.stderr | 8 ++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-65675.rs create mode 100644 src/test/ui/const-generics/issues/issue-65675.stderr diff --git a/src/test/ui/const-generics/issues/issue-65675.rs b/src/test/ui/const-generics/issues/issue-65675.rs new file mode 100644 index 000000000000..3ca527313f93 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-65675.rs @@ -0,0 +1,10 @@ +// run-pass +// compile-flags: -Z chalk + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +pub struct Foo([T; N]); +impl Foo {} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-65675.stderr b/src/test/ui/const-generics/issues/issue-65675.stderr new file mode 100644 index 000000000000..60b388e62783 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-65675.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-65675.rs:4:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From de3fd021f5eef7b3c2fad795920e542798104d1d Mon Sep 17 00:00:00 2001 From: togiberlin Date: Wed, 4 Sep 2019 14:53:47 +0200 Subject: [PATCH 071/109] Target-feature documented as unsafe. rustc book and rustc -C help have been modified. --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/codegen-options/index.md | 2 ++ src/doc/rustc/src/command-line-arguments.md | 2 +- src/doc/rustc/src/targets/index.md | 6 ++++++ src/doc/rustc/src/targets/known-issues.md | 13 +++++++++++++ src/librustc/session/config.rs | 3 ++- 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 src/doc/rustc/src/targets/known-issues.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index d5564fd798f3..b603c7b231e6 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -14,6 +14,7 @@ - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) + - [Known Issues](targets/known-issues.md) - [Profile-guided Optimization](profile-guided-optimization.md) - [Linker-plugin based LTO](linker-plugin-lto.md) - [Contributing to `rustc`](contributing.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index e73fd43f19a5..f5d5f2089d7e 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -61,6 +61,8 @@ enabling or disabling a feature. To see the valid options and an example of use, run `rustc --print target-features`. +Using this flag is unsafe and might result in [undefined runtime behavior](../targets/known-issues.md). + ## passes This flag can be used to add extra LLVM passes to the compilation. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index b2cc65c11fd2..bdb3c5196585 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -145,7 +145,7 @@ of print values are: target CPU may be selected with the `-C target-cpu=val` flag. - `target-features` — List of available target features for the current target. Target features may be enabled with the `-C target-feature=val` - flag. + flag. This flag is unsafe. See [known issues](targets/known-issues.md) for more details. - `relocation-models` — List of relocation models. Relocation models may be selected with the `-C relocation-model=val` flag. - `code-models` — List of code models. Code models may be selected with the diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md index 3d63d072befe..5859df83f645 100644 --- a/src/doc/rustc/src/targets/index.md +++ b/src/doc/rustc/src/targets/index.md @@ -11,3 +11,9 @@ To compile to a particular target, use the `--target` flag: ```bash $ rustc src/main.rs --target=wasm32-unknown-unknown ``` +## Target Features +`x86`, and `ARMv8` are two popular CPU architectures. Their instruction sets form a common baseline across most CPUs. However, some CPUs extend these with custom instruction sets, e.g. vector (`AVX`), bitwise manipulation (`BMI`) or cryptographic (`AES`). + +Developers, who know on which CPUs their compiled code is going to run can choose to add (or remove) CPU specific instruction sets via the `-C target-feature=val` flag. + +Please note, that this flag is generally considered as unsafe. More details can be found in [this section](known-issues.md). diff --git a/src/doc/rustc/src/targets/known-issues.md b/src/doc/rustc/src/targets/known-issues.md new file mode 100644 index 000000000000..89fd8ea6d32e --- /dev/null +++ b/src/doc/rustc/src/targets/known-issues.md @@ -0,0 +1,13 @@ +# Known Issues +This section informs you about known "gotchas". Keep in mind, that this section is (and always will be) incomplete. For suggestions and amendments, feel free to [contribute](../contributing.md) to this guide. + +## Target Features +Most target-feature problems arise, when mixing code that have the target-feature _enabled_ with code that have it _disabled_. If you want to avoid undefined behavior, it is recommended to build _all code_ (including the standard library and imported crates) with a common set of target-features. + +By default, compiling your code with the `-C target-feature` flag will not recompile the entire standard library and/or imported crates with matching target features. Therefore, target features are generally considered as unsafe. Using `#[target_feature]` on individual functions makes the function unsafe. + +Examples: + +| Target-Feature | Issue | Seen on | Description | Details | +| -------------- | ----- | ------- | ----------- | ------- | +| `+soft-float`
and
`-sse` | Segfaults and ABI mismatches | `x86` and `x86-64` | The `x86` and `x86_64` architecture uses SSE registers (aka `xmm`) for floating point operations. Using software emulated floats ("soft-floats") disables usage of `xmm` registers, but parts of Rust's core libraries (e.g. `std::f32` or `std::f64`) are compiled without soft-floats and expect parameters to be passed in `xmm` registers. This leads to ABI mismatches.

Attempting to compile with disabled SSE causes the same error, too. | [#63466](https://github.com/rust-lang/rust/issues/63466) | diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2446d4f4788d..33b9ddaa6223 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1149,7 +1149,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, target_cpu: Option = (None, parse_opt_string, [TRACKED], "select target processor (`rustc --print target-cpus` for details)"), target_feature: String = (String::new(), parse_string, [TRACKED], - "target specific attributes (`rustc --print target-features` for details)"), + "target specific attributes. (`rustc --print target-features` for details). \ + This feature is unsafe."), passes: Vec = (Vec::new(), parse_list, [TRACKED], "a list of extra LLVM passes to run (space separated)"), llvm_args: Vec = (Vec::new(), parse_list, [TRACKED], From fe84809394fbc6ad2d36f6f142671bea7a492a4c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Oct 2019 18:06:30 +0200 Subject: [PATCH 072/109] relax ExactSizeIterator bound on write_bytes: too many iterators don't have that bound --- src/librustc/mir/interpret/allocation.rs | 7 +++++-- src/librustc_mir/interpret/memory.rs | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 796d293e2c63..aa8ac4902a89 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -353,11 +353,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &mut self, cx: &impl HasDataLayout, ptr: Pointer, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let mut src = src.into_iter(); - let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?; + let (lower, upper) = src.size_hint(); + let len = upper.expect("can only write bounded iterators"); + assert_eq!(lower, len, "can only write iterators with a precise length"); + let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(len as u64))?; // `zip` would stop when the first iterator ends; we want to definitely // cover all of `bytes`. for dest in bytes { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index eef1868ec65b..d113ee33162d 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -7,7 +7,7 @@ //! short-circuiting the empty case! use std::collections::VecDeque; -use std::{ptr, iter}; +use std::ptr; use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; @@ -791,11 +791,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn write_bytes( &mut self, ptr: Scalar, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let src = src.into_iter(); - let size = Size::from_bytes(src.len() as u64); + let size = Size::from_bytes(src.size_hint().0 as u64); + // `write_bytes` checks that this lower bound matches the upper bound matches reality. let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? { Some(ptr) => ptr, None => return Ok(()), // zero-sized access From dffc1b32820d740b3e2b3cf8e98b4d0511a62163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 5 Sep 2019 12:23:56 +0200 Subject: [PATCH 073/109] Apply clippy::useless_let_if_seq suggestion --- src/libcore/num/dec2flt/algorithm.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index fa3c8075378c..ed89852dc48d 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -143,13 +143,12 @@ pub fn fast_path(integral: &[u8], fractional: &[u8], e: i64) -> Opt /// > not a bound for the true error, but bounds the difference between the approximation z and /// > the best possible approximation that uses p bits of significand.) pub fn bellerophon(f: &Big, e: i16) -> T { - let slop; - if f <= &Big::from_u64(T::MAX_SIG) { + let slop = if f <= &Big::from_u64(T::MAX_SIG) { // The cases abs(e) < log5(2^N) are in fast_path() - slop = if e >= 0 { 0 } else { 3 }; + if e >= 0 { 0 } else { 3 } } else { - slop = if e >= 0 { 1 } else { 4 }; - } + if e >= 0 { 1 } else { 4 } + }; let z = rawfp::big_to_fp(f).mul(&power_of_ten(e)).normalize(); let exp_p_n = 1 << (P - T::SIG_BITS as u32); let lowbits: i64 = (z.f % exp_p_n) as i64; From 8497f793d57d9d29432f31601068f7face3179c4 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Tue, 22 Oct 2019 20:14:34 +0300 Subject: [PATCH 074/109] Add missing space in librustdoc --- src/librustdoc/doctree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 0dc094ae329f..bbc00147ee14 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -59,7 +59,7 @@ impl Module<'hir> { fns : Vec::new(), mods : Vec::new(), typedefs : Vec::new(), - opaque_tys : Vec::new(), + opaque_tys : Vec::new(), statics : Vec::new(), constants : Vec::new(), traits : Vec::new(), From 95c06a29707c8b2f811495c05b0cd009743e29de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 5 Sep 2019 13:30:30 +0200 Subject: [PATCH 075/109] Apply clippy::needless_return suggestions --- src/liballoc/collections/vec_deque.rs | 2 +- src/liballoc/str.rs | 2 +- src/liballoc/sync.rs | 2 +- src/libpanic_unwind/gcc.rs | 12 ++++++------ src/libpanic_unwind/seh64_gnu.rs | 2 +- src/libstd/panicking.rs | 2 +- src/libstd/sys/unix/rand.rs | 2 +- src/libstd/sys/windows/handle.rs | 2 +- src/libstd/sys/windows/mutex.rs | 2 +- src/libstd/sys/windows/process.rs | 2 +- src/libstd/sys/windows/rand.rs | 2 +- src/libstd/sys/windows/thread_local.rs | 2 +- src/libstd/sys/windows/time.rs | 4 ++-- src/libtest/bench.rs | 4 ++-- src/libtest/cli.rs | 2 +- src/libtest/console.rs | 2 +- 16 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 0bf573f5e253..8f3dfabd8886 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1817,7 +1817,7 @@ impl VecDeque { } } - return elem; + elem } /// Splits the `VecDeque` into two at the given index. diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 9231c2d3f1d5..83816d8b954c 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -456,7 +456,7 @@ impl str { } } } - return s; + s } /// Converts a [`Box`] into a [`String`] without copying or allocating. diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 69f8f71197c1..80d6c6e0d439 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1638,7 +1638,7 @@ impl Clone for Weak { } } - return Weak { ptr: self.ptr }; + Weak { ptr: self.ptr } } } diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 236ed1505057..a35847c85fc2 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -156,21 +156,21 @@ unsafe extern "C" fn rust_eh_personality(version: c_int, if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 { match eh_action { EHAction::None | - EHAction::Cleanup(_) => return uw::_URC_CONTINUE_UNWIND, - EHAction::Catch(_) => return uw::_URC_HANDLER_FOUND, - EHAction::Terminate => return uw::_URC_FATAL_PHASE1_ERROR, + EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND, + EHAction::Catch(_) => uw::_URC_HANDLER_FOUND, + EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR, } } else { match eh_action { - EHAction::None => return uw::_URC_CONTINUE_UNWIND, + EHAction::None => uw::_URC_CONTINUE_UNWIND, EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => { uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t); uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0); uw::_Unwind_SetIP(context, lpad); - return uw::_URC_INSTALL_CONTEXT; + uw::_URC_INSTALL_CONTEXT } - EHAction::Terminate => return uw::_URC_FATAL_PHASE2_ERROR, + EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR, } } } diff --git a/src/libpanic_unwind/seh64_gnu.rs b/src/libpanic_unwind/seh64_gnu.rs index 457ffcd34f9c..16b699a44379 100644 --- a/src/libpanic_unwind/seh64_gnu.rs +++ b/src/libpanic_unwind/seh64_gnu.rs @@ -46,7 +46,7 @@ pub fn payload() -> *mut u8 { pub unsafe fn cleanup(ptr: *mut u8) -> Box { let panic_ctx = Box::from_raw(ptr as *mut PanicData); - return panic_ctx.data; + panic_ctx.data } // SEH doesn't support resuming unwinds after calling a landing pad like diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 2dde81bb0ecd..619b18201908 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -217,7 +217,7 @@ pub fn update_panic_count(amt: isize) -> usize { PANIC_COUNT.with(|c| { let next = (c.get() as isize + amt) as usize; c.set(next); - return next + next }) } diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs index c5be17633025..be112f6fc032 100644 --- a/src/libstd/sys/unix/rand.rs +++ b/src/libstd/sys/unix/rand.rs @@ -8,7 +8,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { mem::size_of_val(&v)); imp::fill_bytes(view); } - return v + v } #[cfg(all(unix, diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs index 3e5aa6933546..3986cda1a504 100644 --- a/src/libstd/sys/windows/handle.rs +++ b/src/libstd/sys/windows/handle.rs @@ -46,7 +46,7 @@ impl Handle { pub fn into_raw(self) -> c::HANDLE { let ret = self.raw(); mem::forget(self); - return ret; + ret } } diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index 37cbdcefcedc..79dec1adf4bc 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -144,7 +144,7 @@ fn kind() -> Kind { Some(..) => Kind::SRWLock, }; KIND.store(ret as usize, Ordering::SeqCst); - return ret; + ret } pub struct ReentrantMutex { inner: UnsafeCell> } diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 8658deb85463..61393680883f 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -257,7 +257,7 @@ impl Stdio { let ret = io.duplicate(0, true, c::DUPLICATE_SAME_ACCESS); io.into_raw(); - return ret + ret } Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)), } diff --git a/src/libstd/sys/windows/rand.rs b/src/libstd/sys/windows/rand.rs index c9bcb5d74151..993831bec188 100644 --- a/src/libstd/sys/windows/rand.rs +++ b/src/libstd/sys/windows/rand.rs @@ -13,7 +13,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); } - return v + v } #[cfg(target_vendor = "uwp")] diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index 4c9734fa0aa6..728257cdd4bb 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -52,7 +52,7 @@ pub unsafe fn create(dtor: Option) -> Key { if let Some(f) = dtor { register_dtor(key, f); } - return key; + key } #[inline] diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index e0f0e3a1a45b..bd533c93d434 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -80,7 +80,7 @@ impl SystemTime { unsafe { let mut t: SystemTime = mem::zeroed(); c::GetSystemTimeAsFileTime(&mut t.t); - return t + t } } @@ -228,7 +228,7 @@ mod perf_counter { FREQUENCY = frequency; STATE.store(2, SeqCst); } - return frequency; + frequency } } diff --git a/src/libtest/bench.rs b/src/libtest/bench.rs index c142c5213d2e..c86bfd16c21b 100644 --- a/src/libtest/bench.rs +++ b/src/libtest/bench.rs @@ -48,7 +48,7 @@ impl Bencher { F: FnMut(&mut Bencher), { f(self); - return self.summary; + self.summary } } @@ -116,7 +116,7 @@ where for _ in 0..k { black_box(inner()); } - return ns_from_dur(start.elapsed()); + ns_from_dur(start.elapsed()) } pub fn iter(inner: &mut F) -> stats::Summary diff --git a/src/libtest/cli.rs b/src/libtest/cli.rs index f95d5aad18a6..a34426305be2 100644 --- a/src/libtest/cli.rs +++ b/src/libtest/cli.rs @@ -149,7 +149,7 @@ fn optgroups() -> getopts::Options { `CRITICAL_TIME` here means the limit that should not be exceeded by test. " ); - return opts; + opts } fn usage(binary: &str, options: &getopts::Options) { diff --git a/src/libtest/console.rs b/src/libtest/console.rs index e17030726cea..244cbd2cf5fe 100644 --- a/src/libtest/console.rs +++ b/src/libtest/console.rs @@ -296,7 +296,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu assert!(st.current_test_count() == st.total); - return out.write_run_finish(&st); + out.write_run_finish(&st) } // Calculates padding for given test description. From e1aa297b8be571eb3b9bf936d9de9ecb13b3eace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 5 Sep 2019 13:38:00 +0200 Subject: [PATCH 076/109] Apply clippy::redundant_pattern_matching suggestion --- src/libcore/fmt/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8413b2e0ac49..0e83a282b18f 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -2025,7 +2025,7 @@ impl Pointer for *const T { if f.alternate() { f.flags |= 1 << (FlagV1::SignAwareZeroPad as u32); - if let None = f.width { + if f.width.is_none() { f.width = Some(((mem::size_of::() * 8) / 4) + 2); } } From 749146827865dfe1f62ce757795415414bb75a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 5 Sep 2019 13:47:59 +0200 Subject: [PATCH 077/109] Apply clippy::while_let_on_iterator suggestions --- src/libstd/sys/windows/process.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 61393680883f..096b7bea8a5f 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -472,9 +472,8 @@ fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result> { cmd.push('"' as u16); } - let mut iter = arg.encode_wide(); let mut backslashes: usize = 0; - while let Some(x) = iter.next() { + for x in arg.encode_wide() { if x == '\\' as u16 { backslashes += 1; } else { From bedbf3bacbff36a477dcf28523cbf6cab67e9e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 5 Sep 2019 14:08:06 +0200 Subject: [PATCH 078/109] Apply clippy::single_match suggestion --- src/libcore/option.rs | 5 ++--- src/libstd/thread/local.rs | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9eb29eae7f75..89f2d7ab29c9 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -837,9 +837,8 @@ impl Option { #[inline] #[stable(feature = "option_entry", since = "1.20.0")] pub fn get_or_insert_with T>(&mut self, f: F) -> &mut T { - match *self { - None => *self = Some(f()), - _ => (), + if let None = *self { + *self = Some(f()); } match *self { diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index e92c0d1c58e4..cfaab4e22e9c 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -509,9 +509,8 @@ pub mod os { pub unsafe fn get(&'static self, init: fn() -> T) -> Option<&'static T> { let ptr = self.os.get() as *mut Value; if ptr as usize > 1 { - match (*ptr).inner.get() { - Some(ref value) => return Some(value), - None => {}, + if let Some(ref value) = (*ptr).inner.get() { + return Some(value); } } self.try_initialize(init) From 76f9b3b4c9230284f9ed3dca7afe27d836415d0f Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 22 Oct 2019 11:15:12 +0200 Subject: [PATCH 079/109] Readd some PartialEq and Hash derives used by Clippy --- src/libsyntax/ast.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8be7f4478fa0..51a62cd06584 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1305,7 +1305,8 @@ impl MacroDef { } } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)] +// Clippy uses Hash and PartialEq +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1327,7 +1328,8 @@ pub struct Lit { pub span: Span, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)] +// Clippy uses Hash and PartialEq +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)] pub enum LitIntType { Signed(IntTy), Unsigned(UintTy), @@ -1337,7 +1339,8 @@ pub enum LitIntType { /// Literal kind. /// /// E.g., `"foo"`, `42`, `12.34`, or `bool`. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +// Clippy uses Hash and PartialEq +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)] pub enum LitKind { /// A string literal (`"foo"`). Str(Symbol, StrStyle), From 6bc16ef3c7c2075e5eb9a6c643dbf4efbd10c495 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Tue, 22 Oct 2019 11:24:18 +0200 Subject: [PATCH 080/109] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index cbedd97b3a58..e8d5a9e95c14 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit cbedd97b3a58023eff365a2fa74700d06115144a +Subproject commit e8d5a9e95c145a3a9be89c582d8a6f88d4ea7037 From ef5acdecebb48a02cb34d19fa17d1bd59e41a4d3 Mon Sep 17 00:00:00 2001 From: Mathias Blikstad Date: Tue, 8 Jan 2019 22:14:04 +0100 Subject: [PATCH 081/109] RFC 2027: "first draft" of implementation These are a squashed series of commits. --- src/librustc/infer/error_reporting/mod.rs | 24 +++++-- src/librustc/traits/error_reporting.rs | 32 ++++----- src/librustc/traits/mod.rs | 3 + src/librustc/traits/select.rs | 8 ++- src/librustc/traits/structural_impls.rs | 4 ++ src/librustc/ty/error.rs | 3 +- src/librustc/ty/structural_impls.rs | 2 + src/librustc/ty/wf.rs | 25 ++++--- src/librustc_errors/diagnostic.rs | 26 +++++++ src/librustc_errors/diagnostic_builder.rs | 5 ++ src/librustc_typeck/astconv.rs | 3 +- src/librustc_typeck/check/cast.rs | 43 +++++++++--- src/librustc_typeck/check/coercion.rs | 31 ++++++--- src/librustc_typeck/coherence/mod.rs | 5 +- src/libsyntax/feature_gate/active.rs | 3 + src/libsyntax_pos/symbol.rs | 1 + .../coherence-unsafe-trait-object-impl.rs | 18 +++++ .../coherence-unsafe-trait-object-impl.stderr | 12 ++++ ...eature-gate-exhaustive-patterns.nll.stderr | 16 ----- .../feature-gate-object_safe_for_dispatch.rs | 41 +++++++++++ ...ature-gate-object_safe_for_dispatch.stderr | 46 +++++++++++++ src/test/ui/issues/issue-19538.stderr | 1 + src/test/ui/issues/issue-20692.stderr | 1 + src/test/ui/issues/issue-38604.stderr | 1 + ...> kindck-inherited-copy-bound.curr.stderr} | 7 +- ...copy-bound.object_safe_for_dispatch.stderr | 25 +++++++ .../ui/kindck/kindck-inherited-copy-bound.rs | 11 ++- ...ject-safety-associated-consts.curr.stderr} | 2 +- ...ted-consts.object_safe_for_dispatch.stderr | 15 ++++ .../object-safety-associated-consts.rs | 6 +- ...err => object-safety-generics.curr.stderr} | 4 +- ...y-generics.object_safe_for_dispatch.stderr | 27 ++++++++ .../object-safety/object-safety-generics.rs | 10 ++- ...> object-safety-mentions-Self.curr.stderr} | 8 +-- ...tions-Self.object_safe_for_dispatch.stderr | 27 ++++++++ .../object-safety-mentions-Self.rs | 20 ++++-- .../object-safety-no-static.curr.stderr | 12 ++++ ...-no-static.object_safe_for_dispatch.stderr | 15 ++++ .../object-safety/object-safety-no-static.rs | 16 ++++- ...derr => object-safety-sized-2.curr.stderr} | 2 +- ...ty-sized-2.object_safe_for_dispatch.stderr | 13 ++++ .../ui/object-safety/object-safety-sized-2.rs | 9 ++- ...stderr => object-safety-sized.curr.stderr} | 2 +- ...fety-sized.object_safe_for_dispatch.stderr | 13 ++++ .../ui/object-safety/object-safety-sized.rs | 7 +- .../downcast-unsafe-trait-objects.rs | 23 +++++++ .../manual-self-impl-for-unsafe-obj.rs | 69 +++++++++++++++++++ .../static-dispatch-unsafe-object.rs | 37 ++++++++++ ...ary-self-types-not-object-safe.curr.stderr | 24 +++++++ ...bject-safe.object_safe_for_dispatch.stderr | 15 ++++ .../arbitrary-self-types-not-object-safe.rs | 8 ++- src/test/ui/traits/trait-object-safety.stderr | 1 + src/test/ui/traits/trait-test-2.stderr | 1 + .../ui/wf/wf-convert-unsafe-trait-obj-box.rs | 18 +++++ .../wf/wf-convert-unsafe-trait-obj-box.stderr | 33 +++++++++ src/test/ui/wf/wf-convert-unsafe-trait-obj.rs | 18 +++++ .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 33 +++++++++ src/test/ui/wf/wf-unsafe-trait-obj-match.rs | 29 ++++++++ .../ui/wf/wf-unsafe-trait-obj-match.stderr | 38 ++++++++++ 59 files changed, 847 insertions(+), 105 deletions(-) create mode 100644 src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs create mode 100644 src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs create mode 100644 src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr rename src/test/ui/kindck/{kindck-inherited-copy-bound.stderr => kindck-inherited-copy-bound.curr.stderr} (86%) create mode 100644 src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr rename src/test/ui/object-safety/{object-safety-associated-consts.stderr => object-safety-associated-consts.curr.stderr} (88%) create mode 100644 src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr rename src/test/ui/object-safety/{object-safety-generics.stderr => object-safety-generics.curr.stderr} (89%) create mode 100644 src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr rename src/test/ui/object-safety/{object-safety-mentions-Self.stderr => object-safety-mentions-Self.curr.stderr} (83%) create mode 100644 src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-no-static.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr rename src/test/ui/object-safety/{object-safety-sized-2.stderr => object-safety-sized-2.curr.stderr} (89%) create mode 100644 src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr rename src/test/ui/object-safety/{object-safety-sized.stderr => object-safety-sized.curr.stderr} (90%) create mode 100644 src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs create mode 100644 src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs create mode 100644 src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs create mode 100644 src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr create mode 100644 src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs create mode 100644 src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr create mode 100644 src/test/ui/wf/wf-convert-unsafe-trait-obj.rs create mode 100644 src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr create mode 100644 src/test/ui/wf/wf-unsafe-trait-obj-match.rs create mode 100644 src/test/ui/wf/wf-unsafe-trait-obj-match.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f1192c7ce10a..8f2fa3067a22 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1146,10 +1146,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let span = cause.span(self.tcx); - diag.span_label(span, terr.to_string()); - if let Some((sp, msg)) = secondary_span { - diag.span_label(sp, msg); - } + // Ignore msg for object safe coercion + // since E0038 message will be printed + match terr { + TypeError::ObjectUnsafeCoercion(_) => {} + _ => { + diag.span_label(span, terr.to_string()); + if let Some((sp, msg)) = secondary_span { + diag.span_label(sp, msg); + } + } + }; if let Some((expected, found)) = expected_found { match (terr, is_simple_error, expected == found) { @@ -1169,6 +1176,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &sort_string(values.found), ); } + (TypeError::ObjectUnsafeCoercion(_), ..) => { + diag.note_unsuccessfull_coercion(found, expected); + } (_, false, _) => { if let Some(exp_found) = exp_found { self.suggest_as_ref_where_appropriate(span, &exp_found, diag); @@ -1267,6 +1277,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let span = trace.cause.span(self.tcx); let failure_code = trace.cause.as_failure_code(terr); let mut diag = match failure_code { + FailureCode::Error0038(did) => { + let violations = self.tcx.object_safety_violations(did); + self.tcx.report_object_safety_error(span, did, violations) + } FailureCode::Error0317(failure_str) => { struct_span_err!(self.tcx.sess, span, E0317, "{}", failure_str) } @@ -1628,6 +1642,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } enum FailureCode { + Error0038(DefId), Error0317(&'static str), Error0580(&'static str), Error0308(&'static str), @@ -1666,6 +1681,7 @@ impl<'tcx> ObligationCause<'tcx> { TypeError::IntrinsicCast => { Error0308("cannot coerce intrinsics to function pointers") } + TypeError::ObjectUnsafeCoercion(did) => Error0038(did.clone()), _ => Error0308("mismatched types"), }, } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 9eb91569ed5c..aa376699c385 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -790,15 +790,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Predicate::ObjectSafe(trait_def_id) => { let violations = self.tcx.object_safety_violations(trait_def_id); - if let Some(err) = self.tcx.report_object_safety_error( + self.tcx.report_object_safety_error( span, trait_def_id, violations, - ) { - err - } else { - return; - } + ) } ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { @@ -934,11 +930,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { TraitNotObjectSafe(did) => { let violations = self.tcx.object_safety_violations(did); - if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) { - err - } else { - return; - } + self.tcx.report_object_safety_error(span, did, violations) } // already reported in the query @@ -1493,11 +1485,7 @@ impl<'tcx> TyCtxt<'tcx> { span: Span, trait_def_id: DefId, violations: Vec, - ) -> Option> { - if self.sess.trait_methods_not_found.borrow().contains(&span) { - // Avoid emitting error caused by non-existing method (#58734) - return None; - } + ) -> DiagnosticBuilder<'tcx> { let trait_str = self.def_path_str(trait_def_id); let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!( @@ -1515,7 +1503,13 @@ impl<'tcx> TyCtxt<'tcx> { }; } } - Some(err) + + if self.sess.trait_methods_not_found.borrow().contains(&span) { + // Avoid emitting error caused by non-existing method (#58734) + err.cancel(); + } + + err } } @@ -1926,6 +1920,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.note(&format!("required for the cast to the object type `{}`", self.ty_to_string(object_ty))); } + ObligationCauseCode::Coercion { source: _, target } => { + err.note(&format!("required by cast to type `{}`", + self.ty_to_string(target))); + } ObligationCauseCode::RepeatVec => { err.note("the `Copy` trait is required because the \ repeated element will be copied"); diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index d96330bf0a9b..eb4b114eb301 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -188,6 +188,9 @@ pub enum ObligationCauseCode<'tcx> { /// Obligation incurred due to an object cast. ObjectCastObligation(/* Object type */ Ty<'tcx>), + /// Obligation incurred due to a coercion. + Coercion { source: Ty<'tcx>, target: Ty<'tcx> }, + // Various cases where expressions must be sized/copy/etc: /// L = X implies that L is Sized AssignmentLhsSized, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 44d611ace77d..d8a27f1e0405 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2246,7 +2246,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if let Some(principal) = data.principal() { - principal.with_self_ty(self.tcx(), self_ty) + if !self.infcx.tcx.features().object_safe_for_dispatch { + principal.with_self_ty(self.tcx(), self_ty) + } else if self.tcx().is_object_safe(principal.def_id()) { + principal.with_self_ty(self.tcx(), self_ty) + } else { + return; + } } else { // Only auto-trait bounds exist. return; diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index dab62a6bcb5b..9729368edfee 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -481,6 +481,10 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { .and_then(|r| Some(super::ObjectTypeBound(ty, r))) ), super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation), + super::Coercion { source, target } => Some(super::Coercion { + source: tcx.lift(&source)?, + target: tcx.lift(&target)?, + }), super::AssignmentLhsSized => Some(super::AssignmentLhsSized), super::TupleInitializerSized => Some(super::TupleInitializerSized), super::StructInitializerSized => Some(super::StructInitializerSized), diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 5851a48a8d37..882f330e6c33 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -45,7 +45,7 @@ pub enum TypeError<'tcx> { ProjectionMismatched(ExpectedFound), ProjectionBoundsLength(ExpectedFound), ExistentialMismatch(ExpectedFound<&'tcx ty::List>>), - + ObjectUnsafeCoercion(DefId), ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>), IntrinsicCast, @@ -179,6 +179,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { IntrinsicCast => { write!(f, "cannot coerce intrinsics to function pointers") } + ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"), } } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 8945e1a1debd..3a5b8b577412 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -749,6 +749,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch), ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch), IntrinsicCast => IntrinsicCast, + ObjectUnsafeCoercion(ref x) => return tcx.lift(x).map(ObjectUnsafeCoercion), }) } } @@ -1356,6 +1357,7 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::ExistentialMismatch)(x), (ty::error::TypeError::ConstMismatch)(x), (ty::error::TypeError::IntrinsicCast), + (ty::error::TypeError::ObjectUnsafeCoercion)(x), } } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index ecb075e30b14..b50e819c956e 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -380,16 +380,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // obligations that don't refer to Self and // checking those - let cause = self.cause(traits::MiscObligation); - let component_traits = - data.auto_traits().chain(data.principal_def_id()); - self.out.extend( - component_traits.map(|did| traits::Obligation::new( - cause.clone(), - param_env, - ty::Predicate::ObjectSafe(did) - )) - ); + let defer_to_coercion = + self.infcx.tcx.features().object_safe_for_dispatch; + + if !defer_to_coercion { + let cause = self.cause(traits::MiscObligation); + let component_traits = + data.auto_traits().chain(data.principal_def_id()); + self.out.extend( + component_traits.map(|did| traits::Obligation::new( + cause.clone(), + param_env, + ty::Predicate::ObjectSafe(did) + )) + ); + } } // Inference variables are the complicated case, since we don't diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index fd74d8673da4..1781f2e16503 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -152,6 +152,32 @@ impl Diagnostic { self.note_expected_found_extra(label, expected, found, &"", &"") } + pub fn note_unsuccessfull_coercion(&mut self, + expected: DiagnosticStyledString, + found: DiagnosticStyledString) + -> &mut Self + { + let mut msg: Vec<_> = + vec![(format!("required when trying to coerce from type `"), + Style::NoStyle)]; + msg.extend(expected.0.iter() + .map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); + msg.push((format!("` to type '"), Style::NoStyle)); + msg.extend(found.0.iter() + .map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); + msg.push((format!("`"), Style::NoStyle)); + + // For now, just attach these as notes + self.highlighted_note(msg); + self + } + pub fn note_expected_found_extra(&mut self, label: &dyn fmt::Display, expected: DiagnosticStyledString, diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index cc60bf89c7ec..40642dd14b8f 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -209,6 +209,11 @@ impl<'a> DiagnosticBuilder<'a> { found_extra: &dyn fmt::Display, ) -> &mut Self); + forward!(pub fn note_unsuccessfull_coercion(&mut self, + expected: DiagnosticStyledString, + found: DiagnosticStyledString, + ) -> &mut Self); + forward!(pub fn note(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_note>(&mut self, sp: S, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b8e2700803a5..2ee5ecfbcdc2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1275,8 +1275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, item.trait_ref().def_id(), object_safety_violations - ) - .map(|mut err| err.emit()); + ).emit(); return tcx.types.err; } } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index dfeb5fb958cd..9cbde276ae97 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -428,21 +428,36 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.report_cast_to_unsized_type(fcx); } else if self.expr_ty.references_error() || self.cast_ty.references_error() { // No sense in giving duplicate error messages - } else if self.try_coercion_cast(fcx) { - self.trivial_cast_lint(fcx); - debug!(" -> CoercionCast"); - fcx.tables.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id); - } else { - match self.do_check(fcx) { - Ok(k) => { - debug!(" -> {:?}", k); + match self.try_coercion_cast(fcx) { + Ok(()) => { + self.trivial_cast_lint(fcx); + debug!(" -> CoercionCast"); + fcx.tables.borrow_mut() + .set_coercion_cast(self.expr.hir_id.local_id); + } + Err(ty::error::TypeError::ObjectUnsafeCoercion(did)) => { + self.report_object_unsafe_cast(&fcx, did); + } + Err(_) => { + match self.do_check(fcx) { + Ok(k) => { + debug!(" -> {:?}", k); + } + Err(e) => self.report_cast_error(fcx, e), + }; } - Err(e) => self.report_cast_error(fcx, e), }; } } + fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) { + let violations = fcx.tcx.object_safety_violations(did); + let mut err = fcx.tcx.report_object_safety_error(self.cast_span, did, violations); + err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty))); + err.emit(); + } + /// Checks a cast, and report an error if one exists. In some cases, this /// can return Ok and create type errors in the fcx rather than returning /// directly. coercion-cast is handled in check instead of here. @@ -646,8 +661,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } - fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No).is_ok() + fn try_coercion_cast( + &self, + fcx: &FnCtxt<'a, 'tcx>, + ) -> Result<(), ty::error::TypeError<'_>> { + match fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No) { + Ok(_) => Ok(()), + Err(err) => Err(err), + } } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 3a89cddda236..5c4c66bb64ed 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -61,10 +61,11 @@ use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{ Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast }; -use rustc::ty::{self, TypeAndMut, Ty, subst::SubstsRef}; +use rustc::ty::{self, TypeAndMut, Ty}; use rustc::ty::fold::TypeFoldable; use rustc::ty::error::TypeError; use rustc::ty::relate::RelateResult; +use rustc::ty::subst::SubstsRef; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; use syntax::feature_gate; @@ -196,9 +197,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // a "spurious" type variable, and we don't want to have that // type variable in memory if the coercion fails. let unsize = self.commit_if_ok(|_| self.coerce_unsized(a, b)); - if unsize.is_ok() { - debug!("coerce: unsize successful"); - return unsize; + match unsize { + Ok(_) => { + debug!("coerce: unsize successful"); + return unsize; + } + Err(TypeError::ObjectUnsafeCoercion(did)) => { + debug!("coerce: unsize not object safe"); + return Err(TypeError::ObjectUnsafeCoercion(did)); + } + Err(_) => {} } debug!("coerce: unsize failed"); @@ -539,7 +547,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let mut selcx = traits::SelectionContext::new(self); // Create an obligation for `Source: CoerceUnsized`. - let cause = ObligationCause::misc(self.cause.span, self.body_id); + let cause = ObligationCause::new( + self.cause.span, + self.body_id, + ObligationCauseCode::Coercion { source, target }, + ); // Use a FIFO queue for this custom fulfillment procedure. // @@ -566,14 +578,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let obligation = queue.remove(0); debug!("coerce_unsized resolve step: {:?}", obligation); let trait_ref = match obligation.predicate { - ty::Predicate::Trait(ref t) if traits.contains(&t.def_id()) => { - if unsize_did == t.def_id() { - if let ty::Tuple(..) = &t.skip_binder().input_types().nth(1).unwrap().kind { + ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => { + if unsize_did == tr.def_id() { + let sty = &tr.skip_binder().input_types().nth(1).unwrap().kind; + if let ty::Tuple(..) = sty { debug!("coerce_unsized: found unsized tuple coercion"); has_unsized_tuple_coercion = true; } } - t.clone() + tr.clone() } _ => { coercion.obligations.push(obligation); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index a44c475e0f8a..8adf4bb94a89 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -183,8 +183,11 @@ fn check_impl_overlap<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId) { for component_def_id in component_def_ids { if !tcx.is_object_safe(component_def_id) { - // This is an error, but it will be reported by wfcheck. Ignore it here. + // Without the 'object_safe_for_dispatch' feature this is an error + // which will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. + // With the feature enabled, the trait is not implemented automatically, + // so this is valid. } else { let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id); diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index 94f0995566f5..1386eac48dae 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -528,6 +528,9 @@ declare_features! ( /// Enable accurate caller location reporting during panic (RFC 2091). (active, track_caller, "1.40.0", Some(47809), None), + /// Non-object safe trait objects safe to use but cannot be created in safe rust + (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index c37efde9923a..b80c5f83830f 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -459,6 +459,7 @@ symbols! { no_std, not, note, + object_safe_for_dispatch, Ok, omit_gdb_pretty_printer_section, on, diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs new file mode 100644 index 000000000000..9859a226efd0 --- /dev/null +++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs @@ -0,0 +1,18 @@ +// Check that unsafe trait object do not implement themselves +// automatically + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized { + fn call(&self); +} + +fn takes_t(s: S) { + s.call(); +} + +fn takes_t_obj(t: &dyn Trait) { + takes_t(t); //~ ERROR E0277 +} + +fn main() {} diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr new file mode 100644 index 000000000000..b5a86acfb978 --- /dev/null +++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr @@ -0,0 +1,12 @@ +error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied + --> $DIR/coherence-unsafe-trait-object-impl.rs:15:13 + | +LL | fn takes_t(s: S) { + | ------- ----- required by this bound in `takes_t` +... +LL | takes_t(t); + | ^ the trait `Trait` is not implemented for `&dyn Trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr deleted file mode 100644 index d77fbc1e8239..000000000000 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/feature-gate-exhaustive-patterns.rs:7:9 - | -LL | let Ok(_x) = foo(); - | ^^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | if let Ok(_x) = foo() { /* */ } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs new file mode 100644 index 000000000000..8945360b7be6 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs @@ -0,0 +1,41 @@ +// Test that the use of the non object-safe trait objects +// are gated by `object_safe_for_dispatch` feature gate. + +trait NonObjectSafe1: Sized {} + +trait NonObjectSafe2 { + fn static_fn() {} +} + +trait NonObjectSafe3 { + fn foo(&self); +} + +trait NonObjectSafe4 { + fn foo(&self, &Self); +} + +fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { + //~^ ERROR E0038 +} + +fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { + //~^ ERROR E0038 + loop {} +} + +fn takes_non_object_safe_box(obj: Box) { + //~^ ERROR E0038 +} + +fn return_non_object_safe_rc() -> std::rc::Rc { + //~^ ERROR E0038 + loop {} +} + +trait Trait {} + +impl Trait for dyn NonObjectSafe1 {} +//~^ ERROR E0038 + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..54e64e2fc1bd --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -0,0 +1,46 @@ +error[E0038]: the trait `NonObjectSafe1` cannot be made into an object + --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:1 + | +LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error[E0038]: the trait `NonObjectSafe2` cannot be made into an object + --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:1 + | +LL | fn static_fn() {} + | --------- associated function `static_fn` has no `self` parameter +... +LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + +error[E0038]: the trait `NonObjectSafe3` cannot be made into an object + --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:1 + | +LL | fn foo(&self); + | --- method `foo` has generic type parameters +... +LL | fn takes_non_object_safe_box(obj: Box) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + +error[E0038]: the trait `NonObjectSafe4` cannot be made into an object + --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:1 + | +LL | fn foo(&self, &Self); + | --- method `foo` references the `Self` type in its parameters or return type +... +LL | fn return_non_object_safe_rc() -> std::rc::Rc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + +error[E0038]: the trait `NonObjectSafe1` cannot be made into an object + --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6 + | +LL | impl Trait for dyn NonObjectSafe1 {} + | ^^^^^ the trait `NonObjectSafe1` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 5415a45f7d62..83c03b514ddc 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -17,6 +17,7 @@ LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ the trait `Bar` cannot be made into an object | = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing` + = note: required by cast to type `&mut dyn Bar` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 66309394a426..06c83f65be26 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -14,6 +14,7 @@ LL | let _ = x | = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T` + = note: required by cast to type `&dyn Array` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index 8ef7d346cb33..8b923a2c6b23 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -14,6 +14,7 @@ LL | Box::new(()); | = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<()>` + = note: required by cast to type `std::boxed::Box` error: aborting due to 2 previous errors diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr similarity index 86% rename from src/test/ui/kindck/kindck-inherited-copy-bound.stderr rename to src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 27901d069279..a93f4686496a 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:18:16 + --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | fn take_param(foo: &T) { } | ---------- --- required by this bound in `take_param` @@ -10,7 +10,7 @@ LL | take_param(&x); = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>` error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/kindck-inherited-copy-bound.rs:24:19 + --> $DIR/kindck-inherited-copy-bound.rs:28:19 | LL | let z = &x as &dyn Foo; | ^^^^^^^^ the trait `Foo` cannot be made into an object @@ -18,13 +18,14 @@ LL | let z = &x as &dyn Foo; = note: the trait cannot require that `Self : Sized` error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/kindck-inherited-copy-bound.rs:24:13 + --> $DIR/kindck-inherited-copy-bound.rs:28:13 | LL | let z = &x as &dyn Foo; | ^^ the trait `Foo` cannot be made into an object | = note: the trait cannot require that `Self : Sized` = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box<{integer}>` + = note: required by cast to type `&dyn Foo` error: aborting due to 3 previous errors diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..7c67c5f9e959 --- /dev/null +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied + --> $DIR/kindck-inherited-copy-bound.rs:21:16 + | +LL | fn take_param(foo: &T) { } + | ---------- --- required by this bound in `take_param` +... +LL | take_param(&x); + | ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>` + | + = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/kindck-inherited-copy-bound.rs:28:13 + | +LL | let z = &x as &dyn Foo; + | ^^ the trait `Foo` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box` + = note: required by cast to type `&dyn Foo` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.rs b/src/test/ui/kindck/kindck-inherited-copy-bound.rs index 61e72908248d..aad693e5b193 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.rs +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.rs @@ -1,5 +1,8 @@ // Test that Copy bounds inherited by trait are checked. +// +// revisions: curr object_safe_for_dispatch +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] #![feature(box_syntax)] use std::any::Any; @@ -15,15 +18,17 @@ fn take_param(foo: &T) { } fn a() { let x: Box<_> = box 3; - take_param(&x); //~ ERROR E0277 + take_param(&x); //[curr]~ ERROR E0277 + //[object_safe_for_dispatch]~^ ERROR E0277 } fn b() { let x: Box<_> = box 3; let y = &x; let z = &x as &dyn Foo; - //~^ ERROR E0038 - //~| ERROR E0038 + //[curr]~^ ERROR E0038 + //[curr]~| ERROR E0038 + //[object_safe_for_dispatch]~^^^ ERROR E0038 } fn main() { } diff --git a/src/test/ui/object-safety/object-safety-associated-consts.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr similarity index 88% rename from src/test/ui/object-safety/object-safety-associated-consts.stderr rename to src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 7d5aa00356e0..67ef7a62f105 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-associated-consts.rs:9:1 + --> $DIR/object-safety-associated-consts.rs:12:1 | LL | const X: usize; | - the trait cannot contain associated consts like `X` diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..20993a680ba4 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -0,0 +1,15 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-associated-consts.rs:14:5 + | +LL | const X: usize; + | - the trait cannot contain associated consts like `X` +... +LL | t + | ^ the trait `Bar` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-associated-consts.rs b/src/test/ui/object-safety/object-safety-associated-consts.rs index 5900019ea915..e1a772e5ab2f 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.rs +++ b/src/test/ui/object-safety/object-safety-associated-consts.rs @@ -1,14 +1,18 @@ // Check that we correctly prevent users from making trait objects // from traits with associated consts. +// +// revisions: curr object_safe_for_dispatch +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] trait Bar { const X: usize; } fn make_bar(t: &T) -> &dyn Bar { - //~^ ERROR E0038 + //[curr]~^ ERROR E0038 t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn main() { diff --git a/src/test/ui/object-safety/object-safety-generics.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr similarity index 89% rename from src/test/ui/object-safety/object-safety-generics.stderr rename to src/test/ui/object-safety/object-safety-generics.curr.stderr index b25e0052e416..8ae9236a5c32 100644 --- a/src/test/ui/object-safety/object-safety-generics.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:14:1 + --> $DIR/object-safety-generics.rs:18:1 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters @@ -8,7 +8,7 @@ LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:19:1 + --> $DIR/object-safety-generics.rs:24:1 | LL | fn bar(&self, t: T); | --- method `bar` has generic type parameters diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..d3d8d3688883 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -0,0 +1,27 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:20:5 + | +LL | fn bar(&self, t: T); + | --- method `bar` has generic type parameters +... +LL | t + | ^ the trait `Bar` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:26:5 + | +LL | fn bar(&self, t: T); + | --- method `bar` has generic type parameters +... +LL | t as &dyn Bar + | ^ the trait `Bar` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-generics.rs b/src/test/ui/object-safety/object-safety-generics.rs index d63ea28c8f22..63dcd169925e 100644 --- a/src/test/ui/object-safety/object-safety-generics.rs +++ b/src/test/ui/object-safety/object-safety-generics.rs @@ -1,6 +1,10 @@ // Check that we correctly prevent users from making trait objects // from traits with generic methods, unless `where Self : Sized` is // present. +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + trait Bar { fn bar(&self, t: T); @@ -12,13 +16,15 @@ trait Quux { } fn make_bar(t: &T) -> &dyn Bar { - //~^ ERROR E0038 + //[curr]~^ ERROR E0038 t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn make_bar_explicit(t: &T) -> &dyn Bar { - //~^ ERROR E0038 + //[curr]~^ ERROR E0038 t as &dyn Bar + //[object_safe_for_dispatch]~^ ERROR E0038 } fn make_quux(t: &T) -> &dyn Quux { diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr similarity index 83% rename from src/test/ui/object-safety/object-safety-mentions-Self.stderr rename to src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 971e79cb0210..297cd876187f 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:17:1 + --> $DIR/object-safety-mentions-Self.rs:22:1 | LL | fn bar(&self, x: &Self); | --- method `bar` references the `Self` type in its parameters or return type @@ -8,10 +8,10 @@ LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:22:1 + --> $DIR/object-safety-mentions-Self.rs:28:1 | -LL | fn bar(&self) -> Self; - | --- method `bar` references the `Self` type in its parameters or return type +LL | fn baz(&self) -> Self; + | --- method `baz` references the `Self` type in its parameters or return type ... LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..03b2b8da0753 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -0,0 +1,27 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:24:5 + | +LL | fn bar(&self, x: &Self); + | --- method `bar` references the `Self` type in its parameters or return type +... +LL | t + | ^ the trait `Bar` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:30:5 + | +LL | fn baz(&self) -> Self; + | --- method `baz` references the `Self` type in its parameters or return type +... +LL | t + | ^ the trait `Baz` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Baz>` for `&T` + = note: required by cast to type `&dyn Baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.rs b/src/test/ui/object-safety/object-safety-mentions-Self.rs index f13ffe536267..412d16ff3c7c 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.rs +++ b/src/test/ui/object-safety/object-safety-mentions-Self.rs @@ -1,27 +1,34 @@ // Check that we correctly prevent users from making trait objects // form traits that make use of `Self` in an argument or return // position, unless `where Self : Sized` is present.. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + trait Bar { fn bar(&self, x: &Self); } trait Baz { - fn bar(&self) -> Self; + fn baz(&self) -> Self; } trait Quux { - fn get(&self, s: &Self) -> Self where Self : Sized; + fn quux(&self, s: &Self) -> Self where Self : Sized; } fn make_bar(t: &T) -> &dyn Bar { - //~^ ERROR E0038 - loop { } + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn make_baz(t: &T) -> &dyn Baz { - //~^ ERROR E0038 + //[curr]~^ ERROR E0038 t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn make_quux(t: &T) -> &dyn Quux { @@ -32,5 +39,4 @@ fn make_quux_explicit(t: &T) -> &dyn Quux { t as &dyn Quux } -fn main() { -} +fn main() {} diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr new file mode 100644 index 000000000000..1641ce577719 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -0,0 +1,12 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:12:1 + | +LL | fn foo() {} + | --- associated function `foo` has no `self` parameter +... +LL | fn diverges() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..91a9285b63cc --- /dev/null +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -0,0 +1,15 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:22:27 + | +LL | fn foo() {} + | --- associated function `foo` has no `self` parameter +... +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` + = note: required by cast to type `std::boxed::Box` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-no-static.rs b/src/test/ui/object-safety/object-safety-no-static.rs index 55d31ce80876..03b622174838 100644 --- a/src/test/ui/object-safety/object-safety-no-static.rs +++ b/src/test/ui/object-safety/object-safety-no-static.rs @@ -1,14 +1,24 @@ // Check that we correctly prevent users from making trait objects // from traits with static methods. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] trait Foo { - fn foo(); + fn foo() {} } -fn foo_implicit(b: Box) -> Box { - //~^ ERROR E0038 +fn diverges() -> Box { + //[curr]~^ ERROR E0038 loop { } } +struct Bar; + +impl Foo for Bar {} + fn main() { + let b: Box = Box::new(Bar); + //[object_safe_for_dispatch]~^ ERROR E0038 } diff --git a/src/test/ui/object-safety/object-safety-sized-2.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr similarity index 89% rename from src/test/ui/object-safety/object-safety-sized-2.stderr rename to src/test/ui/object-safety/object-safety-sized-2.curr.stderr index dcaf2ff0bc29..1e1d2bf64c42 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized-2.rs:10:1 + --> $DIR/object-safety-sized-2.rs:14:1 | LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..06ecfd019c84 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -0,0 +1,13 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized-2.rs:16:5 + | +LL | t + | ^ the trait `Bar` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized-2.rs b/src/test/ui/object-safety/object-safety-sized-2.rs index 7235b22404e2..1e79b8cd917c 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.rs +++ b/src/test/ui/object-safety/object-safety-sized-2.rs @@ -1,5 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] trait Bar where Self : Sized @@ -8,8 +12,9 @@ trait Bar } fn make_bar(t: &T) -> &dyn Bar { - //~^ ERROR E0038 - loop { } + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn main() { diff --git a/src/test/ui/object-safety/object-safety-sized.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr similarity index 90% rename from src/test/ui/object-safety/object-safety-sized.stderr rename to src/test/ui/object-safety/object-safety-sized.curr.stderr index 98bc73e38d4c..1a67e79e83d3 100644 --- a/src/test/ui/object-safety/object-safety-sized.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:8:1 + --> $DIR/object-safety-sized.rs:12:1 | LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..3d88dfc40ed3 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -0,0 +1,13 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized.rs:14:5 + | +LL | t + | ^ the trait `Bar` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized.rs b/src/test/ui/object-safety/object-safety-sized.rs index 1312bb34717e..b424b892d3b4 100644 --- a/src/test/ui/object-safety/object-safety-sized.rs +++ b/src/test/ui/object-safety/object-safety-sized.rs @@ -1,13 +1,18 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] trait Bar : Sized { fn bar(&self, t: T); } fn make_bar(t: &T) -> &dyn Bar { - //~^ ERROR E0038 + //[curr]~^ ERROR E0038 t + //[object_safe_for_dispatch]~^ ERROR E0038 } fn main() { diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs new file mode 100644 index 000000000000..fa04f4b12d5f --- /dev/null +++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs @@ -0,0 +1,23 @@ +// Check that we if we get ahold of an object unsafe trait +// object with auto traits and lifetimes, we can downcast it +// +// check-pass + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { + t +} + +fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) + -> &'b (dyn Trait + 't) +where + 'a: 'b, + 't: 'a + 'b, +{ + t +} + +fn main() {} diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs new file mode 100644 index 000000000000..1dea40122656 --- /dev/null +++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs @@ -0,0 +1,69 @@ +// Check that we can manually implement an object +// unsafe trait for its trait object +// +// run-pass + +#![feature(object_safe_for_dispatch)] + +trait Bad { + fn stat() -> char { + 'A' + } + fn virt(&self) -> char { + 'B' + } + fn indirect(&self) -> char { + Self::stat() + } +} + +trait Good { + fn good_virt(&self) -> char { + panic!() + } + fn good_indirect(&self) -> char { + panic!() + } +} + +impl<'a> Bad for dyn Bad + 'a { + fn stat() -> char { + 'C' + } + fn virt(&self) -> char { + 'D' + } +} + +struct Struct {} + +impl Bad for Struct {} + +impl Good for Struct {} + +fn main() { + let s = Struct {}; + + let mut res = String::new(); + + // Directly call static + res.push(Struct::stat()); // "A" + res.push(::stat()); // "AC" + + let good: &dyn Good = &s; + + // These look similar enough... + let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; + + // Call virtual + res.push(s.virt()); // "ACB" + res.push(bad.virt()); // "ACBD" + + // Indirectly call static + res.push(s.indirect()); // "ACBDA" + res.push(bad.indirect()); // "ACBDAC" + + if &res != "ACBDAC" { + panic!(); + } +} diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs new file mode 100644 index 000000000000..df97d2c13278 --- /dev/null +++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs @@ -0,0 +1,37 @@ +// Check that we can statically dispatch methods for object +// unsafe trait objects, directly and indirectly +// +// check-pass + +#![feature(object_safe_for_dispatch)] + +trait Statics { + fn plain() {} + fn generic() {} +} + +trait Trait: Sized {} + +impl<'a> Statics for dyn Trait + 'a {} + +fn static_poly() { + T::plain(); + T::generic::(); +} + +fn inferred_poly(t: &T) { + static_poly::(); + T::plain(); + T::generic::(); +} + +fn call(t: &dyn Trait) { + static_poly::(); + inferred_poly(t); +} + +fn main() { + static_poly::(); + ::plain(); + ::generic::() +} diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr new file mode 100644 index 000000000000..cdffc1d86edf --- /dev/null +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -0,0 +1,24 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/arbitrary-self-types-not-object-safe.rs:34:32 + | +LL | fn foo(self: &Rc) -> usize; + | --- method `foo`'s `self` parameter cannot be dispatched on +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13 + | +LL | fn foo(self: &Rc) -> usize; + | --- method `foo`'s `self` parameter cannot be dispatched on +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` + = note: required by cast to type `std::rc::Rc` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr new file mode 100644 index 000000000000..725632a12126 --- /dev/null +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -0,0 +1,15 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13 + | +LL | fn foo(self: &Rc) -> usize; + | --- method `foo`'s `self` parameter cannot be dispatched on +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::rc::Rc` + = note: required by cast to type `std::rc::Rc` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs index 7443d888c9ec..2eeabad28db0 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs @@ -1,3 +1,6 @@ +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] #![feature(arbitrary_self_types)] use std::rc::Rc; @@ -29,8 +32,9 @@ impl Bar for usize { fn make_foo() { let x = Rc::new(5usize) as Rc; - //~^ ERROR E0038 - //~| ERROR E0038 + //[curr]~^ ERROR E0038 + //[curr]~| ERROR E0038 + //[object_safe_for_dispatch]~^^^ ERROR E0038 } fn make_bar() { diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 3ac1e96b30c9..028e9eedd641 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -8,6 +8,7 @@ LL | let _: &dyn Tr = &St; | ^^^ the trait `Tr` cannot be made into an object | = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St` + = note: required by cast to type `&dyn Tr` error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 83c2c0652749..9b750d382ec9 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -33,6 +33,7 @@ LL | (box 10 as Box).dup(); | ^^^^^^ the trait `bar` cannot be made into an object | = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box<{integer}>` + = note: required by cast to type `std::boxed::Box` error: aborting due to 4 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs new file mode 100644 index 000000000000..ffdb49a3be5c --- /dev/null +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs @@ -0,0 +1,18 @@ +// Check that we do not allow casts or coercions +// to object unsafe trait objects inside a Box + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +fn takes_box(t: Box) {} + +fn main() { + Box::new(S) as Box; //~ ERROR E0038 + let t_box: Box = Box::new(S); //~ ERROR E0038 + takes_box(Box::new(S)); //~ ERROR E0038 +} diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr new file mode 100644 index 000000000000..0b63aef2bce1 --- /dev/null +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -0,0 +1,33 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 + | +LL | let t_box: Box = Box::new(S); + | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` + = note: required by cast to type `std::boxed::Box` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 + | +LL | takes_box(Box::new(S)); + | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` + = note: required by cast to type `std::boxed::Box<(dyn Trait + 'static)>` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 + | +LL | Box::new(S) as Box; + | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized>` for `std::boxed::Box` + = note: required by cast to type `std::boxed::Box` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs new file mode 100644 index 000000000000..143b854ed6b2 --- /dev/null +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs @@ -0,0 +1,18 @@ +// Check that we do not allow casts or coercions +// to object unsafe trait objects by ref + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +fn takes_trait(t: &dyn Trait) {} + +fn main() { + &S as &dyn Trait; //~ ERROR E0038 + let t: &dyn Trait = &S; //~ ERROR E0038 + takes_trait(&S); //~ ERROR E0038 +} diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr new file mode 100644 index 000000000000..7aeefd731fb2 --- /dev/null +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -0,0 +1,33 @@ +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 + | +LL | let t: &dyn Trait = &S; + | ^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` + = note: required by cast to type `&dyn Trait` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 + | +LL | takes_trait(&S); + | ^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` + = note: required by cast to type `&dyn Trait` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 + | +LL | &S as &dyn Trait; + | ^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` + = note: required by cast to type `&dyn Trait` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.rs b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs new file mode 100644 index 000000000000..c8731a8ecafa --- /dev/null +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs @@ -0,0 +1,29 @@ +// Check that we do not allow coercions to object +// unsafe trait objects in match arms + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +struct R; + +impl Trait for R {} + +fn opt() -> Option<()> { + Some(()) +} + +fn main() { + match opt() { + Some(()) => &S, + None => &R, //~ ERROR E0308 + } + let t: &dyn Trait = match opt() { //~ ERROR E0038 + Some(()) => &S, //~ ERROR E0038 + None => &R, + }; +} diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr new file mode 100644 index 000000000000..185b1e6c36b5 --- /dev/null +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -0,0 +1,38 @@ +error[E0308]: match arms have incompatible types + --> $DIR/wf-unsafe-trait-obj-match.rs:23:17 + | +LL | / match opt() { +LL | | Some(()) => &S, + | | -- this is found to be of type `&S` +LL | | None => &R, + | | ^^ expected struct `S`, found struct `R` +LL | | } + | |_____- `match` arms have incompatible types + | + = note: expected type `&S` + found type `&R` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 + | +LL | Some(()) => &S, + | ^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S` + = note: required by cast to type `&dyn Trait` + +error[E0038]: the trait `Trait` cannot be made into an object + --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 + | +LL | let t: &dyn Trait = match opt() { + | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&R` + = note: required by cast to type `&dyn Trait` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0308. +For more information about an error, try `rustc --explain E0038`. From 4e8d1b229217c7c83ce96b44410ccae9470db973 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 22 Oct 2019 16:53:28 -0400 Subject: [PATCH 082/109] Add some documentation --- src/librustc/lint/context.rs | 24 ++++++++++++++++-------- src/librustc_driver/lib.rs | 1 + src/librustc_interface/interface.rs | 5 +++++ src/librustc_plugin/registry.rs | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 2a0cdba50cb5..595b715c02ef 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -155,23 +155,31 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_early_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync + ) { self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_pre_expansion_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_mod_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_module_passes.push(Box::new(pass)); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2cf1552ed968..a18ef014b4dc 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + /// Called early during compilation to allow other drivers to easily register lints. fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 34ec3c862a3e..3f832f95bd40 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -82,6 +82,11 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + /// This is a callback from the driver that is called when we're registering lints; + /// it is called during plugin registration when we have the LintStore in a non-shared state. + /// + /// Note that if you find a Some here you probably want to call that function in the new + /// function being registered. pub register_lints: Option>, } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 223956a4f5e3..2e23b8c870cf 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -25,6 +25,7 @@ pub struct Registry<'a> { /// from the plugin registrar. pub sess: &'a Session, + /// The `LintStore` allows plugins to register new lints. pub lint_store: &'a mut LintStore, #[doc(hidden)] From fe3dc3171066e26085ca11be77ade8c9f8adee2d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 22 Oct 2019 15:22:57 -0700 Subject: [PATCH 083/109] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 3a9abe3f0655..3ba5f27170db 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 3a9abe3f065554a7fbc59f440df2baba4a6e47ee +Subproject commit 3ba5f27170db10af7a92f2b682e049397197b8fa From eeb549bfc31c27c6cec98eb852409a51f0a8162c Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Sat, 5 Oct 2019 18:23:37 -0400 Subject: [PATCH 084/109] Add Cow::is_borrowed and Cow::is_owned --- src/liballoc/borrow.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/liballoc/lib.rs | 1 + 2 files changed, 42 insertions(+) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index a9c5bce4c25f..d2bdda83fa99 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -207,6 +207,47 @@ impl Clone for Cow<'_, B> { } impl Cow<'_, B> { + /// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work. + /// + /// # Examples + /// + /// ``` + /// #![feature(cow_is_borrowed)] + /// use std::borrow::Cow; + /// + /// let cow = Cow::Borrowed("moo"); + /// assert!(cow.is_borrowed()); + /// + /// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string()); + /// assert!(!bull.is_borrowed()); + /// ``` + #[unstable(feature = "cow_is_borrowed", issue = "65143")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + Owned(_) => false, + } + } + + /// Returns true if the data is owned, i.e. if `to_mut` would be a no-op. + /// + /// # Examples + /// + /// ``` + /// #![feature(cow_is_borrowed)] + /// use std::borrow::Cow; + /// + /// let cow: Cow<'_, str> = Cow::Owned("moo".to_string()); + /// assert!(cow.is_owned()); + /// + /// let bull = Cow::Borrowed("...moo?"); + /// assert!(!bull.is_owned()); + /// ``` + #[unstable(feature = "cow_is_borrowed", issue = "65143")] + pub fn is_owned(&self) -> bool { + !self.is_borrowed() + } + /// Acquires a mutable reference to the owned form of the data. /// /// Clones the data if it is not already owned. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3684162d8b18..94379afc2bd4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -85,6 +85,7 @@ #![feature(const_generic_impls_guard)] #![feature(const_generics)] #![feature(const_in_array_repeat_expressions)] +#![feature(cow_is_borrowed)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] #![feature(container_error_extra)] From 7e0ef6e92e327e9d49b1f4a4202a308ad3936d36 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 23 Oct 2019 02:46:10 +0000 Subject: [PATCH 085/109] update compiletest --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b51095d42900..3f37a1b7eb09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -556,9 +556,9 @@ dependencies = [ [[package]] name = "compiletest_rs" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "676a74b493d50ac33cacd83fd536597e6b52c0b46b9856f7b9c809d82fef4ac0" +checksum = "f75b10a18fb53549fdd090846eb01c7f8593914494d1faabc4d3005c436e417a" dependencies = [ "diff", "filetime", From 557cbd0fd5c783a69a259118ac578e4d575dc7a6 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 23 Oct 2019 03:49:42 +0000 Subject: [PATCH 086/109] Public some types for compiletest_rs --- src/libtest/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 179558e8f9a1..8c1e9f1722a2 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -34,8 +34,10 @@ pub use self::ColorConfig::*; pub use self::types::*; pub use self::types::TestName::*; -pub use self::options::{Options, ShouldPanic}; +pub use self::options::{ColorConfig, Options, OutputFormat, RunIgnored, ShouldPanic}; pub use self::bench::{Bencher, black_box}; +pub use self::console::run_tests_console; +pub use cli::TestOpts; // Module to be used by rustc to compile tests in libtest pub mod test { @@ -84,9 +86,8 @@ mod tests; use test_result::*; use time::TestExecTime; -use options::{RunStrategy, Concurrent, RunIgnored, ColorConfig}; +use options::{RunStrategy, Concurrent}; use event::{CompletedTest, TestEvent}; -use cli::TestOpts; use helpers::sink::Sink; use helpers::concurrency::get_concurrency; use helpers::exit_code::get_exit_code; From f69293ae808dea61a2dacee6057ca5bb0d7dc817 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 16 Oct 2019 22:40:37 +0200 Subject: [PATCH 087/109] Add `core::macros::matches!( $expr, $pat ) -> bool` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Motivation This macro is: * General-purpose (not domain-specific) * Simple (the implementation is short) * Very popular [on crates.io](https://crates.io/crates/matches) (currently 37th in all-time downloads) * The two previous points combined make it number one in [left-pad index](https://twitter.com/bascule/status/1184523027888988160) score As such, I feel it is a good candidate for inclusion in the standard library. In fact I already felt that way five years ago: https://github.com/rust-lang/rust/pull/14685 (Although the proof of popularity was not as strong at the time.) Back then, the main concern was that this macro may not be quite universally-enough useful to belong in the prelude. # API Therefore, this PR adds the macro such that using it requires one of: ``` use core::macros::matches; use std::macros::matches; ``` Like arms of a `match` expression, the macro supports multiple patterns separated by `|` and optionally followed by `if` and a guard expression: ``` let foo = 'f'; assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); let bar = Some(4); assert!(matches!(bar, Some(x) if x > 2)); ``` # Implementation constraints A combination of reasons make it tricky for a standard library macro not to be in the prelude. Currently, all public `macro_rules` macros in the standard library macros end up “in the prelude” of every crate not through `use std::prelude::v1::*;` like for other kinds of items, but through `#[macro_use]` on `extern crate std;`. (Both are injected by `src/libsyntax_ext/standard_library_imports.rs`.) `#[macro_use]` seems to import every macro that is available at the top-level of a crate, even if through a `pub use` re-export. Therefore, for `matches!` not to be in the prelude, we need it to be inside of a module rather than at the root of `core` or `std`. However, the only way to make a `macro_rules` macro public outside of the crate where it is defined appears to be `#[macro_export]`. This exports the macro at the root of the crate regardless of which module defines it. See [macro scoping]( https://doc.rust-lang.org/reference/macros-by-example.html#scoping-exporting-and-importing) in the reference. Therefore, the macro needs to be defined in a crate that is not `core` or `std`. # Implementation This PR adds a new `matches_macro` crate as a private implementation detail of the standard library. This crate is `#![no_core]` so that libcore can depend on it. It contains a `macro_rules` definition with `#[macro_export]`. libcore and libstd each have a new public `macros` module that contains a `pub use` re-export of the macro. Both the module and the macro are unstable, for now. The existing private `macros` modules are renamed `prelude_macros`, though their respective source remains in `macros.rs` files. --- Cargo.lock | 5 ++++ src/libcore/Cargo.toml | 3 ++ src/libcore/lib.rs | 12 +++++++- src/libcore/prelude/v1.rs | 2 +- src/libmatches_macro/Cargo.toml | 10 +++++++ src/libmatches_macro/lib.rs | 29 +++++++++++++++++++ src/libstd/lib.rs | 12 +++++++- src/test/ui/macros/unknown-builtin.stderr | 2 +- src/test/ui/matches_macro_imported.rs | 13 +++++++++ .../ui/matches_macro_not_in_the_prelude.rs | 7 +++++ .../matches_macro_not_in_the_prelude.stderr | 8 +++++ 11 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/libmatches_macro/Cargo.toml create mode 100644 src/libmatches_macro/lib.rs create mode 100644 src/test/ui/matches_macro_imported.rs create mode 100644 src/test/ui/matches_macro_not_in_the_prelude.rs create mode 100644 src/test/ui/matches_macro_not_in_the_prelude.stderr diff --git a/Cargo.lock b/Cargo.lock index 3f37a1b7eb09..343b101990a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,6 +585,7 @@ checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" name = "core" version = "0.0.0" dependencies = [ + "matches_macro", "rand 0.7.0", ] @@ -1900,6 +1901,10 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "matches_macro" +version = "0.0.0" + [[package]] name = "mdbook" version = "0.3.1" diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index ac07ffb14feb..65f7a42824bf 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -20,6 +20,9 @@ path = "../libcore/tests/lib.rs" name = "corebenches" path = "../libcore/benches/lib.rs" +[dependencies] +matches_macro = { path = "../libmatches_macro" } + [dev-dependencies] rand = "0.7" diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 30e8dddff85a..a5af32250e67 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -85,6 +85,7 @@ #![feature(iter_once_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] +#![feature(matches_macro)] #![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] @@ -134,7 +135,16 @@ use prelude::v1::*; #[macro_use] -mod macros; +#[path = "macros.rs"] +mod prelude_macros; + +/// Macros that are not in the prelude and need to be imported explicitly +#[unstable(feature = "matches_macro", issue = "0")] +pub mod macros { + #[unstable(feature = "matches_macro", issue = "0")] + #[doc(inline)] + pub use matches_macro::matches; +} #[macro_use] mod internal_macros; diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 7cc279a9ef2e..285f8d6e077f 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -82,7 +82,7 @@ pub use crate::{ #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow(deprecated)] #[doc(no_inline)] -pub use crate::macros::builtin::{ +pub use crate::prelude_macros::builtin::{ RustcDecodable, RustcEncodable, bench, diff --git a/src/libmatches_macro/Cargo.toml b/src/libmatches_macro/Cargo.toml new file mode 100644 index 000000000000..3ed0aa60350d --- /dev/null +++ b/src/libmatches_macro/Cargo.toml @@ -0,0 +1,10 @@ +[package] +authors = ["The Rust Project Developers"] +name = "matches_macro" +version = "0.0.0" +autotests = false +autobenches = false +edition = "2018" + +[lib] +path = "lib.rs" diff --git a/src/libmatches_macro/lib.rs b/src/libmatches_macro/lib.rs new file mode 100644 index 000000000000..0e3552ed4ea9 --- /dev/null +++ b/src/libmatches_macro/lib.rs @@ -0,0 +1,29 @@ +#![no_core] +#![feature(no_core)] +#![feature(staged_api)] +#![doc(test(no_crate_inject))] + +/// Returns whether the given expression matches (any of) the given pattern(s). +/// +/// # Examples +/// +/// ``` +/// #![feature(matches_macro)] +/// use std::macros::matches; +/// +/// let foo = 'f'; +/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); +/// +/// let bar = Some(4); +/// assert!(matches!(bar, Some(x) if x > 2)); +/// ``` +#[macro_export] +#[unstable(feature = "matches_macro", issue = "0")] +macro_rules! matches { + ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => { + match $expression { + $( $pattern )|+ $( if $guard )? => true, + _ => false + } + } +} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 93d3e4ea3df2..4c079108e2e1 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -276,6 +276,7 @@ #![feature(linkage)] #![feature(log_syntax)] #![feature(manually_drop_take)] +#![feature(matches_macro)] #![feature(maybe_uninit_ref)] #![feature(maybe_uninit_slice)] #![feature(needs_panic_runtime)] @@ -353,7 +354,16 @@ extern crate cfg_if; // The standard macros that are not built-in to the compiler. #[macro_use] -mod macros; +#[path = "macros.rs"] +mod prelude_macros; + +/// Macros that are not in the prelude and need to be imported explicitly +#[unstable(feature = "matches_macro", issue = "0")] +pub mod macros { + #[unstable(feature = "matches_macro", issue = "0")] + #[doc(inline)] + pub use core::macros::matches; +} // The Rust prelude pub mod prelude; diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr index 33b7b055b4e4..27992b466baa 100644 --- a/src/test/ui/macros/unknown-builtin.stderr +++ b/src/test/ui/macros/unknown-builtin.stderr @@ -5,7 +5,7 @@ LL | macro_rules! unknown { () => () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot find a built-in macro with name `line` - --> <::core::macros::builtin::line macros>:1:1 + --> <::core::prelude_macros::builtin::line macros>:1:1 | LL | () => { } | ^^^^^^^^^ diff --git a/src/test/ui/matches_macro_imported.rs b/src/test/ui/matches_macro_imported.rs new file mode 100644 index 000000000000..76b7e692ceea --- /dev/null +++ b/src/test/ui/matches_macro_imported.rs @@ -0,0 +1,13 @@ +// run-pass + +#![feature(matches_macro)] + +use std::macros::matches; + +fn main() { + let foo = 'f'; + assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); + + let foo = '_'; + assert!(!matches!(foo, 'A'..='Z' | 'a'..='z')); +} diff --git a/src/test/ui/matches_macro_not_in_the_prelude.rs b/src/test/ui/matches_macro_not_in_the_prelude.rs new file mode 100644 index 000000000000..489c7b866459 --- /dev/null +++ b/src/test/ui/matches_macro_not_in_the_prelude.rs @@ -0,0 +1,7 @@ +#![feature(matches_macro)] + +fn main() { + let foo = 'f'; + assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); + //~^ Error: cannot find macro `matches` in this scope +} diff --git a/src/test/ui/matches_macro_not_in_the_prelude.stderr b/src/test/ui/matches_macro_not_in_the_prelude.stderr new file mode 100644 index 000000000000..0abe29a835b8 --- /dev/null +++ b/src/test/ui/matches_macro_not_in_the_prelude.stderr @@ -0,0 +1,8 @@ +error: cannot find macro `matches` in this scope + --> $DIR/matches_macro_not_in_the_prelude.rs:5:13 + | +LL | assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); + | ^^^^^^^ + +error: aborting due to previous error + From 7472cd46aa6c004568d12a71ecd90c9c45b69fb0 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 23 Oct 2019 15:30:04 +0200 Subject: [PATCH 088/109] Move the `matches!` macro to the prelude --- Cargo.lock | 5 ---- src/libcore/Cargo.toml | 3 -- src/libcore/lib.rs | 12 +------- src/libcore/macros.rs | 24 +++++++++++++++ src/libcore/prelude/v1.rs | 2 +- src/libmatches_macro/Cargo.toml | 10 ------- src/libmatches_macro/lib.rs | 29 ------------------- src/libstd/lib.rs | 12 ++------ src/test/ui/macros/unknown-builtin.stderr | 2 +- src/test/ui/matches_macro_imported.rs | 13 --------- .../ui/matches_macro_not_in_the_prelude.rs | 7 ----- .../matches_macro_not_in_the_prelude.stderr | 8 ----- 12 files changed, 29 insertions(+), 98 deletions(-) delete mode 100644 src/libmatches_macro/Cargo.toml delete mode 100644 src/libmatches_macro/lib.rs delete mode 100644 src/test/ui/matches_macro_imported.rs delete mode 100644 src/test/ui/matches_macro_not_in_the_prelude.rs delete mode 100644 src/test/ui/matches_macro_not_in_the_prelude.stderr diff --git a/Cargo.lock b/Cargo.lock index 343b101990a4..3f37a1b7eb09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -585,7 +585,6 @@ checksum = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" name = "core" version = "0.0.0" dependencies = [ - "matches_macro", "rand 0.7.0", ] @@ -1901,10 +1900,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -[[package]] -name = "matches_macro" -version = "0.0.0" - [[package]] name = "mdbook" version = "0.3.1" diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index 65f7a42824bf..ac07ffb14feb 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -20,9 +20,6 @@ path = "../libcore/tests/lib.rs" name = "corebenches" path = "../libcore/benches/lib.rs" -[dependencies] -matches_macro = { path = "../libmatches_macro" } - [dev-dependencies] rand = "0.7" diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a5af32250e67..30e8dddff85a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -85,7 +85,6 @@ #![feature(iter_once_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(matches_macro)] #![feature(never_type)] #![feature(nll)] #![feature(exhaustive_patterns)] @@ -135,16 +134,7 @@ use prelude::v1::*; #[macro_use] -#[path = "macros.rs"] -mod prelude_macros; - -/// Macros that are not in the prelude and need to be imported explicitly -#[unstable(feature = "matches_macro", issue = "0")] -pub mod macros { - #[unstable(feature = "matches_macro", issue = "0")] - #[doc(inline)] - pub use matches_macro::matches; -} +mod macros; #[macro_use] mod internal_macros; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 1320e63df063..f2775ffa7ca9 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -238,6 +238,30 @@ macro_rules! debug_assert_ne { ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); }) } +/// Returns whether the given expression matches (any of) the given pattern(s). +/// +/// # Examples +/// +/// ``` +/// #![feature(matches_macro)] +/// +/// let foo = 'f'; +/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); +/// +/// let bar = Some(4); +/// assert!(matches!(bar, Some(x) if x > 2)); +/// ``` +#[macro_export] +#[unstable(feature = "matches_macro", issue = "0")] +macro_rules! matches { + ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => { + match $expression { + $( $pattern )|+ $( if $guard )? => true, + _ => false + } + } +} + /// Unwraps a result or propagates its error. /// /// The `?` operator was added to replace `try!` and should be used instead. diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 285f8d6e077f..7cc279a9ef2e 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -82,7 +82,7 @@ pub use crate::{ #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow(deprecated)] #[doc(no_inline)] -pub use crate::prelude_macros::builtin::{ +pub use crate::macros::builtin::{ RustcDecodable, RustcEncodable, bench, diff --git a/src/libmatches_macro/Cargo.toml b/src/libmatches_macro/Cargo.toml deleted file mode 100644 index 3ed0aa60350d..000000000000 --- a/src/libmatches_macro/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "matches_macro" -version = "0.0.0" -autotests = false -autobenches = false -edition = "2018" - -[lib] -path = "lib.rs" diff --git a/src/libmatches_macro/lib.rs b/src/libmatches_macro/lib.rs deleted file mode 100644 index 0e3552ed4ea9..000000000000 --- a/src/libmatches_macro/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![no_core] -#![feature(no_core)] -#![feature(staged_api)] -#![doc(test(no_crate_inject))] - -/// Returns whether the given expression matches (any of) the given pattern(s). -/// -/// # Examples -/// -/// ``` -/// #![feature(matches_macro)] -/// use std::macros::matches; -/// -/// let foo = 'f'; -/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); -/// -/// let bar = Some(4); -/// assert!(matches!(bar, Some(x) if x > 2)); -/// ``` -#[macro_export] -#[unstable(feature = "matches_macro", issue = "0")] -macro_rules! matches { - ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => { - match $expression { - $( $pattern )|+ $( if $guard )? => true, - _ => false - } - } -} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 4c079108e2e1..d0cb0104f6cb 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -354,16 +354,7 @@ extern crate cfg_if; // The standard macros that are not built-in to the compiler. #[macro_use] -#[path = "macros.rs"] -mod prelude_macros; - -/// Macros that are not in the prelude and need to be imported explicitly -#[unstable(feature = "matches_macro", issue = "0")] -pub mod macros { - #[unstable(feature = "matches_macro", issue = "0")] - #[doc(inline)] - pub use core::macros::matches; -} +mod macros; // The Rust prelude pub mod prelude; @@ -537,6 +528,7 @@ pub use core::{ writeln, // Unstable todo, + matches, }; // Re-export built-in macros defined through libcore. diff --git a/src/test/ui/macros/unknown-builtin.stderr b/src/test/ui/macros/unknown-builtin.stderr index 27992b466baa..33b7b055b4e4 100644 --- a/src/test/ui/macros/unknown-builtin.stderr +++ b/src/test/ui/macros/unknown-builtin.stderr @@ -5,7 +5,7 @@ LL | macro_rules! unknown { () => () } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot find a built-in macro with name `line` - --> <::core::prelude_macros::builtin::line macros>:1:1 + --> <::core::macros::builtin::line macros>:1:1 | LL | () => { } | ^^^^^^^^^ diff --git a/src/test/ui/matches_macro_imported.rs b/src/test/ui/matches_macro_imported.rs deleted file mode 100644 index 76b7e692ceea..000000000000 --- a/src/test/ui/matches_macro_imported.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass - -#![feature(matches_macro)] - -use std::macros::matches; - -fn main() { - let foo = 'f'; - assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); - - let foo = '_'; - assert!(!matches!(foo, 'A'..='Z' | 'a'..='z')); -} diff --git a/src/test/ui/matches_macro_not_in_the_prelude.rs b/src/test/ui/matches_macro_not_in_the_prelude.rs deleted file mode 100644 index 489c7b866459..000000000000 --- a/src/test/ui/matches_macro_not_in_the_prelude.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![feature(matches_macro)] - -fn main() { - let foo = 'f'; - assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); - //~^ Error: cannot find macro `matches` in this scope -} diff --git a/src/test/ui/matches_macro_not_in_the_prelude.stderr b/src/test/ui/matches_macro_not_in_the_prelude.stderr deleted file mode 100644 index 0abe29a835b8..000000000000 --- a/src/test/ui/matches_macro_not_in_the_prelude.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot find macro `matches` in this scope - --> $DIR/matches_macro_not_in_the_prelude.rs:5:13 - | -LL | assert!(matches!(foo, 'A'..='Z' | 'a'..='z')); - | ^^^^^^^ - -error: aborting due to previous error - From f7ebe193389b4c63d9c93d79fff59568985e1763 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 23 Oct 2019 15:34:24 +0200 Subject: [PATCH 089/109] Add tracking issue for the `matches!` macro https://github.com/rust-lang/rust/issues/65721 --- src/libcore/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f2775ffa7ca9..6e19878ef17d 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -252,7 +252,7 @@ macro_rules! debug_assert_ne { /// assert!(matches!(bar, Some(x) if x > 2)); /// ``` #[macro_export] -#[unstable(feature = "matches_macro", issue = "0")] +#[unstable(feature = "matches_macro", issue = "65721")] macro_rules! matches { ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => { match $expression { From e76a1846153209b15dfbf697a33c25214bb753b3 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 23 Oct 2019 15:42:52 +0200 Subject: [PATCH 090/109] Document guard expressions in `matches!` --- src/libcore/macros.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 6e19878ef17d..35558e3abcdd 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -238,7 +238,10 @@ macro_rules! debug_assert_ne { ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); }) } -/// Returns whether the given expression matches (any of) the given pattern(s). +/// Returns whether the given expression matches any of the given patterns. +/// +/// Like in a `match` expression, the pattern can be optionally followed by `if` +/// and a guard expression that has access to names bound by the pattern. /// /// # Examples /// From cc7294c751fd700b77c3556eaae8507661f08f22 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 23 Oct 2019 17:09:56 +0100 Subject: [PATCH 091/109] Add regression test for #62579 --- .../const-generics/issues/issue-62579-no-match.rs | 15 +++++++++++++++ .../issues/issue-62579-no-match.stderr | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-62579-no-match.rs create mode 100644 src/test/ui/const-generics/issues/issue-62579-no-match.stderr diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.rs b/src/test/ui/const-generics/issues/issue-62579-no-match.rs new file mode 100644 index 000000000000..0ff7ddc41fe4 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-62579-no-match.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +#[derive(PartialEq, Eq)] +struct NoMatch; + +fn foo() -> bool { + true +} + +fn main() { + foo::<{NoMatch}>(); +} diff --git a/src/test/ui/const-generics/issues/issue-62579-no-match.stderr b/src/test/ui/const-generics/issues/issue-62579-no-match.stderr new file mode 100644 index 000000000000..759d5fdeb4c1 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-62579-no-match.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-62579-no-match.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From 12f68e6987c4669b90a6cdac1643b99b6c677aea Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 23 Oct 2019 17:40:18 +0100 Subject: [PATCH 092/109] Account for const generalisation in combine --- src/librustc/infer/combine.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 2e724ac56eee..a6c3c2de139b 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -605,9 +605,21 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { match c.val { ConstValue::Infer(InferConst::Var(vid)) => { let mut variable_table = self.infcx.const_unification_table.borrow_mut(); - match variable_table.probe_value(vid).val.known() { - Some(u) => self.relate(&u, &u), - None => Ok(c), + let var_value = variable_table.probe_value(vid); + match var_value.val { + ConstVariableValue::Known { value: u } => self.relate(&u, &u), + ConstVariableValue::Unknown { universe } => { + if self.for_universe.can_name(universe) { + Ok(c) + } else { + let new_var_id = variable_table.new_key(ConstVarValue { + origin: var_value.origin, + val: ConstVariableValue::Unknown { universe: self.for_universe }, + }); + let u = self.tcx().mk_const_var(new_var_id, c.ty); + return Ok(u); + } + } } } _ => relate::super_relate_consts(self, c, c), From 624e34a5d02d47b807bad3a81aa7ce0c088d2452 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 23 Oct 2019 18:00:35 +0100 Subject: [PATCH 093/109] Account for const generalisation in nll_relate --- src/librustc/infer/combine.rs | 7 +++---- src/librustc/infer/nll_relate/mod.rs | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index a6c3c2de139b..51ae4e49493f 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -494,7 +494,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { if sub_vid == self.for_vid_sub_root { // If sub-roots are equal, then `for_vid` and // `vid` are related via subtyping. - return Err(TypeError::CyclicTy(self.root_ty)); + Err(TypeError::CyclicTy(self.root_ty)) } else { match variables.probe(vid) { TypeVariableValue::Known { value: u } => { @@ -527,7 +527,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { let u = self.tcx().mk_ty_var(new_var_id); debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); - return Ok(u); + Ok(u) } } } @@ -616,8 +616,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { origin: var_value.origin, val: ConstVariableValue::Unknown { universe: self.for_universe }, }); - let u = self.tcx().mk_const_var(new_var_id, c.ty); - return Ok(u); + Ok(self.tcx().mk_const_var(new_var_id, c.ty)) } } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index 8d59f455cbb8..d6f76e9ee346 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -28,6 +28,7 @@ use crate::ty::fold::{TypeFoldable, TypeVisitor}; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::subst::GenericArg; use crate::ty::{self, Ty, TyCtxt, InferConst}; +use crate::infer::{ConstVariableValue, ConstVarValue}; use crate::mir::interpret::ConstValue; use rustc_data_structures::fx::FxHashMap; use std::fmt::Debug; @@ -324,7 +325,7 @@ where let vid = pair.vid(); let value_ty = pair.value_ty(); - // FIXME -- this logic assumes invariance, but that is wrong. + // FIXME(invariance) -- this logic assumes invariance, but that is wrong. // This only presently applies to chalk integration, as NLL // doesn't permit type variables to appear on both sides (and // doesn't use lazy norm). @@ -629,6 +630,7 @@ where // Forbid inference variables in the RHS. bug!("unexpected inference var {:?}", b) } + // FIXME(invariance): see the related FIXME above. _ => self.infcx.super_combine_consts(self, a, b) } } @@ -997,11 +999,24 @@ where _: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { match a.val { + ConstValue::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { + bug!( + "unexpected inference variable encountered in NLL generalization: {:?}", + a + ); + } ConstValue::Infer(InferConst::Var(vid)) => { let mut variable_table = self.infcx.const_unification_table.borrow_mut(); - match variable_table.probe_value(vid).val.known() { + let var_value = variable_table.probe_value(vid); + match var_value.val.known() { Some(u) => self.relate(&u, &u), - None => Ok(a), + None => { + let new_var_id = variable_table.new_key(ConstVarValue { + origin: var_value.origin, + val: ConstVariableValue::Unknown { universe: self.universe }, + }); + Ok(self.tcx().mk_const_var(new_var_id, a.ty)) + } } } _ => relate::super_relate_consts(self, a, a), From eb6d757cb0bb2e4bd81158299a118230b099ac41 Mon Sep 17 00:00:00 2001 From: Umesh Kalappa Date: Sun, 20 Oct 2019 23:48:05 -0700 Subject: [PATCH 094/109] UI failures fix --- src/test/ui/intrinsics/intrinsic-alignment.rs | 3 ++- src/test/ui/signal-alternate-stack-cleanup.rs | 1 + src/test/ui/structs-enums/rec-align-u64.rs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs index 6a67d04a54cf..02e3139d2944 100644 --- a/src/test/ui/intrinsics/intrinsic-alignment.rs +++ b/src/test/ui/intrinsics/intrinsic-alignment.rs @@ -19,7 +19,8 @@ mod rusti { target_os = "macos", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris"))] + target_os = "solaris", + target_os = "vxworks"))] mod m { #[main] #[cfg(target_arch = "x86")] diff --git a/src/test/ui/signal-alternate-stack-cleanup.rs b/src/test/ui/signal-alternate-stack-cleanup.rs index 787ff51799a8..8fef66eac8de 100644 --- a/src/test/ui/signal-alternate-stack-cleanup.rs +++ b/src/test/ui/signal-alternate-stack-cleanup.rs @@ -7,6 +7,7 @@ // ignore-wasm32-bare no libc // ignore-windows // ignore-sgx no libc +// ignore-vxworks no SIGWINCH in user space #![feature(rustc_private)] extern crate libc; diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs index c4e9e9ea5ee1..680a690ba34e 100644 --- a/src/test/ui/structs-enums/rec-align-u64.rs +++ b/src/test/ui/structs-enums/rec-align-u64.rs @@ -40,7 +40,8 @@ struct Outer { target_os = "macos", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris"))] + target_os = "solaris", + target_os = "vxworks"))] mod m { #[cfg(target_arch = "x86")] pub mod m { From 8467ceff22477fe567883e6fbd810e0f9e220686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 23 Oct 2019 17:32:33 -0700 Subject: [PATCH 095/109] Tweak format string error to point at arguments always Add secondary span labels with no text to make it clear when there's a mismatch bewteen the positional arguments in a format string and the arguments to the macro. This shouldn't affect experienced users, but it should make it easier for newcomers to more clearly understand how `format!()` and `println!()` are supposed to be used. ``` error: 2 positional arguments in format string, but there is 1 argument --> file8.rs:2:14 | 2 | format!("{} {}", 1); | ^^ ^^ - ``` instead of ``` error: 2 positional arguments in format string, but there is 1 argument --> file8.rs:2:14 | 2 | format!("{} {}", 1); | ^^ ^^ ``` --- src/libsyntax_ext/format.rs | 5 ++++- src/test/ui/fmt/format-string-error.rs | 2 ++ src/test/ui/fmt/format-string-error.stderr | 8 +++++++- src/test/ui/if/ifmt-bad-arg.stderr | 10 ++++++---- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 45d9f79c28fc..37310f46f7ee 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -278,7 +278,7 @@ impl<'a, 'b> Context<'a, 'b> { /// format string. fn report_invalid_references(&self, numbered_position_args: bool) { let mut e; - let sp = if self.is_literal { + let sp = if self.is_literal { // Point at the formatting arguments. MultiSpan::from_spans(self.arg_spans.clone()) } else { MultiSpan::from_span(self.fmtsp) @@ -304,6 +304,9 @@ impl<'a, 'b> Context<'a, 'b> { self.describe_num_args(), ), ); + for arg in &self.args { // Point at the arguments that will be formatted. + e.span_label(arg.span, ""); + } } else { let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip(); // Avoid `invalid reference to positional arguments 7 and 7 (there is 1 argument)` diff --git a/src/test/ui/fmt/format-string-error.rs b/src/test/ui/fmt/format-string-error.rs index cca949aab636..691c06a2402c 100644 --- a/src/test/ui/fmt/format-string-error.rs +++ b/src/test/ui/fmt/format-string-error.rs @@ -48,4 +48,6 @@ fn main() { "###); //~^^^ ERROR invalid format string: unmatched `}` found + println!("{} {} {}", 1, 2); + //~^ ERROR 3 positional arguments in format string, but there are 2 arguments } diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr index 3dc122a7399d..32119b18774b 100644 --- a/src/test/ui/fmt/format-string-error.stderr +++ b/src/test/ui/fmt/format-string-error.stderr @@ -107,5 +107,11 @@ LL | } | = note: if you intended to print `}`, you can escape it using `}}` -error: aborting due to 12 previous errors +error: 3 positional arguments in format string, but there are 2 arguments + --> $DIR/format-string-error.rs:51:15 + | +LL | println!("{} {} {}", 1, 2); + | ^^ ^^ ^^ - - + +error: aborting due to 13 previous errors diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr index 336ea2254bf5..c58cbc312335 100644 --- a/src/test/ui/if/ifmt-bad-arg.stderr +++ b/src/test/ui/if/ifmt-bad-arg.stderr @@ -224,8 +224,9 @@ error: 4 positional arguments in format string, but there are 3 arguments --> $DIR/ifmt-bad-arg.rs:78:15 | LL | println!("{} {:.*} {}", 1, 3.2, 4); - | ^^ ^^--^ ^^ --- this parameter corresponds to the precision flag - | | + | ^^ ^^--^ ^^ - --- - + | | | + | | this parameter corresponds to the precision flag | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected | = note: positional arguments are zero-based @@ -235,8 +236,9 @@ error: 4 positional arguments in format string, but there are 3 arguments --> $DIR/ifmt-bad-arg.rs:81:15 | LL | println!("{} {:07$.*} {}", 1, 3.2, 4); - | ^^ ^^^----^ ^^ --- this parameter corresponds to the precision flag - | | | + | ^^ ^^^----^ ^^ - --- - + | | | | + | | | this parameter corresponds to the precision flag | | this precision flag adds an extra required argument at position 1, which is why there are 4 arguments expected | this width flag expects an `usize` argument at position 7, but there are 3 arguments | From 18d873e8f0d10ad61a6110af28e2d1008e6acd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Oct 2019 00:37:32 -0700 Subject: [PATCH 096/109] Avoid ICE when adjusting bad self ty --- src/librustc_typeck/check/method/confirm.rs | 20 +++++-- src/test/ui/issues/issue-65611.rs | 63 +++++++++++++++++++++ src/test/ui/issues/issue-65611.stderr | 18 ++++++ 3 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/issues/issue-65611.rs create mode 100644 src/test/ui/issues/issue-65611.stderr diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 9baf06be3f6b..59636d32bc03 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -141,14 +141,24 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // ADJUSTMENTS - fn adjust_self_ty(&mut self, - unadjusted_self_ty: Ty<'tcx>, - pick: &probe::Pick<'tcx>) - -> Ty<'tcx> { + fn adjust_self_ty( + &mut self, + unadjusted_self_ty: Ty<'tcx>, + pick: &probe::Pick<'tcx>, + ) -> Ty<'tcx> { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various tables. let mut autoderef = self.autoderef(self.span, unadjusted_self_ty); - let (_, n) = autoderef.nth(pick.autoderefs).unwrap(); + let (_, n) = match autoderef.nth(pick.autoderefs) { + Some(n) => n, + None => { + self.tcx.sess.delay_span_bug( + syntax_pos::DUMMY_SP, + &format!("failed autoderef {}", pick.autoderefs), + ); + return self.tcx.types.err; + } + }; assert_eq!(n, pick.autoderefs); let mut adjustments = autoderef.adjust_steps(self, Needs::None); diff --git a/src/test/ui/issues/issue-65611.rs b/src/test/ui/issues/issue-65611.rs new file mode 100644 index 000000000000..b74ee1b0c6e5 --- /dev/null +++ b/src/test/ui/issues/issue-65611.rs @@ -0,0 +1,63 @@ +use std::mem::MaybeUninit; +use std::ops::Deref; + +pub unsafe trait Array { + /// The array’s element type + type Item; + #[doc(hidden)] + /// The smallest index type that indexes the array. + type Index: Index; + #[doc(hidden)] + fn as_ptr(&self) -> *const Self::Item; + #[doc(hidden)] + fn as_mut_ptr(&mut self) -> *mut Self::Item; + #[doc(hidden)] + fn capacity() -> usize; +} + +pub trait Index : PartialEq + Copy { + fn to_usize(self) -> usize; + fn from(usize) -> Self; +} + +impl Index for usize { + fn to_usize(self) -> usize { self } + fn from(val: usize) -> Self { + val + } +} + +unsafe impl Array for [T; 1] { + type Item = T; + type Index = usize; + fn as_ptr(&self) -> *const T { self as *const _ as *const _ } + fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _} + fn capacity() -> usize { 1 } +} + +impl Deref for ArrayVec { + type Target = [A::Item]; + #[inline] + fn deref(&self) -> &[A::Item] { + panic!() + } +} + +pub struct ArrayVec { + xs: MaybeUninit, + len: usize, +} + +impl ArrayVec { + pub fn new() -> ArrayVec { + panic!() + } +} + +fn main() { + let mut buffer = ArrayVec::new(); + let x = buffer.last().unwrap().0.clone(); + //~^ ERROR type annotations needed + //~| ERROR no field `0` on type `&_` + buffer.reverse(); +} diff --git a/src/test/ui/issues/issue-65611.stderr b/src/test/ui/issues/issue-65611.stderr new file mode 100644 index 000000000000..cb441c13c6b9 --- /dev/null +++ b/src/test/ui/issues/issue-65611.stderr @@ -0,0 +1,18 @@ +error[E0282]: type annotations needed + --> $DIR/issue-65611.rs:59:20 + | +LL | let x = buffer.last().unwrap().0.clone(); + | ^^^^ cannot infer type for `T` + | + = note: type must be known at this point + +error[E0609]: no field `0` on type `&_` + --> $DIR/issue-65611.rs:59:36 + | +LL | let x = buffer.last().unwrap().0.clone(); + | ^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0609. +For more information about an error, try `rustc --explain E0282`. From 060b6cbe74f65b8d517c4d4936f4a361f3e4287d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 24 Oct 2019 08:07:03 -0700 Subject: [PATCH 097/109] Update hashbrown to 0.6.2 Pulls in rust-lang/hashbrown#119 which should be a good improvement for compile times of hashmap-heavy crates. --- Cargo.lock | 6 +++--- src/libstd/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efcbd7b6794f..fb81c0637cca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1297,9 +1297,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6587d09be37fb98a11cb08b9000a3f592451c1b1b613ca69d949160e313a430a" +checksum = "3cd9867f119b19fecb08cd5c326ad4488d7a1da4bf75b4d95d71db742525aaab" dependencies = [ "autocfg", "compiler_builtins", @@ -4146,7 +4146,7 @@ dependencies = [ "core", "dlmalloc", "fortanix-sgx-abi", - "hashbrown 0.6.1", + "hashbrown 0.6.2", "libc", "panic_abort", "panic_unwind", diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 5309af6f4c34..efe5c9d28f0d 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -23,7 +23,7 @@ libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of compiler_builtins = { version = "0.1.16" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } unwind = { path = "../libunwind" } -hashbrown = { version = "0.6.1", default-features = false, features = ['rustc-dep-of-std'] } +hashbrown = { version = "0.6.2", default-features = false, features = ['rustc-dep-of-std'] } [dependencies.backtrace_rs] package = "backtrace" From 2fea52511e7ff554a5061a45f8de514377a91567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Thu, 24 Oct 2019 16:47:56 +0200 Subject: [PATCH 098/109] workaround msys2 bug Co-Authored-By: Pietro Albini --- .../steps/install-windows-build-deps.yml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml index bd4f1ed0cea4..812339900fe4 100644 --- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml +++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml @@ -84,6 +84,17 @@ steps: condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],'')) displayName: Download custom MinGW +# FIXME(#65767): workaround msys bug, step 1 +- bash: | + set -e + arch=i686 + if [ "$MSYS_BITS" = "64" ]; then + arch=x86_64 + fi + curl -O https://ci-mirrors.rust-lang.org/rustc/msys2-repo/mingw/$arch/mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + displayName: Download working ca-certificates for msys + # Otherwise install MinGW through `pacman` - bash: | set -e @@ -96,6 +107,18 @@ steps: condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],'')) displayName: Download standard MinGW +# FIXME(#65767): workaround msys bug, step 2 +- bash: | + set -e + arch=i686 + if [ "$MSYS_BITS" = "64" ]; then + arch=x86_64 + fi + pacman -U --noconfirm --noprogressbar mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz + rm mingw-w64-$arch-ca-certificates-20180409-1-any.pkg.tar.xz + condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) + displayName: Install working ca-certificates for msys + # Make sure we use the native python interpreter instead of some msys equivalent # one way or another. The msys interpreters seem to have weird path conversions # baked in which break LLVM's build system one way or another, so let's use the From 184a61f0bfa4cf6c913d03be3da019ef3e7402cd Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 24 Oct 2019 14:25:23 +0800 Subject: [PATCH 099/109] Don't assert for different instance on impl trait alias --- src/librustc_typeck/check/mod.rs | 3 +-- ...issue-65679-inst-opaque-ty-from-val-twice.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 73a025182a7e..790407aae9ff 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2761,8 +2761,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut opaque_types = self.opaque_types.borrow_mut(); for (ty, decl) in opaque_type_map { - let old_value = opaque_types.insert(ty, decl); - assert!(old_value.is_none(), "instantiated twice: {:?}/{:?}", ty, decl); + let _ = opaque_types.insert(ty, decl); } value diff --git a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs new file mode 100644 index 000000000000..12eb75ae4c01 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type T = impl Sized; +// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed +// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; +// so difference assertion should not be declared on impl-trait-type-alias's instances. +// for details, check RFC-2515: +// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md + +fn take(_: fn() -> T) {} + +fn main() { + take(|| {}); + take(|| {}); +} From 2c16f8449090349c3907b15402d36ff190135c99 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 16 Oct 2019 19:03:21 +0300 Subject: [PATCH 100/109] rustc_driver: Remove unnecessary use of crate store --- src/librustc_driver/lib.rs | 8 ++++---- src/librustc_metadata/locator.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5d9dec14c6c8..15adf7e4add7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -36,11 +36,11 @@ use rustc::session::config::nightly_options; use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; +use rustc::middle::cstore::MetadataLoader; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::TyCtxt; use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported}; use rustc_metadata::locator; -use rustc_metadata::cstore::CStore; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_interface::interface; use rustc_interface::util::get_codegen_sysroot; @@ -277,7 +277,7 @@ pub fn run_compiler( compiler.output_file(), ).and_then(|| RustcDefaultCalls::list_metadata( sess, - compiler.cstore(), + &*compiler.codegen_backend().metadata_loader(), &matches, compiler.input() )); @@ -614,7 +614,7 @@ fn show_content_with_pager(content: &String) { impl RustcDefaultCalls { pub fn list_metadata(sess: &Session, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, matches: &getopts::Matches, input: &Input) -> Compilation { @@ -626,7 +626,7 @@ impl RustcDefaultCalls { let mut v = Vec::new(); locator::list_file_metadata(&sess.target.target, path, - cstore, + metadata_loader, &mut v) .unwrap(); println!("{}", String::from_utf8(v).unwrap()); diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 05676dad3340..b9f787920381 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -212,7 +212,7 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use crate::cstore::{MetadataBlob, CStore}; +use crate::cstore::MetadataBlob; use crate::creader::Library; use crate::schema::{METADATA_HEADER, rustc_version}; @@ -914,7 +914,7 @@ fn get_metadata_section_imp(target: &Target, /// A diagnostic function for dumping crate metadata to an output stream. pub fn list_file_metadata(target: &Target, path: &Path, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, out: &mut dyn io::Write) -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); @@ -925,7 +925,7 @@ pub fn list_file_metadata(target: &Target, } else { CrateFlavor::Dylib }; - match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) { + match get_metadata_section(target, flavor, path, metadata_loader) { Ok(metadata) => metadata.list_crate_metadata(out), Err(msg) => write!(out, "{}\n", msg), } From 2cda75c48f48022690f142b63969660b12536cee Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 16 Oct 2019 19:57:10 +0300 Subject: [PATCH 101/109] rustc_metadata: Remove unnecessary use of crate store in plugin loader --- src/librustc_interface/passes.rs | 7 +-- src/librustc_interface/queries.rs | 2 +- src/librustc_metadata/creader.rs | 94 ++++++++++--------------------- src/librustc_plugin/load.rs | 21 ++----- 4 files changed, 41 insertions(+), 83 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2044b73db8aa..77570bc04630 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -9,7 +9,7 @@ use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; -use rustc::middle::cstore::CrateStore; +use rustc::middle::cstore::{CrateStore, MetadataLoader}; use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; @@ -226,7 +226,7 @@ pub struct PluginInfo { pub fn register_plugins<'a>( sess: &'a Session, - cstore: &'a CStore, + metadata_loader: &'a dyn MetadataLoader, register_lints: impl Fn(&Session, &mut lint::LintStore), mut krate: ast::Crate, crate_name: &str, @@ -274,9 +274,8 @@ pub fn register_plugins<'a>( let registrars = time(sess, "plugin loading", || { plugin::load::load_plugins( sess, - &cstore, + metadata_loader, &krate, - crate_name, Some(sess.opts.debugging_opts.extra_plugins.clone()), ) }); diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 84648ca8326f..847d21b05125 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -118,7 +118,7 @@ impl Compiler { let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), - self.cstore(), + &*self.codegen_backend().metadata_loader(), self.register_lints .as_ref() .map(|p| &**p) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7412e8a2cb9b..fbd1877dc88a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,13 +14,12 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource}; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoader}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; use rustc::hir::def_id::LOCAL_CRATE; -use std::ops::Deref; use std::path::{Path, PathBuf}; use std::{cmp, fs}; @@ -58,29 +57,6 @@ fn dump_crates(cstore: &CStore) { }); } -// Extra info about a crate loaded for plugins or exported macros. -struct ExtensionCrate { - metadata: PMDSource, - dylib: Option, - target_only: bool, -} - -enum PMDSource { - Registered(Lrc), - Owned(Library), -} - -impl Deref for PMDSource { - type Target = MetadataBlob; - - fn deref(&self) -> &MetadataBlob { - match *self { - PMDSource::Registered(ref cmd) => &cmd.blob, - PMDSource::Owned(ref lib) => &lib.metadata - } - } -} - enum LoadResult { Previous(CrateNum), Loaded(Library), @@ -495,21 +471,27 @@ impl<'a> CrateLoader<'a> { self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0 })).collect() } +} - fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate { + fn read_extension_crate( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + name: Symbol, + span: Span, + ) -> (Library, bool) { info!("read extension crate `{}`", name); - let target_triple = self.sess.opts.target_triple.clone(); + let target_triple = sess.opts.target_triple.clone(); let host_triple = TargetTriple::from_triple(config::host_triple()); let is_cross = target_triple != host_triple; let mut target_only = false; let mut locate_ctxt = locator::Context { - sess: self.sess, + sess, span, crate_name: name, hash: None, extra_filename: None, - filesearch: self.sess.host_filesearch(PathKind::Crate), - target: &self.sess.host, + filesearch: sess.host_filesearch(PathKind::Crate), + target: &sess.host, triple: host_triple, root: None, rejected_via_hash: vec![], @@ -519,9 +501,10 @@ impl<'a> CrateLoader<'a> { rejected_via_filename: vec![], should_match_name: true, is_proc_macro: None, - metadata_loader: &*self.cstore.metadata_loader, + metadata_loader, }; - let library = self.load(&mut locate_ctxt).or_else(|| { + + let library = locate_ctxt.maybe_load_library_crate().or_else(|| { if !is_cross { return None } @@ -529,36 +512,21 @@ impl<'a> CrateLoader<'a> { // try to load a plugin registrar function, target_only = true; - locate_ctxt.target = &self.sess.target.target; + locate_ctxt.target = &sess.target.target; locate_ctxt.triple = target_triple; - locate_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate); + locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); - self.load(&mut locate_ctxt) + locate_ctxt.maybe_load_library_crate() }); let library = match library { Some(l) => l, None => locate_ctxt.report_errs(), }; - let (dylib, metadata) = match library { - LoadResult::Previous(cnum) => { - let data = self.cstore.get_crate_data(cnum); - (data.source.dylib.clone(), PMDSource::Registered(data)) - } - LoadResult::Loaded(library) => { - let dylib = library.source.dylib.clone(); - let metadata = PMDSource::Owned(library); - (dylib, metadata) - } - }; - - ExtensionCrate { - metadata, - dylib: dylib.map(|p| p.0), - target_only, - } + (library, target_only) } +impl<'a> CrateLoader<'a> { fn dlsym_proc_macros(&self, path: &Path, disambiguator: CrateDisambiguator, @@ -589,32 +557,33 @@ impl<'a> CrateLoader<'a> { decls } +} /// Look for a plugin registrar. Returns library path, crate /// SVH and DefIndex of the registrar function. - pub fn find_plugin_registrar(&self, + pub fn find_plugin_registrar(sess: &Session, + metadata_loader: &dyn MetadataLoader, span: Span, name: Symbol) -> Option<(PathBuf, CrateDisambiguator)> { - let ekrate = self.read_extension_crate(name, span); + let (library, target_only) = read_extension_crate(sess, metadata_loader, name, span); - if ekrate.target_only { + if target_only { // Need to abort before syntax expansion. let message = format!("plugin `{}` is not available for triple `{}` \ (only found {})", name, config::host_triple(), - self.sess.opts.target_triple); - span_fatal!(self.sess, span, E0456, "{}", &message); + sess.opts.target_triple); + span_fatal!(sess, span, E0456, "{}", &message); } - let root = ekrate.metadata.get_root(); - match ekrate.dylib.as_ref() { + match library.source.dylib { Some(dylib) => { - Some((dylib.to_path_buf(), root.disambiguator)) + Some((dylib.0, library.metadata.get_root().disambiguator)) } None => { - span_err!(self.sess, span, E0457, + span_err!(sess, span, E0457, "plugin `{}` only found in rlib format, but must be available \ in dylib format", name); @@ -625,6 +594,7 @@ impl<'a> CrateLoader<'a> { } } +impl<'a> CrateLoader<'a> { fn inject_panic_runtime(&self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. @@ -957,9 +927,7 @@ impl<'a> CrateLoader<'a> { data.dependencies.borrow_mut().push(krate); }); } -} -impl<'a> CrateLoader<'a> { pub fn postprocess(&self, krate: &ast::Crate) { self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 4481892bcf24..dd0dbf62c736 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -1,8 +1,8 @@ //! Used by `rustc` when loading a plugin. +use rustc::middle::cstore::MetadataLoader; use rustc::session::Session; -use rustc_metadata::creader::CrateLoader; -use rustc_metadata::cstore::CStore; +use rustc_metadata::creader; use crate::registry::Registry; use std::borrow::ToOwned; @@ -25,7 +25,7 @@ pub struct PluginRegistrar { struct PluginLoader<'a> { sess: &'a Session, - reader: CrateLoader<'a>, + metadata_loader: &'a dyn MetadataLoader, plugins: Vec, } @@ -37,11 +37,10 @@ fn call_malformed_plugin_attribute(sess: &Session, span: Span) { /// Read plugin metadata and dynamically load registrar functions. pub fn load_plugins(sess: &Session, - cstore: &CStore, + metadata_loader: &dyn MetadataLoader, krate: &ast::Crate, - crate_name: &str, addl_plugins: Option>) -> Vec { - let mut loader = PluginLoader::new(sess, cstore, crate_name); + let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() }; // do not report any error now. since crate attributes are // not touched by expansion, every use of plugin without @@ -80,16 +79,8 @@ pub fn load_plugins(sess: &Session, } impl<'a> PluginLoader<'a> { - fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self { - PluginLoader { - sess, - reader: CrateLoader::new(sess, cstore, crate_name), - plugins: vec![], - } - } - fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec) { - let registrar = self.reader.find_plugin_registrar(span, name); + let registrar = creader::find_plugin_registrar(self.sess, self.metadata_loader, span, name); if let Some((lib, disambiguator)) = registrar { let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator); From 175d325ccbaccf40907a8bb8184ee65a5f62ca8a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 17 Oct 2019 19:08:06 +0300 Subject: [PATCH 102/109] rustc_metadata: Move some code around Plugin search doesn't need a crate loader, only crate locator --- src/librustc_metadata/creader.rs | 98 +------------------------------- src/librustc_metadata/locator.rs | 80 +++++++++++++++++++++++++- src/librustc_plugin/load.rs | 4 +- 3 files changed, 84 insertions(+), 98 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index fbd1877dc88a..2eaf7536a70a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,20 +14,20 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoader}; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; use rustc::hir::def_id::LOCAL_CRATE; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::{cmp, fs}; use syntax::ast; use syntax::attr; use syntax_expand::allocator::{global_allocator_spans, AllocatorKind}; use syntax::symbol::{Symbol, sym}; -use syntax::{span_err, span_fatal}; +use syntax::span_fatal; use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; use proc_macro::bridge::client::ProcMacro; @@ -471,62 +471,7 @@ impl<'a> CrateLoader<'a> { self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0 })).collect() } -} - fn read_extension_crate( - sess: &Session, - metadata_loader: &dyn MetadataLoader, - name: Symbol, - span: Span, - ) -> (Library, bool) { - info!("read extension crate `{}`", name); - let target_triple = sess.opts.target_triple.clone(); - let host_triple = TargetTriple::from_triple(config::host_triple()); - let is_cross = target_triple != host_triple; - let mut target_only = false; - let mut locate_ctxt = locator::Context { - sess, - span, - crate_name: name, - hash: None, - extra_filename: None, - filesearch: sess.host_filesearch(PathKind::Crate), - target: &sess.host, - triple: host_triple, - root: None, - rejected_via_hash: vec![], - rejected_via_triple: vec![], - rejected_via_kind: vec![], - rejected_via_version: vec![], - rejected_via_filename: vec![], - should_match_name: true, - is_proc_macro: None, - metadata_loader, - }; - - let library = locate_ctxt.maybe_load_library_crate().or_else(|| { - if !is_cross { - return None - } - // Try loading from target crates. This will abort later if we - // try to load a plugin registrar function, - target_only = true; - - locate_ctxt.target = &sess.target.target; - locate_ctxt.triple = target_triple; - locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); - - locate_ctxt.maybe_load_library_crate() - }); - let library = match library { - Some(l) => l, - None => locate_ctxt.report_errs(), - }; - - (library, target_only) - } - -impl<'a> CrateLoader<'a> { fn dlsym_proc_macros(&self, path: &Path, disambiguator: CrateDisambiguator, @@ -557,44 +502,7 @@ impl<'a> CrateLoader<'a> { decls } -} - /// Look for a plugin registrar. Returns library path, crate - /// SVH and DefIndex of the registrar function. - pub fn find_plugin_registrar(sess: &Session, - metadata_loader: &dyn MetadataLoader, - span: Span, - name: Symbol) - -> Option<(PathBuf, CrateDisambiguator)> { - let (library, target_only) = read_extension_crate(sess, metadata_loader, name, span); - - if target_only { - // Need to abort before syntax expansion. - let message = format!("plugin `{}` is not available for triple `{}` \ - (only found {})", - name, - config::host_triple(), - sess.opts.target_triple); - span_fatal!(sess, span, E0456, "{}", &message); - } - - match library.source.dylib { - Some(dylib) => { - Some((dylib.0, library.metadata.get_root().disambiguator)) - } - None => { - span_err!(sess, span, E0457, - "plugin `{}` only found in rlib format, but must be available \ - in dylib format", - name); - // No need to abort because the loading code will just ignore this - // empty dylib. - None - } - } - } - -impl<'a> CrateLoader<'a> { fn inject_panic_runtime(&self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index b9f787920381..a5298402dd41 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -220,12 +220,13 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; use rustc::middle::cstore::{CrateSource, MetadataLoader}; -use rustc::session::{config, Session}; +use rustc::session::{config, Session, CrateDisambiguator}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; +use syntax::{span_err, span_fatal}; use syntax::symbol::{Symbol, sym}; use syntax::struct_span_err; use syntax_pos::Span; @@ -911,6 +912,83 @@ fn get_metadata_section_imp(target: &Target, } } +/// Look for a plugin registrar. Returns its library path and crate disambiguator. +pub fn find_plugin_registrar( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + span: Span, + name: Symbol, +) -> Option<(PathBuf, CrateDisambiguator)> { + info!("find plugin registrar `{}`", name); + let target_triple = sess.opts.target_triple.clone(); + let host_triple = TargetTriple::from_triple(config::host_triple()); + let is_cross = target_triple != host_triple; + let mut target_only = false; + let mut locate_ctxt = Context { + sess, + span, + crate_name: name, + hash: None, + extra_filename: None, + filesearch: sess.host_filesearch(PathKind::Crate), + target: &sess.host, + triple: host_triple, + root: None, + rejected_via_hash: vec![], + rejected_via_triple: vec![], + rejected_via_kind: vec![], + rejected_via_version: vec![], + rejected_via_filename: vec![], + should_match_name: true, + is_proc_macro: None, + metadata_loader, + }; + + let library = locate_ctxt.maybe_load_library_crate().or_else(|| { + if !is_cross { + return None + } + // Try loading from target crates. This will abort later if we + // try to load a plugin registrar function, + target_only = true; + + locate_ctxt.target = &sess.target.target; + locate_ctxt.triple = target_triple; + locate_ctxt.filesearch = sess.target_filesearch(PathKind::Crate); + + locate_ctxt.maybe_load_library_crate() + }); + let library = match library { + Some(l) => l, + None => locate_ctxt.report_errs(), + }; + + if target_only { + // Need to abort before syntax expansion. + let message = format!("plugin `{}` is not available for triple `{}` \ + (only found {})", + name, + config::host_triple(), + sess.opts.target_triple); + span_fatal!(sess, span, E0456, "{}", &message); + } + + match library.source.dylib { + Some(dylib) => { + Some((dylib.0, library.metadata.get_root().disambiguator)) + } + None => { + span_err!(sess, span, E0457, + "plugin `{}` only found in rlib format, but must be available \ + in dylib format", + name); + // No need to abort because the loading code will just ignore this + // empty dylib. + None + } + } +} + /// A diagnostic function for dumping crate metadata to an output stream. pub fn list_file_metadata(target: &Target, path: &Path, diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index dd0dbf62c736..8ceb56b0fd2b 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -2,7 +2,7 @@ use rustc::middle::cstore::MetadataLoader; use rustc::session::Session; -use rustc_metadata::creader; +use rustc_metadata::locator; use crate::registry::Registry; use std::borrow::ToOwned; @@ -80,7 +80,7 @@ pub fn load_plugins(sess: &Session, impl<'a> PluginLoader<'a> { fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec) { - let registrar = creader::find_plugin_registrar(self.sess, self.metadata_loader, span, name); + let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name); if let Some((lib, disambiguator)) = registrar { let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator); From 222503a354d263ee13ee160506443036b799a2ea Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 17 Oct 2019 21:26:13 +0300 Subject: [PATCH 103/109] rustc: Add a convenience alias for `dyn MetadataLoader + Sync` --- src/librustc/middle/cstore.rs | 2 ++ src/librustc_codegen_llvm/lib.rs | 4 ++-- src/librustc_codegen_utils/codegen_backend.rs | 4 ++-- src/librustc_metadata/cstore.rs | 6 +++--- .../hotplug_codegen_backend/the_backend.rs | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index ec1e32988a60..8205383da989 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -191,6 +191,8 @@ pub trait MetadataLoader { -> Result; } +pub type MetadataLoaderDyn = dyn MetadataLoader + Sync; + /// A store of Rust crates, through which their metadata can be accessed. /// /// Note that this trait should probably not be expanding today. All new diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8c1797cfb7de..e09b600afd4e 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -56,7 +56,7 @@ use std::sync::Arc; use std::ffi::CStr; use rustc::dep_graph::DepGraph; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::session::Session; use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; @@ -260,7 +260,7 @@ impl CodegenBackend for LlvmCodegenBackend { target_features(sess) } - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { box metadata::LlvmMetadataLoader } diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 1077c1f42637..0e2c3731eae6 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -14,7 +14,7 @@ use rustc::util::common::ErrorReported; use rustc::session::config::{OutputFilenames, PrintRequest}; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::dep_graph::DepGraph; pub use rustc_data_structures::sync::MetadataRef; @@ -26,7 +26,7 @@ pub trait CodegenBackend { fn print_passes(&self) {} fn print_version(&self) {} - fn metadata_loader(&self) -> Box; + fn metadata_loader(&self) -> Box; fn provide(&self, _providers: &mut Providers<'_>); fn provide_extern(&self, _providers: &mut Providers<'_>); fn codegen_crate<'tcx>( diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 9a0b98ffb73a..a2920884409c 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -5,7 +5,7 @@ use crate::schema; use rustc::dep_graph::DepNodeIndex; use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; -use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader}; +use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoaderDyn}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::FxHashMap; @@ -96,7 +96,7 @@ pub struct CrateMetadata { pub struct CStore { metas: RwLock>>>, - crate metadata_loader: Box, + crate metadata_loader: Box, } pub enum LoadedMacro { @@ -105,7 +105,7 @@ pub enum LoadedMacro { } impl CStore { - pub fn new(metadata_loader: Box) -> CStore { + pub fn new(metadata_loader: Box) -> CStore { CStore { // We add an empty entry for LOCAL_CRATE (which maps to zero) in // order to make array indices in `metas` match with the diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 1566a153ec03..eb96c61060b3 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -9,14 +9,14 @@ extern crate rustc_target; extern crate rustc_driver; use std::any::Any; -use std::sync::{Arc, mpsc}; +use std::sync::Arc; use std::path::Path; use syntax::symbol::Symbol; use rustc::session::Session; use rustc::session::config::OutputFilenames; use rustc::ty::TyCtxt; use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoader}; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn}; use rustc::dep_graph::DepGraph; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; @@ -41,7 +41,7 @@ impl MetadataLoader for NoLlvmMetadataLoader { struct TheBackend; impl CodegenBackend for TheBackend { - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { Box::new(NoLlvmMetadataLoader) } From fb353f050acd1d18bafcf570d7be1459cf454858 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 20 Oct 2019 02:55:39 +0300 Subject: [PATCH 104/109] resolve: Privatize all resolver fields --- src/librustc_interface/passes.rs | 43 ++----------- src/librustc_resolve/lib.rs | 64 ++++++++++++++++--- .../passes/collect_intra_doc_links.rs | 4 +- 3 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 77570bc04630..3d6ea5354a9f 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -6,6 +6,7 @@ use log::{info, warn, log_enabled}; use rustc::dep_graph::DepGraph; use rustc::hir; use rustc::hir::lowering::lower_crate; +use rustc::hir::map::Definitions; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; @@ -154,7 +155,7 @@ pub fn configure_and_expand( } }; box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver)); - ExpansionResult::from_owned_resolver(resolver) + ExpansionResult::from_resolver_outputs(resolver.into_outputs()) }); result.map(|k| (k, resolver)) } @@ -165,42 +166,8 @@ pub struct ExpansionResult { } impl ExpansionResult { - fn from_owned_resolver( - resolver: Resolver<'_>, - ) -> Self { - ExpansionResult { - defs: Steal::new(resolver.definitions), - resolutions: Steal::new(Resolutions { - extern_crate_map: resolver.extern_crate_map, - export_map: resolver.export_map, - trait_map: resolver.trait_map, - glob_map: resolver.glob_map, - maybe_unused_trait_imports: resolver.maybe_unused_trait_imports, - maybe_unused_extern_crates: resolver.maybe_unused_extern_crates, - extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }), - } - } - - pub fn from_resolver_ref( - resolver: &Resolver<'_>, - ) -> Self { - ExpansionResult { - defs: Steal::new(resolver.definitions.clone()), - resolutions: Steal::new(Resolutions { - extern_crate_map: resolver.extern_crate_map.clone(), - export_map: resolver.export_map.clone(), - trait_map: resolver.trait_map.clone(), - glob_map: resolver.glob_map.clone(), - maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(), - maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(), - extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }), - } + fn from_resolver_outputs((defs, resolutions): (Definitions, Resolutions)) -> Self { + ExpansionResult { defs: Steal::new(defs), resolutions: Steal::new(resolutions) } } } @@ -213,7 +180,7 @@ impl BoxedResolver { Err(resolver) => { let resolver = &*resolver; resolver.borrow_mut().access(|resolver| { - ExpansionResult::from_resolver_ref(resolver) + ExpansionResult::from_resolver_outputs(resolver.clone_outputs()) }) } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 17d8f0f211a9..57f1b5186cba 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -831,12 +831,12 @@ pub struct Resolver<'a> { session: &'a Session, cstore: &'a CStore, - pub definitions: Definitions, + definitions: Definitions, - pub graph_root: Module<'a>, + graph_root: Module<'a>, prelude: Option>, - pub extern_prelude: FxHashMap>, + extern_prelude: FxHashMap>, /// N.B., this is used only for better diagnostics, not name resolution itself. has_self: FxHashSet, @@ -869,9 +869,9 @@ pub struct Resolver<'a> { label_res_map: NodeMap, /// `CrateNum` resolutions of `extern crate` items. - pub extern_crate_map: NodeMap, - pub export_map: ExportMap, - pub trait_map: TraitMap, + extern_crate_map: NodeMap, + export_map: ExportMap, + trait_map: TraitMap, /// A map from nodes to anonymous modules. /// Anonymous modules are pseudo-modules that are implicitly created around items @@ -898,11 +898,11 @@ pub struct Resolver<'a> { underscore_disambiguator: u32, /// Maps glob imports to the names of items actually imported. - pub glob_map: GlobMap, + glob_map: GlobMap, used_imports: FxHashSet<(NodeId, Namespace)>, - pub maybe_unused_trait_imports: NodeSet, - pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, + maybe_unused_trait_imports: NodeSet, + maybe_unused_extern_crates: Vec<(NodeId, Span)>, /// Privacy errors are delayed until the end in order to deduplicate them. privacy_errors: Vec>, @@ -920,7 +920,7 @@ pub struct Resolver<'a> { macro_names: FxHashSet, builtin_macros: FxHashMap, macro_use_prelude: FxHashMap>, - pub all_macros: FxHashMap, + all_macros: FxHashMap, macro_map: FxHashMap>, dummy_ext_bang: Lrc, dummy_ext_derive: Lrc, @@ -1236,6 +1236,40 @@ impl<'a> Resolver<'a> { Default::default() } + pub fn into_outputs(self) -> (Definitions, ty::Resolutions) { + ( + self.definitions, + ty::Resolutions { + extern_crate_map: self.extern_crate_map, + export_map: self.export_map, + trait_map: self.trait_map, + glob_map: self.glob_map, + maybe_unused_trait_imports: self.maybe_unused_trait_imports, + maybe_unused_extern_crates: self.maybe_unused_extern_crates, + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + }, + ) + } + + pub fn clone_outputs(&self) -> (Definitions, ty::Resolutions) { + ( + self.definitions.clone(), + ty::Resolutions { + extern_crate_map: self.extern_crate_map.clone(), + export_map: self.export_map.clone(), + trait_map: self.trait_map.clone(), + glob_map: self.glob_map.clone(), + maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(), + maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(), + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + }, + ) + } + fn non_macro_attr(&self, mark_used: bool) -> Lrc { self.non_macro_attrs[mark_used as usize].clone() } @@ -2808,6 +2842,16 @@ impl<'a> Resolver<'a> { seg.id = self.session.next_node_id(); seg } + + // For rustdoc. + pub fn graph_root(&self) -> Module<'a> { + self.graph_root + } + + // For rustdoc. + pub fn all_macros(&self) -> &FxHashMap { + &self.all_macros + } } fn names_to_string(names: &[Name]) -> String { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4270b162bafa..caa7f08f68cf 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -432,13 +432,13 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { let path = ast::Path::from_ident(Ident::from_str(path_str)); cx.enter_resolver(|resolver| { if let Ok((Some(ext), res)) = resolver.resolve_macro_path( - &path, None, &ParentScope::module(resolver.graph_root), false, false + &path, None, &ParentScope::module(resolver.graph_root()), false, false ) { if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind { return Some(res.map_id(|_| panic!("unexpected id"))); } } - if let Some(res) = resolver.all_macros.get(&Symbol::intern(path_str)) { + if let Some(res) = resolver.all_macros().get(&Symbol::intern(path_str)) { return Some(res.map_id(|_| panic!("unexpected id"))); } None From 5fd796ad067f0c23c05524276279d057c9699c97 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 20 Oct 2019 03:19:12 +0300 Subject: [PATCH 105/109] rustc: Combine resolver outputs into a single struct --- src/librustc/ty/context.rs | 2 +- src/librustc/ty/mod.rs | 4 +-- src/librustc_interface/passes.rs | 20 +++++------ src/librustc_interface/queries.rs | 3 +- src/librustc_resolve/lib.rs | 58 ++++++++++++++----------------- 5 files changed, 39 insertions(+), 48 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d5a93e029055..599601b35296 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1199,7 +1199,7 @@ impl<'tcx> TyCtxt<'tcx> { local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, - resolutions: ty::Resolutions, + resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, on_disk_query_result_cache: query::OnDiskCache<'tcx>, crate_name: &str, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index feede00fea1c..e1e88ffd8ea6 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -119,8 +119,8 @@ mod sty; // Data types -#[derive(Clone)] -pub struct Resolutions { +pub struct ResolverOutputs { + pub definitions: hir_map::Definitions, pub extern_crate_map: NodeMap, pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 3d6ea5354a9f..18df4ee51b79 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -6,12 +6,11 @@ use log::{info, warn, log_enabled}; use rustc::dep_graph::DepGraph; use rustc::hir; use rustc::hir::lowering::lower_crate; -use rustc::hir::map::Definitions; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; use rustc::middle::cstore::{CrateStore, MetadataLoader}; -use rustc::ty::{self, AllArenas, Resolutions, TyCtxt, GlobalCtxt}; +use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; use rustc::util::common::{time, ErrorReported}; @@ -47,12 +46,10 @@ use syntax_ext; use rustc_serialize::json; use tempfile::Builder as TempFileBuilder; +use std::{env, fs, iter, mem}; use std::any::Any; -use std::env; use std::ffi::OsString; -use std::fs; use std::io::{self, Write}; -use std::iter; use std::path::PathBuf; use std::cell::RefCell; use std::rc::Rc; @@ -161,13 +158,12 @@ pub fn configure_and_expand( } pub struct ExpansionResult { - pub defs: Steal, - pub resolutions: Steal, + pub resolver_outputs: Steal, } impl ExpansionResult { - fn from_resolver_outputs((defs, resolutions): (Definitions, Resolutions)) -> Self { - ExpansionResult { defs: Steal::new(defs), resolutions: Steal::new(resolutions) } + fn from_resolver_outputs(resolver_outputs: ResolverOutputs) -> Self { + ExpansionResult { resolver_outputs: Steal::new(resolver_outputs) } } } @@ -789,8 +785,7 @@ pub fn create_global_ctxt( compiler: &Compiler, lint_store: Lrc, mut hir_forest: hir::map::Forest, - defs: hir::map::Definitions, - resolutions: Resolutions, + mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, ) -> BoxedGlobalCtxt { @@ -798,6 +793,7 @@ pub fn create_global_ctxt( let cstore = compiler.cstore.clone(); let codegen_backend = compiler.codegen_backend().clone(); let crate_name = crate_name.to_string(); + let defs = mem::take(&mut resolver_outputs.definitions); let ((), result) = BoxedGlobalCtxt::new(static move || { let sess = &*sess; @@ -830,7 +826,7 @@ pub fn create_global_ctxt( local_providers, extern_providers, &arenas, - resolutions, + resolver_outputs, hir_map, query_result_on_disk_cache, &crate_name, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 847d21b05125..2ff5c69b145d 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -234,8 +234,7 @@ impl Compiler { self, lint_store, hir_forest.steal(), - expansion.defs.steal(), - expansion.resolutions.steal(), + expansion.resolver_outputs.steal(), outputs, &crate_name)) }) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 57f1b5186cba..5cdf4d2fb692 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -28,7 +28,7 @@ use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrK use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; use rustc::hir::{TraitMap, GlobMap}; -use rustc::ty::{self, DefIdTree}; +use rustc::ty::{self, DefIdTree, ResolverOutputs}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc::span_bug; @@ -1236,38 +1236,34 @@ impl<'a> Resolver<'a> { Default::default() } - pub fn into_outputs(self) -> (Definitions, ty::Resolutions) { - ( - self.definitions, - ty::Resolutions { - extern_crate_map: self.extern_crate_map, - export_map: self.export_map, - trait_map: self.trait_map, - glob_map: self.glob_map, - maybe_unused_trait_imports: self.maybe_unused_trait_imports, - maybe_unused_extern_crates: self.maybe_unused_extern_crates, - extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }, - ) + pub fn into_outputs(self) -> ResolverOutputs { + ResolverOutputs { + definitions: self.definitions, + extern_crate_map: self.extern_crate_map, + export_map: self.export_map, + trait_map: self.trait_map, + glob_map: self.glob_map, + maybe_unused_trait_imports: self.maybe_unused_trait_imports, + maybe_unused_extern_crates: self.maybe_unused_extern_crates, + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + } } - pub fn clone_outputs(&self) -> (Definitions, ty::Resolutions) { - ( - self.definitions.clone(), - ty::Resolutions { - extern_crate_map: self.extern_crate_map.clone(), - export_map: self.export_map.clone(), - trait_map: self.trait_map.clone(), - glob_map: self.glob_map.clone(), - maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(), - maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(), - extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { - (ident.name, entry.introduced_by_item) - }).collect(), - }, - ) + pub fn clone_outputs(&self) -> ResolverOutputs { + ResolverOutputs { + definitions: self.definitions.clone(), + extern_crate_map: self.extern_crate_map.clone(), + export_map: self.export_map.clone(), + trait_map: self.trait_map.clone(), + glob_map: self.glob_map.clone(), + maybe_unused_trait_imports: self.maybe_unused_trait_imports.clone(), + maybe_unused_extern_crates: self.maybe_unused_extern_crates.clone(), + extern_prelude: self.extern_prelude.iter().map(|(ident, entry)| { + (ident.name, entry.introduced_by_item) + }).collect(), + } } fn non_macro_attr(&self, mark_used: bool) -> Lrc { From 3534ca8f4985afad9b8dfe93ab570b721b80210e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 20 Oct 2019 03:28:36 +0300 Subject: [PATCH 106/109] Turn crate store into a resolver output --- src/librustc/hir/lowering.rs | 12 ++--- src/librustc/ty/context.rs | 6 +-- src/librustc/ty/mod.rs | 2 + src/librustc_interface/interface.rs | 8 --- src/librustc_interface/passes.rs | 60 ++++++++++----------- src/librustc_interface/queries.rs | 9 ++-- src/librustc_metadata/creader.rs | 26 +++++++-- src/librustc_metadata/cstore.rs | 16 +++--- src/librustc_metadata/cstore_impl.rs | 7 +-- src/librustc_resolve/build_reduced_graph.rs | 19 ++++--- src/librustc_resolve/lib.rs | 24 +++++---- src/librustc_resolve/resolve_imports.rs | 2 +- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/core.rs | 7 +-- 14 files changed, 102 insertions(+), 100 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7971c33426b2..002e6874466b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -83,8 +83,6 @@ pub struct LoweringContext<'a> { /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes. sess: &'a Session, - cstore: &'a dyn CrateStore, - resolver: &'a mut dyn Resolver, /// HACK(Centril): there is a cyclic dependency between the parser and lowering @@ -160,6 +158,8 @@ pub struct LoweringContext<'a> { } pub trait Resolver { + fn cstore(&self) -> &dyn CrateStore; + /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&mut self, id: NodeId) -> Option; @@ -240,7 +240,6 @@ impl<'a> ImplTraitContext<'a> { pub fn lower_crate( sess: &Session, - cstore: &dyn CrateStore, dep_graph: &DepGraph, krate: &Crate, resolver: &mut dyn Resolver, @@ -256,7 +255,6 @@ pub fn lower_crate( LoweringContext { crate_root: sess.parse_sess.injected_crate_name.try_get().copied(), sess, - cstore, resolver, nt_to_tokenstream, items: BTreeMap::new(), @@ -980,7 +978,7 @@ impl<'a> LoweringContext<'a> { if id.is_local() { self.resolver.definitions().def_key(id.index) } else { - self.cstore.def_key(id) + self.resolver.cstore().def_key(id) } } @@ -1727,8 +1725,8 @@ impl<'a> LoweringContext<'a> { return n; } assert!(!def_id.is_local()); - let item_generics = - self.cstore.item_generics_cloned_untracked(def_id, self.sess); + let item_generics = self.resolver.cstore() + .item_generics_cloned_untracked(def_id, self.sess); let n = item_generics.own_counts().lifetimes; self.type_def_lifetime_params.insert(def_id, n); n diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 599601b35296..9b2e6df6bea1 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1027,7 +1027,7 @@ pub struct GlobalCtxt<'tcx> { interners: CtxtInterners<'tcx>, - cstore: &'tcx CrateStoreDyn, + cstore: Box, pub sess: &'tcx Session, @@ -1195,7 +1195,6 @@ impl<'tcx> TyCtxt<'tcx> { pub fn create_global_ctxt( s: &'tcx Session, lint_store: Lrc, - cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, arenas: &'tcx AllArenas, @@ -1213,6 +1212,7 @@ impl<'tcx> TyCtxt<'tcx> { let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); let dep_graph = hir.dep_graph.clone(); + let cstore = resolutions.cstore; let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0); let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); providers[LOCAL_CRATE] = local_providers; @@ -1428,7 +1428,7 @@ impl<'tcx> TyCtxt<'tcx> { StableHashingContext::new(self.sess, krate, self.hir().definitions(), - self.cstore) + &*self.cstore) } // This method makes sure that we have a DepNode and a Fingerprint for diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e1e88ffd8ea6..90450494a141 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -15,6 +15,7 @@ use rustc_macros::HashStable; use crate::ich::Fingerprint; use crate::ich::StableHashingContext; use crate::infer::canonical::Canonical; +use crate::middle::cstore::CrateStoreDyn; use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::mir::Body; @@ -121,6 +122,7 @@ mod sty; pub struct ResolverOutputs { pub definitions: hir_map::Definitions, + pub cstore: Box, pub extern_crate_map: NodeMap, pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 24ea0fc8bf63..e014e4ed0fdc 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -11,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::OnDrop; use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; -use rustc_metadata::cstore::CStore; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; @@ -37,7 +36,6 @@ pub struct Compiler { pub(crate) output_dir: Option, pub(crate) output_file: Option, pub(crate) queries: Queries, - pub(crate) cstore: Lrc, pub(crate) crate_name: Option, pub(crate) register_lints: Option>, } @@ -49,9 +47,6 @@ impl Compiler { pub fn codegen_backend(&self) -> &Lrc> { &self.codegen_backend } - pub fn cstore(&self) -> &Lrc { - &self.cstore - } pub fn source_map(&self) -> &Lrc { &self.source_map } @@ -160,13 +155,10 @@ where config.lint_caps, ); - let cstore = Lrc::new(CStore::new(codegen_backend.metadata_loader())); - let compiler = Compiler { sess, codegen_backend, source_map, - cstore, input: config.input, input_path: config.input_path, output_dir: config.output_dir, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 18df4ee51b79..80ce203b4fbb 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -9,7 +9,7 @@ use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; -use rustc::middle::cstore::{CrateStore, MetadataLoader}; +use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt}; use rustc::ty::steal::Steal; use rustc::traits; @@ -23,8 +23,7 @@ use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; use rustc_incremental; -use rustc_metadata::creader::CrateLoader; -use rustc_metadata::cstore::{self, CStore}; +use rustc_metadata::cstore; use rustc_mir as mir; use rustc_passes::{self, ast_validation, hir_stats, layout_test}; use rustc_plugin as plugin; @@ -116,7 +115,7 @@ declare_box_region_type!( pub fn configure_and_expand( sess: Lrc, lint_store: Lrc, - cstore: Lrc, + metadata_loader: Box, krate: ast::Crate, crate_name: &str, plugin_info: PluginInfo, @@ -129,16 +128,14 @@ pub fn configure_and_expand( let crate_name = crate_name.to_string(); let (result, resolver) = BoxedResolver::new(static move || { let sess = &*sess; - let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name); let resolver_arenas = Resolver::arenas(); let res = configure_and_expand_inner( sess, &lint_store, - &*cstore, krate, &crate_name, &resolver_arenas, - &crate_loader, + &*metadata_loader, plugin_info, ); let mut resolver = match res { @@ -275,11 +272,10 @@ pub fn register_plugins<'a>( fn configure_and_expand_inner<'a>( sess: &'a Session, lint_store: &'a lint::LintStore, - cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, resolver_arenas: &'a ResolverArenas<'a>, - crate_loader: &'a CrateLoader<'a>, + metadata_loader: &'a MetadataLoaderDyn, plugin_info: PluginInfo, ) -> Result<(ast::Crate, Resolver<'a>)> { time(sess, "pre-AST-expansion lint checks", || { @@ -293,10 +289,9 @@ fn configure_and_expand_inner<'a>( let mut resolver = Resolver::new( sess, - cstore, &krate, crate_name, - crate_loader, + metadata_loader, &resolver_arenas, ); syntax_ext::register_builtin_macros(&mut resolver, sess.edition()); @@ -496,7 +491,6 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir( sess: &Session, lint_store: &lint::LintStore, - cstore: &CStore, resolver: &mut Resolver<'_>, dep_graph: &DepGraph, krate: &ast::Crate, @@ -504,7 +498,7 @@ pub fn lower_to_hir( // Lower AST to HIR. let hir_forest = time(sess, "lowering AST -> HIR", || { let nt_to_tokenstream = syntax::parse::nt_to_tokenstream; - let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream); + let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream); if sess.opts.debugging_opts.hir_stats { hir_stats::print_hir_stats(&hir_crate); @@ -610,8 +604,12 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } -fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { - let sess = &compiler.sess; +fn write_out_deps( + sess: &Session, + boxed_resolver: &Steal>>, + outputs: &OutputFilenames, + out_filenames: &[PathBuf], +) { // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; @@ -630,18 +628,20 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: .collect(); if sess.binary_dep_depinfo() { - for cnum in compiler.cstore.crates_untracked() { - let source = compiler.cstore.crate_source_untracked(cnum); - if let Some((path, _)) = source.dylib { - files.push(escape_dep_filename(&FileName::Real(path))); + boxed_resolver.borrow().borrow_mut().access(|resolver| { + for cnum in resolver.cstore().crates_untracked() { + let source = resolver.cstore().crate_source_untracked(cnum); + if let Some((path, _)) = source.dylib { + files.push(escape_dep_filename(&FileName::Real(path))); + } + if let Some((path, _)) = source.rlib { + files.push(escape_dep_filename(&FileName::Real(path))); + } + if let Some((path, _)) = source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path))); + } } - if let Some((path, _)) = source.rlib { - files.push(escape_dep_filename(&FileName::Real(path))); - } - if let Some((path, _)) = source.rmeta { - files.push(escape_dep_filename(&FileName::Real(path))); - } - } + }); } let mut file = fs::File::create(&deps_filename)?; @@ -679,6 +679,7 @@ pub fn prepare_outputs( sess: &Session, compiler: &Compiler, krate: &ast::Crate, + boxed_resolver: &Steal>>, crate_name: &str ) -> Result { // FIXME: rustdoc passes &[] instead of &krate.attrs here @@ -720,7 +721,7 @@ pub fn prepare_outputs( } } - write_out_deps(compiler, &outputs, &output_paths); + write_out_deps(sess, boxed_resolver, &outputs, &output_paths); let only_dep_info = sess.opts.output_types.contains_key(&OutputType::DepInfo) && sess.opts.output_types.len() == 1; @@ -790,21 +791,19 @@ pub fn create_global_ctxt( crate_name: &str, ) -> BoxedGlobalCtxt { let sess = compiler.session().clone(); - let cstore = compiler.cstore.clone(); let codegen_backend = compiler.codegen_backend().clone(); let crate_name = crate_name.to_string(); let defs = mem::take(&mut resolver_outputs.definitions); let ((), result) = BoxedGlobalCtxt::new(static move || { let sess = &*sess; - let cstore = &*cstore; let global_ctxt: Option>; let arenas = AllArenas::new(); // Construct the HIR map. let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, cstore, &mut hir_forest, &defs) + hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs) }); let query_result_on_disk_cache = time(sess, "load query result cache", || { @@ -822,7 +821,6 @@ pub fn create_global_ctxt( let gcx = TyCtxt::create_global_ctxt( sess, lint_store, - cstore, local_providers, extern_providers, &arenas, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 2ff5c69b145d..b5c356bf05a1 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -164,7 +164,7 @@ impl Compiler { passes::configure_and_expand( self.sess.clone(), lint_store.clone(), - self.cstore().clone(), + self.codegen_backend().metadata_loader(), krate, &crate_name, plugin_info, @@ -202,7 +202,6 @@ impl Compiler { passes::lower_to_hir( self.session(), lint_store, - self.cstore(), resolver, &*self.dep_graph()?.peek(), &krate @@ -214,11 +213,11 @@ impl Compiler { pub fn prepare_outputs(&self) -> Result<&Query> { self.queries.prepare_outputs.compute(|| { - let krate = self.expansion()?; - let krate = krate.peek(); + let expansion_result = self.expansion()?; + let (krate, boxed_resolver) = &*expansion_result.peek(); let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); - passes::prepare_outputs(self.session(), self, &krate.0, &*crate_name) + passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name) }) } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 2eaf7536a70a..5f4abbc3bdc8 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,7 +14,7 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource}; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; @@ -38,9 +38,12 @@ crate struct Library { } pub struct CrateLoader<'a> { + // Immutable configuration. sess: &'a Session, - cstore: &'a CStore, + metadata_loader: &'a MetadataLoaderDyn, local_crate_name: Symbol, + // Mutable output. + cstore: CStore, } fn dump_crates(cstore: &CStore) { @@ -75,14 +78,27 @@ impl<'a> LoadError<'a> { } impl<'a> CrateLoader<'a> { - pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self { + pub fn new( + sess: &'a Session, + metadata_loader: &'a MetadataLoaderDyn, + local_crate_name: &str, + ) -> Self { CrateLoader { sess, - cstore, + metadata_loader, local_crate_name: Symbol::intern(local_crate_name), + cstore: Default::default(), } } + pub fn cstore(&self) -> &CStore { + &self.cstore + } + + pub fn into_cstore(self) -> CStore { + self.cstore + } + fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind) -> Option { let mut ret = None; @@ -346,7 +362,7 @@ impl<'a> CrateLoader<'a> { rejected_via_filename: vec![], should_match_name: true, is_proc_macro: Some(false), - metadata_loader: &*self.cstore.metadata_loader, + metadata_loader: self.metadata_loader, }; self.load(&mut locate_ctxt).map(|r| (r, None)).or_else(|| { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index a2920884409c..09d37a007033 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -5,12 +5,13 @@ use crate::schema; use rustc::dep_graph::DepNodeIndex; use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; -use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoaderDyn}; +use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell}; use syntax::ast; +use syntax::edition::Edition; use syntax_expand::base::SyntaxExtension; use syntax_pos; use proc_macro::bridge::client::ProcMacro; @@ -36,7 +37,7 @@ crate struct ImportedSourceFile { pub translated_source_file: Lrc, } -pub struct CrateMetadata { +crate struct CrateMetadata { /// The primary crate data - binary metadata blob. crate blob: MetadataBlob, @@ -94,28 +95,29 @@ pub struct CrateMetadata { crate extern_crate: Lock>, } +#[derive(Clone)] pub struct CStore { metas: RwLock>>>, - crate metadata_loader: Box, } pub enum LoadedMacro { - MacroDef(ast::Item), + MacroDef(ast::Item, Edition), ProcMacro(SyntaxExtension), } -impl CStore { - pub fn new(metadata_loader: Box) -> CStore { +impl Default for CStore { + fn default() -> Self { CStore { // We add an empty entry for LOCAL_CRATE (which maps to zero) in // order to make array indices in `metas` match with the // corresponding `CrateNum`. This first entry will always remain // `None`. metas: RwLock::new(IndexVec::from_elem_n(None, 1)), - metadata_loader, } } +} +impl CStore { crate fn alloc_new_crate_num(&self) -> CrateNum { let mut metas = self.metas.borrow_mut(); let cnum = CrateNum::new(metas.len()); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 6aba66a79ab3..c20017ffef66 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -29,7 +29,6 @@ use std::sync::Arc; use syntax::ast; use syntax::attr; use syntax::source_map; -use syntax::edition::Edition; use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; use syntax::source_map::Spanned; @@ -411,10 +410,6 @@ impl cstore::CStore { } } - pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition { - self.get_crate_data(cnum).root.edition - } - pub fn struct_field_names_untracked(&self, def: DefId, sess: &Session) -> Vec> { self.get_crate_data(def.krate).get_struct_field_names(def.index, sess) } @@ -470,7 +465,7 @@ impl cstore::CStore { }), vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited), tokens: None, - }) + }, data.root.edition) } pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 6444a82fd737..c0fb8e33a819 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -110,9 +110,9 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate), None) + (self.cstore().crate_name_untracked(def_id.krate), None) } else { - let def_key = self.cstore.def_key(def_id); + let def_key = self.cstore().def_key(def_id); (def_key.disambiguated_data.data.get_opt_name().unwrap(), Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) }; @@ -153,9 +153,8 @@ impl<'a> Resolver<'a> { return Some(ext.clone()); } - let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) { - LoadedMacro::MacroDef(item) => - self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)), + let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) { + LoadedMacro::MacroDef(item, edition) => self.compile_macro(&item, edition), LoadedMacro::ProcMacro(ext) => ext, }); @@ -177,7 +176,7 @@ impl<'a> Resolver<'a> { crate fn build_reduced_graph_external(&mut self, module: Module<'a>) { let def_id = module.def_id().expect("unpopulated module without a def-id"); - for child in self.cstore.item_children_untracked(def_id, self.session) { + for child in self.cstore().item_children_untracked(def_id, self.session) { let child = child.map_id(|_| panic!("unexpected id")); BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) } .build_reduced_graph_for_external_crate_res(child); @@ -885,19 +884,19 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { bug!("unexpected resolution: {:?}", res) } // Record some extra data for better diagnostics. + let cstore = self.r.cstore(); match res { Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => { - let field_names = - self.r.cstore.struct_field_names_untracked(def_id, self.r.session); + let field_names = cstore.struct_field_names_untracked(def_id, self.r.session); self.insert_field_names(def_id, field_names); } Res::Def(DefKind::Method, def_id) => { - if self.r.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { + if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { self.r.has_self.insert(def_id); } } Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => { - let parent = self.r.cstore.def_key(def_id).parent; + let parent = cstore.def_key(def_id).parent; if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) { self.r.struct_constructors.insert(struct_def_id, (res, vis)); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 5cdf4d2fb692..1c67395fbf0b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -21,7 +21,7 @@ use Determinacy::*; use rustc::hir::map::Definitions; use rustc::hir::{self, PrimTy, Bool, Char, Float, Int, Uint, Str}; -use rustc::middle::cstore::CrateStore; +use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn}; use rustc::session::Session; use rustc::lint; use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrKind, ExportMap}; @@ -829,7 +829,6 @@ pub struct ExternPreludeEntry<'a> { /// This is the visitor that walks the whole crate. pub struct Resolver<'a> { session: &'a Session, - cstore: &'a CStore, definitions: Definitions, @@ -916,7 +915,7 @@ pub struct Resolver<'a> { arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, - crate_loader: &'a CrateLoader<'a>, + crate_loader: CrateLoader<'a>, macro_names: FxHashSet, builtin_macros: FxHashMap, macro_use_prelude: FxHashMap>, @@ -1015,7 +1014,7 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { fn parent(self, id: DefId) -> Option { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, - _ => self.cstore.def_key(id).parent, + _ => self.cstore().def_key(id).parent, }.map(|index| DefId { index, ..id }) } } @@ -1023,6 +1022,10 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. impl<'a> hir::lowering::Resolver for Resolver<'a> { + fn cstore(&self) -> &dyn CrateStore { + self.cstore() + } + fn resolve_str_path( &mut self, span: Span, @@ -1083,10 +1086,9 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { impl<'a> Resolver<'a> { pub fn new(session: &'a Session, - cstore: &'a CStore, krate: &Crate, crate_name: &str, - crate_loader: &'a CrateLoader<'a>, + metadata_loader: &'a MetadataLoaderDyn, arenas: &'a ResolverArenas<'a>) -> Resolver<'a> { let root_def_id = DefId::local(CRATE_DEF_INDEX); @@ -1147,8 +1149,6 @@ impl<'a> Resolver<'a> { Resolver { session, - cstore, - definitions, // The outermost module has def ID 0; this is not reflected in the @@ -1202,7 +1202,7 @@ impl<'a> Resolver<'a> { vis: ty::Visibility::Public, }), - crate_loader, + crate_loader: CrateLoader::new(session, metadata_loader, crate_name), macro_names: FxHashSet::default(), builtin_macros: Default::default(), macro_use_prelude: FxHashMap::default(), @@ -1239,6 +1239,7 @@ impl<'a> Resolver<'a> { pub fn into_outputs(self) -> ResolverOutputs { ResolverOutputs { definitions: self.definitions, + cstore: Box::new(self.crate_loader.into_cstore()), extern_crate_map: self.extern_crate_map, export_map: self.export_map, trait_map: self.trait_map, @@ -1254,6 +1255,7 @@ impl<'a> Resolver<'a> { pub fn clone_outputs(&self) -> ResolverOutputs { ResolverOutputs { definitions: self.definitions.clone(), + cstore: Box::new(self.cstore().clone()), extern_crate_map: self.extern_crate_map.clone(), export_map: self.export_map.clone(), trait_map: self.trait_map.clone(), @@ -1266,6 +1268,10 @@ impl<'a> Resolver<'a> { } } + pub fn cstore(&self) -> &CStore { + self.crate_loader.cstore() + } + fn non_macro_attr(&self, mark_used: bool) -> Lrc { self.non_macro_attrs[mark_used as usize].clone() } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 34edd5eaf4fc..31340ddd6837 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1344,7 +1344,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if res != Res::Err { if let Some(def_id) = res.opt_def_id() { if !def_id.is_local() { - this.cstore.export_macros_untracked(def_id.krate); + this.cstore().export_macros_untracked(def_id.krate); } } reexports.push(Export { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e7cc8b76e485..a6a8fec429e2 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -479,8 +479,8 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemEnum { let imported_from = cx.tcx.original_crate_name(did.krate); - match cx.cstore.load_macro_untracked(did, cx.sess()) { - LoadedMacro::MacroDef(def) => { + match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) { + LoadedMacro::MacroDef(def, _) => { let matchers: hir::HirVec = if let ast::ItemKind::MacroDef(ref def) = def.kind { let tts: Vec<_> = def.stream().into_trees().collect(); tts.chunks(4).map(|arm| arm[0].span()).collect() diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 39ab30e8ecfc..b227f432a4e9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -12,7 +12,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_interface::interface; use rustc_driver::abort_on_err; use rustc_resolve as resolve; -use rustc_metadata::cstore::CStore; use syntax::source_map; use syntax::attr; @@ -43,7 +42,6 @@ pub struct DocContext<'tcx> { pub tcx: TyCtxt<'tcx>, pub resolver: Rc>, - pub cstore: Lrc, /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` @@ -117,9 +115,7 @@ impl<'tcx> DocContext<'tcx> { .def_path_table() .next_id() } else { - self.cstore - .def_path_table(crate_num) - .next_id() + self.enter_resolver(|r| r.cstore().def_path_table(crate_num).next_id()) }; DefId { @@ -376,7 +372,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let mut ctxt = DocContext { tcx, resolver, - cstore: compiler.cstore().clone(), external_traits: Default::default(), active_extern_traits: Default::default(), renderinfo: RefCell::new(renderinfo), From c5fee33e7aa71d7cfc5abd8848a81924cafd2b15 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 20 Oct 2019 12:49:14 +0300 Subject: [PATCH 107/109] rustc_metadata: Remove `RwLock` from `CStore` --- src/librustc_metadata/creader.rs | 26 +++++++++++++++----------- src/librustc_metadata/cstore.rs | 25 +++++++++++-------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 5f4abbc3bdc8..420595a690d5 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -179,7 +179,7 @@ impl<'a> CrateLoader<'a> { } fn register_crate( - &self, + &mut self, host_lib: Option, root: Option<&CratePaths>, span: Span, @@ -319,7 +319,7 @@ impl<'a> CrateLoader<'a> { } fn resolve_crate<'b>( - &'b self, + &'b mut self, name: Symbol, span: Span, dep_kind: DepKind, @@ -329,7 +329,7 @@ impl<'a> CrateLoader<'a> { } fn maybe_resolve_crate<'b>( - &'b self, + &'b mut self, name: Symbol, span: Span, mut dep_kind: DepKind, @@ -458,7 +458,7 @@ impl<'a> CrateLoader<'a> { } // Go through the crate metadata and load any crates that it references - fn resolve_crate_deps(&self, + fn resolve_crate_deps(&mut self, root: &CratePaths, crate_root: &CrateRoot<'_>, metadata: &MetadataBlob, @@ -519,7 +519,7 @@ impl<'a> CrateLoader<'a> { decls } - fn inject_panic_runtime(&self, krate: &ast::Crate) { + fn inject_panic_runtime(&mut self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| { @@ -600,7 +600,7 @@ impl<'a> CrateLoader<'a> { &|data| data.root.needs_panic_runtime); } - fn inject_sanitizer_runtime(&self) { + fn inject_sanitizer_runtime(&mut self) { if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { // Sanitizers can only be used on some tested platforms with // executables linked to `std` @@ -698,7 +698,7 @@ impl<'a> CrateLoader<'a> { } } - fn inject_profiler_runtime(&self) { + fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { @@ -852,7 +852,7 @@ impl<'a> CrateLoader<'a> { }); } - pub fn postprocess(&self, krate: &ast::Crate) { + pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -863,7 +863,11 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum { + pub fn process_extern_crate( + &mut self, + item: &ast::Item, + definitions: &Definitions, + ) -> CrateNum { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", @@ -902,7 +906,7 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum { + pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0; self.update_extern_crate( @@ -920,7 +924,7 @@ impl<'a> CrateLoader<'a> { cnum } - pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option { + pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option { let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0; self.update_extern_crate( diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 09d37a007033..a0589b1f3bd3 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -97,7 +97,7 @@ crate struct CrateMetadata { #[derive(Clone)] pub struct CStore { - metas: RwLock>>>, + metas: IndexVec>>, } pub enum LoadedMacro { @@ -112,34 +112,31 @@ impl Default for CStore { // order to make array indices in `metas` match with the // corresponding `CrateNum`. This first entry will always remain // `None`. - metas: RwLock::new(IndexVec::from_elem_n(None, 1)), + metas: IndexVec::from_elem_n(None, 1), } } } impl CStore { - crate fn alloc_new_crate_num(&self) -> CrateNum { - let mut metas = self.metas.borrow_mut(); - let cnum = CrateNum::new(metas.len()); - metas.push(None); - cnum + crate fn alloc_new_crate_num(&mut self) -> CrateNum { + self.metas.push(None); + CrateNum::new(self.metas.len() - 1) } crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc { - self.metas.borrow()[cnum].clone() + self.metas[cnum].clone() .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) } - crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { - let mut metas = self.metas.borrow_mut(); - assert!(metas[cnum].is_none(), "Overwriting crate metadata entry"); - metas[cnum] = Some(data); + crate fn set_crate_data(&mut self, cnum: CrateNum, data: Lrc) { + assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry"); + self.metas[cnum] = Some(data); } crate fn iter_crate_data(&self, mut i: I) where I: FnMut(CrateNum, &Lrc) { - for (k, v) in self.metas.borrow().iter_enumerated() { + for (k, v) in self.metas.iter_enumerated() { if let &Some(ref v) = v { i(k, v); } @@ -170,7 +167,7 @@ impl CStore { crate fn do_postorder_cnums_untracked(&self) -> Vec { let mut ordering = Vec::new(); - for (num, v) in self.metas.borrow().iter_enumerated() { + for (num, v) in self.metas.iter_enumerated() { if let &Some(_) = v { self.push_dependencies_in_postorder(&mut ordering, num); } From 9f5a530b84c75e34c183eea50ce9a5d7fcf6581b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 20 Oct 2019 14:06:48 +0300 Subject: [PATCH 108/109] rustc_metadata: Minimize use of `Lrc` in crate store Crate metadatas are still stored as `Lrc` in `CStore` because crate store has to be cloneable due to `Resolver::clone_outputs`. --- src/librustc/middle/cstore.rs | 6 ++--- src/librustc/ty/context.rs | 23 ++++++----------- src/librustc_metadata/creader.rs | 37 ++++++++++++++-------------- src/librustc_metadata/cstore.rs | 12 ++++----- src/librustc_metadata/cstore_impl.rs | 10 ++++---- 5 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 8205383da989..d5558db2397e 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -16,7 +16,7 @@ use syntax::ast; use syntax::symbol::Symbol; use syntax_pos::Span; use rustc_target::spec::Target; -use rustc_data_structures::sync::{self, MetadataRef, Lrc}; +use rustc_data_structures::sync::{self, MetadataRef}; use rustc_macros::HashStable; pub use self::NativeLibraryKind::*; @@ -203,13 +203,13 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync; /// (it'd break incremental compilation) and should only be called pre-HIR (e.g. /// during resolve) pub trait CrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc; + fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any; // resolve fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash; - fn def_path_table(&self, cnum: CrateNum) -> Lrc; + fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable; // "queries" used in resolve that aren't tracked for incremental compilation fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 9b2e6df6bea1..f99298281fec 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1213,34 +1213,27 @@ impl<'tcx> TyCtxt<'tcx> { let common_consts = CommonConsts::new(&interners, &common_types); let dep_graph = hir.dep_graph.clone(); let cstore = resolutions.cstore; - let max_cnum = cstore.crates_untracked().iter().map(|c| c.as_usize()).max().unwrap_or(0); + let crates = cstore.crates_untracked(); + let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0); let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); providers[LOCAL_CRATE] = local_providers; let def_path_hash_to_def_id = if s.opts.build_dep_graph() { - let upstream_def_path_tables: Vec<(CrateNum, Lrc<_>)> = cstore - .crates_untracked() + let def_path_tables = crates .iter() .map(|&cnum| (cnum, cstore.def_path_table(cnum))) - .collect(); - - let def_path_tables = || { - upstream_def_path_tables - .iter() - .map(|&(cnum, ref rc)| (cnum, &**rc)) - .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table()))) - }; + .chain(iter::once((LOCAL_CRATE, hir.definitions().def_path_table()))); // Precompute the capacity of the hashmap so we don't have to // re-allocate when populating it. - let capacity = def_path_tables().map(|(_, t)| t.size()).sum::(); + let capacity = def_path_tables.clone().map(|(_, t)| t.size()).sum::(); let mut map: FxHashMap<_, _> = FxHashMap::with_capacity_and_hasher( capacity, ::std::default::Default::default() ); - for (cnum, def_path_table) in def_path_tables() { + for (cnum, def_path_table) in def_path_tables { def_path_table.add_def_path_hashes_to(cnum, &mut map); } @@ -1417,8 +1410,8 @@ impl<'tcx> TyCtxt<'tcx> { // Note that this is *untracked* and should only be used within the query // system if the result is otherwise tracked through queries - pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc { - self.cstore.crate_data_as_rc_any(cnum) + pub fn crate_data_as_any(self, cnum: CrateNum) -> &'tcx dyn Any { + self.cstore.crate_data_as_any(cnum) } #[inline(always)] diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 420595a690d5..f0a68058de8c 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -3,7 +3,7 @@ use crate::cstore::{self, CStore, MetadataBlob}; use crate::locator::{self, CratePaths}; use crate::schema::{CrateRoot, CrateDep}; -use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; +use rustc_data_structures::sync::{RwLock, Lock, AtomicCell}; use rustc::hir::def_id::CrateNum; use rustc_data_structures::svh::Svh; @@ -186,7 +186,7 @@ impl<'a> CrateLoader<'a> { lib: Library, dep_kind: DepKind, name: Symbol - ) -> (CrateNum, Lrc) { + ) -> CrateNum { let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); let Library { source, metadata } = lib; @@ -240,9 +240,9 @@ impl<'a> CrateLoader<'a> { crate_root.def_path_table.decode((&metadata, self.sess)) }); - let cmeta = cstore::CrateMetadata { + self.cstore.set_crate_data(cnum, cstore::CrateMetadata { extern_crate: Lock::new(None), - def_path_table: Lrc::new(def_path_table), + def_path_table, trait_impls, root: crate_root, blob: metadata, @@ -256,11 +256,9 @@ impl<'a> CrateLoader<'a> { private_dep, raw_proc_macros, dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), - }; + }); - let cmeta = Lrc::new(cmeta); - self.cstore.set_crate_data(cnum, cmeta.clone()); - (cnum, cmeta) + cnum } fn load_proc_macro<'b>( @@ -324,7 +322,7 @@ impl<'a> CrateLoader<'a> { span: Span, dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, - ) -> (CrateNum, Lrc) { + ) -> CrateNum { self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report()) } @@ -334,7 +332,7 @@ impl<'a> CrateLoader<'a> { span: Span, mut dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, - ) -> Result<(CrateNum, Lrc), LoadError<'b>> { + ) -> Result> { info!("resolving crate `{}`", name); let (root, hash, extra_filename, path_kind) = match dep { Some((root, dep)) => @@ -380,7 +378,7 @@ impl<'a> CrateLoader<'a> { data.dep_kind.with_lock(|data_dep_kind| { *data_dep_kind = cmp::max(*data_dep_kind, dep_kind); }); - Ok((cnum, data)) + Ok(cnum) } (LoadResult::Loaded(library), host_library) => { Ok(self.register_crate(host_library, root, span, library, dep_kind, name)) @@ -484,7 +482,7 @@ impl<'a> CrateLoader<'a> { DepKind::MacrosOnly => DepKind::MacrosOnly, _ => dep.kind, }; - self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))).0 + self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))) })).collect() } @@ -581,7 +579,8 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let (cnum, data) = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime // and the panic strategy is indeed what we thought it was. @@ -685,7 +684,8 @@ impl<'a> CrateLoader<'a> { }); info!("loading sanitizer: {}", name); - let data = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None).1; + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Explicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime if !data.root.sanitizer_runtime { @@ -705,7 +705,8 @@ impl<'a> CrateLoader<'a> { info!("loading profiler"); let name = Symbol::intern("profiler_builtins"); - let data = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None).1; + let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime if !data.root.profiler_runtime { @@ -886,7 +887,7 @@ impl<'a> CrateLoader<'a> { DepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind, None).0; + let cnum = self.resolve_crate(name, item.span, dep_kind, None); let def_id = definitions.opt_local_def_id(item.id).unwrap(); let path_len = definitions.def_path(def_id.index).data.len(); @@ -907,7 +908,7 @@ impl<'a> CrateLoader<'a> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0; + let cnum = self.resolve_crate(name, span, DepKind::Explicit, None); self.update_extern_crate( cnum, @@ -925,7 +926,7 @@ impl<'a> CrateLoader<'a> { } pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option { - let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0; + let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?; self.update_extern_crate( cnum, diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index a0589b1f3bd3..6b06cf575edc 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -54,7 +54,7 @@ crate struct CrateMetadata { /// hashmap, which gives the reverse mapping. This allows us to /// quickly retrace a `DefPath`, which is needed for incremental /// compilation support. - crate def_path_table: Lrc, + crate def_path_table: DefPathTable, /// Trait impl data. /// FIXME: Used only from queries and can use query cache, /// so pre-decoding can probably be avoided. @@ -123,18 +123,18 @@ impl CStore { CrateNum::new(self.metas.len() - 1) } - crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc { - self.metas[cnum].clone() + crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { + self.metas[cnum].as_ref() .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) } - crate fn set_crate_data(&mut self, cnum: CrateNum, data: Lrc) { + crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry"); - self.metas[cnum] = Some(data); + self.metas[cnum] = Some(Lrc::new(data)); } crate fn iter_crate_data(&self, mut i: I) - where I: FnMut(CrateNum, &Lrc) + where I: FnMut(CrateNum, &CrateMetadata) { for (k, v) in self.metas.iter_enumerated() { if let &Some(ref v) = v { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index c20017ffef66..d942a19194a1 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -53,7 +53,7 @@ macro_rules! provide { let ($def_id, $other) = def_id_arg.into_args(); assert!(!$def_id.is_local()); - let $cdata = $tcx.crate_data_as_rc_any($def_id.krate); + let $cdata = $tcx.crate_data_as_any($def_id.krate); let $cdata = $cdata.downcast_ref::() .expect("CrateStore created data is not a CrateMetadata"); @@ -478,8 +478,8 @@ impl cstore::CStore { } impl CrateStore for cstore::CStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc { - self.get_crate_data(krate) + fn crate_data_as_any(&self, cnum: CrateNum) -> &dyn Any { + self.get_crate_data(cnum) } fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { @@ -520,8 +520,8 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path_hash(def.index) } - fn def_path_table(&self, cnum: CrateNum) -> Lrc { - self.get_crate_data(cnum).def_path_table.clone() + fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable { + &self.get_crate_data(cnum).def_path_table } fn crates_untracked(&self) -> Vec From 94216ce3adfdb7d6c206505fca736d274a98ad2b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 21 Oct 2019 23:32:51 +0300 Subject: [PATCH 109/109] rustc_interface: Remove `ExpansionResult` and some `Steal`s --- src/librustc_interface/passes.rs | 25 ++++--------------------- src/librustc_interface/queries.rs | 17 ++++++++++------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 80ce203b4fbb..58936172c5bc 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -102,7 +102,7 @@ fn count_nodes(krate: &ast::Crate) -> usize { declare_box_region_type!( pub BoxedResolver, for(), - (&mut Resolver<'_>) -> (Result, ExpansionResult) + (&mut Resolver<'_>) -> (Result, ResolverOutputs) ); /// Runs the "early phases" of the compiler: initial `cfg` processing, @@ -149,33 +149,16 @@ pub fn configure_and_expand( } }; box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver)); - ExpansionResult::from_resolver_outputs(resolver.into_outputs()) + resolver.into_outputs() }); result.map(|k| (k, resolver)) } -pub struct ExpansionResult { - pub resolver_outputs: Steal, -} - -impl ExpansionResult { - fn from_resolver_outputs(resolver_outputs: ResolverOutputs) -> Self { - ExpansionResult { resolver_outputs: Steal::new(resolver_outputs) } - } -} - impl BoxedResolver { - pub fn to_expansion_result( - resolver: Rc>, - ) -> ExpansionResult { + pub fn to_resolver_outputs(resolver: Rc>) -> ResolverOutputs { match Rc::try_unwrap(resolver) { Ok(resolver) => resolver.into_inner().complete(), - Err(resolver) => { - let resolver = &*resolver; - resolver.borrow_mut().access(|resolver| { - ExpansionResult::from_resolver_outputs(resolver.clone_outputs()) - }) - } + Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()), } } } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index b5c356bf05a1..ea51e63725ea 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -1,5 +1,5 @@ use crate::interface::{Compiler, Result}; -use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; +use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; use rustc_data_structures::sync::Lrc; @@ -11,6 +11,7 @@ use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; +use rustc::ty::ResolverOutputs; use rustc::dep_graph::DepGraph; use std::cell::{Ref, RefMut, RefCell}; use std::rc::Rc; @@ -81,7 +82,7 @@ pub(crate) struct Queries { register_plugins: Query<(ast::Crate, PluginInfo, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(Steal, ExpansionResult)>, + lower_to_hir: Query<(Steal, Steal)>, prepare_outputs: Query, global_ctxt: Query, ongoing_codegen: Query>, @@ -191,7 +192,9 @@ impl Compiler { }) } - pub fn lower_to_hir(&self) -> Result<&Query<(Steal, ExpansionResult)>> { + pub fn lower_to_hir( + &self, + ) -> Result<&Query<(Steal, Steal)>> { self.queries.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); @@ -207,14 +210,14 @@ impl Compiler { &krate ) })?); - Ok((hir, BoxedResolver::to_expansion_result(resolver))) + Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) }) } pub fn prepare_outputs(&self) -> Result<&Query> { self.queries.prepare_outputs.compute(|| { let expansion_result = self.expansion()?; - let (krate, boxed_resolver) = &*expansion_result.peek(); + let (krate, boxed_resolver, _) = &*expansion_result.peek(); let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name) @@ -228,12 +231,12 @@ impl Compiler { let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?; let hir = hir.peek(); - let (ref hir_forest, ref expansion) = *hir; + let (hir_forest, resolver_outputs) = &*hir; Ok(passes::create_global_ctxt( self, lint_store, hir_forest.steal(), - expansion.resolver_outputs.steal(), + resolver_outputs.steal(), outputs, &crate_name)) })