diff --git a/Cargo.lock b/Cargo.lock index 28bd57ef6735c..9a684a8138bda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,7 +183,16 @@ dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array", + "generic-array 0.12.3", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", ] [[package]] @@ -233,8 +242,11 @@ version = "0.1.0" dependencies = [ "anyhow", "flate2", + "hex 0.4.2", + "rayon", "serde", "serde_json", + "sha2", "tar", "toml", ] @@ -687,6 +699,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6" +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + [[package]] name = "crates-io" version = "0.31.1" @@ -884,7 +902,16 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array", + "generic-array 0.12.3", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", ] [[package]] @@ -1166,6 +1193,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getopts" version = "0.2.21" @@ -1623,9 +1660,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +checksum = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98" dependencies = [ "rustc-std-workspace-core", ] @@ -1726,15 +1763,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "log_settings" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" -dependencies = [ - "lazy_static", -] - [[package]] name = "lsp-codec" version = "0.1.2" @@ -1844,9 +1872,9 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8" dependencies = [ - "block-buffer", - "digest", - "opaque-debug", + "block-buffer 0.7.3", + "digest 0.8.1", + "opaque-debug 0.2.3", ] [[package]] @@ -2106,6 +2134,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "open" version = "1.4.0" @@ -3523,6 +3557,7 @@ dependencies = [ "rustc_target", "tracing", "tracing-subscriber", + "tracing-tree", "winapi 0.3.9", ] @@ -3810,7 +3845,6 @@ version = "0.0.0" dependencies = [ "either", "itertools 0.9.0", - "log_settings", "polonius-engine", "regex", "rustc_apfloat", @@ -4371,10 +4405,23 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ - "block-buffer", - "digest", + "block-buffer 0.7.3", + "digest 0.8.1", "fake-simd", - "opaque-debug", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpuid-bool", + "digest 0.9.0", + "opaque-debug 0.3.0", ] [[package]] @@ -5105,9 +5152,9 @@ dependencies = [ [[package]] name = "tracing-tree" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a3dc4774db3a6b2d66a4f8d8de670e874ec3ed55615860c994927419b32c5f" +checksum = "43aac8afb493b08e1e1904956f7407c1e671b9c83b26a17e1bd83d6a3520e350" dependencies = [ "ansi_term 0.12.1", "atty", diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index bc1d9e1818c2f..e028b2c2dc763 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -3,11 +3,17 @@ use libc::c_uint; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; +use rustc_span::symbol::sym; use crate::llvm::{self, False, True}; use crate::ModuleLlvm; -pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: AllocatorKind) { +pub(crate) unsafe fn codegen( + tcx: TyCtxt<'_>, + mods: &mut ModuleLlvm, + kind: AllocatorKind, + has_alloc_error_handler: bool, +) { let llcx = &*mods.llcx; let llmod = mods.llmod(); let usize = match &tcx.sess.target.target.target_pointer_width[..] { @@ -82,4 +88,41 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc } llvm::LLVMDisposeBuilder(llbuilder); } + + // rust alloc error handler + let args = [usize, usize]; // size, align + + let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False); + let name = format!("__rust_alloc_error_handler"); + let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty); + // -> ! DIFlagNoReturn + llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn); + + if tcx.sess.target.target.options.default_hidden_visibility { + llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); + } + if tcx.sess.must_emit_unwind_tables() { + attributes::emit_uwtable(llfn, true); + } + + let kind = if has_alloc_error_handler { AllocatorKind::Global } else { AllocatorKind::Default }; + let callee = kind.fn_name(sym::oom); + let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty); + // -> ! DIFlagNoReturn + llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, callee); + llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); + + let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); + + let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); + llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); + let args = args + .iter() + .enumerate() + .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) + .collect::>(); + let ret = llvm::LLVMRustBuildCall(llbuilder, callee, args.as_ptr(), args.len() as c_uint, None); + llvm::LLVMSetTailCall(ret, True); + llvm::LLVMBuildRetVoid(llbuilder); + llvm::LLVMDisposeBuilder(llbuilder); } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index f14493e604368..1237b39b300ff 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -95,8 +95,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend { tcx: TyCtxt<'tcx>, mods: &mut ModuleLlvm, kind: AllocatorKind, + has_alloc_error_handler: bool, ) { - unsafe { allocator::codegen(tcx, mods, kind) } + unsafe { allocator::codegen(tcx, mods, kind, has_alloc_error_handler) } } fn compile_codegen_unit( &self, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index d82fc2c9f63d9..8e6f8e193c0e2 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -538,8 +538,9 @@ pub fn codegen_crate( let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); let mut modules = backend.new_metadata(tcx, &llmod_id); - tcx.sess - .time("write_allocator_module", || backend.codegen_allocator(tcx, &mut modules, kind)); + tcx.sess.time("write_allocator_module", || { + backend.codegen_allocator(tcx, &mut modules, kind, tcx.lang_items().oom().is_some()) + }); Some(ModuleCodegen { name: llmod_id, module_llvm: modules, kind: ModuleKind::Allocator }) } else { diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 90520f77e3c04..48c07b0089420 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -109,6 +109,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se tcx: TyCtxt<'tcx>, mods: &mut Self::Module, kind: AllocatorKind, + has_alloc_error_handler: bool, ); /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index adfce1008e1ed..f610e88b7fce5 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib"] libc = "0.2" tracing = { version = "0.1.18" } tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } +tracing-tree = "0.1.6" rustc_middle = { path = "../rustc_middle" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 544efc124e117..3f50c68e3ebf5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1251,11 +1251,21 @@ pub fn init_env_logger(env: &str) { Ok(s) if s.is_empty() => return, Ok(_) => {} } - let builder = tracing_subscriber::FmtSubscriber::builder(); - - let builder = builder.with_env_filter(tracing_subscriber::EnvFilter::from_env(env)); - - builder.init() + let filter = tracing_subscriber::EnvFilter::from_env(env); + let layer = tracing_tree::HierarchicalLayer::default() + .with_indent_lines(true) + .with_ansi(true) + .with_targets(true) + .with_thread_ids(true) + .with_thread_names(true) + .with_wraparound(10) + .with_verbose_exit(true) + .with_verbose_entry(true) + .with_indent_amount(2); + + use tracing_subscriber::layer::SubscriberExt; + let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); } pub fn main() -> ! { diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 060efd270dd51..5cd0a56d52414 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -593,6 +593,9 @@ declare_features! ( /// Allows to use the `#[cmse_nonsecure_entry]` attribute. (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), + /// Allows rustc to inject a default alloc_error_handler + (active, default_alloc_error_handler, "1.48.0", Some(66741), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 33caedfc19826..49e80f9d8a531 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -53,6 +53,7 @@ mod non_ascii_idents; mod nonstandard_style; mod passes; mod redundant_semicolon; +mod traits; mod types; mod unused; @@ -75,6 +76,7 @@ use internal::*; use non_ascii_idents::*; use nonstandard_style::*; use redundant_semicolon::*; +use traits::*; use types::*; use unused::*; @@ -157,6 +159,7 @@ macro_rules! late_lint_passes { MissingDebugImplementations: MissingDebugImplementations::default(), ArrayIntoIter: ArrayIntoIter, ClashingExternDeclarations: ClashingExternDeclarations::new(), + DropTraitConstraints: DropTraitConstraints, ] ); }; diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs new file mode 100644 index 0000000000000..d4f79036e5a18 --- /dev/null +++ b/compiler/rustc_lint/src/traits.rs @@ -0,0 +1,79 @@ +use crate::LateContext; +use crate::LateLintPass; +use crate::LintContext; +use rustc_hir as hir; +use rustc_span::symbol::sym; + +declare_lint! { + /// The `drop_bounds` lint checks for generics with `std::ops::Drop` as + /// bounds. + /// + /// ### Example + /// + /// ```rust + /// fn foo() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// `Drop` bounds do not really accomplish anything. A type may have + /// compiler-generated drop glue without implementing the `Drop` trait + /// itself. The `Drop` trait also only has one method, `Drop::drop`, and + /// that function is by fiat not callable in user code. So there is really + /// no use case for using `Drop` in trait bounds. + /// + /// The most likely use case of a drop bound is to distinguish between + /// types that have destructors and types that don't. Combined with + /// specialization, a naive coder would write an implementation that + /// assumed a type could be trivially dropped, then write a specialization + /// for `T: Drop` that actually calls the destructor. Except that doing so + /// is not correct; String, for example, doesn't actually implement Drop, + /// but because String contains a Vec, assuming it can be trivially dropped + /// will leak memory. + pub DROP_BOUNDS, + Warn, + "bounds of the form `T: Drop` are useless" +} + +declare_lint_pass!( + /// Lint for bounds of the form `T: Drop`, which usually + /// indicate an attempt to emulate `std::mem::needs_drop`. + DropTraitConstraints => [DROP_BOUNDS] +); + +impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + use rustc_middle::ty::PredicateAtom::*; + + let def_id = cx.tcx.hir().local_def_id(item.hir_id); + let predicates = cx.tcx.explicit_predicates_of(def_id); + for &(predicate, span) in predicates.predicates { + let trait_predicate = match predicate.skip_binders() { + Trait(trait_predicate, _constness) => trait_predicate, + _ => continue, + }; + let def_id = trait_predicate.trait_ref.def_id; + if cx.tcx.lang_items().drop_trait() == Some(def_id) { + // Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern. + if trait_predicate.trait_ref.self_ty().is_impl_trait() { + continue; + } + cx.struct_span_lint(DROP_BOUNDS, span, |lint| { + let needs_drop = match cx.tcx.get_diagnostic_item(sym::needs_drop) { + Some(needs_drop) => needs_drop, + None => return, + }; + let msg = format!( + "bounds on `{}` are useless, consider instead \ + using `{}` to detect if a type has a destructor", + predicate, + cx.tcx.def_path_str(needs_drop) + ); + lint.build(&msg).emit() + }); + } + } + } +} diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index a6d22243d6df6..487668cfa1109 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -12,7 +12,6 @@ either = "1.5.0" rustc_graphviz = { path = "../rustc_graphviz" } itertools = "0.9" tracing = "0.1" -log_settings = "0.1.1" polonius-engine = "0.12.0" regex = "1" rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index f97096984fa9b..93da6e3d38a93 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -48,8 +48,41 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { FxHashMap<(Ty<'tcx>, Option>), Pointer>, } +// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread +// boundary and dropped in the other thread, it would exit the span in the other thread. +struct SpanGuard(tracing::Span, std::marker::PhantomData<*const u8>); + +impl SpanGuard { + /// By default a `SpanGuard` does nothing. + fn new() -> Self { + Self(tracing::Span::none(), std::marker::PhantomData) + } + + /// If a span is entered, we exit the previous span (if any, normally none) and enter the + /// new span. This is mainly so we don't have to use `Option` for the `tracing_span` field of + /// `Frame` by creating a dummy span to being with and then entering it once the frame has + /// been pushed. + fn enter(&mut self, span: tracing::Span) { + // This executes the destructor on the previous instance of `SpanGuard`, ensuring that + // we never enter or exit more spans than vice versa. Unless you `mem::leak`, then we + // can't protect the tracing stack, but that'll just lead to weird logging, no actual + // problems. + *self = Self(span, std::marker::PhantomData); + self.0.with_subscriber(|(id, dispatch)| { + dispatch.enter(id); + }); + } +} + +impl Drop for SpanGuard { + fn drop(&mut self) { + self.0.with_subscriber(|(id, dispatch)| { + dispatch.exit(id); + }); + } +} + /// A stack frame. -#[derive(Clone)] pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Function and callsite information @@ -80,6 +113,11 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { /// can either directly contain `Scalar` or refer to some part of an `Allocation`. pub locals: IndexVec>, + /// The span of the `tracing` crate is stored here. + /// When the guard is dropped, the span is exited. This gives us + /// a full stack trace on all tracing statements. + tracing_span: SpanGuard, + //////////////////////////////////////////////////////////////////////////////// // Current position within the function //////////////////////////////////////////////////////////////////////////////// @@ -184,6 +222,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { locals: self.locals, loc: self.loc, extra, + tracing_span: self.tracing_span, } } } @@ -637,11 +676,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return_place: Option>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { - if !self.stack().is_empty() { - info!("PAUSING({}) {}", self.frame_idx(), self.frame().instance); - } - ::log_settings::settings().indentation += 1; - // first push a stack frame so we have access to the local substs let pre_frame = Frame { body, @@ -652,6 +686,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // all methods actually know about the frame locals: IndexVec::new(), instance, + tracing_span: SpanGuard::new(), extra: (), }; let frame = M::init_frame_extra(self, pre_frame)?; @@ -696,7 +731,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().locals = locals; M::after_stack_push(self)?; self.frame_mut().loc = Ok(mir::Location::START); - info!("ENTERING({}) {}", self.frame_idx(), self.frame().instance); + + let span = info_span!("frame", "{}", instance); + self.frame_mut().tracing_span.enter(span); Ok(()) } @@ -747,10 +784,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// cause us to continue unwinding. pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { info!( - "LEAVING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding + "popping stack frame ({})", + if unwinding { "during unwinding" } else { "returning from function" } ); // Sanity check `unwinding`. @@ -766,7 +801,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub_format!("unwinding past the topmost frame of the stack"); } - ::log_settings::settings().indentation -= 1; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); @@ -823,15 +857,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - if !self.stack().is_empty() { - info!( - "CONTINUING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding - ); - } - Ok(()) } @@ -995,7 +1020,16 @@ where { fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) { // Exhaustive match on fields to make sure we forget no field. - let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self; + let Frame { + body, + instance, + return_to_block, + return_place, + locals, + loc, + extra, + tracing_span: _, + } = self; body.hash_stable(hcx, hasher); instance.hash_stable(hcx, hasher); return_to_block.hash_stable(hcx, hasher); diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 6bc2110bfb3e6..effb25b022452 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -64,7 +64,10 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) { if item == LangItem::PanicImpl { tcx.sess.err("`#[panic_handler]` function required, but not found"); } else if item == LangItem::Oom { - tcx.sess.err("`#[alloc_error_handler]` function required, but not found"); + if !tcx.features().default_alloc_error_handler { + tcx.sess.err("`#[alloc_error_handler]` function required, but not found."); + tcx.sess.note_without_error("Use `#![feature(default_alloc_error_handler)]` for a default error handler."); + } } else { tcx.sess.err(&format!("language item required, but not found: `{}`", name)); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e3ad31469b237..6309b00f5f514 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -415,6 +415,7 @@ symbols! { decl_macro, declare_lint_pass, decode, + default_alloc_error_handler, default_lib_allocator, default_type_parameter_fallback, default_type_params, diff --git a/compiler/rustc_target/src/spec/android_base.rs b/compiler/rustc_target/src/spec/android_base.rs index 0ea99af83a1ef..bb11ce8ef28c2 100644 --- a/compiler/rustc_target/src/spec/android_base.rs +++ b/compiler/rustc_target/src/spec/android_base.rs @@ -12,5 +12,6 @@ pub fn opts() -> TargetOptions { base.position_independent_executables = true; base.has_elf_tls = false; base.requires_uwtable = true; + base.crt_static_respected = false; base } diff --git a/compiler/rustc_target/src/spec/linux_base.rs b/compiler/rustc_target/src/spec/linux_base.rs index 52892fc35924e..7ad972b069210 100644 --- a/compiler/rustc_target/src/spec/linux_base.rs +++ b/compiler/rustc_target/src/spec/linux_base.rs @@ -28,6 +28,7 @@ pub fn opts() -> TargetOptions { position_independent_executables: true, relro_level: RelroLevel::Full, has_elf_tls: true, + crt_static_respected: true, ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/linux_musl_base.rs b/compiler/rustc_target/src/spec/linux_musl_base.rs index b90e91d2901a8..16cc3b762f623 100644 --- a/compiler/rustc_target/src/spec/linux_musl_base.rs +++ b/compiler/rustc_target/src/spec/linux_musl_base.rs @@ -10,8 +10,6 @@ pub fn opts() -> TargetOptions { // These targets statically link libc by default base.crt_static_default = true; - // These targets allow the user to choose between static and dynamic linking. - base.crt_static_respected = true; base } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 75158eefcac28..ce70de6ebdd63 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -26,6 +26,8 @@ extern "Rust" { fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; #[rustc_allocator_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; + #[rustc_allocator_nounwind] + fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } /// The global memory allocator. @@ -334,6 +336,24 @@ pub(crate) unsafe fn box_free(ptr: Unique) { /// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html /// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html #[stable(feature = "global_alloc", since = "1.28.0")] +#[cfg(not(any(test, bootstrap)))] +#[rustc_allocator_nounwind] +pub fn handle_alloc_error(layout: Layout) -> ! { + unsafe { + __rust_alloc_error_handler(layout.size(), layout.align()); + } +} + +// For alloc test `std::alloc::handle_alloc_error` can be used directly. +#[cfg(test)] +pub use std::alloc::handle_alloc_error; + +// In stage0 (bootstrap) `__rust_alloc_error_handler`, +// might not be generated yet, because an old compiler is used, +// so use the old direct call. +#[cfg(all(bootstrap, not(test)))] +#[stable(feature = "global_alloc", since = "1.28.0")] +#[doc(hidden)] #[rustc_allocator_nounwind] pub fn handle_alloc_error(layout: Layout) -> ! { extern "Rust" { @@ -342,3 +362,30 @@ pub fn handle_alloc_error(layout: Layout) -> ! { } unsafe { oom_impl(layout) } } + +#[cfg(not(any(test, bootstrap)))] +#[doc(hidden)] +#[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "none")] +pub mod __default_lib_allocator { + use crate::alloc::Layout; + + // called via generated `__rust_alloc_error_handler` + + // if there is no `#[alloc_error_handler]` + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rdl_oom(size: usize, _align: usize) -> ! { + panic!("memory allocation of {} bytes failed", size) + } + + // if there is a `#[alloc_error_handler]` + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rg_oom(size: usize, align: usize) -> ! { + let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; + extern "Rust" { + #[lang = "oom"] + fn oom_impl(layout: Layout) -> !; + } + unsafe { oom_impl(layout) } + } +} diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 5dbc42cc97d5b..939ebe074ed69 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1721,7 +1721,21 @@ impl Weak { pub fn new() -> Weak { Weak { ptr: NonNull::new(usize::MAX as *mut RcBox).expect("MAX is not 0") } } +} +pub(crate) fn is_dangling(ptr: NonNull) -> bool { + let address = ptr.as_ptr() as *mut () as usize; + address == usize::MAX +} + +/// Helper type to allow accessing the reference counts without +/// making any assertions about the data field. +struct WeakInner<'a> { + weak: &'a Cell, + strong: &'a Cell, +} + +impl Weak { /// Returns a raw pointer to the object `T` pointed to by this `Weak`. /// /// The pointer is valid only if there are some strong references. The pointer may be dangling, @@ -1841,33 +1855,20 @@ impl Weak { /// [`new`]: Weak::new #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { - if ptr.is_null() { - Self::new() - } else { - // See Rc::from_raw for details - unsafe { - let offset = data_offset(ptr); - let fake_ptr = ptr as *mut RcBox; - let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") } - } - } - } -} + // SAFETY: data_offset is safe to call, because this pointer originates from a Weak. + // See Weak::as_ptr for context on how the input pointer is derived. + let offset = unsafe { data_offset(ptr) }; -pub(crate) fn is_dangling(ptr: NonNull) -> bool { - let address = ptr.as_ptr() as *mut () as usize; - address == usize::MAX -} + // Reverse the offset to find the original RcBox. + // SAFETY: we use wrapping_offset here because the pointer may be dangling (but only if T: Sized). + let ptr = unsafe { + set_data_ptr(ptr as *mut RcBox, (ptr as *mut u8).wrapping_offset(-offset)) + }; -/// Helper type to allow accessing the reference counts without -/// making any assertions about the data field. -struct WeakInner<'a> { - weak: &'a Cell, - strong: &'a Cell, -} + // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. + Weak { ptr: unsafe { NonNull::new_unchecked(ptr) } } + } -impl Weak { /// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying /// dropping of the inner value if successful. /// diff --git a/library/alloc/src/rc/tests.rs b/library/alloc/src/rc/tests.rs index fed48a59f809e..bb5c3f4f90433 100644 --- a/library/alloc/src/rc/tests.rs +++ b/library/alloc/src/rc/tests.rs @@ -190,6 +190,48 @@ fn test_into_from_raw_unsized() { assert_eq!(rc2.to_string(), "123"); } +#[test] +fn into_from_weak_raw() { + let x = Rc::new(box "hello"); + let y = Rc::downgrade(&x); + + let y_ptr = Weak::into_raw(y); + unsafe { + assert_eq!(**y_ptr, "hello"); + + let y = Weak::from_raw(y_ptr); + let y_up = Weak::upgrade(&y).unwrap(); + assert_eq!(**y_up, "hello"); + drop(y_up); + + assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_weak_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let arc: Rc = Rc::from("foo"); + let weak: Weak = Rc::downgrade(&arc); + + let ptr = Weak::into_raw(weak.clone()); + let weak2 = unsafe { Weak::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert!(weak.ptr_eq(&weak2)); + + let arc: Rc = Rc::new(123); + let weak: Weak = Rc::downgrade(&arc); + + let ptr = Weak::into_raw(weak.clone()); + let weak2 = unsafe { Weak::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert!(weak.ptr_eq(&weak2)); +} + #[test] fn get_mut() { let mut x = Rc::new(3); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 3d7411c79dc4f..3a83aa7cbe5bd 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1509,7 +1509,16 @@ impl Weak { pub fn new() -> Weak { Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner).expect("MAX is not 0") } } +} + +/// Helper type to allow accessing the reference counts without +/// making any assertions about the data field. +struct WeakInner<'a> { + weak: &'a atomic::AtomicUsize, + strong: &'a atomic::AtomicUsize, +} +impl Weak { /// Returns a raw pointer to the object `T` pointed to by this `Weak`. /// /// The pointer is valid only if there are some strong references. The pointer may be dangling, @@ -1629,28 +1638,20 @@ impl Weak { /// [`forget`]: std::mem::forget #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { - if ptr.is_null() { - Self::new() - } else { - // See Arc::from_raw for details - unsafe { - let offset = data_offset(ptr); - let fake_ptr = ptr as *mut ArcInner; - let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") } - } - } - } -} + // SAFETY: data_offset is safe to call, because this pointer originates from a Weak. + // See Weak::as_ptr for context on how the input pointer is derived. + let offset = unsafe { data_offset(ptr) }; + + // Reverse the offset to find the original ArcInner. + // SAFETY: we use wrapping_offset here because the pointer may be dangling (but only if T: Sized) + let ptr = unsafe { + set_data_ptr(ptr as *mut ArcInner, (ptr as *mut u8).wrapping_offset(-offset)) + }; -/// Helper type to allow accessing the reference counts without -/// making any assertions about the data field. -struct WeakInner<'a> { - weak: &'a atomic::AtomicUsize, - strong: &'a atomic::AtomicUsize, -} + // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. + unsafe { Weak { ptr: NonNull::new_unchecked(ptr) } } + } -impl Weak { /// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying /// dropping of the inner value if successful. /// diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs index d25171716061d..77f328d48f94d 100644 --- a/library/alloc/src/sync/tests.rs +++ b/library/alloc/src/sync/tests.rs @@ -140,6 +140,48 @@ fn test_into_from_raw_unsized() { assert_eq!(arc2.to_string(), "123"); } +#[test] +fn into_from_weak_raw() { + let x = Arc::new(box "hello"); + let y = Arc::downgrade(&x); + + let y_ptr = Weak::into_raw(y); + unsafe { + assert_eq!(**y_ptr, "hello"); + + let y = Weak::from_raw(y_ptr); + let y_up = Weak::upgrade(&y).unwrap(); + assert_eq!(**y_up, "hello"); + drop(y_up); + + assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello")); + } +} + +#[test] +fn test_into_from_weak_raw_unsized() { + use std::fmt::Display; + use std::string::ToString; + + let arc: Arc = Arc::from("foo"); + let weak: Weak = Arc::downgrade(&arc); + + let ptr = Weak::into_raw(weak.clone()); + let weak2 = unsafe { Weak::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }, "foo"); + assert!(weak.ptr_eq(&weak2)); + + let arc: Arc = Arc::new(123); + let weak: Weak = Arc::downgrade(&arc); + + let ptr = Weak::into_raw(weak.clone()); + let weak2 = unsafe { Weak::from_raw(ptr) }; + + assert_eq!(unsafe { &*ptr }.to_string(), "123"); + assert!(weak.ptr_eq(&weak2)); +} + #[test] fn test_cowarc_clone_make_mut() { let mut cow0 = Arc::new(75); diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index aa1b5529df222..a2c7da6e6958e 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -568,6 +568,7 @@ pub unsafe fn align_of_val_raw(val: *const T) -> usize { #[inline] #[stable(feature = "needs_drop", since = "1.21.0")] #[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")] +#[rustc_diagnostic_item = "needs_drop"] pub const fn needs_drop() -> bool { intrinsics::needs_drop::() } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index b27b056086a64..33966409c8e04 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } -libc = { version = "0.2.77", default-features = false, features = ['rustc-dep-of-std'] } +libc = { version = "0.2.78", default-features = false, features = ['rustc-dep-of-std'] } compiler_builtins = { version = "0.1.35" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 8e2db217c3151..27e8afe00b1bd 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -14,7 +14,7 @@ doc = false [dependencies] core = { path = "../core" } -libc = { version = "0.2.51", features = ['rustc-dep-of-std'], default-features = false } +libc = { version = "0.2.78", features = ['rustc-dep-of-std'], default-features = false } compiler_builtins = "0.1.0" cfg-if = "0.1.8" diff --git a/library/unwind/build.rs b/library/unwind/build.rs index ab09a6e324d8b..24bcd40c3a8ee 100644 --- a/library/unwind/build.rs +++ b/library/unwind/build.rs @@ -12,11 +12,9 @@ fn main() { } else if target.contains("x86_64-fortanix-unknown-sgx") { llvm_libunwind::compile(); } else if target.contains("linux") { + // linking for Linux is handled in lib.rs if target.contains("musl") { - // linking for musl is handled in lib.rs llvm_libunwind::compile(); - } else if !target.contains("android") { - println!("cargo:rustc-link-lib=gcc_s"); } } else if target.contains("freebsd") { println!("cargo:rustc-link-lib=gcc_s"); diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 20a2ca984057e..e7fa37bc9db19 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -42,6 +42,13 @@ cfg_if::cfg_if! { #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern "C" {} +// When building with crt-static, we get `gcc_eh` from the `libc` crate, since +// glibc needs it, and needs it listed later on the linker command line. We +// don't want to duplicate it here. +#[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "llvm-libunwind")))] +#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] +extern "C" {} + #[cfg(target_os = "redox")] #[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4beeb9c87c4fd..3de5797180cf2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -477,7 +477,7 @@ impl<'a> Builder<'a> { install::Src, install::Rustc ), - Kind::Run => describe!(run::ExpandYamlAnchors,), + Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest,), } } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c846662fd5126..857e06d846de4 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -46,7 +46,7 @@ pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { } } -fn distdir(builder: &Builder<'_>) -> PathBuf { +pub(crate) fn distdir(builder: &Builder<'_>) -> PathBuf { builder.out.join("dist") } @@ -2371,6 +2371,7 @@ impl Step for HashSign { cmd.arg(addr); cmd.arg(&builder.config.channel); cmd.arg(&builder.src); + cmd.env("BUILD_MANIFEST_LEGACY", "1"); builder.create_dir(&distdir(builder)); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index ba593cadbad81..80c093e713eff 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -1,5 +1,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::dist::distdir; use crate::tool::Tool; +use build_helper::output; use std::process::Command; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -41,3 +43,43 @@ fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool { } true } + +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct BuildManifest; + +impl Step for BuildManifest { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/build-manifest") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(BuildManifest); + } + + fn run(self, builder: &Builder<'_>) { + // This gets called by `promote-release` + // (https://github.com/rust-lang/promote-release). + let mut cmd = builder.tool_cmd(Tool::BuildManifest); + let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| { + panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n") + }); + let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| { + panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") + }); + + let today = output(Command::new("date").arg("+%Y-%m-%d")); + + cmd.arg(sign); + cmd.arg(distdir(builder)); + cmd.arg(today.trim()); + cmd.arg(addr); + cmd.arg(&builder.config.channel); + cmd.arg(&builder.src); + + builder.create_dir(&distdir(builder)); + builder.run(&mut cmd); + } +} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index cf94ea384fd60..f234dc5c03b31 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1576,22 +1576,27 @@ fn resolution_failure( }; // See if this was a module: `[path]` or `[std::io::nope]` if let Some(module) = last_found_module { - let module_name = collector.cx.tcx.item_name(module); - let note = format!( - "the module `{}` contains no item named `{}`", - module_name, unresolved - ); + let note = if partial_res.is_some() { + // Part of the link resolved; e.g. `std::io::nonexistent` + let module_name = collector.cx.tcx.item_name(module); + format!("no item named `{}` in module `{}`", unresolved, module_name) + } else { + // None of the link resolved; e.g. `Notimported` + format!("no item named `{}` in scope", unresolved) + }; if let Some(span) = sp { diag.span_label(span, ¬e); } else { diag.note(¬e); } + // If the link has `::` in it, assume it was meant to be an intra-doc link. // Otherwise, the `[]` might be unrelated. // FIXME: don't show this for autolinks (`<>`), `()` style links, or reference links if !path_str.contains("::") { diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#); } + continue; } diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 33260fa0e1e66..9ec9dd4bc9ab7 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -2,7 +2,7 @@ error: unresolved link to `v2` --> $DIR/deny-intra-link-resolution-failure.rs:3:6 | LL | /// [v2] - | ^^ the module `deny_intra_link_resolution_failure` contains no item named `v2` + | ^^ no item named `v2` in scope | note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 0278caf308776..ef928ae02f3e3 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -6,23 +6,23 @@ /// [path::to::nonexistent::module] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE no item named `path` in scope /// [path::to::nonexistent::macro!] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE no item named `path` in scope /// [type@path::to::nonexistent::type] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE no item named `path` in scope /// [std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE no item named `not` in module `io` /// [type@std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE no item named `not` in module `io` /// [std::io::Error::x] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index b63f799535a1f..31e7fc48afde5 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -2,7 +2,7 @@ error: unresolved link to `path::to::nonexistent::module` --> $DIR/intra-link-errors.rs:7:6 | LL | /// [path::to::nonexistent::module] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope | note: the lint level is defined here --> $DIR/intra-link-errors.rs:1:9 @@ -14,25 +14,25 @@ error: unresolved link to `path::to::nonexistent::macro` --> $DIR/intra-link-errors.rs:11:6 | LL | /// [path::to::nonexistent::macro!] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope error: unresolved link to `path::to::nonexistent::type` --> $DIR/intra-link-errors.rs:15:6 | LL | /// [type@path::to::nonexistent::type] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:19:6 | LL | /// [std::io::not::here] - | ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:23:6 | LL | /// [type@std::io::not::here] - | ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` error: unresolved link to `std::io::Error::x` --> $DIR/intra-link-errors.rs:27:6 diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index d946aa939800c..d8afa9e7efd59 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -2,7 +2,7 @@ error: unresolved link to `i` --> $DIR/intra-link-span-ice-55723.rs:9:10 | LL | /// (arr[i]) - | ^ the module `intra_link_span_ice_55723` contains no item named `i` + | ^ no item named `i` in scope | note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 76a2ac0c8cf02..67c48378fd2f4 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -2,7 +2,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:7:6 | LL | /// [error] - | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` + | ^^^^^ no item named `error` in scope | = note: `#[warn(broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -11,7 +11,7 @@ warning: unresolved link to `error1` --> $DIR/intra-links-warning-crlf.rs:12:11 | LL | /// docs [error1] - | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error1` + | ^^^^^^ no item named `error1` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -19,7 +19,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning-crlf.rs:15:11 | LL | /// docs [error2] - | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error2` + | ^^^^^^ no item named `error2` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -27,7 +27,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:23:20 | LL | * It also has an [error]. - | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 09db465df59fb..4cdb8bbdde782 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -10,37 +10,37 @@ warning: unresolved link to `Bar::foo` --> $DIR/intra-links-warning.rs:3:35 | LL | //! Test with [Foo::baz], [Bar::foo], ... - | ^^^^^^^^ the module `intra_links_warning` contains no item named `Bar` + | ^^^^^^^^ no item named `Bar` in scope warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:6:13 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` + | ^^^^^^^^^^ no item named `Uniooon` in scope warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:6:30 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` + | ^^^^^^ no item named `Qux` in scope warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:10:14 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` + | ^^^^^^^^^^ no item named `Uniooon` in scope warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:10:31 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` + | ^^^^^^ no item named `Qux` in scope warning: unresolved link to `Qux:Y` --> $DIR/intra-links-warning.rs:14:13 | LL | /// [Qux:Y] - | ^^^^^ the module `intra_links_warning` contains no item named `Qux:Y` + | ^^^^^ no item named `Qux:Y` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -48,7 +48,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:58:30 | LL | * time to introduce a link [error]*/ - | ^^^^^ the module `intra_links_warning` contains no item named `error` + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -56,7 +56,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:64:30 | LL | * time to introduce a link [error] - | ^^^^^ the module `intra_links_warning` contains no item named `error` + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -70,7 +70,7 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -83,7 +83,7 @@ LL | #[doc = "single line with \"escaping\" [error]"] single line with "escaping" [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -98,14 +98,14 @@ LL | | /// [error] [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` --> $DIR/intra-links-warning.rs:80:11 | LL | /// docs [error1] - | ^^^^^^ the module `intra_links_warning` contains no item named `error1` + | ^^^^^^ no item named `error1` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -113,7 +113,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning.rs:82:11 | LL | /// docs [error2] - | ^^^^^^ the module `intra_links_warning` contains no item named `error2` + | ^^^^^^ no item named `error2` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -121,7 +121,7 @@ warning: unresolved link to `BarA` --> $DIR/intra-links-warning.rs:21:10 | LL | /// bar [BarA] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarA` + | ^^^^ no item named `BarA` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -129,7 +129,7 @@ warning: unresolved link to `BarB` --> $DIR/intra-links-warning.rs:27:9 | LL | * bar [BarB] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarB` + | ^^^^ no item named `BarB` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -137,7 +137,7 @@ warning: unresolved link to `BarC` --> $DIR/intra-links-warning.rs:34:6 | LL | bar [BarC] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarC` + | ^^^^ no item named `BarC` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -151,7 +151,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] bar [BarD] bar ^^^^ - = note: the module `intra_links_warning` contains no item named `BarD` + = note: no item named `BarD` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` @@ -167,7 +167,7 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ - = note: the module `intra_links_warning` contains no item named `BarF` + = note: no item named `BarF` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 4e9134ea469bd..32be90193fe90 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -32,7 +32,7 @@ error: unresolved link to `error` --> $DIR/lint-group.rs:9:29 | LL | /// what up, let's make an [error] - | ^^^^^ the module `lint_group` contains no item named `error` + | ^^^^^ no item named `error` in scope | note: the lint level is defined here --> $DIR/lint-group.rs:7:9 diff --git a/src/test/ui/allocator/auxiliary/helper.rs b/src/test/ui/allocator/auxiliary/helper.rs index 7f6770c226a0c..008fb3501d90d 100644 --- a/src/test/ui/allocator/auxiliary/helper.rs +++ b/src/test/ui/allocator/auxiliary/helper.rs @@ -1,8 +1,10 @@ // no-prefer-dynamic #![crate_type = "rlib"] +#![no_std] -use std::fmt; +extern crate alloc; +use alloc::fmt; pub fn work_with(p: &fmt::Debug) { drop(p); diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs new file mode 100644 index 0000000000000..f09fafbc98a18 --- /dev/null +++ b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs @@ -0,0 +1,97 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use core::ptr::null_mut; +use core::alloc::{GlobalAlloc, Layout}; +use alloc::boxed::Box; + +extern crate helper; + +struct MyAllocator; + +#[alloc_error_handler] +fn my_oom(layout: Layout) -> ! +{ + use alloc::fmt::write; + unsafe { + let size = layout.size(); + let mut s = alloc::string::String::new(); + write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); + let s = s.as_str(); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::exit(0) + } +} + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(1) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs new file mode 100644 index 0000000000000..4d68160379d9c --- /dev/null +++ b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs @@ -0,0 +1,84 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs +// gate-test-default_alloc_error_handler + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(default_alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use alloc::boxed::Box; +use core::alloc::{GlobalAlloc, Layout}; +use core::ptr::null_mut; + +extern crate helper; + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(0) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} diff --git a/src/test/ui/const-generics/issues/issue-75299.rs b/src/test/ui/const-generics/issues/issue-75299.rs new file mode 100644 index 0000000000000..23f30a1eea073 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-75299.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zmir-opt-level=3 +// run-pass + +#![feature(const_generics)] +#![allow(incomplete_features)] +fn main() { + fn foo() -> [u8; N] { + [0; N] + } + let _x = foo::<1>(); +} diff --git a/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs b/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs new file mode 100644 index 0000000000000..063efc7b31abd --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs @@ -0,0 +1,14 @@ +// run-pass +#![deny(drop_bounds)] +// As a special exemption, `impl Drop` in the return position raises no error. +// This allows a convenient way to return an unnamed drop guard. +fn voldemort_type() -> impl Drop { + struct Voldemort; + impl Drop for Voldemort { + fn drop(&mut self) {} + } + Voldemort +} +fn main() { + let _ = voldemort_type(); +} diff --git a/src/test/ui/drop-bounds/drop-bounds.rs b/src/test/ui/drop-bounds/drop-bounds.rs new file mode 100644 index 0000000000000..c73538278d3be --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds.rs @@ -0,0 +1,19 @@ +#![deny(drop_bounds)] +fn foo() {} //~ ERROR +fn bar() +where + U: Drop, //~ ERROR +{ +} +fn baz(_x: impl Drop) {} //~ ERROR +struct Foo { //~ ERROR + _x: T +} +struct Bar where U: Drop { //~ ERROR + _x: U +} +trait Baz: Drop { //~ ERROR +} +impl Baz for T { //~ ERROR +} +fn main() {} diff --git a/src/test/ui/drop-bounds/drop-bounds.stderr b/src/test/ui/drop-bounds/drop-bounds.stderr new file mode 100644 index 0000000000000..15ba4c9a64989 --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds.stderr @@ -0,0 +1,50 @@ +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:2:11 + | +LL | fn foo() {} + | ^^^^ + | +note: the lint level is defined here + --> $DIR/drop-bounds.rs:1:9 + | +LL | #![deny(drop_bounds)] + | ^^^^^^^^^^^ + +error: bounds on `U: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:5:8 + | +LL | U: Drop, + | ^^^^ + +error: bounds on `impl Drop: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:8:17 + | +LL | fn baz(_x: impl Drop) {} + | ^^^^ + +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:9:15 + | +LL | struct Foo { + | ^^^^ + +error: bounds on `U: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:12:24 + | +LL | struct Bar where U: Drop { + | ^^^^ + +error: bounds on `Self: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:15:12 + | +LL | trait Baz: Drop { + | ^^^^ + +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:17:9 + | +LL | impl Baz for T { + | ^^^^ + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/issues/issue-68951.rs b/src/test/ui/issues/issue-68951.rs new file mode 100644 index 0000000000000..1c1e92c5bbcbb --- /dev/null +++ b/src/test/ui/issues/issue-68951.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() { + let array = [0x42u8; 10]; + for b in &array { + let lo = b & 0xf; + let hi = (b >> 4) & 0xf; + } +} diff --git a/src/test/ui/mir/issue-77359-simplify-arm-identity-.rs b/src/test/ui/mir/issue-77359-simplify-arm-identity.rs similarity index 100% rename from src/test/ui/mir/issue-77359-simplify-arm-identity-.rs rename to src/test/ui/mir/issue-77359-simplify-arm-identity.rs diff --git a/src/test/ui/missing/missing-alloc_error_handler.stderr b/src/test/ui/missing/missing-alloc_error_handler.stderr index 5489b2cbbfad8..511d0788b40a7 100644 --- a/src/test/ui/missing/missing-alloc_error_handler.stderr +++ b/src/test/ui/missing/missing-alloc_error_handler.stderr @@ -1,4 +1,6 @@ -error: `#[alloc_error_handler]` function required, but not found +error: `#[alloc_error_handler]` function required, but not found. + +note: Use `#![feature(default_alloc_error_handler)]` for a default error handler. error: aborting due to previous error diff --git a/src/test/ui/pattern/issue-66501.rs b/src/test/ui/pattern/issue-66501.rs new file mode 100644 index 0000000000000..ffcfd4ad83e1f --- /dev/null +++ b/src/test/ui/pattern/issue-66501.rs @@ -0,0 +1,12 @@ +// check-pass + +#![allow(unreachable_patterns)] + +fn main() { + const CONST: &[Option<()>; 1] = &[Some(())]; + match &[Some(())] { + &[None] => {} + CONST => {} + &[Some(())] => {} + } +} diff --git a/src/test/ui/pattern/issue-72565.rs b/src/test/ui/pattern/issue-72565.rs new file mode 100644 index 0000000000000..1e262fd506765 --- /dev/null +++ b/src/test/ui/pattern/issue-72565.rs @@ -0,0 +1,8 @@ +const F: &'static dyn PartialEq = &7u32; + +fn main() { + let a: &dyn PartialEq = &7u32; + match a { + F => panic!(), //~ ERROR: `&dyn PartialEq` cannot be used in patterns + } +} diff --git a/src/test/ui/pattern/issue-72565.stderr b/src/test/ui/pattern/issue-72565.stderr new file mode 100644 index 0000000000000..2f82616b27764 --- /dev/null +++ b/src/test/ui/pattern/issue-72565.stderr @@ -0,0 +1,8 @@ +error: `&dyn PartialEq` cannot be used in patterns + --> $DIR/issue-72565.rs:6:9 + | +LL | F => panic!(), + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.rs b/src/test/ui/type-alias-impl-trait/issue-74244.rs new file mode 100644 index 0000000000000..bb4104b3d2519 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +trait Allocator { + type Buffer; +} + +struct DefaultAllocator; + +impl Allocator for DefaultAllocator { + //~^ ERROR: the type parameter `T` is not constrained + type Buffer = (); +} + +type A = impl Fn(::Buffer); + +fn foo() -> A { + |_| () +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.stderr b/src/test/ui/type-alias-impl-trait/issue-74244.stderr new file mode 100644 index 0000000000000..ff6bacd277e1e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74244.rs:9:6 + | +LL | impl Allocator for DefaultAllocator { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 4f89c31936dda..4ae4dbfc06ede 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -11,3 +11,6 @@ serde_json = "1.0" anyhow = "1.0.32" flate2 = "1.0.16" tar = "0.4.29" +sha2 = "0.9.1" +rayon = "1.3.1" +hex = "0.4.2" diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 4d7d9f7da1874..26e96c9fd8fda 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -20,8 +20,7 @@ Then, you can generate the manifest and all the packages from `path/to/dist` to `path/to/output` with: ``` -$ BUILD_MANIFEST_DISABLE_SIGNING=1 cargo +nightly run \ - path/to/dist path/to/output 1970-01-01 http://example.com \ +$ cargo +nightly run path/to/dist path/to/output 1970-01-01 http://example.com \ CHANNEL path/to/rust/repo ``` diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index e1dc9111bf326..c7e7d88c68fa8 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -4,17 +4,22 @@ //! via `x.py dist hash-and-sign`; the cmdline arguments are set up //! by rustbuild (in `src/bootstrap/dist.rs`). +mod manifest; mod versions; +use crate::manifest::{Component, FileHash, Manifest, Package, Rename, Target}; use crate::versions::{PkgType, Versions}; -use serde::Serialize; -use std::collections::BTreeMap; -use std::collections::HashMap; +use rayon::prelude::*; +use sha2::Digest; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::env; +use std::error::Error; use std::fs::{self, File}; -use std::io::{self, Read, Write}; +use std::io::{self, BufReader, Read, Write}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use std::sync::Mutex; +use std::time::Instant; static HOSTS: &[&str] = &[ "aarch64-unknown-linux-gnu", @@ -167,57 +172,6 @@ static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"]; static NIGHTLY_ONLY_COMPONENTS: &[&str] = &["miri-preview", "rust-analyzer-preview"]; -#[derive(Serialize)] -#[serde(rename_all = "kebab-case")] -struct Manifest { - manifest_version: String, - date: String, - pkg: BTreeMap, - renames: BTreeMap, - profiles: BTreeMap>, -} - -#[derive(Serialize)] -struct Package { - version: String, - git_commit_hash: Option, - target: BTreeMap, -} - -#[derive(Serialize)] -struct Rename { - to: String, -} - -#[derive(Serialize, Default)] -struct Target { - available: bool, - url: Option, - hash: Option, - xz_url: Option, - xz_hash: Option, - components: Option>, - extensions: Option>, -} - -impl Target { - fn unavailable() -> Self { - Self::default() - } -} - -#[derive(Serialize)] -struct Component { - pkg: String, - target: String, -} - -impl Component { - fn from_str(pkg: &str, target: &str) -> Self { - Self { pkg: pkg.to_string(), target: target.to_string() } - } -} - macro_rules! t { ($e:expr) => { match $e { @@ -232,25 +186,33 @@ struct Builder { input: PathBuf, output: PathBuf, - gpg_passphrase: String, - digests: BTreeMap, s3_address: String, date: String, - should_sign: bool, + legacy: bool, + legacy_gpg_passphrase: String, } fn main() { - // Avoid signing packages while manually testing - // Do NOT set this envvar in CI - let should_sign = env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err(); - - // Safety check to ensure signing is always enabled on CI - // The CI environment variable is set by both Travis and AppVeyor - if !should_sign && env::var("CI").is_ok() { - println!("The 'BUILD_MANIFEST_DISABLE_SIGNING' env var can't be enabled on CI."); - println!("If you're not running this on CI, unset the 'CI' env var."); - panic!(); + // Up until Rust 1.48 the release process relied on build-manifest to create the SHA256 + // checksums of released files and to sign the tarballs. That was moved over to promote-release + // in time for the branching of Rust 1.48, but the old release process still had to work the + // old way. + // + // When running build-manifest through the old ./x.py dist hash-and-sign the environment + // variable will be set, enabling the legacy behavior of generating the .sha256 files and + // signing the tarballs. + // + // Once the old release process is fully decommissioned, the environment variable, all the + // related code in this tool and ./x.py dist hash-and-sign can be removed. + let legacy = env::var("BUILD_MANIFEST_LEGACY").is_ok(); + + // Avoid overloading the old server in legacy mode. + if legacy { + rayon::ThreadPoolBuilder::new() + .num_threads(1) + .build_global() + .expect("failed to initialize Rayon"); } let mut args = env::args().skip(1); @@ -263,7 +225,7 @@ fn main() { // Do not ask for a passphrase while manually testing let mut passphrase = String::new(); - if should_sign { + if legacy { // `x.py` passes the passphrase via stdin. t!(io::stdin().read_to_string(&mut passphrase)); } @@ -273,12 +235,11 @@ fn main() { input, output, - gpg_passphrase: passphrase, - digests: BTreeMap::new(), s3_address, date, - should_sign, + legacy, + legacy_gpg_passphrase: passphrase, } .build(); } @@ -286,7 +247,9 @@ fn main() { impl Builder { fn build(&mut self) { self.check_toolstate(); - self.digest_and_sign(); + if self.legacy { + self.digest_and_sign(); + } let manifest = self.build_manifest(); let rust_version = self.versions.package_version(&PkgType::Rust).unwrap(); @@ -324,10 +287,9 @@ impl Builder { /// Hash all files, compute their signatures, and collect the hashes in `self.digests`. fn digest_and_sign(&mut self) { for file in t!(self.input.read_dir()).map(|e| t!(e).path()) { - let filename = file.file_name().unwrap().to_str().unwrap(); - let digest = self.hash(&file); + file.file_name().unwrap().to_str().unwrap(); + self.hash(&file); self.sign(&file); - assert!(self.digests.insert(filename.to_string(), digest).is_none()); } } @@ -343,6 +305,9 @@ impl Builder { self.add_profiles_to(&mut manifest); self.add_renames_to(&mut manifest); manifest.pkg.insert("rust".to_string(), self.rust_package(&manifest)); + + self.fill_missing_hashes(&mut manifest); + manifest } @@ -438,9 +403,12 @@ impl Builder { fn target_host_combination(&mut self, host: &str, manifest: &Manifest) -> Option { let filename = self.versions.tarball_name(&PkgType::Rust, host).unwrap(); - let digest = self.digests.remove(&filename)?; - let xz_filename = filename.replace(".tar.gz", ".tar.xz"); - let xz_digest = self.digests.remove(&xz_filename); + + let mut target = Target::from_compressed_tar(self, &filename); + if !target.available { + return None; + } + let mut components = Vec::new(); let mut extensions = Vec::new(); @@ -496,15 +464,9 @@ impl Builder { extensions.retain(&has_component); components.retain(&has_component); - Some(Target { - available: true, - url: Some(self.url(&filename)), - hash: Some(digest), - xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)), - xz_hash: xz_digest, - components: Some(components), - extensions: Some(extensions), - }) + target.components = Some(components); + target.extensions = Some(extensions); + Some(target) } fn profile( @@ -542,37 +504,19 @@ impl Builder { let targets = targets .iter() .map(|name| { - if is_present { - // The component generally exists, but it might still be missing for this target. + let target = if is_present { let filename = self .versions .tarball_name(&PkgType::from_component(pkgname), name) .unwrap(); - let digest = match self.digests.remove(&filename) { - Some(digest) => digest, - // This component does not exist for this target -- skip it. - None => return (name.to_string(), Target::unavailable()), - }; - let xz_filename = filename.replace(".tar.gz", ".tar.xz"); - let xz_digest = self.digests.remove(&xz_filename); - - ( - name.to_string(), - Target { - available: true, - url: Some(self.url(&filename)), - hash: Some(digest), - xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)), - xz_hash: xz_digest, - components: None, - extensions: None, - }, - ) + + Target::from_compressed_tar(self, &filename) } else { // If the component is not present for this build add it anyway but mark it as // unavailable -- this way rustup won't allow upgrades without --force - (name.to_string(), Target::unavailable()) - } + Target::unavailable() + }; + (name.to_string(), target) }) .collect(); @@ -586,8 +530,9 @@ impl Builder { ); } - fn url(&self, filename: &str) -> String { - format!("{}/{}/{}", self.s3_address, self.date, filename) + fn url(&self, path: &Path) -> String { + let file_name = path.file_name().unwrap().to_str().unwrap(); + format!("{}/{}/{}", self.s3_address, self.date, file_name) } fn hash(&self, path: &Path) -> String { @@ -608,7 +553,7 @@ impl Builder { } fn sign(&self, path: &Path) { - if !self.should_sign { + if !self.legacy { return; } @@ -631,10 +576,45 @@ impl Builder { .arg(path) .stdin(Stdio::piped()); let mut child = t!(cmd.spawn()); - t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes())); + t!(child.stdin.take().unwrap().write_all(self.legacy_gpg_passphrase.as_bytes())); assert!(t!(child.wait()).success()); } + fn fill_missing_hashes(&self, manifest: &mut Manifest) { + // First collect all files that need hashes + let mut need_hashes = HashSet::new(); + crate::manifest::visit_file_hashes(manifest, |file_hash| { + if let FileHash::Missing(path) = file_hash { + need_hashes.insert(path.clone()); + } + }); + + let collected = Mutex::new(HashMap::new()); + let collection_start = Instant::now(); + println!( + "collecting hashes for {} tarballs across {} threads", + need_hashes.len(), + rayon::current_num_threads().min(need_hashes.len()), + ); + need_hashes.par_iter().for_each(|path| match fetch_hash(path) { + Ok(hash) => { + collected.lock().unwrap().insert(path, hash); + } + Err(err) => eprintln!("error while fetching the hash for {}: {}", path.display(), err), + }); + let collected = collected.into_inner().unwrap(); + println!("collected {} hashes in {:.2?}", collected.len(), collection_start.elapsed()); + + crate::manifest::visit_file_hashes(manifest, |file_hash| { + if let FileHash::Missing(path) = file_hash { + match collected.get(path) { + Some(hash) => *file_hash = FileHash::Present(hash.clone()), + None => panic!("missing hash for file {}", path.display()), + } + } + }) + } + fn write_channel_files(&self, channel_name: &str, manifest: &Manifest) { self.write(&toml::to_string(&manifest).unwrap(), channel_name, ".toml"); self.write(&manifest.date, channel_name, "-date.txt"); @@ -648,7 +628,16 @@ impl Builder { fn write(&self, contents: &str, channel_name: &str, suffix: &str) { let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix)); t!(fs::write(&dst, contents)); - self.hash(&dst); - self.sign(&dst); + if self.legacy { + self.hash(&dst); + self.sign(&dst); + } } } + +fn fetch_hash(path: &Path) -> Result> { + let mut file = BufReader::new(File::open(path)?); + let mut sha256 = sha2::Sha256::default(); + std::io::copy(&mut file, &mut sha256)?; + Ok(hex::encode(sha256.finalize())) +} diff --git a/src/tools/build-manifest/src/manifest.rs b/src/tools/build-manifest/src/manifest.rs new file mode 100644 index 0000000000000..20e62abb54cfa --- /dev/null +++ b/src/tools/build-manifest/src/manifest.rs @@ -0,0 +1,114 @@ +use crate::Builder; +use serde::{Serialize, Serializer}; +use std::collections::BTreeMap; +use std::path::{Path, PathBuf}; + +#[derive(Serialize)] +#[serde(rename_all = "kebab-case")] +pub(crate) struct Manifest { + pub(crate) manifest_version: String, + pub(crate) date: String, + pub(crate) pkg: BTreeMap, + pub(crate) renames: BTreeMap, + pub(crate) profiles: BTreeMap>, +} + +#[derive(Serialize)] +pub(crate) struct Package { + pub(crate) version: String, + pub(crate) git_commit_hash: Option, + pub(crate) target: BTreeMap, +} + +#[derive(Serialize)] +pub(crate) struct Rename { + pub(crate) to: String, +} + +#[derive(Serialize, Default)] +pub(crate) struct Target { + pub(crate) available: bool, + pub(crate) url: Option, + pub(crate) hash: Option, + pub(crate) xz_url: Option, + pub(crate) xz_hash: Option, + pub(crate) components: Option>, + pub(crate) extensions: Option>, +} + +impl Target { + pub(crate) fn from_compressed_tar(builder: &Builder, base_path: &str) -> Self { + let base_path = builder.input.join(base_path); + let gz = Self::tarball_variant(&base_path, "gz"); + let xz = Self::tarball_variant(&base_path, "xz"); + + if gz.is_none() { + return Self::unavailable(); + } + + Self { + available: true, + components: None, + extensions: None, + // .gz + url: gz.as_ref().map(|path| builder.url(path)), + hash: gz.map(FileHash::Missing), + // .xz + xz_url: xz.as_ref().map(|path| builder.url(path)), + xz_hash: xz.map(FileHash::Missing), + } + } + + fn tarball_variant(base: &Path, ext: &str) -> Option { + let mut path = base.to_path_buf(); + path.set_extension(ext); + if path.is_file() { Some(path) } else { None } + } + + pub(crate) fn unavailable() -> Self { + Self::default() + } +} + +#[derive(Serialize)] +pub(crate) struct Component { + pub(crate) pkg: String, + pub(crate) target: String, +} + +impl Component { + pub(crate) fn from_str(pkg: &str, target: &str) -> Self { + Self { pkg: pkg.to_string(), target: target.to_string() } + } +} + +#[allow(unused)] +pub(crate) enum FileHash { + Missing(PathBuf), + Present(String), +} + +impl Serialize for FileHash { + fn serialize(&self, serializer: S) -> Result { + match self { + FileHash::Missing(path) => Err(serde::ser::Error::custom(format!( + "can't serialize a missing hash for file {}", + path.display() + ))), + FileHash::Present(inner) => inner.serialize(serializer), + } + } +} + +pub(crate) fn visit_file_hashes(manifest: &mut Manifest, mut f: impl FnMut(&mut FileHash)) { + for pkg in manifest.pkg.values_mut() { + for target in pkg.target.values_mut() { + if let Some(hash) = &mut target.hash { + f(hash); + } + if let Some(hash) = &mut target.xz_hash { + f(hash); + } + } + } +} diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index c17a0e8333058..c5884361dff9d 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -163,3 +163,12 @@ declare_deprecated_lint! { pub REGEX_MACRO, "the regex! macro has been removed from the regex crate in 2018" } + +declare_deprecated_lint! { + /// **What it does:** Nothing. This lint has been deprecated. + /// + /// **Deprecation reason:** This lint has been uplifted to rustc and is now called + /// `drop_bounds`. + pub DROP_BOUNDS, + "this lint has been uplifted to rustc and is now called `drop_bounds`" +} diff --git a/src/tools/clippy/clippy_lints/src/drop_bounds.rs b/src/tools/clippy/clippy_lints/src/drop_bounds.rs deleted file mode 100644 index ec3b6afa6300f..0000000000000 --- a/src/tools/clippy/clippy_lints/src/drop_bounds.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::utils::{match_def_path, paths, span_lint}; -use if_chain::if_chain; -use rustc_hir::{GenericBound, GenericParam, WhereBoundPredicate, WherePredicate}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; - -declare_clippy_lint! { - /// **What it does:** Checks for generics with `std::ops::Drop` as bounds. - /// - /// **Why is this bad?** `Drop` bounds do not really accomplish anything. - /// A type may have compiler-generated drop glue without implementing the - /// `Drop` trait itself. The `Drop` trait also only has one method, - /// `Drop::drop`, and that function is by fiat not callable in user code. - /// So there is really no use case for using `Drop` in trait bounds. - /// - /// The most likely use case of a drop bound is to distinguish between types - /// that have destructors and types that don't. Combined with specialization, - /// a naive coder would write an implementation that assumed a type could be - /// trivially dropped, then write a specialization for `T: Drop` that actually - /// calls the destructor. Except that doing so is not correct; String, for - /// example, doesn't actually implement Drop, but because String contains a - /// Vec, assuming it can be trivially dropped will leak memory. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// fn foo() {} - /// ``` - /// Could be written as: - /// ```rust - /// fn foo() {} - /// ``` - pub DROP_BOUNDS, - correctness, - "bounds of the form `T: Drop` are useless" -} - -const DROP_BOUNDS_SUMMARY: &str = "bounds of the form `T: Drop` are useless, \ - use `std::mem::needs_drop` to detect if a type has drop glue"; - -declare_lint_pass!(DropBounds => [DROP_BOUNDS]); - -impl<'tcx> LateLintPass<'tcx> for DropBounds { - fn check_generic_param(&mut self, cx: &LateContext<'tcx>, p: &'tcx GenericParam<'_>) { - for bound in p.bounds.iter() { - lint_bound(cx, bound); - } - } - fn check_where_predicate(&mut self, cx: &LateContext<'tcx>, p: &'tcx WherePredicate<'_>) { - if let WherePredicate::BoundPredicate(WhereBoundPredicate { bounds, .. }) = p { - for bound in *bounds { - lint_bound(cx, bound); - } - } - } -} - -fn lint_bound<'tcx>(cx: &LateContext<'tcx>, bound: &'tcx GenericBound<'_>) { - if_chain! { - if let GenericBound::Trait(t, _) = bound; - if let Some(def_id) = t.trait_ref.path.res.opt_def_id(); - if match_def_path(cx, def_id, &paths::DROP_TRAIT); - then { - span_lint( - cx, - DROP_BOUNDS, - t.span, - DROP_BOUNDS_SUMMARY - ); - } - } -} diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index c3ff34e6e1eed..70efdaeb9c669 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -179,7 +179,6 @@ mod derive; mod doc; mod double_comparison; mod double_parens; -mod drop_bounds; mod drop_forget_ref; mod duration_subsec; mod else_if_without_else; @@ -478,6 +477,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: "clippy::regex_macro", "the regex! macro has been removed from the regex crate in 2018", ); + store.register_removed( + "clippy::drop_bounds", + "this lint has been uplifted to rustc and is now called `drop_bounds`", + ); // end deprecated lints, do not remove this comment, it’s used in `update_lints` // begin register lints, do not remove this comment, it’s used in `update_lints` @@ -532,7 +535,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &doc::NEEDLESS_DOCTEST_MAIN, &double_comparison::DOUBLE_COMPARISONS, &double_parens::DOUBLE_PARENS, - &drop_bounds::DROP_BOUNDS, &drop_forget_ref::DROP_COPY, &drop_forget_ref::DROP_REF, &drop_forget_ref::FORGET_COPY, @@ -959,7 +961,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box strings::StringLitAsBytes); store.register_late_pass(|| box derive::Derive); store.register_late_pass(|| box types::CharLitAsU8); - store.register_late_pass(|| box drop_bounds::DropBounds); store.register_late_pass(|| box get_last_with_len::GetLastWithLen); store.register_late_pass(|| box drop_forget_ref::DropForgetRef); store.register_late_pass(|| box empty_enum::EmptyEnum); @@ -1282,7 +1283,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&doc::NEEDLESS_DOCTEST_MAIN), LintId::of(&double_comparison::DOUBLE_COMPARISONS), LintId::of(&double_parens::DOUBLE_PARENS), - LintId::of(&drop_bounds::DROP_BOUNDS), LintId::of(&drop_forget_ref::DROP_COPY), LintId::of(&drop_forget_ref::DROP_REF), LintId::of(&drop_forget_ref::FORGET_COPY), @@ -1714,7 +1714,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&copies::IF_SAME_THEN_ELSE), LintId::of(&derive::DERIVE_HASH_XOR_EQ), LintId::of(&derive::DERIVE_ORD_XOR_PARTIAL_ORD), - LintId::of(&drop_bounds::DROP_BOUNDS), LintId::of(&drop_forget_ref::DROP_COPY), LintId::of(&drop_forget_ref::DROP_REF), LintId::of(&drop_forget_ref::FORGET_COPY), diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs index 1583afad208ab..be837a61dc07e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs @@ -31,7 +31,6 @@ pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"]; pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"]; pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"]; pub const DROP: [&str; 3] = ["core", "mem", "drop"]; -pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"]; pub const DURATION: [&str; 3] = ["core", "time", "Duration"]; pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"]; pub const EXIT: [&str; 3] = ["std", "process", "exit"]; diff --git a/src/tools/clippy/src/lintlist/mod.rs b/src/tools/clippy/src/lintlist/mod.rs index 9603023ed0671..f6d529de9a3a2 100644 --- a/src/tools/clippy/src/lintlist/mod.rs +++ b/src/tools/clippy/src/lintlist/mod.rs @@ -423,13 +423,6 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "double_parens", }, - Lint { - name: "drop_bounds", - group: "correctness", - desc: "bounds of the form `T: Drop` are useless", - deprecation: None, - module: "drop_bounds", - }, Lint { name: "drop_copy", group: "correctness", diff --git a/src/tools/clippy/tests/ui/deprecated.rs b/src/tools/clippy/tests/ui/deprecated.rs index 3eefb232780f1..9e32fe36ece4d 100644 --- a/src/tools/clippy/tests/ui/deprecated.rs +++ b/src/tools/clippy/tests/ui/deprecated.rs @@ -8,5 +8,6 @@ #[warn(clippy::into_iter_on_array)] #[warn(clippy::unused_label)] #[warn(clippy::regex_macro)] +#[warn(clippy::drop_bounds)] fn main() {} diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr index a80e2bf31feb6..d3400a7be09fd 100644 --- a/src/tools/clippy/tests/ui/deprecated.stderr +++ b/src/tools/clippy/tests/ui/deprecated.stderr @@ -60,11 +60,17 @@ error: lint `clippy::regex_macro` has been removed: `the regex! macro has been r LL | #[warn(clippy::regex_macro)] | ^^^^^^^^^^^^^^^^^^^ +error: lint `clippy::drop_bounds` has been removed: `this lint has been uplifted to rustc and is now called `drop_bounds`` + --> $DIR/deprecated.rs:11:8 + | +LL | #[warn(clippy::drop_bounds)] + | ^^^^^^^^^^^^^^^^^^^ + error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:1:8 | LL | #[warn(clippy::str_to_string)] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/drop_bounds.rs b/src/tools/clippy/tests/ui/drop_bounds.rs deleted file mode 100644 index 6d6a9dc078399..0000000000000 --- a/src/tools/clippy/tests/ui/drop_bounds.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow(unused)] -fn foo() {} -fn bar() -where - T: Drop, -{ -} -fn main() {} diff --git a/src/tools/clippy/tests/ui/drop_bounds.stderr b/src/tools/clippy/tests/ui/drop_bounds.stderr deleted file mode 100644 index 8208c0ed7e398..0000000000000 --- a/src/tools/clippy/tests/ui/drop_bounds.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: bounds of the form `T: Drop` are useless, use `std::mem::needs_drop` to detect if a type has drop glue - --> $DIR/drop_bounds.rs:2:11 - | -LL | fn foo() {} - | ^^^^ - | - = note: `#[deny(clippy::drop_bounds)]` on by default - -error: bounds of the form `T: Drop` are useless, use `std::mem::needs_drop` to detect if a type has drop glue - --> $DIR/drop_bounds.rs:5:8 - | -LL | T: Drop, - | ^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 356705305d78b..0c52fee68a968 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -116,7 +116,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "libz-sys", "lock_api", "log", - "log_settings", "maybe-uninit", "md-5", "measureme",