From e087871915a46943db670b3e16bd12f25a1d11a2 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Tue, 9 Aug 2022 20:23:40 -0400 Subject: [PATCH 01/13] Make the GATS self outlives error take into GATs in the inputs --- compiler/rustc_typeck/src/check/wfcheck.rs | 2 +- .../generic-associated-types/self-outlives-lint.rs | 13 +++++++++++++ .../self-outlives-lint.stderr | 13 ++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index d0334cd0df7bb..dbbae3e8a64b7 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -383,7 +383,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe tcx, param_env, item_hir_id, - sig.output(), + sig.inputs_and_output, // We also assume that all of the function signature's parameter types // are well formed. &sig.inputs().iter().copied().collect(), diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.rs b/src/test/ui/generic-associated-types/self-outlives-lint.rs index 300907adbfc11..9bb42d4ff1c1b 100644 --- a/src/test/ui/generic-associated-types/self-outlives-lint.rs +++ b/src/test/ui/generic-associated-types/self-outlives-lint.rs @@ -210,4 +210,17 @@ trait StaticReturnAndTakes<'a> { fn bar<'b>(&self, arg: Self::Y<'b>); } +// We require bounds when the GAT appears in the inputs +trait Input { + type Item<'a>; + //~^ missing required + fn takes_item<'a>(&'a self, item: Self::Item<'a>); +} + +// We don't require bounds when the GAT appears in the where clauses +trait WhereClause { + type Item<'a>; + fn takes_item<'a>(&'a self) where Self::Item<'a>: ; +} + fn main() {} diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr index fdb1f50a7764c..a43b35bd79c95 100644 --- a/src/test/ui/generic-associated-types/self-outlives-lint.stderr +++ b/src/test/ui/generic-associated-types/self-outlives-lint.stderr @@ -163,5 +163,16 @@ LL | type Fut<'out>; = note: this bound is currently required to ensure that impls have maximum flexibility = note: we are soliciting feedback, see issue #87479 for more information -error: aborting due to 15 previous errors +error: missing required bound on `Item` + --> $DIR/self-outlives-lint.rs:215:5 + | +LL | type Item<'a>; + | ^^^^^^^^^^^^^- + | | + | help: add the required where clause: `where Self: 'a` + | + = note: this bound is currently required to ensure that impls have maximum flexibility + = note: we are soliciting feedback, see issue #87479 for more information + +error: aborting due to 16 previous errors From 40dcf89a26bde41734f6c3eb71d9eb6420e45ef8 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Mon, 15 Aug 2022 16:10:31 +0900 Subject: [PATCH 02/13] suggest adding a missing semicolon before an item --- compiler/rustc_ast/src/token.rs | 24 ++++++ .../rustc_parse/src/parser/diagnostics.rs | 6 +- .../recover-missing-semi-before-item.fixed | 61 ++++++++++++++ .../recover-missing-semi-before-item.rs | 61 ++++++++++++++ .../recover-missing-semi-before-item.stderr | 83 +++++++++++++++++++ 5 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/parser/recover-missing-semi-before-item.fixed create mode 100644 src/test/ui/parser/recover-missing-semi-before-item.rs create mode 100644 src/test/ui/parser/recover-missing-semi-before-item.stderr diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 85d9687c600dc..dd98946b4cc5e 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -436,6 +436,30 @@ impl Token { || self == &OpenDelim(Delimiter::Parenthesis) } + /// Returns `true` if the token can appear at the start of an item. + pub fn can_begin_item(&self) -> bool { + match self.kind { + Ident(name, _) => [ + kw::Fn, + kw::Use, + kw::Struct, + kw::Enum, + kw::Pub, + kw::Trait, + kw::Extern, + kw::Impl, + kw::Unsafe, + kw::Static, + kw::Union, + kw::Macro, + kw::Mod, + kw::Type, + ] + .contains(&name), + _ => false, + } + } + /// Returns `true` if the token is any literal. pub fn is_lit(&self) -> bool { matches!(self.kind, Literal(..)) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f4c6b33a52924..d0fb768caa687 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -555,10 +555,12 @@ impl<'a> Parser<'a> { return Ok(true); } else if self.look_ahead(0, |t| { t == &token::CloseDelim(Delimiter::Brace) - || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound) + || ((t.can_begin_expr() || t.can_begin_item()) + && t != &token::Semi + && t != &token::Pound) // Avoid triggering with too many trailing `#` in raw string. || (sm.is_multiline( - self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()) + self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()), ) && t == &token::Pound) }) && !expected.contains(&TokenType::Token(token::Comma)) { diff --git a/src/test/ui/parser/recover-missing-semi-before-item.fixed b/src/test/ui/parser/recover-missing-semi-before-item.fixed new file mode 100644 index 0000000000000..0be17e69e8ff7 --- /dev/null +++ b/src/test/ui/parser/recover-missing-semi-before-item.fixed @@ -0,0 +1,61 @@ +// run-rustfix + +#![allow(unused_variables, dead_code)] + +fn for_struct() { + let foo = 3; //~ ERROR expected `;`, found keyword `struct` + struct Foo; +} + +fn for_union() { + let foo = 3; //~ ERROR expected `;`, found `union` + union Foo { + foo: usize, + } +} + +fn for_enum() { + let foo = 3; //~ ERROR expected `;`, found keyword `enum` + enum Foo { + Bar, + } +} + +fn for_fn() { + let foo = 3; //~ ERROR expected `;`, found keyword `fn` + fn foo() {} +} + +fn for_extern() { + let foo = 3; //~ ERROR expected `;`, found keyword `extern` + extern fn foo() {} +} + +fn for_impl() { + struct Foo; + let foo = 3; //~ ERROR expected `;`, found keyword `impl` + impl Foo {} +} + +fn for_use() { + let foo = 3; //~ ERROR expected `;`, found keyword `pub` + pub use bar::Bar; +} + +fn for_mod() { + let foo = 3; //~ ERROR expected `;`, found keyword `mod` + mod foo {} +} + +fn for_type() { + let foo = 3; //~ ERROR expected `;`, found keyword `type` + type Foo = usize; +} + +mod bar { + pub struct Bar; +} + +const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn` + +fn main() {} diff --git a/src/test/ui/parser/recover-missing-semi-before-item.rs b/src/test/ui/parser/recover-missing-semi-before-item.rs new file mode 100644 index 0000000000000..867b7b749bb1f --- /dev/null +++ b/src/test/ui/parser/recover-missing-semi-before-item.rs @@ -0,0 +1,61 @@ +// run-rustfix + +#![allow(unused_variables, dead_code)] + +fn for_struct() { + let foo = 3 //~ ERROR expected `;`, found keyword `struct` + struct Foo; +} + +fn for_union() { + let foo = 3 //~ ERROR expected `;`, found `union` + union Foo { + foo: usize, + } +} + +fn for_enum() { + let foo = 3 //~ ERROR expected `;`, found keyword `enum` + enum Foo { + Bar, + } +} + +fn for_fn() { + let foo = 3 //~ ERROR expected `;`, found keyword `fn` + fn foo() {} +} + +fn for_extern() { + let foo = 3 //~ ERROR expected `;`, found keyword `extern` + extern fn foo() {} +} + +fn for_impl() { + struct Foo; + let foo = 3 //~ ERROR expected `;`, found keyword `impl` + impl Foo {} +} + +fn for_use() { + let foo = 3 //~ ERROR expected `;`, found keyword `pub` + pub use bar::Bar; +} + +fn for_mod() { + let foo = 3 //~ ERROR expected `;`, found keyword `mod` + mod foo {} +} + +fn for_type() { + let foo = 3 //~ ERROR expected `;`, found keyword `type` + type Foo = usize; +} + +mod bar { + pub struct Bar; +} + +const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn` + +fn main() {} diff --git a/src/test/ui/parser/recover-missing-semi-before-item.stderr b/src/test/ui/parser/recover-missing-semi-before-item.stderr new file mode 100644 index 0000000000000..61c43f2f18998 --- /dev/null +++ b/src/test/ui/parser/recover-missing-semi-before-item.stderr @@ -0,0 +1,83 @@ +error: expected `;`, found keyword `struct` + --> $DIR/recover-missing-semi-before-item.rs:6:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | struct Foo; + | ------ unexpected token + +error: expected `;`, found `union` + --> $DIR/recover-missing-semi-before-item.rs:11:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | union Foo { + | ----- unexpected token + +error: expected `;`, found keyword `enum` + --> $DIR/recover-missing-semi-before-item.rs:18:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | enum Foo { + | ---- unexpected token + +error: expected `;`, found keyword `fn` + --> $DIR/recover-missing-semi-before-item.rs:25:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | fn foo() {} + | -- unexpected token + +error: expected `;`, found keyword `extern` + --> $DIR/recover-missing-semi-before-item.rs:30:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | extern fn foo() {} + | ------ unexpected token + +error: expected `;`, found keyword `impl` + --> $DIR/recover-missing-semi-before-item.rs:36:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | impl Foo {} + | ---- unexpected token + +error: expected `;`, found keyword `pub` + --> $DIR/recover-missing-semi-before-item.rs:41:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | pub use bar::Bar; + | --- unexpected token + +error: expected `;`, found keyword `mod` + --> $DIR/recover-missing-semi-before-item.rs:46:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | mod foo {} + | --- unexpected token + +error: expected `;`, found keyword `type` + --> $DIR/recover-missing-semi-before-item.rs:51:16 + | +LL | let foo = 3 + | ^ help: add `;` here +LL | type Foo = usize; + | ---- unexpected token + +error: expected `;`, found keyword `fn` + --> $DIR/recover-missing-semi-before-item.rs:59:19 + | +LL | const X: i32 = 123 + | ^ help: add `;` here +LL | +LL | fn main() {} + | -- unexpected token + +error: aborting due to 10 previous errors + From ed27a4c51601b624e410bb60328b5844fc6c5dd4 Mon Sep 17 00:00:00 2001 From: Corwin Date: Tue, 16 Aug 2022 20:10:31 +0100 Subject: [PATCH 03/13] add the armv4t-none-eabi target --- compiler/rustc_target/src/spec/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 0b49edc232c06..cf6cb75d49a50 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1028,6 +1028,7 @@ supported_targets! { ("mipsel-sony-psp", mipsel_sony_psp), ("mipsel-unknown-none", mipsel_unknown_none), ("thumbv4t-none-eabi", thumbv4t_none_eabi), + ("armv4t-none-eabi", armv4t_none_eabi), ("aarch64_be-unknown-linux-gnu", aarch64_be_unknown_linux_gnu), ("aarch64-unknown-linux-gnu_ilp32", aarch64_unknown_linux_gnu_ilp32), From f77a545e94abc578b22cf48eb0085dc903f9d262 Mon Sep 17 00:00:00 2001 From: Corwin Date: Tue, 16 Aug 2022 23:15:42 +0100 Subject: [PATCH 04/13] add target armv4t-none-eabi --- src/doc/rustc/src/platform-support.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 01489e9aafb25..f0f57f9338672 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -223,6 +223,7 @@ target | std | host | notes `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM Apple WatchOS 64-bit with 32-bit pointers +`armv4t-none-eabi` | * | | ARMv4T A32 `armv4t-unknown-linux-gnueabi` | ? | | `armv5te-unknown-linux-uclibceabi` | ? | | ARMv5TE Linux with uClibc `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD From ba7272959df7447c7393a14f475663de1f250f8f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Aug 2022 03:23:23 +0000 Subject: [PATCH 05/13] Use separate infcx to solve obligations during negative coherence --- .../src/traits/coherence.rs | 21 +++++++------------ .../coherence-negative-outlives-lifetimes.rs | 7 ++++++- ...-negative-outlives-lifetimes.stock.stderr} | 2 +- ...s-lifetimes.with_negative_coherence.stderr | 11 ++++++++++ 4 files changed, 26 insertions(+), 15 deletions(-) rename src/test/ui/coherence/{coherence-negative-outlives-lifetimes.stderr => coherence-negative-outlives-lifetimes.stock.stderr} (88%) create mode 100644 src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 985600d9ebcc2..3bc08fba91a10 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -342,10 +342,8 @@ fn equate<'cx, 'tcx>( }; let selcx = &mut SelectionContext::new(&infcx); - let opt_failing_obligation = obligations - .into_iter() - .chain(more_obligations) - .find(|o| negative_impl_exists(selcx, impl_env, o)); + let opt_failing_obligation = + obligations.into_iter().chain(more_obligations).find(|o| negative_impl_exists(selcx, o)); if let Some(failing_obligation) = opt_failing_obligation { debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); @@ -359,18 +357,15 @@ fn equate<'cx, 'tcx>( #[instrument(level = "debug", skip(selcx))] fn negative_impl_exists<'cx, 'tcx>( selcx: &SelectionContext<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, o: &PredicateObligation<'tcx>, ) -> bool { - let infcx = &selcx.infcx().fork(); - - if resolve_negative_obligation(infcx, param_env, o) { + if resolve_negative_obligation(selcx.infcx().fork(), o) { return true; } // Try to prove a negative obligation exists for super predicates - for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { - if resolve_negative_obligation(infcx, param_env, &o) { + for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) { + if resolve_negative_obligation(selcx.infcx().fork(), &o) { return true; } } @@ -380,8 +375,7 @@ fn negative_impl_exists<'cx, 'tcx>( #[instrument(level = "debug", skip(infcx))] fn resolve_negative_obligation<'cx, 'tcx>( - infcx: &InferCtxt<'cx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, + infcx: InferCtxt<'cx, 'tcx>, o: &PredicateObligation<'tcx>, ) -> bool { let tcx = infcx.tcx; @@ -390,7 +384,8 @@ fn resolve_negative_obligation<'cx, 'tcx>( return false; }; - let errors = super::fully_solve_obligation(infcx, o); + let param_env = o.param_env; + let errors = super::fully_solve_obligation(&infcx, o); if !errors.is_empty() { return false; } diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs index 159788b1b77f7..221c1bc23b3f4 100644 --- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.rs @@ -1,10 +1,15 @@ +// revisions: stock with_negative_coherence #![feature(negative_impls)] +#![cfg_attr(with_negative_coherence, feature(with_negative_coherence))] // FIXME: this should compile trait MyPredicate<'a> {} -impl<'a, T> !MyPredicate<'a> for &T where T: 'a {} + +impl<'a, T> !MyPredicate<'a> for &'a T where T: 'a {} + trait MyTrait<'a> {} + impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} impl<'a, T> MyTrait<'a> for &'a T {} //~^ ERROR: conflicting implementations of trait `MyTrait<'_>` for type `&_` diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr similarity index 88% rename from src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr rename to src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr index 263bd19b4249e..097cc4e0fe3e6 100644 --- a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stderr +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_` - --> $DIR/coherence-negative-outlives-lifetimes.rs:9:1 + --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1 | LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here diff --git a/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr new file mode 100644 index 0000000000000..097cc4e0fe3e6 --- /dev/null +++ b/src/test/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `MyTrait<'_>` for type `&_` + --> $DIR/coherence-negative-outlives-lifetimes.rs:14:1 + | +LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} + | ---------------------------------------------- first implementation here +LL | impl<'a, T> MyTrait<'a> for &'a T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. From 12386da38aa46eff4c229fdbfb2496ce0a4c5b7e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 20 Aug 2022 22:07:04 -0700 Subject: [PATCH 06/13] bootstrap: Remove some unused fields from the tool_extended macro. --- src/bootstrap/tool.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 06fa5039fdf92..570da20e7d60d 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -778,12 +778,10 @@ impl Step for RustAnalyzerProcMacroSrv { macro_rules! tool_extended { (($sel:ident, $builder:ident), $($name:ident, - $toolstate:ident, $path:expr, $tool_name:expr, stable = $stable:expr, $(in_tree = $in_tree:expr,)? - $(submodule = $submodule:literal,)? $(tool_std = $tool_std:literal,)? $extra_deps:block;)+) => { $( @@ -828,7 +826,6 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option { $extra_deps - $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )? $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, @@ -854,12 +851,12 @@ macro_rules! tool_extended { // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to // invoke Cargo to build bootstrap. See the comment there for more details. tool_extended!((self, builder), - Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {}; - CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {}; - Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; - Miri, miri, "src/tools/miri", "miri", stable=false, {}; - CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {}; - Rls, rls, "src/tools/rls", "rls", stable=true, { + Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {}; + CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {}; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; + Miri, "src/tools/miri", "miri", stable=false, {}; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {}; + Rls, "src/tools/rls", "rls", stable=true, { builder.ensure(Clippy { compiler: self.compiler, target: self.target, @@ -870,8 +867,8 @@ tool_extended!((self, builder), // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. - RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; - Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; + RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; ); impl<'a> Builder<'a> { From 3b1b35bf03bafc9df9b854ac1bf83af671483aa3 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 20 Aug 2022 22:08:50 -0700 Subject: [PATCH 07/13] Remove rustfmt from publish_toolstate Rustfmt is no longer tracked in toolstate, so this isn't necessary. --- src/tools/publish_toolstate.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index fe5195738c10a..e609d7bf92fe2 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -32,7 +32,6 @@ MAINTAINERS = { 'miri': {'oli-obk', 'RalfJung'}, 'rls': {'Xanewok'}, - 'rustfmt': {'topecongiro', 'calebcartwright'}, 'book': {'carols10cents', 'steveklabnik'}, 'nomicon': {'frewsxcv', 'Gankra', 'JohnTitor'}, 'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'}, @@ -45,7 +44,6 @@ LABELS = { 'miri': ['A-miri', 'C-bug'], 'rls': ['A-rls', 'C-bug'], - 'rustfmt': ['A-rustfmt', 'C-bug'], 'book': ['C-bug'], 'nomicon': ['C-bug'], 'reference': ['C-bug'], @@ -58,7 +56,6 @@ REPOS = { 'miri': 'https://github.com/rust-lang/miri', 'rls': 'https://github.com/rust-lang/rls', - 'rustfmt': 'https://github.com/rust-lang/rustfmt', 'book': 'https://github.com/rust-lang/book', 'nomicon': 'https://github.com/rust-lang/nomicon', 'reference': 'https://github.com/rust-lang/reference', From 45e2fc3d4fd948441806f273bf34218fced0ad07 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 20 Aug 2022 22:11:27 -0700 Subject: [PATCH 08/13] Remove Steve from toolstate failure notices. They have not been involved in a while. --- src/tools/publish_toolstate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index e609d7bf92fe2..1c57b731aaa3f 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -32,12 +32,12 @@ MAINTAINERS = { 'miri': {'oli-obk', 'RalfJung'}, 'rls': {'Xanewok'}, - 'book': {'carols10cents', 'steveklabnik'}, + 'book': {'carols10cents'}, 'nomicon': {'frewsxcv', 'Gankra', 'JohnTitor'}, - 'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'}, - 'rust-by-example': {'steveklabnik', 'marioidival'}, + 'reference': {'Havvy', 'matthewjasper', 'ehuss'}, + 'rust-by-example': {'marioidival'}, 'embedded-book': {'adamgreig', 'andre-richter', 'jamesmunns', 'therealprof'}, - 'edition-guide': {'ehuss', 'steveklabnik'}, + 'edition-guide': {'ehuss'}, 'rustc-dev-guide': {'spastorino', 'amanjeev', 'JohnTitor'}, } From 757913df08f11e216b617a557959f5c28d2974ca Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 20 Aug 2022 22:24:31 -0700 Subject: [PATCH 09/13] bootstrap: Don't allow rustfmt to fail on dist. When running `x.py dist`, rustfmt was being allowed to fail when missing-tools is true. This isn't much of an issue in practice since other CI jobs will fail if rustfmt fails. This code was just leftovers from when rustfmt was tracked in toolstate, and this removes it to make it clear that it no longer works that way. --- src/bootstrap/dist.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6291b204e485f..6bf57a89e896f 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1226,17 +1226,10 @@ impl Step for Rustfmt { let rustfmt = builder .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() }) - .or_else(|| { - missing_tool("Rustfmt", builder.build.config.missing_tools); - None - })?; + .expect("rustfmt expected to build - essential tool"); let cargofmt = builder .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() }) - .or_else(|| { - missing_tool("Cargofmt", builder.build.config.missing_tools); - None - })?; - + .expect("cargo fmt expected to build - essential tool"); let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); tarball.set_overlay(OverlayKind::Rustfmt); tarball.is_preview(true); From d7ee421870f8937fe351b4143036c2730129757a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Aug 2022 20:00:38 -0400 Subject: [PATCH 10/13] fix ICE with extra-const-ub-checks --- .../src/const_eval/eval_queries.rs | 22 +++++++++++++++---- .../src/const_eval/machine.rs | 12 ++++++++-- .../src/might_permit_raw_init.rs | 6 ++++- .../ui/consts/extra-const-ub/issue-100771.rs | 20 +++++++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/consts/extra-const-ub/issue-100771.rs diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 936044fbe24b2..5cfa63bd105c4 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -81,7 +81,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( } /// The `InterpCx` is only meant to be used to do field and index projections into constants for -/// `simd_shuffle` and const patterns in match arms. +/// `simd_shuffle` and const patterns in match arms. It never performs alignment checks. /// /// The function containing the `match` that is currently being analyzed may have generic bounds /// that inform us about the generic bounds of the constant. E.g., using an associated constant @@ -98,7 +98,11 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>( tcx, root_span, param_env, - CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics), + CompileTimeInterpreter::new( + tcx.const_eval_limit(), + can_access_statics, + /*check_alignment:*/ false, + ), ) } @@ -203,7 +207,13 @@ pub(crate) fn turn_into_const_value<'tcx>( let cid = key.value; let def_id = cid.instance.def.def_id(); let is_static = tcx.is_static(def_id); - let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static); + // This is just accessing an already computed constant, so no need to check alginment here. + let ecx = mk_eval_cx( + tcx, + tcx.def_span(key.value.instance.def_id()), + key.param_env, + /*can_access_statics:*/ is_static, + ); let mplace = ecx.raw_const_to_mplace(constant).expect( "can only fail if layout computation failed, \ @@ -300,7 +310,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>( key.param_env, // Statics (and promoteds inside statics) may access other statics, because unlike consts // they do not have to behave "as if" they were evaluated at runtime. - CompileTimeInterpreter::new(tcx.const_eval_limit(), /*can_access_statics:*/ is_static), + CompileTimeInterpreter::new( + tcx.const_eval_limit(), + /*can_access_statics:*/ is_static, + /*check_alignment:*/ tcx.sess.opts.unstable_opts.extra_const_ub_checks, + ), ); let res = ecx.load_mir(cid.instance.def, cid.promoted); diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 684877cae7677..f24b19089c113 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -101,14 +101,22 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> { /// * Pointers to allocations inside of statics can never leak outside, to a non-static global. /// This boolean here controls the second part. pub(super) can_access_statics: bool, + + /// Whether to check alignment during evaluation. + check_alignment: bool, } impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { - pub(crate) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self { + pub(crate) fn new( + const_eval_limit: Limit, + can_access_statics: bool, + check_alignment: bool, + ) -> Self { CompileTimeInterpreter { steps_remaining: const_eval_limit.0, stack: Vec::new(), can_access_statics, + check_alignment, } } } @@ -238,7 +246,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, #[inline(always)] fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { - ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks + ecx.machine.check_alignment } #[inline(always)] diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs index f971c2238c7bb..37ffa19ccd6b9 100644 --- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs +++ b/compiler/rustc_const_eval/src/might_permit_raw_init.rs @@ -13,7 +13,11 @@ pub fn might_permit_raw_init<'tcx>( let strict = tcx.sess.opts.unstable_opts.strict_init_checks; if strict { - let machine = CompileTimeInterpreter::new(Limit::new(0), false); + let machine = CompileTimeInterpreter::new( + Limit::new(0), + /*can_access_statics:*/ false, + /*check_alignment:*/ true, + ); let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); diff --git a/src/test/ui/consts/extra-const-ub/issue-100771.rs b/src/test/ui/consts/extra-const-ub/issue-100771.rs new file mode 100644 index 0000000000000..a3296032841fd --- /dev/null +++ b/src/test/ui/consts/extra-const-ub/issue-100771.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: -Zextra-const-ub-checks + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(packed)] +struct Foo { + field: (i64, u32, u32, u32), +} + +const FOO: Foo = Foo { + field: (5, 6, 7, 8), +}; + +fn main() { + match FOO { + Foo { field: (5, 6, 7, 8) } => {}, + FOO => unreachable!(), + _ => unreachable!(), + } +} From add04f93defe876ff75c6957878dc3c57254a994 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 21 Aug 2022 17:11:51 -0700 Subject: [PATCH 11/13] tidy: remove crossbeam-utils --- Cargo.lock | 1 - src/tools/tidy/Cargo.toml | 1 - src/tools/tidy/src/main.rs | 7 +++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8c8466ffe9b5..cac946cb4e3c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5294,7 +5294,6 @@ name = "tidy" version = "0.1.0" dependencies = [ "cargo_metadata 0.14.0", - "crossbeam-utils", "lazy_static", "regex", "walkdir", diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 96ab42b4719a2..471d78a2922a0 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -9,7 +9,6 @@ cargo_metadata = "0.14" regex = "1" lazy_static = "1" walkdir = "2" -crossbeam-utils = "0.8.0" [[bin]] name = "rust-tidy" diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index aa8d8b4f64d7d..c1ce94f470559 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -6,7 +6,6 @@ use tidy::*; -use crossbeam_utils::thread::{scope, ScopedJoinHandle}; use std::collections::VecDeque; use std::env; use std::num::NonZeroUsize; @@ -14,6 +13,7 @@ use std::path::PathBuf; use std::process; use std::str::FromStr; use std::sync::atomic::{AtomicBool, Ordering}; +use std::thread::{scope, ScopedJoinHandle}; fn main() { let root_path: PathBuf = env::args_os().nth(1).expect("need path to root of repo").into(); @@ -44,7 +44,7 @@ fn main() { handles.pop_front().unwrap().join().unwrap(); } - let handle = s.spawn(|_| { + let handle = s.spawn(|| { let mut flag = false; $p::check($($args),* , &mut flag); if (flag) { @@ -102,8 +102,7 @@ fn main() { r }; check!(unstable_book, &src_path, collected); - }) - .unwrap(); + }); if bad.load(Ordering::Relaxed) { eprintln!("some tidy checks failed"); From b562f9596373881caa704e6046b2e168dd4a4eed Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 22 Aug 2022 11:25:56 -0700 Subject: [PATCH 12/13] Refactor part of codegen_call_terminator --- compiler/rustc_codegen_ssa/src/mir/block.rs | 91 ++++++++++----------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 3eee58d9d1c84..47a40be5d8c5b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -798,58 +798,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut op = self.codegen_operand(&mut bx, arg); if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { - if let Pair(..) = op.val { - // In the case of Rc, we need to explicitly pass a - // *mut RcBox with a Scalar (not ScalarPair) ABI. This is a hack - // that is understood elsewhere in the compiler as a method on - // `dyn Trait`. - // To get a `*mut RcBox`, we just keep unwrapping newtypes until - // we get a value of a built-in pointer type - 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() - && !op.layout.ty.is_region_ptr() - { - for i in 0..op.layout.fields.count() { - let field = op.extract_field(&mut bx, i); - if !field.layout.is_zst() { - // we found the one non-zero-sized field that is allowed - // now find *its* non-zero-sized field, or stop if it's a - // pointer - op = field; - continue 'descend_newtypes; + match op.val { + Pair(data_ptr, meta) => { + // In the case of Rc, we need to explicitly pass a + // *mut RcBox with a Scalar (not ScalarPair) ABI. This is a hack + // that is understood elsewhere in the compiler as a method on + // `dyn Trait`. + // To get a `*mut RcBox`, we just keep unwrapping newtypes until + // we get a value of a built-in pointer type + 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() + && !op.layout.ty.is_region_ptr() + { + for i in 0..op.layout.fields.count() { + let field = op.extract_field(&mut bx, i); + if !field.layout.is_zst() { + // we found the one non-zero-sized field that is allowed + // now find *its* non-zero-sized field, or stop if it's a + // pointer + op = field; + continue 'descend_newtypes; + } } + + span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); } - span_bug!(span, "receiver has no non-zero-sized fields {:?}", op); + // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its + // data pointer and vtable. Look up the method in the vtable, and pass + // the data pointer as the first argument + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); + llargs.push(data_ptr); + continue 'make_args; } - - // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its - // data pointer and vtable. Look up the method in the vtable, and pass - // the data pointer as the first argument - match op.val { - Pair(data_ptr, meta) => { - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( - &mut bx, - meta, - op.layout.ty, - &fn_abi, - )); - llargs.push(data_ptr); - continue 'make_args; - } - other => bug!("expected a Pair, got {:?}", other), + Ref(data_ptr, Some(meta), _) => { + // by-value dynamic dispatch + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( + &mut bx, + meta, + op.layout.ty, + &fn_abi, + )); + llargs.push(data_ptr); + continue; } - } else if let Ref(data_ptr, Some(meta), _) = op.val { - // by-value dynamic dispatch - llfn = Some(meth::VirtualIndex::from_index(idx).get_fn( - &mut bx, - meta, - op.layout.ty, - &fn_abi, - )); - llargs.push(data_ptr); - continue; - } else { - span_bug!(span, "can't codegen a virtual call on {:?}", op); + _ => span_bug!(span, "can't codegen a virtual call on {:?}", op), } } From 3d2b61c1af3442b24786e8152af75ae7cfdeae6a Mon Sep 17 00:00:00 2001 From: Thiago Trannin <51510921+thinety@users.noreply.github.com> Date: Mon, 22 Aug 2022 20:03:53 -0300 Subject: [PATCH 13/13] Remove out-of-context comment in `mem::MaybeUninit` documentation --- library/core/src/mem/maybe_uninit.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index b4ea536083392..997494c769ec7 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -130,11 +130,8 @@ use crate::slice; /// MaybeUninit::uninit().assume_init() /// }; /// -/// // Dropping a `MaybeUninit` does nothing. Thus using raw pointer -/// // assignment instead of `ptr::write` does not cause the old -/// // uninitialized value to be dropped. Also if there is a panic during -/// // this loop, we have a memory leak, but there is no memory safety -/// // issue. +/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop, +/// // we have a memory leak, but there is no memory safety issue. /// for elem in &mut data[..] { /// elem.write(vec![42]); /// }