diff options
51 files changed, 742 insertions, 143 deletions
diff --git a/RELEASES.md b/RELEASES.md index 722f7e5dd08..242b1c2eefd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -65,16 +65,16 @@ Rustdoc Stabilized APIs --------------- -- [`impl<T: Send> Sync for mpsc::Sender<T>`](https://doc.rust-lang.org/nightly/std/sync/mpsc/struct.Sender.html#impl-Sync-for-Sender%3CT%3E) -- [`impl TryFrom<&OsStr> for &str`](https://doc.rust-lang.org/nightly/std/primitive.str.html#impl-TryFrom%3C%26'a+OsStr%3E-for-%26'a+str) -- [`String::leak`](https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.leak) +- [`impl<T: Send> Sync for mpsc::Sender<T>`](https://doc.rust-lang.org/stable/std/sync/mpsc/struct.Sender.html#impl-Sync-for-Sender%3CT%3E) +- [`impl TryFrom<&OsStr> for &str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-TryFrom%3C%26'a+OsStr%3E-for-%26'a+str) +- [`String::leak`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.leak) These APIs are now stable in const contexts: -- [`CStr::from_bytes_with_nul`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul) -- [`CStr::to_bytes`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul) -- [`CStr::to_bytes_with_nul`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul) -- [`CStr::to_str`](https://doc.rust-lang.org/nightly/std/ffi/struct.CStr.html#method.from_bytes_with_nul) +- [`CStr::from_bytes_with_nul`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.from_bytes_with_nul) +- [`CStr::to_bytes`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_bytes) +- [`CStr::to_bytes_with_nul`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_bytes_with_nul) +- [`CStr::to_str`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#method.to_str) <a id="1.72.0-Cargo"></a> diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index a81585d4128..d1bfd833cd8 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -55,7 +55,7 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _llfn: RValue<'gcc>, _mir: &mir::Body<'tcx>, - ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>> { + ) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>> { // TODO(antoyo) None } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index d174a3593b9..7a68c291aa5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -20,7 +20,7 @@ pub fn compute_mir_scopes<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>, mir: &Body<'tcx>, - debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>, + debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>, ) { // Find all scopes with variables defined in them. let variables = if cx.sess().opts.debuginfo == DebugInfo::Full { @@ -51,7 +51,7 @@ fn make_mir_scope<'ll, 'tcx>( instance: Instance<'tcx>, mir: &Body<'tcx>, variables: &Option<BitSet<SourceScope>>, - debug_context: &mut FunctionDebugContext<&'ll DIScope, &'ll DILocation>, + debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>, instantiated: &mut BitSet<SourceScope>, scope: SourceScope, ) { @@ -84,7 +84,6 @@ fn make_mir_scope<'ll, 'tcx>( } let loc = cx.lookup_debug_loc(scope_data.span.lo()); - let file_metadata = file_metadata(cx, &loc.file); let dbg_scope = match scope_data.inlined { Some((callee, _)) => { @@ -95,18 +94,26 @@ fn make_mir_scope<'ll, 'tcx>( ty::ParamEnv::reveal_all(), ty::EarlyBinder::bind(callee), ); - let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty()); - cx.dbg_scope_fn(callee, callee_fn_abi, None) + debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| { + let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty()); + cx.dbg_scope_fn(callee, callee_fn_abi, None) + }) + } + None => { + let file_metadata = file_metadata(cx, &loc.file); + debug_context + .lexical_blocks + .entry((parent_scope.dbg_scope, loc.line, loc.col, file_metadata)) + .or_insert_with(|| unsafe { + llvm::LLVMRustDIBuilderCreateLexicalBlock( + DIB(cx), + parent_scope.dbg_scope, + file_metadata, + loc.line, + loc.col, + ) + }) } - None => unsafe { - llvm::LLVMRustDIBuilderCreateLexicalBlock( - DIB(cx), - parent_scope.dbg_scope, - file_metadata, - loc.line, - loc.col, - ) - }, }; let inlined_at = scope_data.inlined.map(|(_, callsite_span)| { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 40714a0afe9..9cdeae2841b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; use self::metadata::{file_metadata, type_di_node}; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER}; use self::namespace::mangled_name_of_instance; -use self::utils::{create_DIArray, is_node_local_to_unit, DIB}; +use self::utils::{create_DIArray, debug_context, is_node_local_to_unit, DIB}; use crate::abi::FnAbi; use crate::builder::Builder; @@ -67,6 +67,8 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> { type_map: metadata::TypeMap<'ll, 'tcx>, namespace_map: RefCell<DefIdMap<&'ll DIScope>>, recursion_marker_type: OnceCell<&'ll DIType>, + /// Maps a variable (name, scope, kind (argument or local), span) to its debug information. + variables: RefCell<FxHashMap<(Symbol, &'ll DIScope, VariableKind, Span), &'ll DIVariable>>, } impl Drop for CodegenUnitDebugContext<'_, '_> { @@ -91,6 +93,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { type_map: Default::default(), namespace_map: RefCell::new(Default::default()), recursion_marker_type: OnceCell::new(), + variables: RefCell::new(Default::default()), } } @@ -292,7 +295,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: &'ll Value, mir: &mir::Body<'tcx>, - ) -> Option<FunctionDebugContext<&'ll DIScope, &'ll DILocation>> { + ) -> Option<FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>> { if self.sess().opts.debuginfo == DebugInfo::None { return None; } @@ -304,8 +307,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { file_start_pos: BytePos(0), file_end_pos: BytePos(0), }; - let mut fn_debug_context = - FunctionDebugContext { scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes) }; + let mut fn_debug_context = FunctionDebugContext { + scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes), + inlined_function_scopes: Default::default(), + lexical_blocks: Default::default(), + }; // Fill in all the scopes, with the information from the MIR body. compute_mir_scopes(self, instance, mir, &mut fn_debug_context); @@ -606,33 +612,39 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { variable_kind: VariableKind, span: Span, ) -> &'ll DIVariable { - let loc = self.lookup_debug_loc(span.lo()); - let file_metadata = file_metadata(self, &loc.file); - - let type_metadata = type_di_node(self, variable_type); - - let (argument_index, dwarf_tag) = match variable_kind { - ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable => (0, DW_TAG_auto_variable), - }; - let align = self.align_of(variable_type); - - let name = variable_name.as_str(); - unsafe { - llvm::LLVMRustDIBuilderCreateVariable( - DIB(self), - dwarf_tag, - scope_metadata, - name.as_ptr().cast(), - name.len(), - file_metadata, - loc.line, - type_metadata, - true, - DIFlags::FlagZero, - argument_index, - align.bytes() as u32, - ) - } + debug_context(self) + .variables + .borrow_mut() + .entry((variable_name, scope_metadata, variable_kind, span)) + .or_insert_with(|| { + let loc = self.lookup_debug_loc(span.lo()); + let file_metadata = file_metadata(self, &loc.file); + + let type_metadata = type_di_node(self, variable_type); + + let (argument_index, dwarf_tag) = match variable_kind { + ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), + LocalVariable => (0, DW_TAG_auto_variable), + }; + let align = self.align_of(variable_type); + + let name = variable_name.as_str(); + unsafe { + llvm::LLVMRustDIBuilderCreateVariable( + DIB(self), + dwarf_tag, + scope_metadata, + name.as_ptr().cast(), + name.len(), + file_metadata, + loc.line, + type_metadata, + true, + DIFlags::FlagZero, + argument_index, + align.bytes() as u32, + ) + } + }) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 564b5da32cc..7df830692d3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -1,10 +1,12 @@ use crate::traits::*; +use rustc_data_structures::fx::FxHashMap; use rustc_index::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::Instance; use rustc_middle::ty::Ty; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; @@ -17,11 +19,19 @@ use super::{FunctionCx, LocalRef}; use std::ops::Range; -pub struct FunctionDebugContext<S, L> { +pub struct FunctionDebugContext<'tcx, S, L> { + /// Maps from source code to the corresponding debug info scope. pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>, + + /// Maps from a given inlined function to its debug info declaration. + pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>, + + /// Maps from a lexical block (parent scope, line, column, file) to its debug info declaration. + /// This is particularily useful if the parent scope is an inlined function. + pub lexical_blocks: FxHashMap<(S, u32, u32, S), S>, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] pub enum VariableKind { ArgumentVariable(usize /*index*/), LocalVariable, diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 3464f910829..ccf93f208d5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -45,7 +45,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { mir: &'tcx mir::Body<'tcx>, - debug_context: Option<FunctionDebugContext<Bx::DIScope, Bx::DILocation>>, + debug_context: Option<FunctionDebugContext<'tcx, Bx::DIScope, Bx::DILocation>>, llfn: Bx::Function, diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index 63fecaf34fd..4acc0ea076c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -26,7 +26,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Function, mir: &mir::Body<'tcx>, - ) -> Option<FunctionDebugContext<Self::DIScope, Self::DILocation>>; + ) -> Option<FunctionDebugContext<'tcx, Self::DIScope, Self::DILocation>>; // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 945953edd5a..cd7e9917204 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -44,20 +44,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { false } - fn check_asm_operand_type( - &self, - idx: usize, - reg: InlineAsmRegOrRegClass, - expr: &'tcx hir::Expr<'tcx>, - template: &[InlineAsmTemplatePiece], - is_input: bool, - tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>, - target_features: &FxIndexSet<Symbol>, - ) -> Option<InlineAsmType> { - let ty = (self.get_operand_ty)(expr); - if ty.has_non_region_infer() { - bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); - } + fn get_asm_ty(&self, ty: Ty<'tcx>) -> Option<InlineAsmType> { let asm_ty_isize = match self.tcx.sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, @@ -65,10 +52,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { _ => unreachable!(), }; - let asm_ty = match *ty.kind() { - // `!` is allowed for input but not for output (issue #87802) - ty::Never if is_input => return None, - _ if ty.references_error() => return None, + match *ty.kind() { ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16), ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32), @@ -99,7 +83,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { }; match ty.kind() { - ty::Never | ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => { Some(InlineAsmType::VecI16(size)) @@ -128,6 +111,38 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } ty::Infer(_) => unreachable!(), _ => None, + } + } + + fn check_asm_operand_type( + &self, + idx: usize, + reg: InlineAsmRegOrRegClass, + expr: &'tcx hir::Expr<'tcx>, + template: &[InlineAsmTemplatePiece], + is_input: bool, + tied_input: Option<(&'tcx hir::Expr<'tcx>, Option<InlineAsmType>)>, + target_features: &FxIndexSet<Symbol>, + ) -> Option<InlineAsmType> { + let ty = (self.get_operand_ty)(expr); + if ty.has_non_region_infer() { + bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); + } + + let asm_ty = match *ty.kind() { + // `!` is allowed for input but not for output (issue #87802) + ty::Never if is_input => return None, + _ if ty.references_error() => return None, + ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => { + let fields = &adt.non_enum_variant().fields; + let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); + let ty::Adt(ty, args) = ty.kind() else { unreachable!() }; + assert!(ty.is_manually_drop()); + let fields = &ty.non_enum_variant().fields; + let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args); + self.get_asm_ty(ty) + } + _ => self.get_asm_ty(ty), }; let Some(asm_ty) = asm_ty else { let msg = format!("cannot use value of type `{ty}` for inline assembly"); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index c4a7f717840..d7cb159149d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -323,6 +323,8 @@ lint_invalid_reference_casting_assign_to_ref = assigning to `&T` is undefined be lint_invalid_reference_casting_borrow_as_mut = casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` .label = casting happend here +lint_invalid_reference_casting_note_book = for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 25982a45853..993c576d697 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -764,11 +764,13 @@ pub enum InvalidFromUtf8Diag { #[derive(LintDiagnostic)] pub enum InvalidReferenceCastingDiag { #[diag(lint_invalid_reference_casting_borrow_as_mut)] + #[note(lint_invalid_reference_casting_note_book)] BorrowAsMut { #[label] orig_cast: Option<Span>, }, #[diag(lint_invalid_reference_casting_assign_to_ref)] + #[note(lint_invalid_reference_casting_note_book)] AssignToRef { #[label] orig_cast: Option<Span>, diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 2577cabb3f0..883f6242b56 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -56,20 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - // &mut <expr> - let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind { - expr - // <expr> = ... - } else if let ExprKind::Assign(expr, _, _) = expr.kind { - expr - // <expr> += ... - } else if let ExprKind::AssignOp(_, expr, _) = expr.kind { - expr - } else { - return; - }; - - let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else { + let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else { return; }; @@ -86,15 +73,58 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { cx.emit_spanned_lint( INVALID_REFERENCE_CASTING, expr.span, - if matches!(expr.kind, ExprKind::AddrOf(..)) { - InvalidReferenceCastingDiag::BorrowAsMut { orig_cast } - } else { + if is_assignment { InvalidReferenceCastingDiag::AssignToRef { orig_cast } + } else { + InvalidReferenceCastingDiag::BorrowAsMut { orig_cast } }, ); } } +fn is_operation_we_care_about<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'tcx>, +) -> Option<(bool, &'tcx Expr<'tcx>)> { + fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> { + // &mut <expr> + let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind { + expr + // <expr> = ... + } else if let ExprKind::Assign(expr, _, _) = expr.kind { + expr + // <expr> += ... + } else if let ExprKind::AssignOp(_, expr, _) = expr.kind { + expr + } else { + return None; + }; + + if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind { + Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e)) + } else { + None + } + } + + fn ptr_write<'tcx>( + cx: &LateContext<'tcx>, + e: &'tcx Expr<'tcx>, + ) -> Option<(bool, &'tcx Expr<'tcx>)> { + if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned)) + { + Some((true, arg_ptr)) + } else { + None + } + } + + deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e)) +} + fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool { let e = e.peel_blocks(); diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp index 35d6b9ed7a4..54fdc84c77d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp @@ -203,7 +203,12 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, } } +#if LLVM_VERSION_LT(18, 0) auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false); +#else + auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab; + auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false); +#endif if (!Result) return LLVMRustResult::Success; LLVMRustSetLastError(toString(std::move(Result)).c_str()); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 046eed2dd19..079cf9eb4e9 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -99,7 +99,11 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); - pm::run_passes( + // We don't validate MIR here because the shims may generate code that's + // only valid in a reveal-all param-env. However, since we do initial + // validation with the MirBuilt phase, which uses a user-facing param-env. + // This causes validation errors when TAITs are involved. + pm::run_passes_no_validate( tcx, &mut result, &[ diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index f9d34ea71ba..e62833b358b 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -98,15 +98,11 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { self.worklist.push(def_id); } else { match res { - // If this path leads to a constant, then we need to - // recurse into the constant to continue finding - // items that are reachable. - Res::Def(DefKind::Const | DefKind::AssocConst, _) => { + // Reachable constants and reachable statics can have their contents inlined + // into other crates. Mark them as reachable and recurse into their body. + Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => { self.worklist.push(def_id); } - - // If this wasn't a static, then the destination is - // surely reachable. _ => { self.reachable_symbols.insert(def_id); } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 078ff67446f..ebacb7cce83 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -80,6 +80,10 @@ impl<'tcx> Tables<'tcx> { self.def_ids[impl_def.0] } + pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId { + self.def_ids[generic_def.0] + } + pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { stable_mir::CrateItem(self.create_def_id(did)) } @@ -120,6 +124,10 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::TraitDef(self.create_def_id(did)) } + pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef { + stable_mir::ty::GenericDef(self.create_def_id(did)) + } + pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef { stable_mir::ty::ConstDef(self.create_def_id(did)) } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 7e8ac9a141a..aea59c31379 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -10,7 +10,8 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; use crate::stable_mir::ty::{ - allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy, + allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy, + Movability, RigidTy, TyKind, UintTy, }; use crate::stable_mir::{self, Context}; use rustc_hir as hir; @@ -101,6 +102,12 @@ impl<'tcx> Context for Tables<'tcx> { let ty = self.types[ty.0]; ty.stable(self) } + + fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics { + let def_id = self.generic_def_id(generic_def); + let generic_def = self.tcx.generics_of(def_id); + generic_def.stable(self) + } } pub struct Tables<'tcx> { @@ -1205,3 +1212,67 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) } } } + +impl<'tcx> Stable<'tcx> for ty::Generics { + type T = stable_mir::ty::Generics; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::Generics; + + let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect(); + let param_def_id_to_index = + params.iter().map(|param| (param.def_id, param.index)).collect(); + + Generics { + parent: self.parent.map(|did| tables.generic_def(did)), + parent_count: self.parent_count, + params, + param_def_id_to_index, + has_self: self.has_self, + has_late_bound_regions: self + .has_late_bound_regions + .as_ref() + .map(|late_bound_regions| late_bound_regions.stable(tables)), + host_effect_index: self.host_effect_index, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_span::Span { + type T = stable_mir::ty::Span; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + opaque(self) + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { + type T = stable_mir::ty::GenericParamDefKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::GenericParamDefKind; + match self { + ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime, + ty::GenericParamDefKind::Type { has_default, synthetic } => { + GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic } + } + ty::GenericParamDefKind::Const { has_default } => { + GenericParamDefKind::Const { has_default: *has_default } + } + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { + type T = stable_mir::ty::GenericParamDef; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + GenericParamDef { + name: self.name.to_string(), + def_id: tables.generic_def(self.def_id), + index: self.index, + pure_wrt_drop: self.pure_wrt_drop, + kind: self.kind.stable(tables), + } + } +} diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 2ae334c6a95..8e38e394b98 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -15,7 +15,7 @@ use std::cell::Cell; use crate::rustc_smir::Tables; -use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind}; +use self::ty::{GenericDef, Generics, ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind}; pub mod mir; pub mod ty; @@ -110,6 +110,7 @@ pub trait Context { fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl; fn all_trait_impls(&mut self) -> ImplTraitDecls; fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait; + fn generics_of(&mut self, generic_def: &GenericDef) -> Generics; /// Get information about the local crate. fn local_crate(&self) -> Crate; /// Retrieve a list of all external crates. diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 7a6601f09da..fe7fef5d0c1 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -22,7 +22,7 @@ pub struct Const { type Ident = Opaque; pub(crate) type Region = Opaque; -type Span = Opaque; +pub type Span = Opaque; #[derive(Clone, Debug)] pub enum TyKind { @@ -87,34 +87,37 @@ pub enum Movability { Movable, } -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ForeignDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct FnDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ClosureDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct GeneratorDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ParamDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct BrNamedDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct AdtDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct AliasDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct TraitDef(pub(crate) DefId); -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct GenericDef(pub(crate) DefId); + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ConstDef(pub(crate) DefId); impl TraitDef { @@ -132,6 +135,12 @@ impl ImplDef { } } +impl GenericDef { + pub fn generics_of(&self) -> Generics { + with(|tcx| tcx.generics_of(self)) + } +} + #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec<GenericArgKind>); @@ -461,3 +470,30 @@ pub struct TraitRef { pub def_id: TraitDef, pub args: GenericArgs, } + +#[derive(Clone, Debug)] +pub struct Generics { + pub parent: Option<GenericDef>, + pub parent_count: usize, + pub params: Vec<GenericParamDef>, + pub param_def_id_to_index: Vec<(GenericDef, u32)>, + pub has_self: bool, + pub has_late_bound_regions: Option<Span>, + pub host_effect_index: Option<usize>, +} + +#[derive(Clone, Debug)] +pub enum GenericParamDefKind { + Lifetime, + Type { has_default: bool, synthetic: bool }, + Const { has_default: bool }, +} + +#[derive(Clone, Debug)] +pub struct GenericParamDef { + pub name: super::Symbol, + pub def_id: GenericDef, + pub index: u32, + pub pure_wrt_drop: bool, + pub kind: GenericParamDefKind, +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 28a2dfebcfe..8aec12f128e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1179,6 +1179,9 @@ symbols! { ptr_offset_from, ptr_offset_from_unsigned, ptr_unique, + ptr_write, + ptr_write_unaligned, + ptr_write_volatile, pub_macro_rules, pub_restricted, public, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5f094ac4e7e..01e36044899 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1357,6 +1357,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] +#[rustc_diagnostic_item = "ptr_write"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write<T>(dst: *mut T, src: T) { // Semantically, it would be fine for this to be implemented as a @@ -1459,6 +1460,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] +#[rustc_diagnostic_item = "ptr_write_unaligned"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) { // SAFETY: the caller must guarantee that `dst` is valid for writes. @@ -1607,6 +1609,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T { /// ``` #[inline] #[stable(feature = "volatile", since = "1.9.0")] +#[rustc_diagnostic_item = "ptr_write_volatile"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { // SAFETY: the caller must uphold the safety contract for `volatile_store`. diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index eb46f4e54bb..873bfb6218b 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1820,7 +1820,7 @@ mod true_keyword {} #[doc(keyword = "type")] // -/// Define an alias for an existing type. +/// Define an [alias] for an existing type. /// /// The syntax is `type Name = ExistingType;`. /// @@ -1838,6 +1838,13 @@ mod true_keyword {} /// assert_eq!(m, k); /// ``` /// +/// A type can be generic: +/// +/// ```rust +/// # use std::sync::{Arc, Mutex}; +/// type ArcMutex<T> = Arc<Mutex<T>>; +/// ``` +/// /// In traits, `type` is used to declare an [associated type]: /// /// ```rust @@ -1860,6 +1867,7 @@ mod true_keyword {} /// /// [`trait`]: keyword.trait.html /// [associated type]: ../reference/items/associated-items.html#associated-types +/// [alias]: ../reference/items/type-aliases.html mod type_keyword {} #[doc(keyword = "unsafe")] diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs index dbad425976a..a0eefa8811a 100644 --- a/library/std/src/sys/wasi/thread.rs +++ b/library/std/src/sys/wasi/thread.rs @@ -47,12 +47,20 @@ cfg_if::cfg_if! { stack_size: libc::size_t, ) -> ffi::c_int; pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> ffi::c_int; + pub fn pthread_detach(thread: pthread_t) -> ffi::c_int; } } pub struct Thread { id: libc::pthread_t, } + + impl Drop for Thread { + fn drop(&mut self) { + let ret = unsafe { libc::pthread_detach(self.id) }; + debug_assert_eq!(ret, 0); + } + } } else { pub struct Thread(!); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 4821d20a898..762e66ac7cc 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1276,7 +1276,8 @@ impl Config { } config.initial_rustc = if let Some(rustc) = build.rustc { - config.check_build_rustc_version(&rustc); + // FIXME(#115065): re-enable this check + // config.check_build_rustc_version(&rustc); PathBuf::from(rustc) } else { config.download_beta_toolchain(); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index db3b7ffbea4..d1018978f78 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1174,6 +1174,11 @@ impl Step for ExpandYamlAnchors { /// appropriate configuration for all our CI providers. This step ensures the tool was called /// by the user before committing CI changes. fn run(self, builder: &Builder<'_>) { + // Note: `.github/` is not included in dist-src tarballs + if !builder.src.join(".github/workflows/ci.yml").exists() { + builder.info("Skipping YAML anchors check: GitHub Actions config not found"); + return; + } builder.info("Ensuring the YAML anchors in the GitHub Actions config were expanded"); builder.run_delaying_failure( &mut builder.tool_cmd(Tool::ExpandYamlAnchors).arg("check").arg(&builder.src), diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index 377d4a9ce5e..b3c5f41bdd7 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ sudo \ bzip2 \ xz-utils \ + texinfo \ wget \ libssl-dev \ pkg-config \ diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 17cd456b995..0d02636db91 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -4,7 +4,7 @@ set -eux arch=$1 -binutils_version=2.25.1 +binutils_version=2.40 freebsd_version=12.3 triple=$arch-unknown-freebsd12 sysroot=/usr/local/$triple diff --git a/src/ci/docker/scripts/illumos-toolchain.sh b/src/ci/docker/scripts/illumos-toolchain.sh index 3f1d5f3426a..0b2c09b3eed 100644 --- a/src/ci/docker/scripts/illumos-toolchain.sh +++ b/src/ci/docker/scripts/illumos-toolchain.sh @@ -52,8 +52,8 @@ SYSROOT_URL='https://github.com/illumos/sysroot/releases/download/' SYSROOT_URL+="$SYSROOT_VER/$SYSROOT_TAR" SYSROOT_DIR="$PREFIX/sysroot" -BINUTILS_VERSION='2.25.1' -BINUTILS_SUM='b5b14added7d78a8d1ca70b5cb75fef57ce2197264f4f5835326b0df22ac9f22' +BINUTILS_VERSION='2.40' +BINUTILS_SUM='f8298eb153a4b37d112e945aa5cb2850040bcf26a3ea65b5a715c83afe05e48a' BINUTILS_BASE="binutils-$BINUTILS_VERSION" BINUTILS_TAR="$BINUTILS_BASE.tar.bz2" BINUTILS_URL="https://ftp.gnu.org/gnu/binutils/$BINUTILS_TAR" diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 81fb13f4166..1ce7efdfc20 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -273,6 +273,8 @@ pub(crate) struct RenderOptions { pub(crate) call_locations: AllCallLocations, /// If `true`, Context::init will not emit shared files. pub(crate) no_emit_shared: bool, + /// If `true`, HTML source code pages won't be generated. + pub(crate) html_no_source: bool, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -686,6 +688,7 @@ impl Options { let generate_link_to_definition = matches.opt_present("generate-link-to-definition"); let extern_html_root_takes_precedence = matches.opt_present("extern-html-root-takes-precedence"); + let html_no_source = matches.opt_present("html-no-source"); if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) { diag.struct_err( @@ -769,6 +772,7 @@ impl Options { generate_link_to_definition, call_locations, no_emit_shared: false, + html_no_source, }; Ok((options, render_options)) } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index d7ff248a9bf..bb1c186668c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -463,6 +463,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { generate_link_to_definition, call_locations, no_emit_shared, + html_no_source, .. } = options; @@ -488,7 +489,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { scrape_examples_extension: !call_locations.is_empty(), }; let mut issue_tracker_base_url = None; - let mut include_sources = true; + let mut include_sources = !html_no_source; // Crawl the crate attributes looking for attributes which control how we're // going to emit HTML diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8220df5d4f3..92e06f3ab0f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -656,6 +656,9 @@ fn opts() -> Vec<RustcOptGroup> { "[rust]", ) }), + unstable("html-no-source", |o| { + o.optflag("", "html-no-source", "Disable HTML source code pages generation") + }), ] } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 36872266ee1..7b0a7a90d31 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1430,20 +1430,15 @@ impl LinkCollector<'_, '_> { // Otherwise, check if 2 links are same, if so, skip the resolve process. // // Notice that this algorithm is passive, might possibly miss actual redudant cases. - let explicit_link = &explicit_link.to_string(); + let explicit_link = explicit_link.to_string(); let display_text = ori_link.display_text.as_ref().unwrap(); - let display_len = display_text.len(); - let explicit_len = explicit_link.len(); - if display_len == explicit_len { + if display_text.len() == explicit_link.len() { // Whether they are same or not, skip the resolve process. return; } - if (explicit_len >= display_len - && &explicit_link[(explicit_len - display_len)..] == display_text) - || (display_len >= explicit_len - && &display_text[(display_len - explicit_len)..] == explicit_link) + if explicit_link.ends_with(&display_text[..]) || display_text.ends_with(&explicit_link[..]) { self.resolve_with_disambiguator_cached( display_res_info, diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index ef0f8716aa8..67cd2cc9732 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -98,13 +98,8 @@ fn check_redundant_explicit_link<'md>( let explicit_link = dest.to_string(); let display_link = link_data.resolvable_link.clone()?; - let explicit_len = explicit_link.len(); - let display_len = display_link.len(); - if (explicit_len >= display_len - && &explicit_link[(explicit_len - display_len)..] == display_link) - || (display_len >= explicit_len - && &display_link[(display_len - explicit_len)..] == explicit_link) + if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link) { match link_type { LinkType::Inline | LinkType::ReferenceUnknown => { diff --git a/src/llvm-project b/src/llvm-project -Subproject 1833c2be108aefcb5d25f6280cf9763b1feb800 +Subproject 50eecd007f6bf135ad60493bc62102739038d59 diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 80eca0e58fb2ff52c1e94fc191b55b37ed73e0e +Subproject 2cc50bc0b63ad20da193e002ba11d391af0104b diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index fdc35cd4ddf..98441e83eb4 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -10,6 +10,7 @@ use rustc_hir::{ GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; +use rustc_hir::MatchSource::TryDesugar; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; use rustc_middle::ty::TypeckResults; @@ -311,7 +312,7 @@ impl HirEqInterExpr<'_, '_, '_> { lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name) }, (&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => { - ls == rs + (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_))))) && self.eq_expr(le, re) && over(la, ra, |l, r| { self.eq_pat(l.pat, r.pat) diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.rs b/src/tools/clippy/tests/ui/if_same_then_else2.rs index c545434efe5..0b171f21d0c 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else2.rs +++ b/src/tools/clippy/tests/ui/if_same_then_else2.rs @@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> { }; if true { - // FIXME: should emit "this `if` has identical blocks" + //~^ ERROR: this `if` has identical blocks Ok("foo")?; } else { Ok("foo")?; diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr index 37fe787d1de..56e5f3e45b2 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr +++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr @@ -83,6 +83,25 @@ LL | | }; | |_____^ error: this `if` has identical blocks + --> $DIR/if_same_then_else2.rs:100:13 + | +LL | if true { + | _____________^ +LL | | +LL | | Ok("foo")?; +LL | | } else { + | |_____^ + | +note: same as this + --> $DIR/if_same_then_else2.rs:103:12 + | +LL | } else { + | ____________^ +LL | | Ok("foo")?; +LL | | } + | |_____^ + +error: this `if` has identical blocks --> $DIR/if_same_then_else2.rs:124:20 | LL | } else if true { @@ -103,5 +122,5 @@ LL | | return Ok(&foo[0..]); LL | | } | |_____^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs new file mode 100644 index 00000000000..d7e4a948954 --- /dev/null +++ b/tests/codegen/asm-maybe-uninit.rs @@ -0,0 +1,27 @@ +// compile-flags: -O +// only-x86_64 + +#![crate_type = "rlib"] +#![allow(asm_sub_register)] + +use std::mem::MaybeUninit; +use std::arch::asm; + +// CHECK-LABEL: @int +#[no_mangle] +pub unsafe fn int(x: MaybeUninit<i32>) -> MaybeUninit<i32> { + let y: MaybeUninit<i32>; + asm!("/*{}{}*/", in(reg) x, out(reg) y); + y +} + +// CHECK-LABEL: @inout +#[no_mangle] +pub unsafe fn inout(mut x: i32) -> MaybeUninit<u32> { + let mut y: MaybeUninit<u32>; + asm!("/*{}*/", inout(reg) x => y); + asm!("/*{}*/", inout(reg) y => x); + asm!("/*{}*/", inlateout(reg) x => y); + asm!("/*{}*/", inlateout(reg) y => x); + y +} diff --git a/tests/codegen/box-maybe-uninit.rs b/tests/codegen/box-uninit-bytes.rs index 282af99b067..732da0a1794 100644 --- a/tests/codegen/box-maybe-uninit.rs +++ b/tests/codegen/box-uninit-bytes.rs @@ -25,6 +25,20 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> { Box::new(MaybeUninit::uninit()) } +#[repr(align(1024))] +pub struct LotsaPadding(usize); + +// Boxing a value with padding should not copy junk from the stack +#[no_mangle] +pub fn box_lotsa_padding() -> Box<LotsaPadding> { + // CHECK-LABEL: @box_lotsa_padding + // CHECK-NOT: alloca + // CHECK-NOT: getelementptr + // CHECK-NOT: memcpy + // CHECK-NOT: memset + Box::new(LotsaPadding(42)) +} + // Hide the `allocalign` attribute in the declaration of __rust_alloc // from the CHECK-NOT above, and also verify the attributes got set reasonably. // CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]] diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs new file mode 100644 index 00000000000..e2ea9dda4a0 --- /dev/null +++ b/tests/codegen/debuginfo-inline-callsite-location.rs @@ -0,0 +1,26 @@ +// compile-flags: -g -O + +// Check that each inline call site for the same function uses the same "sub-program" so that LLVM +// can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail +// calls to panic. + +// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E +// CHECK-SAME: !dbg ![[#first_dbg:]] +// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E +// CHECK-SAME: !dbg ![[#second_dbg:]] + +// CHECK: ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap<i32>" +// CHECK: ![[#first_dbg]] = !DILocation(line: [[#]] +// CHECK-SAME: scope: ![[#func_dbg]], inlinedAt: ![[#]]) +// CHECK: ![[#second_dbg]] = !DILocation(line: [[#]] +// CHECK-SAME: scope: ![[#func_dbg]], inlinedAt: ![[#]]) + +#![crate_type = "lib"] + +#[no_mangle] +extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 { + let x1 = x.unwrap(); + let y1 = y.unwrap(); + + x1 + y1 +} diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout index b280698230d..de8ff0e5f89 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -191,6 +191,8 @@ Options: removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information + --html-no-source + Disable HTML source code pages generation @path Read newline separated options from `path` diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs new file mode 100644 index 00000000000..fecefb7b25f --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs @@ -0,0 +1,18 @@ +// check-pass + +/// [`…foo`] [`…bar`] [`Err`] +pub struct Broken {} + +/// [`…`] [`…`] [`Err`] +pub struct Broken2 {} + +/// [`…`][…] [`…`][…] [`Err`] +pub struct Broken3 {} + +/// […………………………][Broken3] +pub struct Broken4 {} + +/// [Broken3][…………………………] +pub struct Broken5 {} + +pub struct Err; diff --git a/tests/rustdoc/html-no-source.rs b/tests/rustdoc/html-no-source.rs new file mode 100644 index 00000000000..25615a73c3f --- /dev/null +++ b/tests/rustdoc/html-no-source.rs @@ -0,0 +1,30 @@ +// compile-flags: -Zunstable-options --html-no-source + +// This test ensures that the `--html-no-source` flag disables +// the creation of the `src` folder. + +#![feature(staged_api)] +#![stable(feature = "bar", since = "1.0")] +#![crate_name = "foo"] + +// Ensures that there is no items in the corresponding "src" folder. +// @files 'src/foo' '[]' + +// @has foo/fn.foo.html +// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · ' +// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · ' +#[stable(feature = "bar", since = "1.0")] +pub fn foo() {} + +// @has foo/struct.Bar.html +// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · ' +// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · ' +#[stable(feature = "bar", since = "1.0")] +pub struct Bar; + +impl Bar { + // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0' + // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0 ·' + #[stable(feature = "foobar", since = "2.0")] + pub fn bar() {} +} diff --git a/tests/ui/const-generics/issues/issue-100313.stderr b/tests/ui/const-generics/issues/issue-100313.stderr index 42ad4d61c8e..796966b22d5 100644 --- a/tests/ui/const-generics/issues/issue-100313.stderr +++ b/tests/ui/const-generics/issues/issue-100313.stderr @@ -4,6 +4,7 @@ error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` LL | *(B as *const bool as *mut bool) = false; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> = note: `#[deny(invalid_reference_casting)]` on by default error[E0080]: evaluation of constant value failed diff --git a/tests/ui/cross-crate/auxiliary/static_init_aux.rs b/tests/ui/cross-crate/auxiliary/static_init_aux.rs index 3b664f43654..5e172ef3198 100644 --- a/tests/ui/cross-crate/auxiliary/static_init_aux.rs +++ b/tests/ui/cross-crate/auxiliary/static_init_aux.rs @@ -1,10 +1,14 @@ pub static V: &u32 = &X; pub static F: fn() = f; +pub static G: fn() = G0; static X: u32 = 42; +static G0: fn() = g; pub fn v() -> *const u32 { V } fn f() {} + +fn g() {} diff --git a/tests/ui/cross-crate/static-init.rs b/tests/ui/cross-crate/static-init.rs index 2e893c5d9bf..0b50c41fc5e 100644 --- a/tests/ui/cross-crate/static-init.rs +++ b/tests/ui/cross-crate/static-init.rs @@ -1,9 +1,11 @@ +// Regression test for #84455 and #115052. // run-pass // aux-build:static_init_aux.rs extern crate static_init_aux as aux; static V: &u32 = aux::V; static F: fn() = aux::F; +static G: fn() = aux::G; fn v() -> *const u32 { V @@ -12,4 +14,5 @@ fn v() -> *const u32 { fn main() { assert_eq!(aux::v(), crate::v()); F(); + G(); } diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 6c38bca3daa..92d985948ec 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -71,6 +71,11 @@ unsafe fn assign_to_ref() { //~^ ERROR assigning to `&T` is undefined behavior *std::mem::transmute::<_, *mut i32>(num) += 1; //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write( + //~^ ERROR assigning to `&T` is undefined behavior + std::mem::transmute::<*const i32, *mut i32>(num), + -1i32, + ); let value = num as *const i32 as *mut i32; *value = 1; @@ -79,6 +84,12 @@ unsafe fn assign_to_ref() { //~^ ERROR assigning to `&T` is undefined behavior *(num as *const _ as usize as *mut i32) = 2; //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write_unaligned(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write_volatile(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior unsafe fn generic_assign_to_ref<T>(this: &T, a: T) { *(this as *const _ as *mut _) = a; diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 7ff9b76a85e..47b95460ec3 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -4,6 +4,7 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is LL | let _num = &mut *(num as *const i32 as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> = note: `#[deny(invalid_reference_casting)]` on by default error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` @@ -11,54 +12,72 @@ error: casting `&T` to `&mut T` is undefined behavior, even if the reference is | LL | let _num = &mut *(num as *const i32).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:23:16 | LL | let _num = &mut *std::ptr::from_ref(num).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:25:16 | LL | let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:27:16 | LL | let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:29:16 | LL | let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:31:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:33:16 | LL | let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:35:16 | LL | let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:37:16 | LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:41:16 @@ -67,6 +86,8 @@ LL | let deferred = num as *const i32 as *mut i32; | ----------------------------- casting happend here LL | let _num = &mut *deferred; | ^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:44:16 @@ -75,86 +96,159 @@ LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).ca | ---------------------------------------------------------------------------- casting happend here LL | let _num = &mut *deferred; | ^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:46:16 | LL | let _num = &mut *(num as *const _ as usize as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:50:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:60:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:62:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:64:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:66:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:68:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:70:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` --> $DIR/reference_casting.rs:72:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:74:5 + | +LL | / std::ptr::write( +LL | | +LL | | std::mem::transmute::<*const i32, *mut i32>(num), +LL | | -1i32, +LL | | ); + | |_____^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:76:5 + --> $DIR/reference_casting.rs:81:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here LL | *value = 1; | ^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:78:5 + --> $DIR/reference_casting.rs:83:5 | LL | *(num as *const i32).cast::<i32>().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:80:5 + --> $DIR/reference_casting.rs:85:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:87:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +... +LL | std::ptr::write(value, 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:84:9 + --> $DIR/reference_casting.rs:89:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +... +LL | std::ptr::write_unaligned(value, 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:91:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +... +LL | std::ptr::write_volatile(value, 2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:95:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html> -error: aborting due to 25 previous errors +error: aborting due to 29 previous errors diff --git a/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs new file mode 100644 index 00000000000..54a22510066 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/auxiliary/drop-shim-relates-opaque-aux.rs @@ -0,0 +1,21 @@ +// crate foo + +#![feature(type_alias_impl_trait)] + +type Tait = impl Sized; +fn _constrain() -> Tait {} + +struct WrapperWithDrop<T>(T); +impl<T> Drop for WrapperWithDrop<T> { + fn drop(&mut self) {} +} + +pub struct Foo(WrapperWithDrop<Tait>); + +trait Id { + type Id: ?Sized; +} +impl<T: ?Sized> Id for T { + type Id = T; +} +pub struct Bar(WrapperWithDrop<<Tait as Id>::Id>); diff --git a/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs b/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs new file mode 100644 index 00000000000..51d28704972 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/drop-shim-relates-opaque-issue-114375.rs @@ -0,0 +1,10 @@ +// aux-build:drop-shim-relates-opaque-aux.rs +// compile-flags: -Zvalidate-mir --crate-type=lib +// build-pass + +extern crate drop_shim_relates_opaque_aux; + +pub fn drop_foo(_: drop_shim_relates_opaque_aux::Foo) {} +pub fn drop_bar(_: drop_shim_relates_opaque_aux::Bar) {} + +fn main() {} diff --git a/triagebot.toml b/triagebot.toml index 2f380ef1dda..aef5b5bb8dc 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -177,6 +177,98 @@ exclude_labels = [ "T-*", ] +[autolabel."O-android"] +trigger_files = [ + "library/std/src/os/android" +] + +[autolabel."O-fuchsia"] +trigger_files = [ + "library/std/src/os/fuchsia" +] + +[autolabel."O-hermit"] +trigger_files = [ + "library/std/src/sys/hermit", + "library/std/src/os/hermit" +] + +[autolabel."O-ios"] +trigger_files = [ + "library/std/src/os/ios" +] + +[autolabel."O-itron"] +trigger_files = [ + "library/std/src/sys/itron" +] + +[autolabel."O-linux"] +trigger_files = [ + "library/std/src/os/linux" +] + +[autolabel."O-macos"] +trigger_files = [ + "library/std/src/os/macos" +] + +[autolabel."O-netbsd"] +trigger_files = [ + "library/std/src/os/netbsd" +] + +[autolabel."O-redox"] +trigger_files = [ + "library/std/src/os/redox" +] + +[autolabel."O-SGX"] +trigger_files = [ + "library/std/src/sys/sgx", + "library/std/src/os/fortanix_sgx" +] + +[autolabel."O-solaris"] +trigger_files = [ + "library/std/src/os/solaris" +] + +[autolabel."O-solid"] +trigger_files = [ + "library/std/src/sys/solid", + "library/std/src/os/solid" +] + +[autolabel."O-unix"] +trigger_files = [ + "library/std/src/sys/unix", + "library/std/src/os/unix" +] + +[autolabel."O-wasi"] +trigger_files = [ + "library/std/src/sys/wasi", + "library/std/src/os/wasi" +] + +[autolabel."O-wasm"] +trigger_files = [ + "library/std/src/sys/wasm", + "library/std/src/os/wasm" +] + +[autolabel."O-watchos"] +trigger_files = [ + "library/std/src/os/watchos" +] + +[autolabel."O-windows"] +trigger_files = [ + "library/std/src/sys/windows", + "library/std/src/os/windows" +] + [autolabel."T-bootstrap"] trigger_files = [ "x.py", |
