diff --git a/Cargo.lock b/Cargo.lock index cb245ce0ff828..ebacd32db4fc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5295,7 +5295,6 @@ name = "tidy" version = "0.1.0" dependencies = [ "cargo_metadata 0.14.0", - "crossbeam-utils", "lazy_static", "regex", "walkdir", 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_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), } } 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/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 2c9f9a2c2c200..b8884dd32d621 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -927,10 +927,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/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), 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/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index ed653f0f9c82d..e8243d666b641 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -387,7 +387,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/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]); /// } 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); 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> { 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 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`. 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!(), + } +} 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 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 + diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index fe5195738c10a..1c57b731aaa3f 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -32,20 +32,18 @@ MAINTAINERS = { 'miri': {'oli-obk', 'RalfJung'}, 'rls': {'Xanewok'}, - 'rustfmt': {'topecongiro', 'calebcartwright'}, - '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'}, } 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', 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");