From a90cb05da642607545560fb64dd057d3fedf2e97 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Thu, 9 Jan 2025 17:34:58 +0000 Subject: [PATCH 01/14] interpret: adjust vtable validity check for higher-ranked types --- .../rustc_const_eval/src/interpret/cast.rs | 10 +++-- .../src/interpret/eval_context.rs | 40 +------------------ .../rustc_const_eval/src/interpret/traits.rs | 20 ++++------ .../validity/dyn-transmute-inner-binder.rs | 30 ++++++++++++++ .../dyn-transmute-inner-binder.stderr | 15 +++++++ src/tools/miri/tests/pass/dyn-upcast.rs | 30 ++++++++++++++ 6 files changed, 89 insertions(+), 56 deletions(-) create mode 100644 src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs create mode 100644 src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index e110c155da089..86fdfae1ffbf5 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -430,10 +430,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let erased_trait_ref = ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref); - assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env( - erased_trait_ref, - self.tcx.instantiate_bound_regions_with_erased(b) - ))); + assert_eq!( + data_b.principal().map(|b| { + self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b) + }), + Some(erased_trait_ref), + ); } else { // In this case codegen would keep using the old vtable. We don't want to do // that as it has the wrong trait. The reason codegen can do this is that diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 95a72d3cbc1d7..242cf6484dd9f 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -4,9 +4,6 @@ use either::{Left, Right}; use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout}; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::at::ToTrace; -use rustc_infer::traits::ObligationCause; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ @@ -17,8 +14,7 @@ use rustc_middle::{mir, span_bug}; use rustc_session::Limit; use rustc_span::Span; use rustc_target::callconv::FnAbi; -use rustc_trait_selection::traits::ObligationCtxt; -use tracing::{debug, instrument, trace}; +use tracing::{debug, trace}; use super::{ Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine, @@ -323,40 +319,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - /// Check if the two things are equal in the current param_env, using an infcx to get proper - /// equality checks. - #[instrument(level = "trace", skip(self), ret)] - pub(super) fn eq_in_param_env(&self, a: T, b: T) -> bool - where - T: PartialEq + TypeFoldable> + ToTrace<'tcx>, - { - // Fast path: compare directly. - if a == b { - return true; - } - // Slow path: spin up an inference context to check if these traits are sufficiently equal. - let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); - let ocx = ObligationCtxt::new(&infcx); - let cause = ObligationCause::dummy_with_span(self.cur_span()); - // equate the two trait refs after normalization - let a = ocx.normalize(&cause, param_env, a); - let b = ocx.normalize(&cause, param_env, b); - - if let Err(terr) = ocx.eq(&cause, param_env, a, b) { - trace!(?terr); - return false; - } - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - trace!(?errors); - return false; - } - - // All good. - true - } - /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a /// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic, /// and is primarily intended for the panic machinery. diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 4cfaacebfcd0e..a5029eea5a796 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -86,21 +86,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type }); } + // This checks whether there is a subtyping relation between the predicates in either direction. + // For example: + // - casting between `dyn for<'a> Trait` and `dyn Trait` is OK + // - casting between `dyn Trait fn(&'a u8)>` and either of the above is UB for (a_pred, b_pred) in std::iter::zip(sorted_vtable, sorted_expected) { - let is_eq = match (a_pred.skip_binder(), b_pred.skip_binder()) { - ( - ty::ExistentialPredicate::Trait(a_data), - ty::ExistentialPredicate::Trait(b_data), - ) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)), + let a_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, a_pred); + let b_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b_pred); - ( - ty::ExistentialPredicate::Projection(a_data), - ty::ExistentialPredicate::Projection(b_data), - ) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)), - - _ => false, - }; - if !is_eq { + if a_pred != b_pred { throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type }); } } diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs new file mode 100644 index 0000000000000..7de4aef422a08 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs @@ -0,0 +1,30 @@ +// Test that transmuting from `&dyn Trait` to `&dyn Trait fn(&'a ())>` is UB. +// +// The vtable of `() as Trait` and `() as Trait fn(&'a ())>` can have +// different entries and, because in the former the entry for `foo` is vacant, this test will +// segfault at runtime. + +trait Trait { + fn foo(&self) + where + U: HigherRanked, + { + } +} +impl Trait for T {} + +trait HigherRanked {} +impl HigherRanked for for<'a> fn(&'a ()) {} + +// 2nd candidate is required so that selecting `(): Trait` will +// evaluate the candidates and fail the leak check instead of returning the +// only applicable candidate. +trait Unsatisfied {} +impl HigherRanked for T {} + +fn main() { + let x: &dyn Trait = &(); + let y: &dyn Trait fn(&'a ())> = unsafe { std::mem::transmute(x) }; + //~^ ERROR: wrong trait in wide pointer vtable + y.foo(); +} diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr new file mode 100644 index 0000000000000..cfdf279a60538 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait fn(&'a ())>`, but encountered `Trait` + --> tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC + | +LL | let y: &dyn Trait fn(&'a ())> = unsafe { std::mem::transmute(x) }; + | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `Trait fn(&'a ())>`, but encountered `Trait` + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs index f100c4d6a869e..394e80aa25787 100644 --- a/src/tools/miri/tests/pass/dyn-upcast.rs +++ b/src/tools/miri/tests/pass/dyn-upcast.rs @@ -12,6 +12,7 @@ fn main() { drop_principal(); modulo_binder(); modulo_assoc(); + bidirectional_subtyping(); } fn vtable_nop_cast() { @@ -534,3 +535,32 @@ fn modulo_assoc() { (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); } + +fn bidirectional_subtyping() { + // Test that transmuting between subtypes of dyn traits is fine, even in the + // "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait. + // Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the + // *outside* here! + + trait Trait {} + impl Trait for T {} + + struct Wrapper(T); + + let x: &dyn Trait = &(); + let _y: &dyn for<'a> Trait = unsafe { std::mem::transmute(x) }; + + let x: &dyn for<'a> Trait = &(); + let _y: &dyn Trait = unsafe { std::mem::transmute(x) }; + + let x: &dyn Trait> = &(); + let _y: &dyn for<'a> Trait> = unsafe { std::mem::transmute(x) }; + + let x: &dyn for<'a> Trait> = &(); + let _y: &dyn Trait> = unsafe { std::mem::transmute(x) }; + + // This lowers to a ptr-to-ptr cast (which behaves like a transmute) + // and not an unsizing coercion: + let x: *const dyn for<'a> Trait<&'a ()> = &(); + let _y: *const Wrapper> = x as _; +} From a467ecacd4e77a3704924f5ac46f8a752e1e73e5 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 19 Feb 2025 08:35:51 +0800 Subject: [PATCH 02/14] Add custom sort for link in rustdoc --- src/librustdoc/html/render/sidebar.rs | 18 +++++++++++++++++- .../rustdoc-gui/sidebar-foreign-impl-sort.goml | 15 +++++++++++++++ tests/rustdoc-gui/src/test_docs/lib.rs | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc-gui/sidebar-foreign-impl-sort.goml diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 50c09b98db441..64dbaf9083e70 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::cmp::Ordering; use rinja::Template; use rustc_data_structures::fx::FxHashSet; @@ -12,6 +13,7 @@ use crate::clean; use crate::formats::Impl; use crate::formats::item_type::ItemType; use crate::html::markdown::{IdMap, MarkdownWithToc}; +use crate::html::render::print_item::compare_names; #[derive(Clone, Copy)] pub(crate) enum ModuleLike { @@ -77,7 +79,7 @@ impl<'a> LinkBlock<'a> { } /// A link to an item. Content should not be escaped. -#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)] +#[derive(Ord, PartialEq, Eq, Hash, Clone)] pub(crate) struct Link<'a> { /// The content for the anchor tag and title attr name: Cow<'a, str>, @@ -89,6 +91,20 @@ pub(crate) struct Link<'a> { children: Vec>, } +impl PartialOrd for Link<'_> { + fn partial_cmp(&self, other: &Link<'_>) -> Option { + match compare_names(&self.name, &other.name) { + Ordering::Equal => (), + result => return Some(result), + } + (&self.name_html, &self.href, &self.children).partial_cmp(&( + &other.name_html, + &other.href, + &other.children, + )) + } +} + impl<'a> Link<'a> { pub fn new(href: impl Into>, name: impl Into>) -> Self { Self { href: href.into(), name: name.into(), children: vec![], name_html: None } diff --git a/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml b/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml new file mode 100644 index 0000000000000..f09f09713514d --- /dev/null +++ b/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml @@ -0,0 +1,15 @@ +// Checks sidebar resizing close the Settings popover +go-to: "file://" + |DOC_PATH| + "/test_docs/SidebarSort/trait.Sort.html#foreign-impls" + +// Check that the sidebar contains the expected foreign implementations +assert-text: (".sidebar-elems section ul > li:nth-child(1)", "&'a str") +assert-text: (".sidebar-elems section ul > li:nth-child(2)", "AtomicBool") +assert-text: (".sidebar-elems section ul > li:nth-child(3)", "AtomicU8") +assert-text: (".sidebar-elems section ul > li:nth-child(4)", "AtomicU16") +assert-text: (".sidebar-elems section ul > li:nth-child(5)", "AtomicU32") +assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Cell") +assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Cell") +assert-text: (".sidebar-elems section ul > li:nth-child(8)", "u8") +assert-text: (".sidebar-elems section ul > li:nth-child(9)", "u16") +assert-text: (".sidebar-elems section ul > li:nth-child(10)", "u32") +assert-text: (".sidebar-elems section ul > li:nth-child(11)", "usize") diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index 1a9ffbe889851..f9c20ab22b89d 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -713,3 +713,21 @@ pub trait ItemsTrait { /// blablala fn bar(); } + +pub mod SidebarSort { + use std::cell::Cell; + use std::sync::atomic::*; + pub trait Sort {} + + impl Sort for u32 {} + impl Sort for u8 {} + impl Sort for u16 {} + impl Sort for usize {} + impl Sort for AtomicU32 {} + impl Sort for AtomicU16 {} + impl Sort for AtomicU8 {} + impl Sort for AtomicBool {} + impl Sort for Cell {} + impl Sort for Cell {} + impl<'a> Sort for &'a str {} +} From b02eac37ffa30ad4f0ffb703ac7e598fa7213c7a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 03:58:31 +0000 Subject: [PATCH 03/14] Restrict bevy hack --- .../rustc_hir_analysis/src/check/wfcheck.rs | 54 +++++++++---------- compiler/rustc_span/src/symbol.rs | 2 + compiler/rustc_type_ir/src/visit.rs | 7 +++ tests/ui/implied-bounds/bevy_world_query.rs | 2 + 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index edfa897860b7d..f98504e19decb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, @@ -143,33 +142,7 @@ where return Ok(()); } - let is_bevy = 'is_bevy: { - // We don't want to emit this for dependents of Bevy, for now. - // See #119956 - let is_bevy_paramset = |def: ty::AdtDef<'_>| { - let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did)); - adt_did.contains("ParamSet") - }; - for ty in assumed_wf_types.iter() { - match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - ty::Ref(_, ty, _) => match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - _ => {} - }, - _ => {} - } - } - false - }; + let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break(); // If we have set `no_implied_bounds_compat`, then do not attempt compatibility. // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`, @@ -194,6 +167,31 @@ where } } +struct ContainsBevyParamSet<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> TypeVisitor> for ContainsBevyParamSet<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + // We only care to match `ParamSet` or `&ParamSet`. + match t.kind() { + ty::Adt(def, _) => { + if self.tcx.item_name(def.did()) == sym::ParamSet + && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs + { + return ControlFlow::Break(()); + } + } + ty::Ref(_, ty, _) => ty.visit_with(self)?, + _ => {} + } + + ControlFlow::Continue(()) + } +} + fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let node = tcx.hir_node_by_def_id(def_id); let mut res = match node { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d155e95078be2..d4d435d9b7467 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -289,6 +289,7 @@ symbols! { OsString, Output, Param, + ParamSet, PartialEq, PartialOrd, Path, @@ -520,6 +521,7 @@ symbols! { bang, begin_panic, bench, + bevy_ecs, bikeshed_guaranteed_no_drop, bin, binaryheap_iter, diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index a12e9856304a9..0d8da2bacfcb2 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -224,6 +224,13 @@ impl, Ix: Idx> TypeVisitable for IndexVec, S> TypeVisitable for indexmap::IndexSet { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + walk_visitable_list!(visitor, self.iter()); + V::Result::output() + } +} + pub trait Flags { fn flags(&self) -> TypeFlags; fn outer_exclusive_binder(&self) -> ty::DebruijnIndex; diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs index e36be26d003f2..6548c03d1b00c 100644 --- a/tests/ui/implied-bounds/bevy_world_query.rs +++ b/tests/ui/implied-bounds/bevy_world_query.rs @@ -1,3 +1,5 @@ +#![crate_name = "bevy_ecs"] + //@ check-pass // We currently special case bevy from erroring on incorrect implied bounds From b78c626a9516f7e8ad6be3e0698f6b6c6fddd286 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 06:54:15 +0000 Subject: [PATCH 04/14] Make fewer crates depend on rustc_ast_ir --- Cargo.lock | 7 ------- compiler/rustc_ast_ir/src/lib.rs | 7 +++++++ compiler/rustc_hir_typeck/Cargo.toml | 1 - compiler/rustc_infer/Cargo.toml | 1 - compiler/rustc_infer/src/traits/structural_impls.rs | 3 +-- compiler/rustc_macros/src/type_visitable.rs | 6 +++--- compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/macros.rs | 2 +- compiler/rustc_middle/src/mir/interpret/error.rs | 3 +-- compiler/rustc_middle/src/traits/solve.rs | 2 +- compiler/rustc_middle/src/ty/generic_args.rs | 4 +--- compiler/rustc_middle/src/ty/mod.rs | 3 +-- compiler/rustc_middle/src/ty/structural_impls.rs | 3 +-- compiler/rustc_middle/src/ty/visit.rs | 2 +- compiler/rustc_next_trait_solver/Cargo.toml | 2 -- .../src/solve/assembly/structural_traits.rs | 3 +-- compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 5 +++-- compiler/rustc_trait_selection/Cargo.toml | 1 - .../rustc_trait_selection/src/solve/inspect/analyse.rs | 3 +-- compiler/rustc_transmute/Cargo.toml | 2 -- compiler/rustc_ty_utils/Cargo.toml | 1 - compiler/rustc_ty_utils/src/sig_types.rs | 3 +-- compiler/rustc_type_ir/src/lib.rs | 1 + compiler/rustc_type_ir/src/visit.rs | 4 ++-- compiler/rustc_type_ir_macros/src/lib.rs | 6 +++--- 25 files changed, 30 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb17717aceb42..048af61e998f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3748,7 +3748,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -3813,7 +3812,6 @@ dependencies = [ name = "rustc_infer" version = "0.0.0" dependencies = [ - "rustc_ast_ir", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4004,7 +4002,6 @@ dependencies = [ "rustc_apfloat", "rustc_arena", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_error_messages", @@ -4134,7 +4131,6 @@ name = "rustc_next_trait_solver" version = "0.0.0" dependencies = [ "derive-where", - "rustc_ast_ir", "rustc_data_structures", "rustc_index", "rustc_macros", @@ -4454,7 +4450,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -4493,7 +4488,6 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", - "rustc_ast_ir", "rustc_data_structures", "rustc_hir", "rustc_infer", @@ -4509,7 +4503,6 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", - "rustc_ast_ir", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index ff9d940ce9f28..9884e191ea7bd 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -1,3 +1,10 @@ +//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`. +//! +//! Don't depend on this crate directly; both of those crates should re-export +//! the functionality. Additionally, if you're in scope of `rustc_middle`, then +//! prefer imports via that too, to avoid needing to directly depend on (e.g.) +//! `rustc_type_ir` for a single import. + // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 1f5acaa58a972..0331a20f95b79 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 6d1a2d3de9e35..baf5dbbfd4226 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -8,7 +8,6 @@ doctest = false [dependencies] # tidy-alphabetical-start -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 31f585c0c9edd..b346e193d0b84 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -1,8 +1,7 @@ use std::fmt; -use rustc_ast_ir::try_visit; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor, try_visit}; use rustc_middle::ty::{self, TyCtxt}; use crate::traits; diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 527ca26c0eb10..a7906d50d0f2d 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -36,12 +36,12 @@ pub(super) fn type_visitable_derive( s.add_bounds(synstructure::AddBounds::Generics); let body_visit = s.each(|bind| { quote! { - match ::rustc_ast_ir::visit::VisitorResult::branch( + match ::rustc_middle::ty::visit::VisitorResult::branch( ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { - return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + return ::rustc_middle::ty::visit::VisitorResult::from_residual(r); }, } } @@ -56,7 +56,7 @@ pub(super) fn type_visitable_derive( __visitor: &mut __V ) -> __V::Result { match *self { #body_visit } - <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + <__V::Result as ::rustc_middle::ty::visit::VisitorResult>::output() } }, ) diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 1b6a174c09322..389c861c3b524 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -14,7 +14,6 @@ rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index b3064d8fe25cb..b5f3a0e1482a9 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -83,7 +83,7 @@ macro_rules! TrivialTypeTraversalImpls { _: &mut F) -> F::Result { - ::output() + ::output() } } )+ diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 8861e31b0991c..743812e3a20a7 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -5,7 +5,6 @@ use std::{convert, fmt, mem, ops}; use either::Either; use rustc_abi::{Align, Size, VariantIdx, WrappingRange}; -use rustc_ast_ir::Mutability; use rustc_data_structures::sync::Lock; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; @@ -16,7 +15,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar}; use crate::error; use crate::mir::{ConstAlloc, ConstValue}; -use crate::ty::{self, Ty, TyCtxt, ValTree, layout, tls}; +use crate::ty::{self, Mutability, Ty, TyCtxt, ValTree, layout, tls}; #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum ErrorHandled { diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index f659bf8125a0e..9c74f6263b3ce 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,9 +1,9 @@ -use rustc_ast_ir::try_visit; use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; use rustc_type_ir as ir; pub use rustc_type_ir::solve::*; +use crate::ty::visit::try_visit; use crate::ty::{ self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 56a38a84c9f1a..b74ddb817103e 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -6,8 +6,6 @@ use std::mem; use std::num::NonZero; use std::ptr::NonNull; -use rustc_ast_ir::visit::VisitorResult; -use rustc_ast_ir::walk_visitable_list; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; @@ -18,7 +16,7 @@ use smallvec::SmallVec; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::ty::visit::{TypeVisitable, TypeVisitor}; +use crate::ty::visit::{TypeVisitable, TypeVisitor, VisitorResult, walk_visitable_list}; use crate::ty::{ self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs, Lift, List, Ty, TyCtxt, }; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c52e774c8b7e9..a1d44882e63f3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -27,7 +27,6 @@ pub use intrinsic::IntrinsicDef; use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::node_id::NodeMap; -pub use rustc_ast_ir::{Movability, Mutability, try_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -48,7 +47,7 @@ pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::relate::VarianceDiagInfo; -pub use rustc_type_ir::*; +pub use rustc_type_ir::{Movability, Mutability, *}; use tracing::{debug, instrument}; pub use vtable::*; use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6c15e033bb04b..b2286c744020f 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -7,13 +7,12 @@ use std::fmt::{self, Debug}; use rustc_abi::TyAndLayout; use rustc_ast::InlineAsmTemplatePiece; -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::Namespace; use rustc_hir::def_id::LocalDefId; use rustc_span::Span; use rustc_span::source_map::Spanned; use rustc_type_ir::ConstKind; +use rustc_type_ir::visit::{VisitorResult, try_visit}; use super::print::PrettyPrinter; use super::{GenericArg, GenericArgKind, Pattern, Region}; diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 4efaccefcf74b..95256b55bb4a1 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -2,7 +2,7 @@ use std::ops::ControlFlow; use rustc_data_structures::fx::FxIndexSet; use rustc_type_ir::fold::TypeFoldable; -pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +pub use rustc_type_ir::visit::*; use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 451c215566be2..eacb6002f5a41 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start derive-where = "1.2.7" -rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } @@ -22,7 +21,6 @@ nightly = [ "dep:rustc_data_structures", "dep:rustc_macros", "dep:rustc_serialize", - "rustc_ast_ir/nightly", "rustc_index/nightly", "rustc_type_ir/nightly", ] diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 082c356cc5fbd..dc0f4c4483e6f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -2,12 +2,11 @@ //! traits, `Copy`/`Clone`. use derive_where::derive_where; -use rustc_ast_ir::{Movability, Mutability}; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate}; +use rustc_type_ir::{self as ty, Interner, Movability, Mutability, Upcast as _, elaborate}; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index dabfa5cc04c8d..1665dbb30189e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1,13 +1,14 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. -use rustc_ast_ir::Movability; use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::solve::CanonicalResponse; use rustc_type_ir::visit::TypeVisitableExt as _; -use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate}; +use rustc_type_ir::{ + self as ty, Interner, Movability, TraitPredicate, TypingMode, Upcast as _, elaborate, +}; use tracing::{instrument, trace}; use crate::delegate::SolverDelegate; diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index b13a753c4ed1e..2f2361609a26c 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 9fbc1d64d7429..4b1bc316d5f1d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -11,12 +11,11 @@ use std::assert_matches::assert_matches; -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_macros::extension; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult}; +use rustc_middle::ty::visit::{VisitorResult, try_visit}; use rustc_middle::ty::{TyCtxt, TypeFoldable}; use rustc_middle::{bug, ty}; use rustc_next_trait_solver::resolve::EagerResolver; diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 6a98be1850390..94c7695117c63 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi", optional = true } -rustc_ast_ir = { path = "../rustc_ast_ir", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir", optional = true } rustc_infer = { path = "../rustc_infer", optional = true } @@ -19,7 +18,6 @@ tracing = "0.1" [features] rustc = [ "dep:rustc_abi", - "dep:rustc_ast_ir", "dep:rustc_hir", "dep:rustc_infer", "dep:rustc_macros", diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index f88f8c38d5087..ab903c6ed73f8 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 64e5a609b2f6d..d6f9277813d12 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -1,11 +1,10 @@ //! This module contains helpers for walking all types of //! a signature, while preserving spans as much as possible -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; +use rustc_middle::ty::visit::{VisitorResult, try_visit}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e7ca24178cbf7..15ef4e7d6c1d2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -74,6 +74,7 @@ pub use opaque_ty::*; pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; +pub use rustc_ast_ir::{Movability, Mutability, Pinnedness}; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index a12e9856304a9..f7d6b20603956 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -45,8 +45,8 @@ use std::fmt; use std::ops::ControlFlow; use std::sync::Arc; -use rustc_ast_ir::visit::VisitorResult; -use rustc_ast_ir::{try_visit, walk_visitable_list}; +pub use rustc_ast_ir::visit::VisitorResult; +pub use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; use smallvec::SmallVec; use thin_vec::ThinVec; diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index ede6dcd469cce..640299c216796 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -45,12 +45,12 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok s.add_bounds(synstructure::AddBounds::Fields); let body_visit = s.each(|bind| { quote! { - match ::rustc_ast_ir::visit::VisitorResult::branch( + match ::rustc_type_ir::visit::VisitorResult::branch( ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { - return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + return ::rustc_type_ir::visit::VisitorResult::from_residual(r); }, } } @@ -65,7 +65,7 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok __visitor: &mut __V ) -> __V::Result { match *self { #body_visit } - <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + <__V::Result as ::rustc_type_ir::visit::VisitorResult>::output() } }, ) From 047e77cff13f5c3282486247c9791b484f1f53de Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Feb 2025 07:19:25 +0000 Subject: [PATCH 05/14] Register USAGE_OF_TYPE_IR_INHERENT, remove inherent usages --- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_monomorphize/src/mono_checks/abi_check.rs | 5 ++--- .../src/error_reporting/infer/need_type_info.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c8de5e877531e..044a613dad62b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -641,6 +641,7 @@ fn register_internals(store: &mut LintStore) { LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(USAGE_OF_QUALIFIED_TY), LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT), + LintId::of(USAGE_OF_TYPE_IR_INHERENT), LintId::of(BAD_OPT_ACCESS), LintId::of(SPAN_USE_EQ_CTXT), ], diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 36cd3e00b76c8..8e93bdc61d04a 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -1,9 +1,8 @@ //! This module ensures that if a function's ABI requires a particular target feature, //! that target feature is enabled both on the callee and all callers. -use rustc_abi::{BackendRepr, RegKind}; +use rustc_abi::{BackendRepr, ExternAbi, RegKind}; use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::{self, traversal}; -use rustc_middle::ty::inherent::*; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES; use rustc_span::def_id::DefId; @@ -97,7 +96,7 @@ fn check_call_site_abi<'tcx>( span: Span, caller: InstanceKind<'tcx>, ) { - if callee.fn_sig(tcx).abi().is_rust() { + if callee.fn_sig(tcx).abi() == ExternAbi::Rust { // "Rust" ABI never passes arguments in vector registers. return; } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 2bb38f3ed14af..42b8199cb265e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -18,7 +18,6 @@ use rustc_middle::ty::{ TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, }; use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym}; -use rustc_type_ir::inherent::*; use rustc_type_ir::visit::TypeVisitableExt; use tracing::{debug, instrument, warn}; @@ -217,7 +216,7 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { // `_` because then we'd end up with `Vec<_, _>`, instead of // `Vec<_>`. arg - } else if let GenericArgKind::Type(_) = arg.kind() { + } else if let GenericArgKind::Type(_) = arg.unpack() { // We don't replace lifetime or const params, only type params. self.new_infer().into() } else { From cee430b2ce152092d14e7b8832a725582b4bcf64 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 19 Feb 2025 14:39:09 +1100 Subject: [PATCH 06/14] Add `super_local` method to the MIR visitors. `visit_local` is the only method that doesn't call a corresponding `super_local` method. This is valid, because `super_local` would be empty. But it's inconsistent with every other case; we have multiple other empty `super` methods: `super_span`, `super_ty`, etc. This commit adds an empty `super_local` and makes `visit_local` call it. --- compiler/rustc_middle/src/mir/visit.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8ad88fbda7c89..35906009618c2 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -270,10 +270,12 @@ macro_rules! make_mir_visitor { fn visit_local( &mut self, - _local: $(& $mutability)? Local, - _context: PlaceContext, - _location: Location, - ) {} + local: $(& $mutability)? Local, + context: PlaceContext, + location: Location, + ) { + self.super_local(local, context, location) + } fn visit_source_scope( &mut self, @@ -868,6 +870,14 @@ macro_rules! make_mir_visitor { } } + fn super_local( + &mut self, + _local: $(& $mutability)? Local, + _context: PlaceContext, + _location: Location, + ) { + } + fn super_var_debug_info( &mut self, var_debug_info: & $($mutability)? VarDebugInfo<'tcx> From 311e8d3e5dbcd0db9ca478f18ed0f8324a5e750e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 19 Feb 2025 15:52:05 +1100 Subject: [PATCH 07/14] Remove `MirVisitable`. The `MirVisitable` trait is just a complicated way to visit either a statement or a terminator. (And its impl for `Terminator` is unused.) It has a single use. This commit removes it, replacing it with an if/else, which is shorter and simpler. --- .../src/diagnostics/find_use.rs | 34 ++++++++++--------- compiler/rustc_middle/src/mir/mod.rs | 5 --- compiler/rustc_middle/src/mir/visit.rs | 22 ------------ 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index 26a090f5579ce..96f48840468e5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; @@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { let block_data = &self.body[p.block]; - match self.def_use(p, block_data.visitable(p.statement_index)) { + let mut visitor = DefUseVisitor { + body: self.body, + tcx: self.tcx, + region_vid: self.region_vid, + def_use_result: None, + }; + + let is_statement = p.statement_index < block_data.statements.len(); + + if is_statement { + visitor.visit_statement(&block_data.statements[p.statement_index], p); + } else { + visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p); + } + + match visitor.def_use_result { Some(DefUseResult::Def) => {} Some(DefUseResult::UseLive { local }) => { @@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { } None => { - if p.statement_index < block_data.statements.len() { + if is_statement { queue.push_back(p.successor_within_block()); } else { queue.extend( @@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { None } - - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option { - let mut visitor = DefUseVisitor { - body: self.body, - tcx: self.tcx, - region_vid: self.region_vid, - def_use_result: None, - }; - - thing.apply(location, &mut visitor); - - visitor.def_use_result - } } struct DefUseVisitor<'a, 'tcx> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 528da4ca05776..ff493fa65a6ab 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -32,7 +32,6 @@ use tracing::{debug, trace}; pub use self::query::*; use self::visit::TyContext; use crate::mir::interpret::{AllocRange, Scalar}; -use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; @@ -1364,10 +1363,6 @@ impl<'tcx> BasicBlockData<'tcx> { self.terminator.as_mut().expect("invalid terminator state") } - pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> { - if index < self.statements.len() { &self.statements[index] } else { &self.terminator } - } - /// Does the block have no statements and an unreachable terminator? #[inline] pub fn is_empty_unreachable(&self) -> bool { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 35906009618c2..9c5c0862261cc 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1265,28 +1265,6 @@ macro_rules! visit_place_fns { make_mir_visitor!(Visitor,); make_mir_visitor!(MutVisitor, mut); -pub trait MirVisitable<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>); -} - -impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_statement(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Option> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self.as_ref().unwrap(), location) - } -} - /// Extra information passed to `visit_ty` and friends to give context /// about where the type etc appears. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] From 5bb37ce76409f2e2b03d7b7b44b6fd129ea7b02d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 19 Feb 2025 14:56:46 +1100 Subject: [PATCH 08/14] Improve formatting within `make_mir_visitor` macro body. rustfmt doesn't touch it because it's a macro body, but it's large enough that the misformatting is annoying. This commit improves it. The most common problems fixed: - Unnecessary multi-line patterns reduced to one line. - Multi-line function headers adjusted so the parameter indentation doesn't depend on the length of the function name. (This is Rust code, not C.) - `|` used at the start of lines, not the end. - More consistent formatting of empty function bodies. - Overly long lines are broken. --- compiler/rustc_middle/src/mir/visit.rs | 270 ++++++++++++------------- 1 file changed, 128 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9c5c0862261cc..193806f238b1d 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -294,9 +294,11 @@ macro_rules! make_mir_visitor { super_body!(self, body, $($mutability, true)?); } - fn super_basic_block_data(&mut self, - block: BasicBlock, - data: & $($mutability)? BasicBlockData<'tcx>) { + fn super_basic_block_data( + &mut self, + block: BasicBlock, + data: & $($mutability)? BasicBlockData<'tcx>) + { let BasicBlockData { statements, terminator, @@ -341,24 +343,24 @@ macro_rules! make_mir_visitor { match callee_def { ty::InstanceKind::Item(_def_id) => {} - ty::InstanceKind::Intrinsic(_def_id) | - ty::InstanceKind::VTableShim(_def_id) | - ty::InstanceKind::ReifyShim(_def_id, _) | - ty::InstanceKind::Virtual(_def_id, _) | - ty::InstanceKind::ThreadLocalShim(_def_id) | - ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } | - ty::InstanceKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Intrinsic(_def_id) + | ty::InstanceKind::VTableShim(_def_id) + | ty::InstanceKind::ReifyShim(_def_id, _) + | ty::InstanceKind::Virtual(_def_id, _) + | ty::InstanceKind::ThreadLocalShim(_def_id) + | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } + | ty::InstanceKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, receiver_by_ref: _, - } | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) | - ty::InstanceKind::DropGlue(_def_id, None) => {} - - ty::InstanceKind::FnPtrShim(_def_id, ty) | - ty::InstanceKind::DropGlue(_def_id, Some(ty)) | - ty::InstanceKind::CloneShim(_def_id, ty) | - ty::InstanceKind::FnPtrAddrShim(_def_id, ty) | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { + } + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) + | ty::InstanceKind::DropGlue(_def_id, None) => {} + + ty::InstanceKind::FnPtrShim(_def_id, ty) + | ty::InstanceKind::DropGlue(_def_id, Some(ty)) + | ty::InstanceKind::CloneShim(_def_id, ty) + | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } @@ -370,19 +372,16 @@ macro_rules! make_mir_visitor { } } - fn super_statement(&mut self, - statement: & $($mutability)? Statement<'tcx>, - location: Location) { - let Statement { - source_info, - kind, - } = statement; + fn super_statement( + &mut self, + statement: & $($mutability)? Statement<'tcx>, + location: Location + ) { + let Statement { source_info, kind } = statement; self.visit_source_info(source_info); match kind { - StatementKind::Assign( - box (place, rvalue) - ) => { + StatementKind::Assign(box (place, rvalue)) => { self.visit_assign(place, rvalue, location); } StatementKind::FakeRead(box (_, place)) => { @@ -430,11 +429,13 @@ macro_rules! make_mir_visitor { location ); } - StatementKind::AscribeUserType( - box (place, user_ty), - variance - ) => { - self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location); + StatementKind::AscribeUserType(box (place, user_ty), variance) => { + self.visit_ascribe_user_ty( + place, + $(& $mutability)? *variance, + user_ty, + location + ); } StatementKind::Coverage(coverage) => { self.visit_coverage( @@ -445,7 +446,11 @@ macro_rules! make_mir_visitor { StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => { match intrinsic { NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location), - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => { + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src, + dst, + count + }) => { self.visit_operand(src, location); self.visit_operand(dst, location); self.visit_operand(count, location); @@ -458,10 +463,12 @@ macro_rules! make_mir_visitor { } } - fn super_assign(&mut self, - place: &$($mutability)? Place<'tcx>, - rvalue: &$($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_assign( + &mut self, + place: &$($mutability)? Place<'tcx>, + rvalue: &$($mutability)? Rvalue<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Store), @@ -470,20 +477,22 @@ macro_rules! make_mir_visitor { self.visit_rvalue(rvalue, location); } - fn super_terminator(&mut self, - terminator: &$($mutability)? Terminator<'tcx>, - location: Location) { + fn super_terminator( + &mut self, + terminator: &$($mutability)? Terminator<'tcx>, + location: Location + ) { let Terminator { source_info, kind } = terminator; self.visit_source_info(source_info); match kind { - TerminatorKind::Goto { .. } | - TerminatorKind::UnwindResume | - TerminatorKind::UnwindTerminate(_) | - TerminatorKind::CoroutineDrop | - TerminatorKind::Unreachable | - TerminatorKind::FalseEdge { .. } | - TerminatorKind::FalseUnwind { .. } => {} + TerminatorKind::Goto { .. } + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + | TerminatorKind::CoroutineDrop + | TerminatorKind::Unreachable + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } => {} TerminatorKind::Return => { // `return` logically moves from the return place `_0`. Note that the place @@ -502,19 +511,11 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::SwitchInt { - discr, - targets: _ - } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.visit_operand(discr, location); } - TerminatorKind::Drop { - place, - target: _, - unwind: _, - replace: _, - } => { + TerminatorKind::Drop { place, target: _, unwind: _, replace: _ } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), @@ -543,11 +544,7 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::TailCall { - func, - args, - fn_span, - } => { + TerminatorKind::TailCall { func, args, fn_span } => { self.visit_span($(& $mutability)? *fn_span); self.visit_operand(func, location); for arg in args { @@ -555,23 +552,12 @@ macro_rules! make_mir_visitor { } }, - TerminatorKind::Assert { - cond, - expected: _, - msg, - target: _, - unwind: _, - } => { + TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.visit_operand(cond, location); self.visit_assert_message(msg, location); } - TerminatorKind::Yield { - value, - resume: _, - resume_arg, - drop: _, - } => { + TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => { self.visit_operand(value, location); self.visit_place( resume_arg, @@ -624,9 +610,11 @@ macro_rules! make_mir_visitor { } } - fn super_assert_message(&mut self, - msg: & $($mutability)? AssertMessage<'tcx>, - location: Location) { + fn super_assert_message( + &mut self, + msg: & $($mutability)? AssertMessage<'tcx>, + location: Location + ) { use crate::mir::AssertKind::*; match msg { BoundsCheck { len, index } => { @@ -650,9 +638,11 @@ macro_rules! make_mir_visitor { } } - fn super_rvalue(&mut self, - rvalue: & $($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_rvalue( + &mut self, + rvalue: & $($mutability)? Rvalue<'tcx>, + location: Location + ) { match rvalue { Rvalue::Use(operand) => { self.visit_operand(operand, location); @@ -679,6 +669,7 @@ macro_rules! make_mir_visitor { }; self.visit_place(path, ctx, location); } + Rvalue::CopyForDeref(place) => { self.visit_place( place, @@ -742,8 +733,7 @@ macro_rules! make_mir_visitor { AggregateKind::Array(ty) => { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - AggregateKind::Tuple => { - } + AggregateKind::Tuple => {} AggregateKind::Adt( _adt_def, _variant_index, @@ -753,22 +743,13 @@ macro_rules! make_mir_visitor { ) => { self.visit_args(args, location); } - AggregateKind::Closure( - _, - closure_args - ) => { + AggregateKind::Closure(_, closure_args) => { self.visit_args(closure_args, location); } - AggregateKind::Coroutine( - _, - coroutine_args, - ) => { + AggregateKind::Coroutine(_, coroutine_args) => { self.visit_args(coroutine_args, location); } - AggregateKind::CoroutineClosure( - _, - coroutine_closure_args, - ) => { + AggregateKind::CoroutineClosure(_, coroutine_closure_args) => { self.visit_args(coroutine_closure_args, location); } AggregateKind::RawPtr(ty, _) => { @@ -793,9 +774,11 @@ macro_rules! make_mir_visitor { } } - fn super_operand(&mut self, - operand: & $($mutability)? Operand<'tcx>, - location: Location) { + fn super_operand( + &mut self, + operand: & $($mutability)? Operand<'tcx>, + location: Location + ) { match operand { Operand::Copy(place) => { self.visit_place( @@ -817,28 +800,36 @@ macro_rules! make_mir_visitor { } } - fn super_ascribe_user_ty(&mut self, - place: & $($mutability)? Place<'tcx>, - variance: $(& $mutability)? ty::Variance, - user_ty: & $($mutability)? UserTypeProjection, - location: Location) { + fn super_ascribe_user_ty( + &mut self, + place: & $($mutability)? Place<'tcx>, + variance: $(& $mutability)? ty::Variance, + user_ty: & $($mutability)? UserTypeProjection, + location: Location) + { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)), + PlaceContext::NonUse( + NonUseContext::AscribeUserTy($(* &$mutability *)? variance) + ), location ); self.visit_user_type_projection(user_ty); } - fn super_coverage(&mut self, - _kind: & $($mutability)? coverage::CoverageKind, - _location: Location) { + fn super_coverage( + &mut self, + _kind: & $($mutability)? coverage::CoverageKind, + _location: Location + ) { } - fn super_retag(&mut self, - _kind: $(& $mutability)? RetagKind, - place: & $($mutability)? Place<'tcx>, - location: Location) { + fn super_retag( + &mut self, + _kind: $(& $mutability)? RetagKind, + place: & $($mutability)? Place<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Retag), @@ -846,9 +837,11 @@ macro_rules! make_mir_visitor { ); } - fn super_local_decl(&mut self, - local: Local, - local_decl: & $($mutability)? LocalDecl<'tcx>) { + fn super_local_decl( + &mut self, + local: Local, + local_decl: & $($mutability)? LocalDecl<'tcx> + ) { let LocalDecl { mutability: _, ty, @@ -892,7 +885,10 @@ macro_rules! make_mir_visitor { self.visit_source_info(source_info); let location = Location::START; - if let Some(box VarDebugInfoFragment { ref $($mutability)? ty, ref $($mutability)? projection }) = composite { + if let Some(box VarDebugInfoFragment { + ref $($mutability)? ty, + ref $($mutability)? projection + }) = composite { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); for elem in projection { let ProjectionElem::Field(_, ty) = elem else { bug!() }; @@ -910,10 +906,7 @@ macro_rules! make_mir_visitor { } } - fn super_source_scope( - &mut self, - _scope: $(& $mutability)? SourceScope - ) {} + fn super_source_scope(&mut self, _scope: $(& $mutability)? SourceScope) {} fn super_const_operand( &mut self, @@ -929,8 +922,12 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); match const_ { Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location), - Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), - Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), + Const::Val(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } + Const::Unevaluated(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } } } @@ -939,27 +936,18 @@ macro_rules! make_mir_visitor { _ct: $(& $mutability)? ty::Const<'tcx>, _location: Location, ) { - } - fn super_span(&mut self, _span: $(& $mutability)? Span) { - } + fn super_span(&mut self, _span: $(& $mutability)? Span) {} fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) { - let SourceInfo { - span, - scope, - } = source_info; + let SourceInfo { span, scope } = source_info; self.visit_span($(& $mutability)? *span); self.visit_source_scope($(& $mutability)? *scope); } - fn super_user_type_projection( - &mut self, - _ty: & $($mutability)? UserTypeProjection, - ) { - } + fn super_user_type_projection(&mut self, _ty: & $($mutability)? UserTypeProjection) {} fn super_user_type_annotation( &mut self, @@ -970,14 +958,11 @@ macro_rules! make_mir_visitor { self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span)); } - fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) { - } + fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {} - fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) { - } + fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {} - fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) { - } + fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {} // Convenience methods @@ -986,7 +971,8 @@ macro_rules! make_mir_visitor { body: &$($mutability)? Body<'tcx>, location: Location ) { - let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; + let basic_block = + & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; if basic_block.statements.len() == location.statement_index { if let Some(ref $($mutability)? terminator) = basic_block.terminator { self.visit_terminator(terminator, location) From ef6df3b7135a0f70e83e840b6d6256709504b022 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 19 Feb 2025 00:04:26 -0800 Subject: [PATCH 09/14] add a failing test --- .../migration_lint.fixed | 6 +++++ .../migration_lint.rs | 6 +++++ .../migration_lint.stderr | 23 ++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index e35896f32ad7d..bb4ecc09063b7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -244,4 +244,10 @@ fn main() { let &[migration_lint_macros::bind_ref!(a)] = &[0]; //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` assert_type_eq(a, &0u32); + + // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. + let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; + //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 10a23e6f2fa18..2837c8d81dbdd 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -244,4 +244,10 @@ fn main() { let [migration_lint_macros::bind_ref!(a)] = &[0]; //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` assert_type_eq(a, &0u32); + + // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. + let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 3dd91c86a3b8f..eb76615aac129 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -580,5 +580,26 @@ help: make the implied reference pattern explicit LL | let &[migration_lint_macros::bind_ref!(a)] = &[0]; | + -error: aborting due to 30 previous errors +error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + --> $DIR/auxiliary/migration_lint_macros.rs:15:22 + | +LL | ($foo:ident) => { + | ______________________^ +LL | | ref $foo + | |________________^ reference pattern not allowed under `ref` default binding mode + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/migration_lint.rs:249:9 + | +LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` +help: make the implied reference pattern explicit + --> $DIR/migration_lint.rs:249:9 + | +LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; + | + + +error: aborting due to 31 previous errors From 51a2ee3252b33d31574ad0d03766e1b7a4034812 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 19 Feb 2025 00:50:31 -0800 Subject: [PATCH 10/14] don't get trapped inside of expansions when trimming labels --- compiler/rustc_hir_typeck/src/pat.rs | 26 +++++++++---------- .../migration_lint.stderr | 9 +++---- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ae00bb4e218ab..242536e001821 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -835,20 +835,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - ident.span, + 't', def_br_mutbl, ); BindingMode(ByRef::No, Mutability::Mut) } } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => { + BindingMode(ByRef::Yes(user_br_mutbl), _) => { if let ByRef::Yes(def_br_mutbl) = def_br { // `ref`/`ref mut` overrides the binding mode on edition <= 2021 self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - ident.span, + if user_br_mutbl.is_mut() { 't' } else { 'f' }, def_br_mutbl, ); } @@ -2387,7 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - inner.span, + if pat_mutbl.is_mut() { 't' } else { '&' }, inh_mut, ) } @@ -2779,18 +2779,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat_id: HirId, subpat: &'tcx Pat<'tcx>, - cutoff_span: Span, + final_char: char, def_br_mutbl: Mutability, ) { // Try to trim the span we're labeling to just the `&` or binding mode that's an issue. // If the subpattern's span is is from an expansion, the emitted label will not be trimmed. - let source_map = self.tcx.sess.source_map(); - let cutoff_span = source_map - .span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(') - .unwrap_or(cutoff_span); - // Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard - // error if the subpattern is of edition >= 2024. - let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt()); + // Importantly, the edition of the trimmed span should be the same as `subpat.span`; this + // will be a hard error if the subpattern is of edition >= 2024. + let from_expansion = subpat.span.from_expansion(); + let trimmed_span = if from_expansion { + subpat.span + } else { + self.tcx.sess.source_map().span_through_char(subpat.span, final_char) + }; let mut typeck_results = self.typeck_results.borrow_mut(); let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); @@ -2824,7 +2825,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Only provide a detailed label if the problematic subpattern isn't from an expansion. // In the case that it's from a macro, we'll add a more detailed note in the emitter. - let from_expansion = subpat.span.from_expansion(); let primary_label = if from_expansion { // We can't suggest eliding modifiers within expansions. info.suggest_eliding_modes = false; diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index eb76615aac129..6efda4f757ff6 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -581,12 +581,10 @@ LL | let &[migration_lint_macros::bind_ref!(a)] = &[0]; | + error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 - --> $DIR/auxiliary/migration_lint_macros.rs:15:22 + --> $DIR/migration_lint.rs:249:10 | -LL | ($foo:ident) => { - | ______________________^ -LL | | ref $foo - | |________________^ reference pattern not allowed under `ref` default binding mode +LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + | ^ reference pattern not allowed under `ref` default binding mode | = warning: this changes meaning in Rust 2024 = note: for more information, see @@ -596,7 +594,6 @@ note: matching on a reference type with a non-reference pattern changes the defa LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` help: make the implied reference pattern explicit - --> $DIR/migration_lint.rs:249:9 | LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; | + From a090e76dab39b3771b5e99096766b5ffac588145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 19 Feb 2025 17:26:03 +0000 Subject: [PATCH 11/14] Tweak "expected ident" parse error to avoid talking about doc comments When encountering a doc comment without an identifier after, we'd unconditionally state "this doc comment doesn't document anything", swallowing the *actual* error which is that the thing *after* the doc comment wasn't expected. Added a check that the found token is something that "conceptually" closes the previous item before emitting that error, otherwise just complain about the missing identifier. In both of the following cases, the syntax error follows a doc comment: ``` error: expected identifier, found keyword `Self` --> $DIR/doc-before-bad-variant.rs:4:5 | LL | enum TestEnum { | -------- while parsing this enum ... LL | Self, | ^^^^ expected identifier, found keyword | = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` ``` ``` error: expected identifier, found `<` --> $DIR/doc-before-syntax-error.rs:2:1 | LL | <> | ^ expected identifier ``` Fix #71982. --- compiler/rustc_parse/src/parser/diagnostics.rs | 16 +++++++++------- tests/ui/parser/doc-before-bad-variant.rs | 6 ++++++ tests/ui/parser/doc-before-bad-variant.stderr | 13 +++++++++++++ tests/ui/parser/doc-before-syntax-error.rs | 2 ++ tests/ui/parser/doc-before-syntax-error.stderr | 8 ++++++++ 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 tests/ui/parser/doc-before-bad-variant.rs create mode 100644 tests/ui/parser/doc-before-bad-variant.stderr create mode 100644 tests/ui/parser/doc-before-syntax-error.rs create mode 100644 tests/ui/parser/doc-before-syntax-error.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 72aebb5d12144..67abc2d539401 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -301,13 +301,6 @@ impl<'a> Parser<'a> { &mut self, recover: bool, ) -> PResult<'a, (Ident, IdentIsRaw)> { - if let TokenKind::DocComment(..) = self.prev_token.kind { - return Err(self.dcx().create_err(DocCommentDoesNotDocumentAnything { - span: self.prev_token.span, - missing_comma: None, - })); - } - let valid_follow = &[ TokenKind::Eq, TokenKind::Colon, @@ -319,6 +312,15 @@ impl<'a> Parser<'a> { TokenKind::CloseDelim(Delimiter::Brace), TokenKind::CloseDelim(Delimiter::Parenthesis), ]; + if let TokenKind::DocComment(..) = self.prev_token.kind + && valid_follow.contains(&self.token.kind) + { + let err = self.dcx().create_err(DocCommentDoesNotDocumentAnything { + span: self.prev_token.span, + missing_comma: None, + }); + return Err(err); + } let mut recovered_ident = None; // we take this here so that the correct original token is retained in diff --git a/tests/ui/parser/doc-before-bad-variant.rs b/tests/ui/parser/doc-before-bad-variant.rs new file mode 100644 index 0000000000000..bfede28c10892 --- /dev/null +++ b/tests/ui/parser/doc-before-bad-variant.rs @@ -0,0 +1,6 @@ +enum TestEnum { + Works, + /// Some documentation + Self, //~ ERROR expected identifier, found keyword `Self` + //~^ HELP enum variants can be +} diff --git a/tests/ui/parser/doc-before-bad-variant.stderr b/tests/ui/parser/doc-before-bad-variant.stderr new file mode 100644 index 0000000000000..5e4d4116f259f --- /dev/null +++ b/tests/ui/parser/doc-before-bad-variant.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `Self` + --> $DIR/doc-before-bad-variant.rs:4:5 + | +LL | enum TestEnum { + | -------- while parsing this enum +... +LL | Self, + | ^^^^ expected identifier, found keyword + | + = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/doc-before-syntax-error.rs b/tests/ui/parser/doc-before-syntax-error.rs new file mode 100644 index 0000000000000..435f497d186ed --- /dev/null +++ b/tests/ui/parser/doc-before-syntax-error.rs @@ -0,0 +1,2 @@ +/// Some documentation +<> //~ ERROR expected identifier diff --git a/tests/ui/parser/doc-before-syntax-error.stderr b/tests/ui/parser/doc-before-syntax-error.stderr new file mode 100644 index 0000000000000..93e39d6300077 --- /dev/null +++ b/tests/ui/parser/doc-before-syntax-error.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `<` + --> $DIR/doc-before-syntax-error.rs:2:1 + | +LL | <> + | ^ expected identifier + +error: aborting due to 1 previous error + From 452c14e7c2f749a664ada644d294d40187c0a540 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 19 Feb 2025 09:48:06 -0800 Subject: [PATCH 12/14] re-add explicit `with_ctxt` and tweak comments --- compiler/rustc_hir_typeck/src/pat.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 242536e001821..00ee3e10db127 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2783,14 +2783,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_br_mutbl: Mutability, ) { // Try to trim the span we're labeling to just the `&` or binding mode that's an issue. - // If the subpattern's span is is from an expansion, the emitted label will not be trimmed. - // Importantly, the edition of the trimmed span should be the same as `subpat.span`; this - // will be a hard error if the subpattern is of edition >= 2024. let from_expansion = subpat.span.from_expansion(); let trimmed_span = if from_expansion { + // If the subpattern is from an expansion, highlight the whole macro call instead. subpat.span } else { - self.tcx.sess.source_map().span_through_char(subpat.span, final_char) + let trimmed = self.tcx.sess.source_map().span_through_char(subpat.span, final_char); + // The edition of the trimmed span should be the same as `subpat.span`; this will be a + // a hard error if the subpattern is of edition >= 2024. We set it manually to be sure: + trimmed.with_ctxt(subpat.span.ctxt()) }; let mut typeck_results = self.typeck_results.borrow_mut(); From 2be26f0fe80ce2bcf25653ad3e4ca7fe9f4d4b26 Mon Sep 17 00:00:00 2001 From: dianne Date: Wed, 19 Feb 2025 10:01:13 -0800 Subject: [PATCH 13/14] add clarifying comments to chars used for label-trimming --- compiler/rustc_hir_typeck/src/pat.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 00ee3e10db127..0ef1b923399b6 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -835,7 +835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - 't', + 't', // last char of `mut` def_br_mutbl, ); BindingMode(ByRef::No, Mutability::Mut) @@ -848,7 +848,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - if user_br_mutbl.is_mut() { 't' } else { 'f' }, + match user_br_mutbl { + Mutability::Not => 'f', // last char of `ref` + Mutability::Mut => 't', // last char of `ref mut` + }, def_br_mutbl, ); } @@ -2387,7 +2390,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - if pat_mutbl.is_mut() { 't' } else { '&' }, + match pat_mutbl { + Mutability::Not => '&', // last char of `&` + Mutability::Mut => 't', // last char of `&mut` + }, inh_mut, ) } From b24f77507f2b1684f69b68ac122f0b368cac7302 Mon Sep 17 00:00:00 2001 From: may Date: Wed, 19 Feb 2025 16:20:45 +0100 Subject: [PATCH 14/14] stabilize `inherent_str_constructors` --- library/core/src/str/mod.rs | 25 +++----- tests/ui/lint/invalid_from_utf8.rs | 1 - tests/ui/lint/invalid_from_utf8.stderr | 80 +++++++++++++------------- 3 files changed, 47 insertions(+), 59 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index c0ee49fbb301f..4754d18b06eac 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -198,8 +198,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// @@ -213,8 +211,6 @@ impl str { /// Incorrect bytes: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // some invalid bytes, in a vector /// let sparkle_heart = vec![0, 159, 146, 150]; /// @@ -227,8 +223,6 @@ impl str { /// A "stack allocated string": /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // some bytes, in a stack-allocated array /// let sparkle_heart = [240, 159, 146, 150]; /// @@ -237,7 +231,8 @@ impl str { /// /// assert_eq!("💖", sparkle_heart); /// ``` - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8"] pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { converts::from_utf8(v) @@ -250,8 +245,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // "Hello, Rust!" as a mutable vector /// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33]; /// @@ -264,8 +257,6 @@ impl str { /// Incorrect bytes: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // Some invalid bytes in a mutable vector /// let mut invalid = vec![128, 223]; /// @@ -273,7 +264,7 @@ impl str { /// ``` /// See the docs for [`Utf8Error`] for more details on the kinds of /// errors that can be returned. - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] #[rustc_diagnostic_item = "str_inherent_from_utf8_mut"] pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { @@ -294,8 +285,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// @@ -307,7 +296,8 @@ impl str { /// ``` #[inline] #[must_use] - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked"] pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { // SAFETY: converts::from_utf8_unchecked has the same safety requirements as this function. @@ -324,8 +314,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(inherent_str_constructors)] - /// /// let mut heart = vec![240, 159, 146, 150]; /// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) }; /// @@ -333,7 +321,8 @@ impl str { /// ``` #[inline] #[must_use] - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked_mut"] pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { // SAFETY: converts::from_utf8_unchecked_mut has the same safety requirements as this function. diff --git a/tests/ui/lint/invalid_from_utf8.rs b/tests/ui/lint/invalid_from_utf8.rs index 8f8000fe34d4d..87a906761c075 100644 --- a/tests/ui/lint/invalid_from_utf8.rs +++ b/tests/ui/lint/invalid_from_utf8.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(concat_bytes)] -#![feature(inherent_str_constructors)] #![warn(invalid_from_utf8_unchecked)] #![warn(invalid_from_utf8)] diff --git a/tests/ui/lint/invalid_from_utf8.stderr b/tests/ui/lint/invalid_from_utf8.stderr index 715ecf56f218b..3cd4d227fc276 100644 --- a/tests/ui/lint/invalid_from_utf8.stderr +++ b/tests/ui/lint/invalid_from_utf8.stderr @@ -1,5 +1,5 @@ warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:22:9 + --> $DIR/invalid_from_utf8.rs:21:9 | LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -7,13 +7,13 @@ LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112 | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:5:9 + --> $DIR/invalid_from_utf8.rs:4:9 | LL | #![warn(invalid_from_utf8_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:24:9 + --> $DIR/invalid_from_utf8.rs:23:9 | LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -21,7 +21,7 @@ LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121 | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:26:9 + --> $DIR/invalid_from_utf8.rs:25:9 | LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -29,7 +29,7 @@ LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:28:9 + --> $DIR/invalid_from_utf8.rs:27:9 | LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -37,7 +37,7 @@ LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:50:9 + --> $DIR/invalid_from_utf8.rs:49:9 | LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -45,7 +45,7 @@ LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:52:9 + --> $DIR/invalid_from_utf8.rs:51:9 | LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -53,7 +53,7 @@ LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:54:9 + --> $DIR/invalid_from_utf8.rs:53:9 | LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -61,7 +61,7 @@ LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:56:9 + --> $DIR/invalid_from_utf8.rs:55:9 | LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -69,7 +69,7 @@ LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:58:9 + --> $DIR/invalid_from_utf8.rs:57:9 | LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^ @@ -77,7 +77,7 @@ LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:60:9 + --> $DIR/invalid_from_utf8.rs:59:9 | LL | str::from_utf8_unchecked(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------^ @@ -85,7 +85,7 @@ LL | str::from_utf8_unchecked(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:62:9 + --> $DIR/invalid_from_utf8.rs:61:9 | LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -93,7 +93,7 @@ LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:64:9 + --> $DIR/invalid_from_utf8.rs:63:9 | LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -101,7 +101,7 @@ LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:84:9 + --> $DIR/invalid_from_utf8.rs:83:9 | LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -109,13 +109,13 @@ LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:6:9 + --> $DIR/invalid_from_utf8.rs:5:9 | LL | #![warn(invalid_from_utf8)] | ^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:86:9 + --> $DIR/invalid_from_utf8.rs:85:9 | LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -123,7 +123,7 @@ LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:88:9 + --> $DIR/invalid_from_utf8.rs:87:9 | LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -131,7 +131,7 @@ LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:90:9 + --> $DIR/invalid_from_utf8.rs:89:9 | LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -139,7 +139,7 @@ LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:112:9 + --> $DIR/invalid_from_utf8.rs:111:9 | LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -147,7 +147,7 @@ LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:114:9 + --> $DIR/invalid_from_utf8.rs:113:9 | LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^----------------------------------^ @@ -155,7 +155,7 @@ LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:116:9 + --> $DIR/invalid_from_utf8.rs:115:9 | LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -163,7 +163,7 @@ LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']) | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:118:9 + --> $DIR/invalid_from_utf8.rs:117:9 | LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -171,7 +171,7 @@ LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:120:9 + --> $DIR/invalid_from_utf8.rs:119:9 | LL | std::str::from_utf8(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^-------------^ @@ -179,7 +179,7 @@ LL | std::str::from_utf8(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:122:9 + --> $DIR/invalid_from_utf8.rs:121:9 | LL | str::from_utf8(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^-------------^ @@ -187,7 +187,7 @@ LL | str::from_utf8(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:124:9 + --> $DIR/invalid_from_utf8.rs:123:9 | LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -195,7 +195,7 @@ LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:126:9 + --> $DIR/invalid_from_utf8.rs:125:9 | LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^---------------------------------^ @@ -203,7 +203,7 @@ LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:133:5 + --> $DIR/invalid_from_utf8.rs:132:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -211,7 +211,7 @@ LL | std::str::from_utf8_mut(&mut a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:135:5 + --> $DIR/invalid_from_utf8.rs:134:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -220,7 +220,7 @@ LL | str::from_utf8_mut(&mut a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:139:5 + --> $DIR/invalid_from_utf8.rs:138:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -229,7 +229,7 @@ LL | std::str::from_utf8_mut(c); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:141:5 + --> $DIR/invalid_from_utf8.rs:140:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -238,7 +238,7 @@ LL | str::from_utf8_mut(c); | ^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:144:5 + --> $DIR/invalid_from_utf8.rs:143:5 | LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -246,7 +246,7 @@ LL | std::str::from_utf8(c); | ^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:146:5 + --> $DIR/invalid_from_utf8.rs:145:5 | LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -255,7 +255,7 @@ LL | str::from_utf8(c); | ^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:149:5 + --> $DIR/invalid_from_utf8.rs:148:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -263,7 +263,7 @@ LL | std::str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:151:5 + --> $DIR/invalid_from_utf8.rs:150:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -272,7 +272,7 @@ LL | str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:154:5 + --> $DIR/invalid_from_utf8.rs:153:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -280,7 +280,7 @@ LL | std::str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:156:5 + --> $DIR/invalid_from_utf8.rs:155:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -289,7 +289,7 @@ LL | str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:159:5 + --> $DIR/invalid_from_utf8.rs:158:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -297,7 +297,7 @@ LL | std::str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:161:5 + --> $DIR/invalid_from_utf8.rs:160:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -306,7 +306,7 @@ LL | str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:164:5 + --> $DIR/invalid_from_utf8.rs:163:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -314,7 +314,7 @@ LL | std::str::from_utf8(INVALID_4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:166:5 + --> $DIR/invalid_from_utf8.rs:165:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes