diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 738435891f16f..026758958f04f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -4211,9 +4211,7 @@ impl ForeignItemKind { impl From for ItemKind { fn from(foreign_item_kind: ForeignItemKind) -> ItemKind { match foreign_item_kind { - ForeignItemKind::Static(box static_foreign_item) => { - ItemKind::Static(Box::new(static_foreign_item)) - } + ForeignItemKind::Static(static_foreign_item) => ItemKind::Static(static_foreign_item), ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind), ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind), ForeignItemKind::MacCall(a) => ItemKind::MacCall(a), @@ -4226,7 +4224,7 @@ impl TryFrom for ForeignItemKind { fn try_from(item_kind: ItemKind) -> Result { Ok(match item_kind { - ItemKind::Static(box static_item) => ForeignItemKind::Static(Box::new(static_item)), + ItemKind::Static(static_item) => ForeignItemKind::Static(static_item), ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind), ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind), ItemKind::MacCall(a) => ForeignItemKind::MacCall(a), diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index b6e18240cbab1..738e3330254b7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -626,7 +626,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let predicates = match parent.kind { hir::ExprKind::Call(callee, _) => { let ty = typeck_result.node_type_opt(callee.hir_id)?; - let ty::FnDef(fn_def_id, args) = ty.kind() else { return None }; + let ty::FnDef(fn_def_id, args) = *ty.kind() else { return None }; tcx.predicates_of(fn_def_id).instantiate(tcx, args) } hir::ExprKind::MethodCall(..) => { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 824125099cfde..a0e53248c9047 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -614,7 +614,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } _ => { let local = &self.body.local_decls[local]; - match local.local_info() { + match *local.local_info() { LocalInfo::StaticRef { def_id, .. } => { let span = self.infcx.tcx.def_span(def_id); err.span_label(span, format!("this `static` cannot be {acted_on}")); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a9c00660c3a20..a3738689ed05f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -926,7 +926,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let tcx = self.infcx.tcx; let ConstraintCategory::CallArgument(Some(func_ty)) = category else { return }; - let ty::FnDef(fn_did, args) = func_ty.kind() else { return }; + let ty::FnDef(fn_did, args) = *func_ty.kind() else { return }; debug!(?fn_did, ?args); // Only suggest this on function calls, not closures @@ -938,7 +938,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, self.infcx.typing_env(self.infcx.param_env), - *fn_did, + fn_did, self.infcx.resolve_vars_if_possible(args), ) else { return; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2935559147b7e..29d38af472c22 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1013,12 +1013,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let is_implicit_coercion = coercion_source == CoercionSource::Implicit; let src_ty = op.ty(self.body, tcx); let mut src_sig = src_ty.fn_sig(tcx); - if let ty::FnDef(def_id, _) = src_ty.kind() + if let ty::FnDef(def_id, _) = *src_ty.kind() && let ty::FnPtr(_, target_hdr) = *ty.kind() && tcx.codegen_fn_attrs(def_id).safe_target_features && target_hdr.safety.is_safe() && let Some(safe_sig) = tcx.adjust_target_feature_sig( - *def_id, + def_id, src_sig, self.body.source.def_id(), ) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index acc1c0b9f0de8..388503c720532 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -18,18 +18,18 @@ use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; -use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; +use rustc_errors::DiagCtxtHandle; use rustc_fs_util::{TempDirBuilder, fix_windows_verbatim_for_gcc, try_canonicalize}; use rustc_hir::attrs::NativeLibKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_macros::LintDiagnostic; +use rustc_macros::Diagnostic; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; use rustc_metadata::{ EncodedMetadata, NativeLibSearchFallback, find_native_static_library, walk_native_lib_search_dirs, }; use rustc_middle::bug; -use rustc_middle::lint::lint_level; +use rustc_middle::lint::diag_lint_level; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; @@ -662,7 +662,7 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out } } -#[derive(LintDiagnostic)] +#[derive(Diagnostic)] #[diag("{$inner}")] /// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just /// end up with inconsistent languages within the same diagnostic. @@ -938,9 +938,7 @@ fn link_natively( let level = codegen_results.crate_info.lint_levels.linker_messages; let lint = |msg| { - lint_level(sess, LINKER_MESSAGES, level, None, |diag| { - LinkerOutput { inner: msg }.decorate_lint(diag) - }) + diag_lint_level(sess, LINKER_MESSAGES, level, None, LinkerOutput { inner: msg }); }; if !prog.stderr.is_empty() { diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index e4f99be339df5..43a4c41eaeffc 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -577,7 +577,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Aggregate(kind, ..) => { if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref() - && let Some(coroutine_kind) = self.tcx.coroutine_kind(def_id) + && let Some(coroutine_kind) = self.tcx.coroutine_kind(*def_id) { self.check_op(ops::Coroutine(coroutine_kind)); } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 303183fd924da..dc6841bb89dda 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -2,7 +2,6 @@ use either::Either; use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; -use rustc_data_structures::assert_matches; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; @@ -838,7 +837,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { vector_layout: TyAndLayout<'tcx>, alignment: SimdAlign, ) -> InterpResult<'tcx> { - assert_matches!(vector_layout.backend_repr, BackendRepr::SimdVector { .. }); + // Packed SIMD types with non-power-of-two element counts use BackendRepr::Memory + // instead of BackendRepr::SimdVector. We need to handle both cases. + // FIXME: remove the BackendRepr::Memory case when SIMD vectors are always passed as BackendRepr::SimdVector. + assert!(vector_layout.ty.is_simd(), "check_simd_ptr_alignment called on non-SIMD type"); + match vector_layout.backend_repr { + BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => {} + _ => { + span_bug!( + self.cur_span(), + "SIMD type has unexpected backend_repr: {:?}", + vector_layout.backend_repr + ); + } + } let align = match alignment { ty::SimdAlign::Unaligned => { diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 583ca36f07130..a2807c852632e 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -109,10 +109,18 @@ impl MultiSpan { MultiSpan { primary_spans: vec, span_labels: vec![] } } + pub fn push_primary_span(&mut self, primary_span: Span) { + self.primary_spans.push(primary_span); + } + pub fn push_span_label(&mut self, span: Span, label: impl Into) { self.span_labels.push((span, label.into())); } + pub fn push_span_diag(&mut self, span: Span, diag: DiagMessage) { + self.span_labels.push((span, diag)); + } + /// Selects the first primary span (if any). pub fn primary_span(&self) -> Option { self.primary_spans.first().cloned() @@ -179,6 +187,11 @@ impl MultiSpan { span_labels } + /// Returns the span labels as contained by `MultiSpan`. + pub fn span_labels_raw(&self) -> &[(Span, DiagMessage)] { + &self.span_labels + } + /// Returns `true` if any of the span labels is displayable. pub fn has_span_labels(&self) -> bool { self.span_labels.iter().any(|(sp, _)| !sp.is_dummy()) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index c8ba7dbec97ca..41005d12a1918 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1324,6 +1324,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { drop(self); } + /// Cancels this diagnostic and returns its first message, if it exists. + pub fn cancel_into_message(self) -> Option { + let s = self.diag.as_ref()?.messages.get(0)?.0.as_str().map(ToString::to_string); + self.cancel(); + s + } + /// See `DiagCtxt::stash_diagnostic` for details. pub fn stash(mut self, span: Span, key: StashKey) -> Option { let diag = self.take_diag(); diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 1da14ce0155d3..839e68d0bb433 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan}; use rustc_parse::lexer::{StripTokens, nfc_normalize}; use rustc_parse::parser::Parser; -use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; +use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream}; use rustc_proc_macro::bridge::{ DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree, server, }; @@ -415,6 +415,13 @@ impl ToInternal for Level { } } +fn cancel_diags_into_string(diags: Vec>) -> String { + let mut messages = diags.into_iter().flat_map(Diag::cancel_into_message); + let msg = messages.next().expect("no diagnostic has a message"); + messages.for_each(|_| ()); // consume iterator to cancel the remaining diagnostics + msg +} + pub(crate) struct Rustc<'a, 'b> { ecx: &'a mut ExtCtxt<'b>, def_site: Span, @@ -478,35 +485,32 @@ impl server::Server for Rustc<'_, '_> { self.psess().file_depinfo.borrow_mut().insert(Symbol::intern(path)); } - fn literal_from_str(&mut self, s: &str) -> Result, ()> { + fn literal_from_str(&mut self, s: &str) -> Result, String> { let name = FileName::proc_macro_source_code(s); - let mut parser = unwrap_or_emit_fatal(new_parser_from_source_str( - self.psess(), - name, - s.to_owned(), - StripTokens::Nothing, - )); + let mut parser = + new_parser_from_source_str(self.psess(), name, s.to_owned(), StripTokens::Nothing) + .map_err(cancel_diags_into_string)?; let first_span = parser.token.span.data(); let minus_present = parser.eat(exp!(Minus)); let lit_span = parser.token.span.data(); let token::Literal(mut lit) = parser.token.kind else { - return Err(()); + return Err("not a literal".to_string()); }; // Check no comment or whitespace surrounding the (possibly negative) // literal, or more tokens after it. if (lit_span.hi.0 - first_span.lo.0) as usize != s.len() { - return Err(()); + return Err("comment or whitespace around literal".to_string()); } if minus_present { // If minus is present, check no comment or whitespace in between it // and the literal token. if first_span.hi.0 != lit_span.lo.0 { - return Err(()); + return Err("comment or whitespace after minus".to_string()); } // Check literal is a kind we allow to be negated in a proc macro token. @@ -520,7 +524,9 @@ impl server::Server for Rustc<'_, '_> { | token::LitKind::ByteStrRaw(_) | token::LitKind::CStr | token::LitKind::CStrRaw(_) - | token::LitKind::Err(_) => return Err(()), + | token::LitKind::Err(_) => { + return Err("non-numeric literal may not be negated".to_string()); + } token::LitKind::Integer | token::LitKind::Float => {} } @@ -560,13 +566,14 @@ impl server::Server for Rustc<'_, '_> { stream.is_empty() } - fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { - unwrap_or_emit_fatal(source_str_to_stream( + fn ts_from_str(&mut self, src: &str) -> Result { + source_str_to_stream( self.psess(), FileName::proc_macro_source_code(src), src.to_string(), Some(self.call_site), - )) + ) + .map_err(cancel_diags_into_string) } fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 04773ad3f8bc1..349ad4f7fc43b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1221,7 +1221,7 @@ fn check_impl_items_against_trait<'tcx>( match impl_trait_header.polarity { ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {} ty::ImplPolarity::Negative => { - if let [first_item_ref, ..] = impl_item_refs { + if let [first_item_ref, ..] = *impl_item_refs { let first_item_span = tcx.def_span(first_item_ref); struct_span_code_err!( tcx.dcx(), diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c29ebe67a158e..43a4f0574f5b0 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1333,7 +1333,7 @@ fn check_region_late_boundedness<'tcx>( .iter() .map(|param| { let (LateEarlyMismatch::EarlyInImpl(impl_param_def_id, ..) - | LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = param; + | LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = *param; tcx.def_span(impl_param_def_id) }) .collect(); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index ff919bd58ba16..18244d62f2ae6 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -2445,12 +2445,12 @@ fn is_late_bound_map( )) => { // See comments on `ConstrainedCollectorPostHirTyLowering` for why this arm does not // just consider args to be unconstrained. - let generics = self.tcx.generics_of(alias_def); + let generics = self.tcx.generics_of(*alias_def); let mut walker = ConstrainedCollectorPostHirTyLowering { arg_is_constrained: vec![false; generics.own_params.len()] .into_boxed_slice(), }; - walker.visit_ty(self.tcx.type_of(alias_def).instantiate_identity()); + walker.visit_ty(self.tcx.type_of(*alias_def).instantiate_identity()); match segments.last() { Some(hir::PathSegment { args: Some(args), .. }) => { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2b23abce894c1..52e5cce140ad8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -214,7 +214,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if let [best_trait] = visible_traits .iter() .copied() - .filter(|trait_def_id| { + .filter(|&trait_def_id| { tcx.associated_items(trait_def_id) .filter_by_name_unhygienic(suggested_name) .any(|item| item.tag() == assoc_tag) @@ -1234,7 +1234,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && let name = Symbol::intern(&format!("{ident2}_{ident3}")) && let Some(item) = inherent_impls .iter() - .flat_map(|inherent_impl| { + .flat_map(|&inherent_impl| { tcx.associated_items(inherent_impl).filter_by_name_unhygienic(name) }) .next() diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index f5c77c6800003..312b01d70f00e 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -101,7 +101,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained( let lifetimes_in_associated_types: FxHashSet<_> = tcx .associated_item_def_ids(impl_def_id) .iter() - .flat_map(|def_id| { + .flat_map(|&def_id| { let item = tcx.associated_item(def_id); match item.kind { ty::AssocKind::Type { .. } => { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 8df75148346a7..3d044c1086b06 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -87,7 +87,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { result = self.try_overloaded_call_step(call_expr, callee_expr, arg_exprs, &autoderef); } - match autoderef.final_ty().kind() { + match *autoderef.final_ty().kind() { ty::FnDef(def_id, _) => { let abi = self.tcx.fn_sig(def_id).skip_binder().skip_binder().abi; self.check_call_abi(abi, call_expr.span); @@ -430,11 +430,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn is_scalable_vector_ctor(&self, callee_ty: Ty<'_>) -> bool { - if let ty::FnDef(def_id, _) = callee_ty.kind() + if let ty::FnDef(def_id, _) = *callee_ty.kind() && let def::DefKind::Ctor(def::CtorOf::Struct, _) = self.tcx.def_kind(def_id) { self.tcx - .opt_parent(*def_id) + .opt_parent(def_id) .and_then(|id| self.tcx.adt_def(id).repr().scalable) .is_some() } else { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 8baa671972139..f3ca04c6bbe27 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2448,7 +2448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(def_id) .into_iter() - .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) + .flat_map(|&i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. .filter(|item| item.is_fn() && !item.is_method()) .filter_map(|item| { @@ -3183,7 +3183,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if there is an associated function with the same name. if let Some(def_id) = base_ty.peel_refs().ty_adt_def().map(|d| d.did()) { - for impl_def_id in self.tcx.inherent_impls(def_id) { + for &impl_def_id in self.tcx.inherent_impls(def_id) { for item in self.tcx.associated_items(impl_def_id).in_definition_order() { if let ExprKind::Field(base_expr, _) = expr.kind && item.name() == field.name diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e8d5ff017cf8c..1931222bba30e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1118,7 +1118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // error in `validate_res_from_ribs` -- it's just difficult to tell whether the // self type has any generic types during rustc_resolve, which is what we use // to determine if this is a hard error or warning. - if std::iter::successors(Some(self.body_id.to_def_id()), |def_id| { + if std::iter::successors(Some(self.body_id.to_def_id()), |&def_id| { self.tcx.generics_of(def_id).parent }) .all(|def_id| def_id != impl_def_id) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index bdc991abf34b8..c82a779ca8326 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -567,7 +567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } if self.may_coerce(Ty::new_box(self.tcx, found), expected) { - let suggest_boxing = match found.kind() { + let suggest_boxing = match *found.kind() { ty::Tuple(tuple) if tuple.is_empty() => { errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index c5e055e68aea1..862a51288730d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1414,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .collect::>(); if !inherent_impls_candidate.is_empty() { - inherent_impls_candidate.sort_by_key(|id| self.tcx.def_path_str(id)); + inherent_impls_candidate.sort_by_key(|&id| self.tcx.def_path_str(id)); inherent_impls_candidate.dedup(); // number of types to show at most @@ -2256,7 +2256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_args: Option>>, ) -> Option { if let ty::Adt(adt, adt_args) = rcvr_ty.kind() { - for inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter() { + for &inherent_impl_did in self.tcx.inherent_impls(adt.did()).into_iter() { for inherent_method in self.tcx.associated_items(inherent_impl_did).in_definition_order() { @@ -2315,7 +2315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sources: &mut Vec, sugg_span: Option, ) { - sources.sort_by_key(|source| match source { + sources.sort_by_key(|source| match *source { CandidateSource::Trait(id) => (0, self.tcx.def_path_str(id)), CandidateSource::Impl(id) => (1, self.tcx.def_path_str(id)), }); @@ -2468,7 +2468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .tcx .inherent_impls(adt_def.did()) .iter() - .flat_map(|i| self.tcx.associated_items(i).in_definition_order()) + .flat_map(|&i| self.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers and only if // they are resolvable .filter(|item| { @@ -2521,7 +2521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { String::new() }; - match &items[..] { + match items[..] { [] => {} [(def_id, ret_ty)] => { err.span_note( @@ -2536,7 +2536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { let span: MultiSpan = items .iter() - .map(|(def_id, _)| self.tcx.def_span(def_id)) + .map(|&(def_id, _)| self.tcx.def_span(def_id)) .collect::>() .into(); err.span_note( @@ -2546,7 +2546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { following associated functions:\n{}{post}", items .iter() - .map(|(def_id, _ret_ty)| self.tcx.def_path_str(def_id)) + .map(|&(def_id, _ret_ty)| self.tcx.def_path_str(def_id)) .collect::>() .join("\n") ), @@ -3518,7 +3518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { traits.push(trait_pred.def_id()); } } - traits.sort_by_key(|id| self.tcx.def_path_str(id)); + traits.sort_by_key(|&id| self.tcx.def_path_str(id)); traits.dedup(); let len = traits.len(); @@ -3920,7 +3920,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { valid_out_of_scope_traits.retain(|id| self.tcx.is_user_visible_dep(id.krate)); if !valid_out_of_scope_traits.is_empty() { let mut candidates = valid_out_of_scope_traits; - candidates.sort_by_key(|id| self.tcx.def_path_str(id)); + candidates.sort_by_key(|&id| self.tcx.def_path_str(id)); candidates.dedup(); // `TryFrom` and `FromIterator` have no methods diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index cb75e8a943b3e..e9d79a2ece2ec 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -380,8 +380,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .associated_item_def_ids(def_id) .iter() - .find(|item_def_id| { - self.tcx.associated_item(*item_def_id).name() == sym::Output + .find(|&&item_def_id| { + self.tcx.associated_item(item_def_id).name() == sym::Output }) .cloned() }); diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 5e5f9b6f097fa..c7fa779447a49 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -308,7 +308,7 @@ where return true; }; // We only computed variance of lifetimes... - debug_assert_matches!(self.tcx.def_kind(def_id), DefKind::LifetimeParam); + debug_assert_matches!(self.tcx.def_kind(*def_id), DefKind::LifetimeParam); let uncaptured = match *kind { ParamKind::Early(name, index) => ty::Region::new_early_param( self.tcx, @@ -342,7 +342,7 @@ where let uncaptured_spans: Vec<_> = uncaptured_args .into_iter() - .map(|(def_id, _)| self.tcx.def_span(def_id)) + .map(|(&def_id, _)| self.tcx.def_span(def_id)) .collect(); self.tcx.emit_node_span_lint( diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 87c36f41afab1..0723395d6d1cd 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -282,9 +282,9 @@ fn lint_ty_kind_usage(cx: &LateContext<'_>, res: &Res) -> bool { } fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &hir::Path<'_>) -> Option { - match &path.res { + match path.res { Res::Def(_, def_id) => { - if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(*def_id) { + if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(def_id) { return Some(format!("{}{}", name, gen_args(path.segments.last().unwrap()))); } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index f039799c3b7b6..4204855f199d4 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -2,7 +2,7 @@ use std::cmp; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedMap; -use rustc_errors::{Diag, MultiSpan}; +use rustc_errors::{Diag, Diagnostic, MultiSpan}; use rustc_hir::{HirId, ItemLocalId}; use rustc_lint_defs::EditionFcw; use rustc_macros::{Decodable, Encodable, HashStable}; @@ -482,3 +482,205 @@ pub fn lint_level( } lint_level_impl(sess, lint, level, span, Box::new(decorate)) } + +/// The innermost function for emitting lints implementing the [`trait@Diagnostic`] trait. +/// +/// If you are looking to implement a lint, look for higher level functions, +/// for example: +/// +/// - [`TyCtxt::emit_node_span_lint`] +/// - [`TyCtxt::node_span_lint`] +/// - [`TyCtxt::emit_node_lint`] +/// - [`TyCtxt::node_lint`] +/// - `LintContext::opt_span_lint` +/// +/// This function will replace `lint_level` once all `LintDiagnostic` items have been migrated to +/// `Diagnostic`. +#[track_caller] +pub fn diag_lint_level<'a, D: Diagnostic<'a, ()> + 'a>( + sess: &'a Session, + lint: &'static Lint, + level: LevelAndSource, + span: Option, + decorate: D, +) { + // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to + // the "real" work. + #[track_caller] + fn diag_lint_level_impl<'a>( + sess: &'a Session, + lint: &'static Lint, + level: LevelAndSource, + span: Option, + decorate: Box< + dyn FnOnce(rustc_errors::DiagCtxtHandle<'a>, rustc_errors::Level) -> Diag<'a, ()> + 'a, + >, + ) { + let LevelAndSource { level, lint_id, src } = level; + + // Check for future incompatibility lints and issue a stronger warning. + let future_incompatible = lint.future_incompatible; + + let has_future_breakage = future_incompatible.map_or( + // Default allow lints trigger too often for testing. + sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow, + |incompat| incompat.report_in_deps, + ); + + // Convert lint level to error level. + let err_level = match level { + Level::Allow => { + if has_future_breakage { + rustc_errors::Level::Allow + } else { + return; + } + } + Level::Expect => { + // This case is special as we actually allow the lint itself in this context, but + // we can't return early like in the case for `Level::Allow` because we still + // need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`. + // + // We can also not mark the lint expectation as fulfilled here right away, as it + // can still be cancelled in the decorate function. All of this means that we simply + // create a `Diag` and continue as we would for warnings. + rustc_errors::Level::Expect + } + Level::ForceWarn => rustc_errors::Level::ForceWarning, + Level::Warn => rustc_errors::Level::Warning, + Level::Deny | Level::Forbid => rustc_errors::Level::Error, + }; + // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly), + // so we need to make sure when we do call `decorate` that the diagnostic is eventually + // emitted or we'll get a `must_produce_diag` ICE. + // + // When is a diagnostic *eventually* emitted? Well, that is determined by 2 factors: + // 1. If the corresponding `rustc_errors::Level` is beyond warning, i.e. `ForceWarning(_)` + // or `Error`, then the diagnostic will be emitted regardless of CLI options. + // 2. If the corresponding `rustc_errors::Level` is warning, then that can be affected by + // `-A warnings` or `--cap-lints=xxx` on the command line. In which case, the diagnostic + // will be emitted if `can_emit_warnings` is true. + let skip = err_level == rustc_errors::Level::Warning && !sess.dcx().can_emit_warnings(); + + let disable_suggestions = if let Some(ref span) = span + // If this code originates in a foreign macro, aka something that this crate + // did not itself author, then it's likely that there's nothing this crate + // can do about it. We probably want to skip the lint entirely. + && span.primary_spans().iter().any(|s| s.in_external_macro(sess.source_map())) + { + true + } else { + false + }; + + let mut err: Diag<'_, ()> = if !skip { + decorate(sess.dcx(), err_level) + } else { + Diag::new(sess.dcx(), err_level, "") + }; + if let Some(span) = span + && err.span.primary_span().is_none() + { + // We can't use `err.span()` because it overwrites the labels, so we need to do it manually. + for primary in span.primary_spans() { + err.span.push_primary_span(*primary); + } + for (label_span, label) in span.span_labels_raw() { + err.span.push_span_diag(*label_span, label.clone()); + } + } + if let Some(lint_id) = lint_id { + err.lint_id(lint_id); + } + + if disable_suggestions { + // Any suggestions made here are likely to be incorrect, so anything we + // emit shouldn't be automatically fixed by rustfix. + err.disable_suggestions(); + + // If this is a future incompatible that is not an edition fixing lint + // it'll become a hard error, so we have to emit *something*. Also, + // if this lint occurs in the expansion of a macro from an external crate, + // allow individual lints to opt-out from being reported. + let incompatible = future_incompatible.is_some_and(|f| f.reason.edition().is_none()); + + if !incompatible && !lint.report_in_external_macro { + err.cancel(); + + // Don't continue further, since we don't want to have + // `diag_span_note_once` called for a diagnostic that isn't emitted. + return; + } + } + + err.is_lint(lint.name_lower(), has_future_breakage); + // Lint diagnostics that are covered by the expect level will not be emitted outside + // the compiler. It is therefore not necessary to add any information for the user. + // This will therefore directly call the decorate function which will in turn emit + // the diagnostic. + if let Level::Expect = level { + err.emit(); + return; + } + + if let Some(future_incompatible) = future_incompatible { + let explanation = match future_incompatible.reason { + FutureIncompatibilityReason::FutureReleaseError(_) => { + "this was previously accepted by the compiler but is being phased out; \ + it will become a hard error in a future release!" + .to_owned() + } + FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) => { + "this will change its meaning in a future release!".to_owned() + } + FutureIncompatibilityReason::EditionError(EditionFcw { edition, .. }) => { + let current_edition = sess.edition(); + format!( + "this is accepted in the current edition (Rust {current_edition}) but is a hard error in Rust {edition}!" + ) + } + FutureIncompatibilityReason::EditionSemanticsChange(EditionFcw { + edition, .. + }) => { + format!("this changes meaning in Rust {edition}") + } + FutureIncompatibilityReason::EditionAndFutureReleaseError(EditionFcw { + edition, + .. + }) => { + format!( + "this was previously accepted by the compiler but is being phased out; \ + it will become a hard error in Rust {edition} and in a future release in all editions!" + ) + } + FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange( + EditionFcw { edition, .. }, + ) => { + format!( + "this changes meaning in Rust {edition} and in a future release in all editions!" + ) + } + FutureIncompatibilityReason::Custom(reason, _) => reason.to_owned(), + FutureIncompatibilityReason::Unreachable => unreachable!(), + }; + + if future_incompatible.explain_reason { + err.warn(explanation); + } + + let citation = + format!("for more information, see {}", future_incompatible.reason.reference()); + err.note(citation); + } + + explain_lint_level_source(sess, lint, level, src, &mut err); + err.emit(); + } + diag_lint_level_impl( + sess, + lint, + level, + span, + Box::new(move |dcx, level| decorate.into_diag(dcx, level)), + ); +} diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs index cbfeae2051777..30a781b025fd5 100644 --- a/compiler/rustc_middle/src/mir/graphviz.rs +++ b/compiler/rustc_middle/src/mir/graphviz.rs @@ -16,12 +16,12 @@ where let mirs = def_ids .iter() - .filter(|def_id| !tcx.is_trivial_const(*def_id)) - .flat_map(|def_id| { - if tcx.is_const_fn(*def_id) { - vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)] + .filter(|&&def_id| !tcx.is_trivial_const(def_id)) + .flat_map(|&def_id| { + if tcx.is_const_fn(def_id) { + vec![tcx.optimized_mir(def_id), tcx.mir_for_ctfe(def_id)] } else { - vec![tcx.instance_mir(ty::InstanceKind::Item(*def_id))] + vec![tcx.instance_mir(ty::InstanceKind::Item(def_id))] } }) .collect::>(); diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index a4ab1f364c168..654404f9790cb 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -309,7 +309,7 @@ impl<'tcx> GlobalAlloc<'tcx> { pub fn mutability(&self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Mutability { // Let's see what kind of memory we are. - match self { + match *self { GlobalAlloc::Static(did) => { let DefKind::Static { safety: _, mutability, nested } = tcx.def_kind(did) else { bug!() @@ -351,7 +351,7 @@ impl<'tcx> GlobalAlloc<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ) -> (Size, Align) { - match self { + match *self { GlobalAlloc::Static(def_id) => { let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!("GlobalAlloc::Static is not a static") diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 03618ee6acd46..6b19bf23edc2f 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -633,13 +633,6 @@ mod sealed { } } - impl<'a, P: Copy> IntoQueryParam

for &'a P { - #[inline(always)] - fn into_query_param(self) -> P { - *self - } - } - impl IntoQueryParam for OwnerId { #[inline(always)] fn into_query_param(self) -> LocalDefId { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 47843a260440e..b57de30201876 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1331,8 +1331,8 @@ impl<'tcx> TyCtxt<'tcx> { caller: DefId, ) -> Option>> { let fun_features = &self.codegen_fn_attrs(fun_def).target_features; - let callee_features = &self.codegen_fn_attrs(caller).target_features; - if self.is_target_feature_call_safe(&fun_features, &callee_features) { + let caller_features = &self.body_codegen_attrs(caller).target_features; + if self.is_target_feature_call_safe(&fun_features, &caller_features) { return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig })); } None @@ -2086,7 +2086,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given a `ty`, return whether it's an `impl Future<...>`. pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { - let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; + let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, DUMMY_SP); self.explicit_item_self_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { diff --git a/compiler/rustc_middle/src/ty/significant_drop_order.rs b/compiler/rustc_middle/src/ty/significant_drop_order.rs index f1aa7076d98ac..5035127b8c9ca 100644 --- a/compiler/rustc_middle/src/ty/significant_drop_order.rs +++ b/compiler/rustc_middle/src/ty/significant_drop_order.rs @@ -119,7 +119,7 @@ pub fn extract_component_with_significant_dtor<'tcx>( /// when we are working with current local crate. #[instrument(level = "trace", skip(tcx))] pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { - match ty.kind() { + match *ty.kind() { ty::Bool | ty::Char | ty::Int(_) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c3be0b630d6ed..c29f3e7458e54 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -417,7 +417,7 @@ impl<'tcx> TyCtxt<'tcx> { continue; } - let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + let Some(&item_id) = self.associated_item_def_ids(impl_did).first() else { self.dcx() .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function"); continue; @@ -435,7 +435,7 @@ impl<'tcx> TyCtxt<'tcx> { .delay_as_bug(); } - dtor_candidate = Some(*item_id); + dtor_candidate = Some(item_id); } let did = dtor_candidate?; diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index e8427b5d6e1eb..24d184121ffd0 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -370,7 +370,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Some intrinsics are handled here because they desperately want to avoid introducing // unnecessary copies. ExprKind::Call { ty, fun, ref args, .. } - if let ty::FnDef(def_id, generic_args) = ty.kind() + if let ty::FnDef(def_id, generic_args) = *ty.kind() && let Some(intrinsic) = this.tcx.intrinsic(def_id) && matches!(intrinsic.name, sym::write_via_move | sym::write_box_via_move) => { diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 001c4338ad0e1..24c85b7ec3f5d 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -471,7 +471,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => { let fn_ty = self.thir[fun].ty; let sig = fn_ty.fn_sig(self.tcx); - let (callee_features, safe_target_features): (&[_], _) = match fn_ty.kind() { + let (callee_features, safe_target_features): (&[_], _) = match *fn_ty.kind() { ty::FnDef(func_id, ..) => { let cg_attrs = self.tcx.codegen_fn_attrs(func_id); (&cg_attrs.target_features, cg_attrs.safe_target_features) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 8998be26412d5..f33e43162c3f4 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -251,19 +251,16 @@ where // impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...' // (#140974). // Such code will report error, so just generate sync drop here and return - let Some(drop_fn_def_id) = tcx - .associated_item_def_ids(drop_trait) - .first() - .and_then(|def_id| { + let Some(drop_fn_def_id) = + tcx.associated_item_def_ids(drop_trait).first().and_then(|&def_id| { if tcx.def_kind(def_id) == DefKind::AssocFn - && tcx.check_args_compatible(*def_id, trait_args) + && tcx.check_args_compatible(def_id, trait_args) { Some(def_id) } else { None } }) - .copied() else { tcx.dcx().span_delayed_bug( self.elaborator.body().span, diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 78c161ebd58c9..656b74e15f727 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -440,7 +440,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { } } - if let ty::FnDef(did, ..) = func.ty(&self.body.local_decls, self.tcx).kind() + if let ty::FnDef(did, ..) = *func.ty(&self.body.local_decls, self.tcx).kind() && self.body.phase >= MirPhase::Runtime(RuntimePhase::Optimized) && matches!(self.tcx.codegen_fn_attrs(did).inline, InlineAttr::Force { .. }) { diff --git a/compiler/rustc_monomorphize/src/collector/autodiff.rs b/compiler/rustc_monomorphize/src/collector/autodiff.rs index e3646596e75e6..67d4b8c8afff2 100644 --- a/compiler/rustc_monomorphize/src/collector/autodiff.rs +++ b/compiler/rustc_monomorphize/src/collector/autodiff.rs @@ -28,13 +28,13 @@ fn collect_autodiff_fn_from_arg<'tcx>( output: &mut MonoItems<'tcx>, ) { let (instance, span) = match arg.kind() { - ty::GenericArgKind::Type(ty) => match ty.kind() { + ty::GenericArgKind::Type(ty) => match *ty.kind() { ty::FnDef(def_id, substs) => { let span = tcx.def_span(def_id); let instance = ty::Instance::expect_resolve( tcx, ty::TypingEnv::non_body_analysis(tcx, def_id), - *def_id, + def_id, substs, span, ); diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 249c5e6397461..abe63e073ad78 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -37,7 +37,7 @@ fn custom_coerce_unsize_info<'tcx>( Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { impl_def_id, .. - })) => Ok(tcx.coerce_unsized_info(impl_def_id)?.custom_kind.unwrap()), + })) => Ok(tcx.coerce_unsized_info(*impl_def_id)?.custom_kind.unwrap()), impl_source => { bug!( "invalid `CoerceUnsized` from {source_ty} to {target_ty}: impl_source: {:?}", diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 0adf1b089b53e..a8f3104c0d98d 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -190,7 +190,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { } fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option { - for impl_def_id in tcx.inherent_impls(def_id) { + for &impl_def_id in tcx.inherent_impls(def_id) { if let Some(new) = tcx.associated_items(impl_def_id).find_by_ident_and_kind( tcx, fn_ident, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ad667df47123f..b01afe550e74f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2207,7 +2207,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) }) .collect(); - if let Some(def_id) = path.get(0) + if let Some(&def_id) = path.get(0) && let Some(path) = path_names { if let Some(def_id) = def_id.as_local() { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 59a5c0728a753..0fba8295afbac 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1295,7 +1295,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .tcx .associated_item_def_ids(def_id) .iter() - .map(|field_id| self.tcx.visibility(field_id)) + .map(|&field_id| self.tcx.visibility(field_id)) .collect(); (ctor_res, ctor_vis, field_visibilities) }) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b1d6e3526d9cd..9f5196d894893 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2359,7 +2359,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .tcx .associated_item_def_ids(def_id) .iter() - .map(|field_id| self.r.tcx.visibility(field_id)) + .map(|&field_id| self.r.tcx.visibility(field_id)) .collect(); (ctor_res, ctor_vis, field_visibilities) }) @@ -2594,7 +2594,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .tcx .inherent_impls(def_id) .iter() - .flat_map(|i| self.r.tcx.associated_items(i).in_definition_order()) + .flat_map(|&i| self.r.tcx.associated_items(i).in_definition_order()) // Only assoc fn with no receivers. .filter(|item| item.is_fn() && !item.is_method()) .filter_map(|item| { @@ -2702,7 +2702,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .tcx .associated_item_def_ids(def_id) .iter() - .map(|field_id| self.r.tcx.visibility(field_id)) + .map(|&field_id| self.r.tcx.visibility(field_id)) .collect(), ), }; diff --git a/compiler/rustc_target/src/callconv/powerpc64.rs b/compiler/rustc_target/src/callconv/powerpc64.rs index a77724a572dca..1d83799d7dab1 100644 --- a/compiler/rustc_target/src/callconv/powerpc64.rs +++ b/compiler/rustc_target/src/callconv/powerpc64.rs @@ -5,7 +5,7 @@ use rustc_abi::{Endian, HasDataLayout, TyAbiInterface}; use crate::callconv::{Align, ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::spec::{Env, HasTargetSpec, Os}; +use crate::spec::{Abi, HasTargetSpec, Os}; #[derive(Debug, Clone, Copy, PartialEq)] enum ABI { @@ -106,8 +106,10 @@ where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec, { - let abi = if cx.target_spec().env == Env::Musl || cx.target_spec().os == Os::FreeBsd { + let abi = if cx.target_spec().options.abi == Abi::ElfV2 { ELFv2 + } else if cx.target_spec().options.abi == Abi::ElfV1 { + ELFv1 } else if cx.target_spec().os == Os::Aix { AIX } else { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2d2f15651c431..d9c872c9b4352 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3194,6 +3194,27 @@ impl Target { "ARM targets must set `llvm-floatabi` to `hard` or `soft`", ) } + // PowerPC64 targets that are not AIX must set their ABI to either ELFv1 or ELFv2 + Arch::PowerPC64 => { + if self.os == Os::Aix { + check!( + self.llvm_abiname.is_empty(), + "AIX targets always use the AIX ABI and `llvm_abiname` should be left empty", + ); + } else if self.endian == Endian::Big { + check_matches!( + &*self.llvm_abiname, + "elfv1" | "elfv2", + "invalid PowerPC64 ABI name: {}", + self.llvm_abiname, + ); + } else { + check!( + self.llvm_abiname == "elfv2", + "little-endian PowerPC64 targets only support the `elfv2` ABI", + ); + } + } _ => {} } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 16c4ac68cdf0c..060204946d014 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -362,7 +362,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && self.tcx.trait_of_assoc(*item_id) == Some(*trait_id) && let None = self.tainted_by_errors() { - let assoc_item = self.tcx.associated_item(item_id); + let assoc_item = self.tcx.associated_item(*item_id); let (verb, noun) = match assoc_item.kind { ty::AssocKind::Const { .. } => ("refer to the", "constant"), ty::AssocKind::Fn { .. } => ("call", "function"), @@ -394,7 +394,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id); - if let Some(impl_def_id) = + if let Some(&impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next() { let non_blanket_impl_count = @@ -418,7 +418,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .non_blanket_impls() .values() .flatten() - .map(|id| { + .map(|&id| { format!( "{}", self.tcx.type_of(id).instantiate_identity() diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 2c7105ab4ebea..983890f6b48db 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1799,7 +1799,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { with_forced_trimmed_paths! { if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) { - let (span, closure_span) = if let ty::Closure(def_id, _) = self_ty.kind() { + let (span, closure_span) = if let ty::Closure(def_id, _) = *self_ty.kind() { let def_span = self.tcx.def_span(def_id); if let Some(local_def_id) = def_id.as_local() && let node = self.tcx.hir_node_by_def_id(local_def_id) @@ -2305,7 +2305,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; if candidates.len() < 5 { let spans: Vec<_> = - candidates.iter().map(|(_, def_id)| self.tcx.def_span(def_id)).collect(); + candidates.iter().map(|&(_, def_id)| self.tcx.def_span(def_id)).collect(); let mut span: MultiSpan = spans.into(); for (c, def_id) in &candidates { let msg = if all_traits_equal { @@ -2317,7 +2317,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.short_string(c.print_only_trait_path(), err.long_ty_path()), ) }; - span.push_span_label(self.tcx.def_span(def_id), msg); + span.push_span_label(self.tcx.def_span(*def_id), msg); } err.span_help( span, @@ -2631,16 +2631,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) }; let trait_name = self.tcx.item_name(trait_def_id); - if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| { - trait_def_id != *def_id + if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|&def_id| { + trait_def_id != def_id && trait_name == self.tcx.item_name(def_id) - && trait_has_same_params(*def_id) + && trait_has_same_params(def_id) && self.predicate_must_hold_modulo_regions(&Obligation::new( self.tcx, obligation.cause.clone(), obligation.param_env, trait_pred.map_bound(|tr| ty::TraitPredicate { - trait_ref: ty::TraitRef::new(self.tcx, *def_id, tr.trait_ref.args), + trait_ref: ty::TraitRef::new(self.tcx, def_id, tr.trait_ref.args), ..tr }), )) @@ -3314,7 +3314,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { terr: TypeError<'tcx>, ) -> Diag<'a> { let self_ty = found_trait_ref.self_ty(); - let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { + let (cause, terr) = if let ty::Closure(def_id, _) = *self_ty.kind() { ( ObligationCause::dummy_with_span(self.tcx.def_span(def_id)), TypeError::CyclicTy(self_ty), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index a7a685d62b345..c239f0b56c83f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -373,12 +373,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.extern_crate(trait_def_id.krate), ) { ( - Some(ExternCrate { + Some(&ExternCrate { src: ExternCrateSource::Extern(expected_def_id), dependency_of: LOCAL_CRATE, .. }), - Some(ExternCrate { + Some(&ExternCrate { src: ExternCrateSource::Extern(trait_def_id), dependency_of: LOCAL_CRATE, .. @@ -402,9 +402,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let krate = self.tcx.crate_name(expected_did.krate); let name = self.tcx.item_name(expected_did); let definitions_with_same_path: UnordSet<_> = found_dids - .filter(|def_id| { + .filter(|&def_id| { def_id.krate != expected_did.krate - && (self.extern_crates_with_the_same_name(expected_did, *def_id) + && (self.extern_crates_with_the_same_name(expected_did, def_id) || self.tcx.crate_name(def_id.krate) == krate) && self.tcx.item_name(def_id) == name }) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 9c146d7326135..0af7b0e3253dd 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -207,7 +207,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if self_ty.is_fn() { let fn_sig = self_ty.fn_sig(self.tcx); - let shortname = if let ty::FnDef(def_id, _) = self_ty.kind() + let shortname = if let ty::FnDef(def_id, _) = *self_ty.kind() && self.tcx.codegen_fn_attrs(def_id).safe_target_features { "#[target_feature] fn" diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs index 8488d76e2c773..360a01a8a3759 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs @@ -231,7 +231,7 @@ fn parse_arg<'tcx>( is_source_literal: bool, ) -> FormatArg { let (Ctx::RustcOnUnimplemented { tcx, trait_def_id } - | Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx; + | Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = *ctx; let span = slice_span(input_span, arg.position_span.clone(), is_source_literal); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 18b926ad28c89..176cc8c4c2cab 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -2244,9 +2244,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check // that the predicate that we failed to satisfy is a `Fn`-like trait. - if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = cause + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) - && let Some(pred) = predicates.predicates.get(*idx) + && let Some(pred) = predicates.predicates.get(idx) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() && self.tcx.is_fn_trait(trait_pred.def_id()) { @@ -2257,7 +2257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Find another predicate whose self-type is equal to the expected self type, // but whose args don't match. - let other_pred = predicates.into_iter().enumerate().find(|(other_idx, (pred, _))| { + let other_pred = predicates.into_iter().enumerate().find(|&(other_idx, (pred, _))| { match pred.kind().skip_binder() { ty::ClauseKind::Trait(trait_pred) if self.tcx.is_fn_trait(trait_pred.def_id()) @@ -3029,10 +3029,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let len = impls.len(); let mut types = impls .iter() - .map(|t| { + .map(|&&t| { with_no_trimmed_paths!(format!( " {}", - tcx.type_of(*t).instantiate_identity(), + tcx.type_of(t).instantiate_identity(), )) }) .collect::>(); @@ -3421,7 +3421,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let ty_str = tcx.short_string(ty, err.long_ty_path()); format!("required because it appears within the type `{ty_str}`") }; - match ty.kind() { + match *ty.kind() { ty::Adt(def, _) => { let msg = msg(); match tcx.opt_item_ident(def.did()) { @@ -4216,11 +4216,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // to an associated type (as seen from `trait_pred`) in the predicate. Like in // trait_pred `S: Sum<::Item>` and predicate `i32: Sum<&()>` let mut type_diffs = vec![]; - if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = parent_code + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = *parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) - && let Some(where_pred) = where_clauses.predicates.get(*idx) + && let Some(where_pred) = where_clauses.predicates.get(idx) { if let Some(where_pred) = where_pred.as_trait_clause() && let Some(failed_pred) = failed_pred.as_trait_clause() diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 2e60805cd10a5..8a61d9a021752 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -267,7 +267,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( return; } - match ty.kind() { + match *ty.kind() { ty::Bool | ty::Char | ty::Int(_) @@ -287,7 +287,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( ty::Pat(ety, _) | ty::Array(ety, _) | ty::Slice(ety) => { // single-element containers, behave like their element rustc_data_structures::stack::ensure_sufficient_stack(|| { - dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, *ety, constraints) + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ety, constraints) }); } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index cec41524325e0..f63351ebfd809 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -289,6 +289,7 @@ struct RcInner { } /// Calculate layout for `RcInner` using the inner value's layout +#[inline] fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression @@ -2518,15 +2519,25 @@ impl Default for Rc { /// ``` #[inline] fn default() -> Self { + // First create an uninitialized allocation before creating an instance + // of `T`. This avoids having `T` on the stack and avoids the need to + // codegen a call to the destructor for `T` leading to generally better + // codegen. See #131460 for some more details. + let mut rc = Rc::new_uninit(); + + // SAFETY: this is a freshly allocated `Rc` so it's guaranteed there are + // no other strong or weak pointers other than `rc` itself. unsafe { - Self::from_inner( - Box::leak(Box::write( - Box::new_uninit(), - RcInner { strong: Cell::new(1), weak: Cell::new(1), value: T::default() }, - )) - .into(), - ) + let raw = Rc::get_mut_unchecked(&mut rc); + + // Note that `ptr::write` here is used specifically instead of + // `MaybeUninit::write` to avoid creating an extra stack copy of `T` + // in debug mode. See #136043 for more context. + ptr::write(raw.as_mut_ptr(), T::default()); } + + // SAFETY: this allocation was just initialized above. + unsafe { rc.assume_init() } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index dc82357dd146b..d097588f8e633 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -392,6 +392,7 @@ struct ArcInner { } /// Calculate layout for `ArcInner` using the inner value's layout +#[inline] fn arcinner_layout_for_value_layout(layout: Layout) -> Layout { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression @@ -3724,19 +3725,25 @@ impl Default for Arc { /// assert_eq!(*x, 0); /// ``` fn default() -> Arc { + // First create an uninitialized allocation before creating an instance + // of `T`. This avoids having `T` on the stack and avoids the need to + // codegen a call to the destructor for `T` leading to generally better + // codegen. See #131460 for some more details. + let mut arc = Arc::new_uninit(); + + // SAFETY: this is a freshly allocated `Arc` so it's guaranteed there + // are no other strong or weak pointers other than `arc` itself. unsafe { - Self::from_inner( - Box::leak(Box::write( - Box::new_uninit(), - ArcInner { - strong: atomic::AtomicUsize::new(1), - weak: atomic::AtomicUsize::new(1), - data: T::default(), - }, - )) - .into(), - ) + let raw = Arc::get_mut_unchecked(&mut arc); + + // Note that `ptr::write` here is used specifically instead of + // `MaybeUninit::write` to avoid creating an extra stack copy of `T` + // in debug mode. See #136043 for more context. + ptr::write(raw.as_mut_ptr(), T::default()); } + + // SAFETY: this allocation was just initialized above. + unsafe { arc.assume_init() } } } diff --git a/library/core/src/bstr/mod.rs b/library/core/src/bstr/mod.rs index 3e3b78b452e01..4a99e0bdcc037 100644 --- a/library/core/src/bstr/mod.rs +++ b/library/core/src/bstr/mod.rs @@ -172,39 +172,38 @@ impl fmt::Debug for ByteStr { #[unstable(feature = "bstr", issue = "134915")] impl fmt::Display for ByteStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fn fmt_nopad(this: &ByteStr, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for chunk in this.utf8_chunks() { - f.write_str(chunk.valid())?; - if !chunk.invalid().is_empty() { - f.write_str("\u{FFFD}")?; - } - } - Ok(()) - } - - let Some(align) = f.align() else { - return fmt_nopad(self, f); - }; let nchars: usize = self .utf8_chunks() .map(|chunk| { chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 } }) .sum(); + let padding = f.width().unwrap_or(0).saturating_sub(nchars); let fill = f.fill(); - let (lpad, rpad) = match align { - fmt::Alignment::Left => (0, padding), - fmt::Alignment::Right => (padding, 0), - fmt::Alignment::Center => { + + let (lpad, rpad) = match f.align() { + Some(fmt::Alignment::Right) => (padding, 0), + Some(fmt::Alignment::Center) => { let half = padding / 2; (half, half + padding % 2) } + // Either alignment is not specified or it's left aligned + // which behaves the same with padding + _ => (0, padding), }; + for _ in 0..lpad { write!(f, "{fill}")?; } - fmt_nopad(self, f)?; + + for chunk in self.utf8_chunks() { + f.write_str(chunk.valid())?; + if !chunk.invalid().is_empty() { + f.write_str("\u{FFFD}")?; + } + } + for _ in 0..rpad { write!(f, "{fill}")?; } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 94396752ac6da..33cf7af28df57 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -17,8 +17,8 @@ macro_rules! uint_impl { fsh_op = $fsh_op:literal, fshl_result = $fshl_result:literal, fshr_result = $fshr_result:literal, - clmul_lhs = $clmul_rhs:literal, - clmul_rhs = $clmul_lhs:literal, + clmul_lhs = $clmul_lhs:literal, + clmul_rhs = $clmul_rhs:literal, clmul_result = $clmul_result:literal, swap_op = $swap_op:literal, swapped = $swapped:literal, diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 603adf720789f..72f4e2dcdd7c2 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -37,14 +37,14 @@ macro_rules! with_api { fn injected_env_var(var: &str) -> Option; fn track_env_var(var: &str, value: Option<&str>); fn track_path(path: &str); - fn literal_from_str(s: &str) -> Result, ()>; + fn literal_from_str(s: &str) -> Result, String>; fn emit_diagnostic(diagnostic: Diagnostic<$Span>); fn ts_drop(stream: $TokenStream); fn ts_clone(stream: &$TokenStream) -> $TokenStream; fn ts_is_empty(stream: &$TokenStream) -> bool; fn ts_expand_expr(stream: &$TokenStream) -> Result<$TokenStream, ()>; - fn ts_from_str(src: &str) -> $TokenStream; + fn ts_from_str(src: &str) -> Result<$TokenStream, String>; fn ts_to_string(stream: &$TokenStream) -> String; fn ts_from_token_tree( tree: TokenTree<$TokenStream, $Span, $Symbol>, diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index e2f39c015bdd7..a01bf38a62dbf 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -110,15 +110,18 @@ impl !Send for TokenStream {} impl !Sync for TokenStream {} /// Error returned from `TokenStream::from_str`. +/// +/// The contained error message is explicitly not guaranteed to be stable in any way, +/// and may change between Rust versions or across compilations. #[stable(feature = "proc_macro_lib", since = "1.15.0")] #[non_exhaustive] #[derive(Debug)] -pub struct LexError; +pub struct LexError(String); #[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")] impl fmt::Display for LexError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("cannot parse string into token stream") + f.write_str(&self.0) } } @@ -197,7 +200,7 @@ impl FromStr for TokenStream { type Err = LexError; fn from_str(src: &str) -> Result { - Ok(TokenStream(Some(BridgeMethods::ts_from_str(src)))) + Ok(TokenStream(Some(BridgeMethods::ts_from_str(src).map_err(LexError)?))) } } @@ -1594,7 +1597,7 @@ impl FromStr for Literal { fn from_str(src: &str) -> Result { match BridgeMethods::literal_from_str(src) { Ok(literal) => Ok(Literal(literal)), - Err(()) => Err(LexError), + Err(msg) => Err(LexError(msg)), } } } diff --git a/library/rtstartup/rsbegin.rs b/library/rtstartup/rsbegin.rs index 62d247fafb7ad..6ee06cce5c630 100644 --- a/library/rtstartup/rsbegin.rs +++ b/library/rtstartup/rsbegin.rs @@ -90,12 +90,12 @@ pub mod eh_frames { unsafe extern "C" fn init() { // register unwind info on module startup - __register_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8); + __register_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &raw mut OBJ as *mut u8); } unsafe extern "C" fn uninit() { // unregister on shutdown - __deregister_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &mut OBJ as *mut _ as *mut u8); + __deregister_frame_info(&__EH_FRAME_BEGIN__ as *const u8, &raw mut OBJ as *mut u8); } // MinGW-specific init/uninit routine registration diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index b32c6cd442ffa..ff3ae8145e0f6 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -573,7 +573,8 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { /// /// # Example /// - /// ``` + #[cfg_attr(target_vendor = "win7", doc = "```no_run")] + #[cfg_attr(not(target_vendor = "win7"), doc = "```")] /// #![feature(windows_process_extensions_raw_attribute)] /// use std::ffi::c_void; /// use std::os::windows::process::{CommandExt, ProcThreadAttributeList}; diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs index 4094b7acd8749..8997b8ad192dc 100644 --- a/library/std/tests/path.rs +++ b/library/std/tests/path.rs @@ -2291,6 +2291,26 @@ fn display_format_flags() { assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b"); } +#[test] +fn display_path_with_padding_no_align() { + assert_eq!(format!("{:10}", Path::new("/foo/bar").display()), "/foo/bar "); +} + +#[test] +fn display_path_with_padding_align_left() { + assert_eq!(format!("{:<10}", Path::new("/foo/bar").display()), "/foo/bar "); +} + +#[test] +fn display_path_with_padding_align_right() { + assert_eq!(format!("{:>10}", Path::new("/foo/bar").display()), " /foo/bar"); +} + +#[test] +fn display_path_with_padding_align_center() { + assert_eq!(format!("{:^10}", Path::new("/foo/bar").display()), " /foo/bar "); +} + #[test] fn into_rc() { let orig = "hello/world"; diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md index 68fbec2ff4b4c..611ec04b42c8a 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/armv7a-vex-v5.md @@ -24,7 +24,7 @@ This target is cross-compiled. Dynamic linking is unsupported. `std` has only partial support due to platform limitations. Notably: - `std::process` and `std::net` are unimplemented. `std::thread` only supports sleeping and yielding, as this is a single-threaded environment. - `std::time` has full support for `Instant`, but no support for `SystemTime`. -- `std::io` has full support for `stdin`/`stdout`/`stderr`. `stdout` and `stderr` both write to to USB channel 1 on this platform and are not differentiated. +- `std::io` has full support for `stdin`/`stdout`/`stderr`. `stdout` and `stderr` both write to USB channel 1 on this platform and are not differentiated. - `std::fs` has limited support for reading or writing to files. Directory operations, file deletion, and some file opening features are unsupported and will return errors. - A global allocator implemented on top of `dlmalloc` is provided. - Modules that do not need to interact with the OS beyond allocation such as `std::collections`, `std::hash`, `std::future`, `std::sync`, etc are fully supported. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9c7685ca30bc9..fb0dbac7c41df 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -191,7 +191,7 @@ pub(crate) fn try_inline_glob( .iter() .filter(|child| !child.reexport_chain.is_empty()) .filter_map(|child| child.res.opt_def_id()) - .filter(|def_id| !cx.tcx.is_doc_hidden(def_id)) + .filter(|&def_id| !cx.tcx.is_doc_hidden(def_id)) .collect(); let attrs = cx.tcx.hir_attrs(import.hir_id()); let mut items = build_module_items( diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 927a7e0f07159..b58daceed0702 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -94,7 +94,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // While the `impl` blocks themselves are only in `libcore`, the module with `doc` // attached is directly included in `libstd` as well. if did.is_local() { - for def_id in prim.impls(tcx).filter(|def_id| { + for def_id in prim.impls(tcx).filter(|&def_id| { // Avoid including impl blocks with filled-in generics. // https://github.com/rust-lang/rust/issues/94937 // diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index bb94a111f7a14..20cf3796c8be9 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -150,16 +150,16 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx let callee_ty_adjustments = typeck.expr_adjustments(callee); let callee_ty_adjusted = callee_ty_adjustments.last().map_or(callee_ty, |a| a.target); - let sig = match callee_ty_adjusted.kind() { + let sig = match *callee_ty_adjusted.kind() { ty::FnDef(def, _) => { // Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location` - if find_attr!(cx.tcx, *def, TrackCaller(..)) { + if find_attr!(cx.tcx, def, TrackCaller(..)) { return; } cx.tcx.fn_sig(def).skip_binder().skip_binder() }, - ty::FnPtr(sig_tys, hdr) => sig_tys.with(*hdr).skip_binder(), + ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr).skip_binder(), ty::Closure(_, subs) => cx .tcx .signature_unclosure(subs.as_closure().sig(), Safety::Safe) diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index aed4a0075c2fd..832197d36cc65 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -133,7 +133,7 @@ fn check_unwrap_or_default( let output_type_implements_default = |fun| { let fun_ty = cx.typeck_results().expr_ty(fun); - if let ty::FnDef(def_id, args) = fun_ty.kind() { + if let ty::FnDef(def_id, args) = *fun_ty.kind() { let output_ty = cx.tcx.fn_sig(def_id).instantiate(cx.tcx, args).skip_binder().output(); cx.tcx .get_diagnostic_item(sym::Default) @@ -153,7 +153,7 @@ fn check_unwrap_or_default( cx.tcx .inherent_impls(adt_def.did()) .iter() - .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) + .flat_map(|&impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) .find_map(|assoc| { if assoc.is_method() && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1 { Some(assoc.def_id) diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs index 43c62e1e131a3..92515bd3fb804 100644 --- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs +++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs @@ -287,7 +287,7 @@ fn is_assoc_fn_without_type_instance<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<' .. }, )) = func.kind - && let output_ty = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder().output() + && let output_ty = cx.tcx.fn_sig(*def_id).instantiate_identity().skip_binder().output() && let ty::Param(ty::ParamTy { name: kw::SelfUpper, .. }) = output_ty.kind() diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index c1e03b7e8c705..1b7d7fd6c68cb 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -335,8 +335,8 @@ impl UnconditionalRecursion { let impls = cx.tcx.trait_impls_of(default_trait_id); for (ty, impl_def_ids) in impls.non_blanket_impls() { let Some(self_def_id) = ty.def() else { continue }; - for impl_def_id in impl_def_ids { - if !cx.tcx.is_automatically_derived(*impl_def_id) && + for &impl_def_id in impl_def_ids { + if !cx.tcx.is_automatically_derived(impl_def_id) && let Some(assoc_item) = cx .tcx .associated_items(impl_def_id) diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 9a49845d9d46b..fdd270c2774af 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -601,9 +601,9 @@ pub fn is_default_equivalent_call( && let StatementKind::Assign(assign) = &block_data.statements[0].kind && assign.0.local == RETURN_PLACE && let Rvalue::Aggregate(kind, _places) = &assign.1 - && let AggregateKind::Adt(did, variant_index, _, _, _) = &**kind + && let AggregateKind::Adt(did, variant_index, _, _, _) = **kind && let def = cx.tcx.adt_def(did) - && let variant = &def.variant(*variant_index) + && let variant = &def.variant(variant_index) && variant.fields.is_empty() && let Some((_, did)) = variant.ctor && did == repl_def_id diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 8aa663163caf1..e6593aa8b5541 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -335,7 +335,7 @@ fn non_local_item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, ns: PathNS, name .associated_item_def_ids(def_id) .iter() .copied() - .find(|assoc_def_id| tcx.item_name(*assoc_def_id) == name && ns.matches(tcx.def_kind(assoc_def_id).ns())), + .find(|&assoc_def_id| tcx.item_name(assoc_def_id) == name && ns.matches(tcx.def_kind(assoc_def_id).ns())), _ => None, } } diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index 3e1ad6c0ef515..36410a81fbf65 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -310,13 +310,13 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { // Returns whether the type has #[must_use] attribute pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - match ty.kind() { + match *ty.kind() { ty::Adt(adt, _) => find_attr!(cx.tcx, adt.did(), MustUse { .. }), - ty::Foreign(did) => find_attr!(cx.tcx, *did, MustUse { .. }), + ty::Foreign(did) => find_attr!(cx.tcx, did, MustUse { .. }), ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => { // for the Array case we don't need to care for the len == 0 case // because we don't want to lint functions returning empty arrays - is_must_use_ty(cx, *ty) + is_must_use_ty(cx, ty) }, ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => { @@ -330,7 +330,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { false }, ty::Dynamic(binder, _) => { - for predicate in *binder { + for predicate in binder { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() && find_attr!(cx.tcx, trait_ref.def_id, MustUse { .. }) { diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 5dcd2d9ec2084..facfade026be8 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -62,7 +62,7 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option) // Go over the modules. for &segment in modules { let Some(next_item) = find_children(tcx, cur_item, segment) - .find(|item| tcx.def_kind(item) == DefKind::Mod) + .find(|&item| tcx.def_kind(item) == DefKind::Mod) else { continue 'crates; }; @@ -72,7 +72,7 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option) match item { Some((item_name, namespace)) => { let Some(item) = find_children(tcx, cur_item, item_name) - .find(|item| tcx.def_kind(item).ns() == Some(namespace)) + .find(|&item| tcx.def_kind(item).ns() == Some(namespace)) else { continue 'crates; }; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index c114d52ec33c6..d85deba75728e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -62,8 +62,9 @@ impl server::Server for RaSpanServer<'_> { self.tracked_paths.insert(path.into()); } - fn literal_from_str(&mut self, s: &str) -> Result, ()> { + fn literal_from_str(&mut self, s: &str) -> Result, String> { literal_from_str(s, self.call_site) + .map_err(|()| "cannot parse string into literal".to_string()) } fn emit_diagnostic(&mut self, _: Diagnostic) { @@ -81,14 +82,9 @@ impl server::Server for RaSpanServer<'_> { fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { - Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { - Self::TokenStream::from_str( - &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), - self.call_site, - ) - .unwrap() - }) + fn ts_from_str(&mut self, src: &str) -> Result { + Self::TokenStream::from_str(src, self.call_site) + .map_err(|e| format!("failed to parse str to token stream: {e}")) } fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 70484c4dc28fe..e1c96095c8fc1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -67,8 +67,9 @@ impl server::Server for SpanIdServer<'_> { self.tracked_paths.insert(path.into()); } - fn literal_from_str(&mut self, s: &str) -> Result, ()> { + fn literal_from_str(&mut self, s: &str) -> Result, String> { literal_from_str(s, self.call_site) + .map_err(|()| "cannot parse string into literal".to_string()) } fn emit_diagnostic(&mut self, _: Diagnostic) {} @@ -84,14 +85,9 @@ impl server::Server for SpanIdServer<'_> { fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { - Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { - Self::TokenStream::from_str( - &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), - self.call_site, - ) - .unwrap() - }) + fn ts_from_str(&mut self, src: &str) -> Result { + Self::TokenStream::from_str(src, self.call_site) + .map_err(|e| format!("failed to parse str to token stream: {e}")) } fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() diff --git a/tests/codegen-llvm/issues/issue-111603.rs b/tests/codegen-llvm/issues/issue-111603.rs index 2ba5a3f876aed..91eb836478eb1 100644 --- a/tests/codegen-llvm/issues/issue-111603.rs +++ b/tests/codegen-llvm/issues/issue-111603.rs @@ -10,9 +10,9 @@ use std::sync::Arc; pub fn new_from_array(x: u64) -> Arc<[u64]> { // Ensure that we only generate one alloca for the array. - // CHECK: alloca + // CHECK: %[[A:.+]] = alloca // CHECK-SAME: [8000 x i8] - // CHECK-NOT: alloca + // CHECK-NOT: %[[B:.+]] = alloca let array = [x; 1000]; Arc::new(array) } @@ -20,8 +20,9 @@ pub fn new_from_array(x: u64) -> Arc<[u64]> { // CHECK-LABEL: @new_uninit #[no_mangle] pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> { - // CHECK: call alloc::sync::arcinner_layout_for_value_layout - // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout + // CHECK: %[[A:.+]] = alloca + // CHECK-SAME: [8000 x i8] + // CHECK-NOT: %[[B:.+]] = alloca let mut arc = Arc::new_uninit(); unsafe { Arc::get_mut_unchecked(&mut arc) }.write([x; 1000]); unsafe { arc.assume_init() } @@ -30,8 +31,7 @@ pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> { // CHECK-LABEL: @new_uninit_slice #[no_mangle] pub fn new_uninit_slice(x: u64) -> Arc<[u64]> { - // CHECK: call alloc::sync::arcinner_layout_for_value_layout - // CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout + // CHECK-NOT: %[[B:.+]] = alloca let mut arc = Arc::new_uninit_slice(1000); for elem in unsafe { Arc::get_mut_unchecked(&mut arc) } { elem.write(x); diff --git a/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs b/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs new file mode 100644 index 0000000000000..f09e52e9298bb --- /dev/null +++ b/tests/ui/consts/const-eval/simd/simd-packed-non-pow2.rs @@ -0,0 +1,18 @@ +//@ check-pass +// Fixes #151537 +#![feature(portable_simd, core_intrinsics)] +use std::intrinsics::simd::SimdAlign; +use std::{ptr::null, simd::prelude::*}; + +const _: () = { + let c = Simd::from_array([0; 3]); + unsafe { + core::intrinsics::simd::simd_masked_store::<_, _, _, { SimdAlign::Element }>( + c, + null::(), + c, + ) + }; +}; + +fn main() {} diff --git a/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs b/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs index 47d0608646704..1777eb07de953 100644 --- a/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs +++ b/tests/ui/proc-macro/auxiliary/invalid-punct-ident.rs @@ -20,5 +20,9 @@ pub fn invalid_raw_ident(_: TokenStream) -> TokenStream { #[proc_macro] pub fn lexer_failure(_: TokenStream) -> TokenStream { - "a b ) c".parse().expect("parsing failed without panic") + assert_eq!( + "a b ) c".parse::().unwrap_err().to_string(), + "unexpected closing delimiter: `)`" + ); + TokenStream::new() } diff --git a/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs b/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs index 854d27d7ed323..f58aa1b228e31 100644 --- a/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs +++ b/tests/ui/proc-macro/auxiliary/nonfatal-parsing-body.rs @@ -110,6 +110,10 @@ pub fn run() { lit("3//\n4", NormalErr); lit("18.u8E", NormalErr); lit("/*a*/ //", NormalErr); + stream("1 ) 2", NormalErr); + stream("( x [ ) ]", NormalErr); + lit("1 ) 2", NormalErr); + lit("( x [ ) ]", NormalErr); // FIXME: all of the cases below should return an Err and emit no diagnostics, but don't yet. // emits diagnostics and returns LexError @@ -122,8 +126,6 @@ pub fn run() { for parse in [stream as fn(&str, Mode), lit] { // emits diagnostic(s), then panics - parse("1 ) 2", OtherWithPanic); - parse("( x [ ) ]", OtherWithPanic); parse("r#", OtherWithPanic); // emits diagnostic(s), then returns Ok(Literal { kind: ErrWithGuar, .. }) diff --git a/tests/ui/proc-macro/invalid-punct-ident-4.rs b/tests/ui/proc-macro/invalid-punct-ident-4.rs index dbffddd158579..7fb39b0cae629 100644 --- a/tests/ui/proc-macro/invalid-punct-ident-4.rs +++ b/tests/ui/proc-macro/invalid-punct-ident-4.rs @@ -1,13 +1,9 @@ //@ proc-macro: invalid-punct-ident.rs -//@ needs-unwind proc macro panics to report errors +//@ check-pass #[macro_use] extern crate invalid_punct_ident; lexer_failure!(); -//~^ ERROR proc macro panicked -//~| ERROR unexpected closing delimiter: `)` -fn main() { - let _recovery_witness: () = 0; //~ ERROR mismatched types -} +fn main() {} diff --git a/tests/ui/proc-macro/invalid-punct-ident-4.stderr b/tests/ui/proc-macro/invalid-punct-ident-4.stderr deleted file mode 100644 index ab4116141d813..0000000000000 --- a/tests/ui/proc-macro/invalid-punct-ident-4.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: unexpected closing delimiter: `)` - --> $DIR/invalid-punct-ident-4.rs:7:1 - | -LL | lexer_failure!(); - | ^^^^^^^^^^^^^^^^ unexpected closing delimiter - | - = note: this error originates in the macro `lexer_failure` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: proc macro panicked - --> $DIR/invalid-punct-ident-4.rs:7:1 - | -LL | lexer_failure!(); - | ^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/invalid-punct-ident-4.rs:12:33 - | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/proc-macro/nonfatal-parsing.stderr b/tests/ui/proc-macro/nonfatal-parsing.stderr index a44f77e7d534e..6780a359c2248 100644 --- a/tests/ui/proc-macro/nonfatal-parsing.stderr +++ b/tests/ui/proc-macro/nonfatal-parsing.stderr @@ -40,26 +40,6 @@ LL | nonfatal_parsing::run!(); = note: prefixed identifiers and literals are reserved since Rust 2021 = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) -error: unexpected closing delimiter: `)` - --> $DIR/nonfatal-parsing.rs:15:5 - | -LL | nonfatal_parsing::run!(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected closing delimiter - | - = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: unexpected closing delimiter: `]` - --> $DIR/nonfatal-parsing.rs:15:5 - | -LL | nonfatal_parsing::run!(); - | -^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the nearest open delimiter - | missing open `(` for this delimiter - | unexpected closing delimiter - | - = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) - error: found invalid character; only `#` is allowed in raw string delimitation: \u{0} --> $DIR/nonfatal-parsing.rs:15:5 | @@ -135,21 +115,6 @@ LL | nonfatal_parsing::run!(); = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: this error originates in the macro `nonfatal_parsing::run` (in Nightly builds, run with -Z macro-backtrace for more info) -error: unexpected closing delimiter: `)` - --> :1:3 - | -LL | 1 ) 2 - | ^ unexpected closing delimiter - -error: unexpected closing delimiter: `]` - --> :1:10 - | -LL | ( x [ ) ] - | - - ^ unexpected closing delimiter - | | | - | | missing open `(` for this delimiter - | the nearest open delimiter - error: found invalid character; only `#` is allowed in raw string delimitation: \u{0} --> :1:1 | @@ -210,6 +175,6 @@ error: invalid digit for a base 2 literal LL | /*a*/ 0b2 // | ^ -error: aborting due to 24 previous errors +error: aborting due to 20 previous errors For more information about this error, try `rustc --explain E0768`. diff --git a/tests/ui/proc-macro/nonfatal-parsing.stdout b/tests/ui/proc-macro/nonfatal-parsing.stdout index 08e0e6b1f8439..2b92474fb8b4c 100644 --- a/tests/ui/proc-macro/nonfatal-parsing.stdout +++ b/tests/ui/proc-macro/nonfatal-parsing.stdout @@ -29,15 +29,19 @@ Ok(TokenStream [Literal { kind: Integer, symbol: "3", suffix: None, span: #44 by Ok(TokenStream [Literal { kind: Char, symbol: "c", suffix: None, span: #44 bytes(361..385) }]) Ok(TokenStream []) ### ERRORS -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) -Err(LexError) +Err(LexError("comment or whitespace around literal")) +Err(LexError("comment or whitespace around literal")) +Err(LexError("comment or whitespace around literal")) +Err(LexError("comment or whitespace around literal")) +Err(LexError("comment or whitespace around literal")) +Err(LexError("comment or whitespace around literal")) +Err(LexError("not a literal")) +Err(LexError("unexpected closing delimiter: `)`")) +Err(LexError("unexpected closing delimiter: `]`")) +Err(LexError("unexpected closing delimiter: `)`")) +Err(LexError("unexpected closing delimiter: `]`")) +Err(LexError("not a literal")) +Err(LexError("not a literal")) Ok(TokenStream [Ident { ident: "r", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) Ok(TokenStream [Ident { ident: "c", span: #44 bytes(361..385) }, Literal { kind: Char, symbol: "r", suffix: None, span: #44 bytes(361..385) }]) Ok(TokenStream [Literal { kind: ErrWithGuar, symbol: "0b2", suffix: None, span: #44 bytes(361..385) }]) @@ -51,4 +55,4 @@ Ok(Literal { kind: ErrWithGuar, symbol: "0b", suffix: Some("f32"), span: #44 byt Ok(Literal { kind: ErrWithGuar, symbol: "0b0.0", suffix: Some("f32"), span: #44 bytes(361..385) }) Ok(Literal { kind: ErrWithGuar, symbol: "'''", suffix: None, span: #44 bytes(361..385) }) Ok(Literal { kind: ErrWithGuar, symbol: "'\n'", suffix: None, span: #44 bytes(361..385) }) -Err(LexError) +Err(LexError("comment or whitespace around literal")) diff --git a/tests/ui/target-feature/const-target-feature-fn-ptr-coercion.rs b/tests/ui/target-feature/const-target-feature-fn-ptr-coercion.rs new file mode 100644 index 0000000000000..380de2412b728 --- /dev/null +++ b/tests/ui/target-feature/const-target-feature-fn-ptr-coercion.rs @@ -0,0 +1,33 @@ +//@ only-x86_64 +//@ check-pass +// +// Regression test for . + +#![allow(dead_code)] + +#[target_feature(enable = "sse2")] +const fn foo() {} + +// DefKind::Const +const _: () = unsafe { + let _: unsafe fn() = foo; +}; + +// DefKind::AssocConst +struct S; +impl S { + const C: () = unsafe { + let _: unsafe fn() = foo; + }; +} + +// DefKind::InlineConst +fn bar() { + let _ = const { + unsafe { + let _: unsafe fn() = foo; + } + }; +} + +fn main() {}