From c1c3daac35c4638c7220ed6fea19738abdc1a8c0 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 07:26:51 -0300 Subject: [PATCH 01/24] Uplift flatten_answer_tree to next-solver --- Cargo.lock | 2 + compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_next_trait_solver/Cargo.toml | 2 + .../rustc_next_trait_solver/src/solve/mod.rs | 49 +++++++++++- .../src/traits/select/confirmation.rs | 74 ++----------------- 5 files changed, 61 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e11fd2189569c..838e7975dd58a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4582,6 +4582,8 @@ dependencies = [ "rustc_data_structures", "rustc_index", "rustc_macros", + "rustc_middle", + "rustc_transmute", "rustc_type_ir", "rustc_type_ir_macros", "thin-vec", diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1f2ffb17cc2c7..10bd4d464e458 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -30,7 +30,7 @@ use rustc_abi::{ }; use rustc_ast::{self as ast}; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -use rustc_attr_ir::lang_items::LangItem; +pub use rustc_attr_ir::lang_items::LangItem; use rustc_attr_ir::{self as attr, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index f151b880bb114..e4f9312e1d815 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -9,6 +9,8 @@ derive-where = "1.2.7" rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } +rustc_middle = { path = "../rustc_middle" } +rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } thin-vec = "0.2.21" diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 9ed4963577458..e2789055ceecf 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,10 +21,13 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_type_ir::inherent::*; +use rustc_transmute::{Assume, Condition}; +use rustc_type_ir::{Upcast, inherent::*}; +use thin_vec::{ThinVec, thin_vec}; pub use rustc_type_ir::solve::*; use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt}; use tracing::instrument; +use rustc_middle::ty::{self as mty, TyCtxt, Ty as MiddleTy, LangItem}; pub use self::eval_ctxt::{ EvalCtxt, GenerateProofTree, SolverDelegateEvalExt, @@ -491,3 +494,47 @@ pub struct GoalEvaluation { /// before rerunning it. pub stalled_on: Option>, } + +/// Flatten the `Condition` tree into a conjunction of predicates. +#[instrument(level = "debug", skip(tcx, predicate))] +pub fn flatten_answer_tree<'tcx>( + tcx: TyCtxt<'tcx> , + predicate: mty::TraitClause<'tcx>, + cond: Condition, MiddleTy<'tcx>>, + assume: Assume, +) -> ThinVec> { + match cond { + // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` + // Not possible until the trait solver supports disjunctions of obligations + Condition::IfAll(conds) | Condition::IfAny(conds) => conds + .into_iter() + .flat_map(|cond| flatten_answer_tree(tcx, predicate, cond, assume)) + .collect(), + Condition::Immutable { ty } => { + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Freeze, Span::dummy()), + [mty::GenericArg::from(ty)], + ); + thin_vec![trait_ref.upcast(tcx)] + } + Condition::Outlives { long, short } => { + let outlives = ty::OutlivesClause(long, short); + thin_vec![outlives.upcast(tcx)] + } + Condition::Transmutable { src, dst } => { + let transmute_trait = predicate.def_id(); + let assume = predicate.trait_ref.args.const_at(2); + let trait_ref = ty::TraitRef::new( + tcx, + transmute_trait, + [ + mty::GenericArg::from(dst), + mty::GenericArg::from(src), + mty::GenericArg::from(assume), + ], + ); + thin_vec![trait_ref.upcast(tcx)] + } + } +} diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 81517955181ee..69d31f8cdc813 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -14,8 +14,9 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{ - self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Unnormalized, Upcast, + self, GenericArgsRef, SizedTraitKind, Ty, Unnormalized, Upcast, }; +use rustc_next_trait_solver::solve::flatten_answer_tree; use rustc_span::def_id::DefId; use rustc_span::{bug, span_bug}; use thin_vec::thin_vec; @@ -285,69 +286,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result, SelectionError<'tcx>> { - use rustc_transmute::{Answer, Assume, Condition}; - - /// Flatten the `Condition` tree into a conjunction of obligations. - #[instrument(level = "debug", skip(tcx, obligation))] - fn flatten_answer_tree<'tcx>( - tcx: TyCtxt<'tcx>, - obligation: &PolyTraitObligation<'tcx>, - cond: Condition, Ty<'tcx>>, - assume: Assume, - ) -> PredicateObligations<'tcx> { - match cond { - // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` - // Not possible until the trait solver supports disjunctions of obligations - Condition::IfAll(conds) | Condition::IfAny(conds) => conds - .into_iter() - .flat_map(|cond| flatten_answer_tree(tcx, obligation, cond, assume)) - .collect(), - Condition::Immutable { ty } => { - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Freeze, obligation.cause.span), - [ty::GenericArg::from(ty)], - ); - thin_vec![Obligation::with_depth( - tcx, - obligation.cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - trait_ref, - )] - } - Condition::Outlives { long, short } => { - let outlives = ty::OutlivesClause(long, short); - thin_vec![Obligation::with_depth( - tcx, - obligation.cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - outlives, - )] - } - Condition::Transmutable { src, dst } => { - let transmute_trait = obligation.predicate.def_id(); - let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2); - let trait_ref = ty::TraitRef::new( - tcx, - transmute_trait, - [ - ty::GenericArg::from(dst), - ty::GenericArg::from(src), - ty::GenericArg::from(assume), - ], - ); - thin_vec![Obligation::with_depth( - tcx, - obligation.cause.clone(), - obligation.recursion_depth + 1, - obligation.param_env, - trait_ref, - )] - } - } - } + use rustc_transmute::Answer; let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); @@ -367,9 +306,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let maybe_transmutable = transmute_env.is_transmutable(src, dst, assume); let fully_flattened = match maybe_transmutable { - Answer::No(_) => Err(SelectionError::Unimplemented)?, - Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, cond, assume), + Answer::No(_) => return Err(SelectionError::Unimplemented), Answer::Yes => PredicateObligations::new(), + Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation.predicate.skip_binder(), cond, assume) + .into_iter() + .map(|predicate| Obligation::new(self.infcx.tcx, obligation.cause.clone(), obligation.param_env, predicate)) + .collect(), }; debug!(?fully_flattened); From 61d4201b278075f5e0df74c3df0a1ed37929941b Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Tue, 6 Oct 2026 14:39:31 -0300 Subject: [PATCH 02/24] Add test for transmute recycle on next solver --- .../ui/transmutability/vec-recycle-next-solver.rs | 15 +++++++++++++++ .../vec-recycle-next-solver.stderr | 14 ++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/ui/transmutability/vec-recycle-next-solver.rs create mode 100644 tests/ui/transmutability/vec-recycle-next-solver.stderr diff --git a/tests/ui/transmutability/vec-recycle-next-solver.rs b/tests/ui/transmutability/vec-recycle-next-solver.rs new file mode 100644 index 0000000000000..58cf0bcf68310 --- /dev/null +++ b/tests/ui/transmutability/vec-recycle-next-solver.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -Znext-solver=globally +//@ check-fail + +#![feature(vec_recycle, transmutability)] + +fn main() { + let a: Vec = vec![0; 100]; + let capacity = a.capacity(); + let addr = a.as_ptr().addr(); + let b: Vec = a.recycle(); + //~^ ERROR `&MaybeUninit` cannot be safely transmuted into `&MaybeUninit` [E0277] + assert_eq!(b.len(), 0); + assert_eq!(b.capacity(), capacity); + assert_eq!(b.as_ptr().addr(), addr); +} diff --git a/tests/ui/transmutability/vec-recycle-next-solver.stderr b/tests/ui/transmutability/vec-recycle-next-solver.stderr new file mode 100644 index 0000000000000..231d5421a079e --- /dev/null +++ b/tests/ui/transmutability/vec-recycle-next-solver.stderr @@ -0,0 +1,14 @@ +error[E0277]: `&MaybeUninit` cannot be safely transmuted into `&MaybeUninit` + --> $DIR/vec-recycle-next-solver.rs:10:24 + | +LL | let b: Vec = a.recycle(); + | ^^^^^^^ unsatisfied trait bound + | + = help: the nightly-only, unstable trait `for<'a> TransmuteFrom<&'a MaybeUninit, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'a MaybeUninit` + = note: required for `i8` to implement `vec::Recyclable` +note: required by a bound in `Vec::::recycle` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 01d70abec069b7a607c74b3a6f22038348f883e5 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 09:13:10 -0300 Subject: [PATCH 03/24] Update is_transmutable on next solver to consider nested goals --- compiler/rustc_next_trait_solver/src/delegate.rs | 6 ++++-- .../src/solve/eval_ctxt/mod.rs | 7 ++++--- .../src/solve/trait_goals.rs | 8 +++++++- .../rustc_trait_selection/src/solve/delegate.rs | 16 ++++++++++------ 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 24e321fc68c67..85d6038c86731 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -5,7 +5,8 @@ use rustc_type_ir::solve::{ Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck, }; -use rustc_type_ir::{self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TypeFoldable}; +use rustc_type_ir::{self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TraitClause, TypeFoldable}; +use thin_vec::ThinVec; /// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer /// between rustc and rust-analyzer abstracting over the [InferCtxt][inferctxt-doc], which had to be @@ -112,8 +113,9 @@ pub trait SolverDelegate: Deref + Sized { &self, src: ::Ty, dst: ::Ty, + predicate: TraitClause, assume: Const, - ) -> Result; + ) -> Result<(Certainty, ThinVec<::Predicate>), NoSolution>; /// Obtain canonicalizer state, either by allocating it afresh (the default) or by reusing /// previously allocated state. diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index f97bc0bbeb626..ea6edda89fa77 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; #[cfg(feature = "nightly")] use rustc_macros::StableHash; use rustc_type_ir::data_structures::HashSet; -use rustc_type_ir::inherent::*; +use rustc_type_ir::{TraitClause, inherent::*}; use rustc_type_ir::region_constraint::RegionConstraint; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; @@ -1564,9 +1564,10 @@ where &mut self, src: I::Ty, dst: I::Ty, + predicate: TraitClause, assume: Const, - ) -> Result { - self.delegate.is_transmutable(dst, src, assume) + ) -> Result<(Certainty, ThinVec), NoSolution> { + self.delegate.is_transmutable(dst, src, predicate, assume) } pub(super) fn replace_bound_vars>( 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 31c0f72af8a28..8423803a515e5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -678,11 +678,17 @@ where goal.predicate.trait_ref.args.const_at(2), )?; - let certainty = ecx.is_transmutable( + let (certainty, predicates) = ecx.is_transmutable( goal.predicate.trait_ref.args.type_at(0), goal.predicate.trait_ref.args.type_at(1), + goal.predicate, assume, )?; + + ecx.add_goals(GoalSource::Misc, predicates.into_iter().map(|predicate| { + Goal::new(ecx.cx(), goal.param_env, predicate) + }).collect::>())?; + ecx.evaluate_added_goals_and_make_canonical_response(certainty) }, ) diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 3e0796bd1f585..d3581fafe7d4e 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -22,10 +22,9 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{Certainty, MaybeInfo}; use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{ - self, CanonicalizerState, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + self, CanonicalizerState, MayBeErased, TraitClause, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; -use rustc_next_trait_solver::solve::{GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar}; +use rustc_next_trait_solver::solve::{GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar, flatten_answer_tree}; use rustc_span::{DUMMY_SP, Span}; use rustc_structures::Limit; use thin_vec::{ThinVec, thin_vec}; @@ -490,8 +489,9 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< &self, src: Ty<'tcx>, dst: Ty<'tcx>, + predicate: TraitClause<'tcx>, assume: ty::Const<'tcx>, - ) -> Result { + ) -> Result<(Certainty, ThinVec>), NoSolution> { // Erase regions because we compute layouts in `rustc_transmute`, // which will ICE for region vars. let (dst, src) = self.tcx.erase_and_anonymize_regions((dst, src)); @@ -502,8 +502,12 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume) { - rustc_transmute::Answer::Yes => Ok(Certainty::Yes), - rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution), + rustc_transmute::Answer::No(_) => Err(NoSolution), + rustc_transmute::Answer::Yes => Ok((Certainty::Yes, ThinVec::new())), + rustc_transmute::Answer::If(cond) => { + let predicates = flatten_answer_tree(self.tcx, predicate, cond, assume); + Ok((Certainty::Yes, predicates)) + } } } From 247b4de295ebb63772d8f2e079546ed5617a77d2 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 09:17:31 -0300 Subject: [PATCH 04/24] Update test to reflect previous fix --- .../ui/transmutability/vec-recycle-next-solver.rs | 3 +-- .../transmutability/vec-recycle-next-solver.stderr | 14 -------------- 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 tests/ui/transmutability/vec-recycle-next-solver.stderr diff --git a/tests/ui/transmutability/vec-recycle-next-solver.rs b/tests/ui/transmutability/vec-recycle-next-solver.rs index 58cf0bcf68310..0d1fc6cf7675c 100644 --- a/tests/ui/transmutability/vec-recycle-next-solver.rs +++ b/tests/ui/transmutability/vec-recycle-next-solver.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Znext-solver=globally -//@ check-fail +//@ check-pass #![feature(vec_recycle, transmutability)] @@ -8,7 +8,6 @@ fn main() { let capacity = a.capacity(); let addr = a.as_ptr().addr(); let b: Vec = a.recycle(); - //~^ ERROR `&MaybeUninit` cannot be safely transmuted into `&MaybeUninit` [E0277] assert_eq!(b.len(), 0); assert_eq!(b.capacity(), capacity); assert_eq!(b.as_ptr().addr(), addr); diff --git a/tests/ui/transmutability/vec-recycle-next-solver.stderr b/tests/ui/transmutability/vec-recycle-next-solver.stderr deleted file mode 100644 index 231d5421a079e..0000000000000 --- a/tests/ui/transmutability/vec-recycle-next-solver.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0277]: `&MaybeUninit` cannot be safely transmuted into `&MaybeUninit` - --> $DIR/vec-recycle-next-solver.rs:10:24 - | -LL | let b: Vec = a.recycle(); - | ^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `for<'a> TransmuteFrom<&'a MaybeUninit, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'a MaybeUninit` - = note: required for `i8` to implement `vec::Recyclable` -note: required by a bound in `Vec::::recycle` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. From 5eb32c99594cc1dfffe6d15aba147a671dd3b890 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 11:57:56 -0300 Subject: [PATCH 05/24] tidy up! --- .../rustc_next_trait_solver/src/delegate.rs | 4 +++- .../src/solve/eval_ctxt/mod.rs | 6 +++--- .../rustc_next_trait_solver/src/solve/mod.rs | 10 +++++----- .../src/solve/trait_goals.rs | 10 +++++++--- .../src/solve/delegate.rs | 7 +++++-- .../src/traits/select/confirmation.rs | 19 +++++++++++++------ 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 85d6038c86731..2a6bc63139c15 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -5,7 +5,9 @@ use rustc_type_ir::solve::{ Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck, }; -use rustc_type_ir::{self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TraitClause, TypeFoldable}; +use rustc_type_ir::{ + self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TraitClause, TypeFoldable, +}; use thin_vec::ThinVec; /// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index ea6edda89fa77..1ba22d44cc1cd 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; #[cfg(feature = "nightly")] use rustc_macros::StableHash; use rustc_type_ir::data_structures::HashSet; -use rustc_type_ir::{TraitClause, inherent::*}; +use rustc_type_ir::inherent::*; use rustc_type_ir::region_constraint::RegionConstraint; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; @@ -18,8 +18,8 @@ use rustc_type_ir::solve::{ }; use rustc_type_ir::{ self as ty, ClauseKind, Const, InferCtxtLike, Interner, MayBeErased, OpaqueTypeKey, - PredicateKind, PredicateProxy, Region, RegionVid, TypeFoldable, TypeSuperVisitable, - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, max_universe, + PredicateKind, PredicateProxy, Region, RegionVid, TraitClause, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, max_universe, }; use thin_vec::ThinVec; use tracing::{Level, debug, instrument, trace, warn}; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index e2789055ceecf..12be25f1b2720 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,13 +21,13 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; +use rustc_middle::ty::{self as mty, LangItem, Ty as MiddleTy, TyCtxt}; use rustc_transmute::{Assume, Condition}; -use rustc_type_ir::{Upcast, inherent::*}; -use thin_vec::{ThinVec, thin_vec}; +use rustc_type_ir::inherent::*; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt}; +use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt, Upcast}; +use thin_vec::{ThinVec, thin_vec}; use tracing::instrument; -use rustc_middle::ty::{self as mty, TyCtxt, Ty as MiddleTy, LangItem}; pub use self::eval_ctxt::{ EvalCtxt, GenerateProofTree, SolverDelegateEvalExt, @@ -498,7 +498,7 @@ pub struct GoalEvaluation { /// Flatten the `Condition` tree into a conjunction of predicates. #[instrument(level = "debug", skip(tcx, predicate))] pub fn flatten_answer_tree<'tcx>( - tcx: TyCtxt<'tcx> , + tcx: TyCtxt<'tcx>, predicate: mty::TraitClause<'tcx>, cond: Condition, MiddleTy<'tcx>>, assume: Assume, 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 8423803a515e5..1a82d5373a511 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -685,9 +685,13 @@ where assume, )?; - ecx.add_goals(GoalSource::Misc, predicates.into_iter().map(|predicate| { - Goal::new(ecx.cx(), goal.param_env, predicate) - }).collect::>())?; + ecx.add_goals( + GoalSource::Misc, + predicates + .into_iter() + .map(|predicate| Goal::new(ecx.cx(), goal.param_env, predicate)) + .collect::>(), + )?; ecx.evaluate_added_goals_and_make_canonical_response(certainty) }, diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index d3581fafe7d4e..f5d2b53e13902 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -22,9 +22,12 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{Certainty, MaybeInfo}; use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{ - self, CanonicalizerState, MayBeErased, TraitClause, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + self, CanonicalizerState, MayBeErased, TraitClause, Ty, TyCtxt, TypeFlags, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, +}; +use rustc_next_trait_solver::solve::{ + GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar, flatten_answer_tree, }; -use rustc_next_trait_solver::solve::{GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar, flatten_answer_tree}; use rustc_span::{DUMMY_SP, Span}; use rustc_structures::Limit; use thin_vec::{ThinVec, thin_vec}; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 69d31f8cdc813..5c977f7ea61bc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -13,9 +13,7 @@ use rustc_attr_ir::lang_items::LangItem; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{ - self, GenericArgsRef, SizedTraitKind, Ty, Unnormalized, Upcast, -}; +use rustc_middle::ty::{self, GenericArgsRef, SizedTraitKind, Ty, Unnormalized, Upcast}; use rustc_next_trait_solver::solve::flatten_answer_tree; use rustc_span::def_id::DefId; use rustc_span::{bug, span_bug}; @@ -308,10 +306,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let fully_flattened = match maybe_transmutable { Answer::No(_) => return Err(SelectionError::Unimplemented), Answer::Yes => PredicateObligations::new(), - Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation.predicate.skip_binder(), cond, assume) + Answer::If(cond) => { + flatten_answer_tree(self.tcx(), obligation.predicate.skip_binder(), cond, assume) .into_iter() - .map(|predicate| Obligation::new(self.infcx.tcx, obligation.cause.clone(), obligation.param_env, predicate)) - .collect(), + .map(|predicate| { + Obligation::new( + self.infcx.tcx, + obligation.cause.clone(), + obligation.param_env, + predicate, + ) + }) + .collect() + } }; debug!(?fully_flattened); From b6fecaf033d3f7768976ec5a2364005eccb9d2a7 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 15:21:24 -0300 Subject: [PATCH 06/24] Replace require_lang_item with require_trait_lang_item (avoiding dummy and pub) --- compiler/rustc_middle/src/ty/context/impl_interner.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_next_trait_solver/src/solve/mod.rs | 5 +++-- compiler/rustc_type_ir/src/lang_items.rs | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index a6688b668aab3..dcbe3f74c733e 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -819,6 +819,7 @@ bidirectional_lang_item_map! { FnMut, FnOnce, FnPtrTrait, + Freeze, FusedIterator, Future, Iterator, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 10bd4d464e458..1f2ffb17cc2c7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -30,7 +30,7 @@ use rustc_abi::{ }; use rustc_ast::{self as ast}; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -pub use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_attr_ir::{self as attr, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 12be25f1b2720..31cc4c34cebf7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,9 +21,10 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_middle::ty::{self as mty, LangItem, Ty as MiddleTy, TyCtxt}; +use rustc_middle::ty::{self as mty, Ty as MiddleTy, TyCtxt}; use rustc_transmute::{Assume, Condition}; use rustc_type_ir::inherent::*; +use rustc_type_ir::lang_items::SolverTraitLangItem; pub use rustc_type_ir::solve::*; use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt, Upcast}; use thin_vec::{ThinVec, thin_vec}; @@ -513,7 +514,7 @@ pub fn flatten_answer_tree<'tcx>( Condition::Immutable { ty } => { let trait_ref = ty::TraitRef::new( tcx, - tcx.require_lang_item(LangItem::Freeze, Span::dummy()), + tcx.require_trait_lang_item(SolverTraitLangItem::Freeze), [mty::GenericArg::from(ty)], ); thin_vec![trait_ref.upcast(tcx)] diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 0bc901e07ea96..246d6241ec8ba 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -46,6 +46,7 @@ pub enum SolverTraitLangItem { FnMut, FnOnce, FnPtrTrait, + Freeze, FusedIterator, Future, Iterator, From da484831ba73e61a4b3f1d301c062188bc1e7dcf Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 15:23:43 -0300 Subject: [PATCH 07/24] Avoid needless collect --- compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1a82d5373a511..0c06f93431e73 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -685,12 +685,12 @@ where assume, )?; + let tcx = ecx.cx(); ecx.add_goals( GoalSource::Misc, predicates .into_iter() - .map(|predicate| Goal::new(ecx.cx(), goal.param_env, predicate)) - .collect::>(), + .map(|predicate| Goal::new(tcx, goal.param_env, predicate)), )?; ecx.evaluate_added_goals_and_make_canonical_response(certainty) From 1266bc0d1c0783a49683a98e8b01574c4fcafb91 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 15:33:04 -0300 Subject: [PATCH 08/24] Add a couple more tests --- .../pointer-aligned-to-next-solver.rs | 18 ++++++++++++++++++ .../transmute-from-next-solver.rs | 10 ++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/ui/transmutability/pointer-aligned-to-next-solver.rs create mode 100644 tests/ui/transmutability/transmute-from-next-solver.rs diff --git a/tests/ui/transmutability/pointer-aligned-to-next-solver.rs b/tests/ui/transmutability/pointer-aligned-to-next-solver.rs new file mode 100644 index 0000000000000..6c628b697708d --- /dev/null +++ b/tests/ui/transmutability/pointer-aligned-to-next-solver.rs @@ -0,0 +1,18 @@ +//! Regression test for . +//@ compile-flags: -Znext-solver=globally +//@ check-pass + +#![feature(pointer_is_aligned_to, transmutability)] +use std::mem::{Assume, TransmuteFrom}; + +fn main() { + let src: &[u8; 2] = &[0xFF, 0xFF]; + + let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::()) { + Some(unsafe { + <_ as TransmuteFrom<_, { Assume::ALIGNMENT }>>::transmute(src) + }) + } else { + None + }; +} diff --git a/tests/ui/transmutability/transmute-from-next-solver.rs b/tests/ui/transmutability/transmute-from-next-solver.rs new file mode 100644 index 0000000000000..9b86e4c66a4ff --- /dev/null +++ b/tests/ui/transmutability/transmute-from-next-solver.rs @@ -0,0 +1,10 @@ +//! Regression test for . +//@ compile-flags: -Znext-solver=globally +//@ check-pass + +#![feature(transmutability)] +use std::mem::TransmuteFrom; + +fn main() { + let bytes: &[u8; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; +} From d995a7346daee95c18113038989079eae7c833b8 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Wed, 7 Oct 2026 15:52:58 -0300 Subject: [PATCH 09/24] Make flatten_answer_tree Interner generic --- .../rustc_next_trait_solver/src/solve/mod.rs | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 31cc4c34cebf7..d639fedf24c5f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,12 +21,12 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_middle::ty::{self as mty, Ty as MiddleTy, TyCtxt}; +use rustc_middle::ty::{self as mty, Ty as MiddleTy}; use rustc_transmute::{Assume, Condition}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; pub use rustc_type_ir::solve::*; -use rustc_type_ir::{self as ty, Const, Interner, Region, TypeVisitableExt, Upcast}; +use rustc_type_ir::{self as ty, Const, Interner, Region, TraitClause, TypeVisitableExt, Upcast}; use thin_vec::{ThinVec, thin_vec}; use tracing::instrument; @@ -497,45 +497,41 @@ pub struct GoalEvaluation { } /// Flatten the `Condition` tree into a conjunction of predicates. -#[instrument(level = "debug", skip(tcx, predicate))] -pub fn flatten_answer_tree<'tcx>( - tcx: TyCtxt<'tcx>, - predicate: mty::TraitClause<'tcx>, - cond: Condition, MiddleTy<'tcx>>, +#[instrument(level = "debug", skip(interner, predicate))] +pub fn flatten_answer_tree( + interner: I, + predicate: TraitClause, + cond: Condition, I::Ty>, assume: Assume, -) -> ThinVec> { +) -> ThinVec { match cond { // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` // Not possible until the trait solver supports disjunctions of obligations Condition::IfAll(conds) | Condition::IfAny(conds) => conds .into_iter() - .flat_map(|cond| flatten_answer_tree(tcx, predicate, cond, assume)) + .flat_map(|cond| flatten_answer_tree(interner, predicate, cond, assume)) .collect(), Condition::Immutable { ty } => { let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_trait_lang_item(SolverTraitLangItem::Freeze), - [mty::GenericArg::from(ty)], + interner, + interner.require_trait_lang_item(SolverTraitLangItem::Freeze), + [I::GenericArg::from(ty)], ); - thin_vec![trait_ref.upcast(tcx)] + thin_vec![trait_ref.upcast(interner)] } Condition::Outlives { long, short } => { let outlives = ty::OutlivesClause(long, short); - thin_vec![outlives.upcast(tcx)] + thin_vec![outlives.upcast(interner)] } Condition::Transmutable { src, dst } => { let transmute_trait = predicate.def_id(); let assume = predicate.trait_ref.args.const_at(2); let trait_ref = ty::TraitRef::new( - tcx, + interner, transmute_trait, - [ - mty::GenericArg::from(dst), - mty::GenericArg::from(src), - mty::GenericArg::from(assume), - ], + [I::GenericArg::from(dst), I::GenericArg::from(src), I::GenericArg::from(assume)], ); - thin_vec![trait_ref.upcast(tcx)] + thin_vec![trait_ref.upcast(interner)] } } } From 0f6564e75c9ee4cc1db78bf6a085af95f864db2d Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Thu, 8 Oct 2026 06:49:06 -0300 Subject: [PATCH 10/24] Remove middle from next-solver (sorry) --- Cargo.lock | 1 - compiler/rustc_next_trait_solver/Cargo.toml | 1 - compiler/rustc_next_trait_solver/src/solve/mod.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 838e7975dd58a..6799105a5361a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4582,7 +4582,6 @@ dependencies = [ "rustc_data_structures", "rustc_index", "rustc_macros", - "rustc_middle", "rustc_transmute", "rustc_type_ir", "rustc_type_ir_macros", diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index e4f9312e1d815..046294f9a5257 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -9,7 +9,6 @@ derive-where = "1.2.7" rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_middle = { path = "../rustc_middle" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index d639fedf24c5f..5b3353a0429eb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,7 +21,6 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_middle::ty::{self as mty, Ty as MiddleTy}; use rustc_transmute::{Assume, Condition}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; From 372a9e950e10aef0e2c8bb228b5c9009c04e089d Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 07:13:45 -0300 Subject: [PATCH 11/24] Remove needless param: assume --- compiler/rustc_next_trait_solver/src/solve/mod.rs | 5 ++--- compiler/rustc_trait_selection/src/solve/delegate.rs | 2 +- .../rustc_trait_selection/src/traits/select/confirmation.rs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 5b3353a0429eb..bd9e0604c364c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,7 +21,7 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_transmute::{Assume, Condition}; +use rustc_transmute::Condition; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; pub use rustc_type_ir::solve::*; @@ -501,14 +501,13 @@ pub fn flatten_answer_tree( interner: I, predicate: TraitClause, cond: Condition, I::Ty>, - assume: Assume, ) -> ThinVec { match cond { // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` // Not possible until the trait solver supports disjunctions of obligations Condition::IfAll(conds) | Condition::IfAny(conds) => conds .into_iter() - .flat_map(|cond| flatten_answer_tree(interner, predicate, cond, assume)) + .flat_map(|cond| flatten_answer_tree(interner, predicate, cond)) .collect(), Condition::Immutable { ty } => { let trait_ref = ty::TraitRef::new( diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f5d2b53e13902..b1c5bf4e0bafd 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -508,7 +508,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< rustc_transmute::Answer::No(_) => Err(NoSolution), rustc_transmute::Answer::Yes => Ok((Certainty::Yes, ThinVec::new())), rustc_transmute::Answer::If(cond) => { - let predicates = flatten_answer_tree(self.tcx, predicate, cond, assume); + let predicates = flatten_answer_tree(self.tcx, predicate, cond); Ok((Certainty::Yes, predicates)) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 5c977f7ea61bc..1f72a7c02c942 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -307,7 +307,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Answer::No(_) => return Err(SelectionError::Unimplemented), Answer::Yes => PredicateObligations::new(), Answer::If(cond) => { - flatten_answer_tree(self.tcx(), obligation.predicate.skip_binder(), cond, assume) + flatten_answer_tree(self.tcx(), obligation.predicate.skip_binder(), cond) .into_iter() .map(|predicate| { Obligation::new( From 21b29a69da96cf78937dab2e166129e316e7f1c7 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 07:31:57 -0300 Subject: [PATCH 12/24] is_transmutable returns answer now --- .../rustc_next_trait_solver/src/delegate.rs | 9 +++--- .../src/solve/eval_ctxt/mod.rs | 10 +++---- .../src/solve/trait_goals.rs | 27 +++++++++++------- .../src/solve/delegate.rs | 28 ++++++------------- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 2a6bc63139c15..241002257f3fe 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,14 +1,14 @@ use std::fmt::Debug; use std::ops::Deref; +use rustc_transmute::Answer; use rustc_type_ir::solve::{ - Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, + ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck, }; use rustc_type_ir::{ - self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, TraitClause, TypeFoldable, + self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, Region, TypeFoldable, }; -use thin_vec::ThinVec; /// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer /// between rustc and rust-analyzer abstracting over the [InferCtxt][inferctxt-doc], which had to be @@ -115,9 +115,8 @@ pub trait SolverDelegate: Deref + Sized { &self, src: ::Ty, dst: ::Ty, - predicate: TraitClause, assume: Const, - ) -> Result<(Certainty, ThinVec<::Predicate>), NoSolution>; + ) -> Result, ::Ty>, NoSolution>; /// Obtain canonicalizer state, either by allocating it afresh (the default) or by reusing /// previously allocated state. diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 1ba22d44cc1cd..31bf7cc0519ee 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -3,6 +3,7 @@ use std::ops::ControlFlow; #[cfg(feature = "nightly")] use rustc_macros::StableHash; +use rustc_transmute::Answer; use rustc_type_ir::data_structures::HashSet; use rustc_type_ir::inherent::*; use rustc_type_ir::region_constraint::RegionConstraint; @@ -18,8 +19,8 @@ use rustc_type_ir::solve::{ }; use rustc_type_ir::{ self as ty, ClauseKind, Const, InferCtxtLike, Interner, MayBeErased, OpaqueTypeKey, - PredicateKind, PredicateProxy, Region, RegionVid, TraitClause, TypeFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, max_universe, + PredicateKind, PredicateProxy, Region, RegionVid, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, max_universe, }; use thin_vec::ThinVec; use tracing::{Level, debug, instrument, trace, warn}; @@ -1564,10 +1565,9 @@ where &mut self, src: I::Ty, dst: I::Ty, - predicate: TraitClause, assume: Const, - ) -> Result<(Certainty, ThinVec), NoSolution> { - self.delegate.is_transmutable(dst, src, predicate, assume) + ) -> Result, I::Ty>, NoSolution> { + self.delegate.is_transmutable(dst, src, assume) } pub(super) fn replace_bound_vars>( 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 0c06f93431e73..e1f8b55455df9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -24,7 +24,7 @@ use crate::solve::assembly::{ use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - MergeCandidateInfo, NoSolution, ParamEnvSource, StalledOnCoroutines, + MergeCandidateInfo, NoSolution, ParamEnvSource, StalledOnCoroutines, flatten_answer_tree, has_only_region_constraints, }; @@ -678,20 +678,27 @@ where goal.predicate.trait_ref.args.const_at(2), )?; - let (certainty, predicates) = ecx.is_transmutable( + let answer = ecx.is_transmutable( goal.predicate.trait_ref.args.type_at(0), goal.predicate.trait_ref.args.type_at(1), - goal.predicate, assume, )?; - let tcx = ecx.cx(); - ecx.add_goals( - GoalSource::Misc, - predicates - .into_iter() - .map(|predicate| Goal::new(tcx, goal.param_env, predicate)), - )?; + let certainty = match answer { + rustc_transmute::Answer::No(_) => return Err(NoSolution.into()), + rustc_transmute::Answer::Yes => Certainty::Yes, + rustc_transmute::Answer::If(cond) => { + let tcx = ecx.cx(); + ecx.add_goals( + GoalSource::Misc, + flatten_answer_tree(tcx, goal.predicate, cond) + .into_iter() + .map(|predicate| Goal::new(tcx, goal.param_env, predicate)), + )?; + + Certainty::Yes + } + }; ecx.evaluate_added_goals_and_make_canonical_response(certainty) }, diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index b1c5bf4e0bafd..ad20826eed862 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -19,17 +19,16 @@ use rustc_infer::traits::solve::{ }; use rustc_lint_defs::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT; use rustc_middle::traits::query::NoSolution; -use rustc_middle::traits::solve::{Certainty, MaybeInfo}; +use rustc_middle::traits::solve::MaybeInfo; use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{ - self, CanonicalizerState, MayBeErased, TraitClause, Ty, TyCtxt, TypeFlags, TypeFoldable, + self, CanonicalizerState, MayBeErased, Region, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, }; -use rustc_next_trait_solver::solve::{ - GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar, flatten_answer_tree, -}; +use rustc_next_trait_solver::solve::{GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar}; use rustc_span::{DUMMY_SP, Span}; use rustc_structures::Limit; +use rustc_transmute::{Answer, TransmuteTypeEnv}; use thin_vec::{ThinVec, thin_vec}; use super::inspect::InferCtxtProofTreeExt; @@ -492,26 +491,15 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< &self, src: Ty<'tcx>, dst: Ty<'tcx>, - predicate: TraitClause<'tcx>, assume: ty::Const<'tcx>, - ) -> Result<(Certainty, ThinVec>), NoSolution> { + ) -> Result, Ty<'tcx>>, NoSolution> { // Erase regions because we compute layouts in `rustc_transmute`, // which will ICE for region vars. let (dst, src) = self.tcx.erase_and_anonymize_regions((dst, src)); - let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, assume) else { - return Err(NoSolution); - }; - - // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` - match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume) { - rustc_transmute::Answer::No(_) => Err(NoSolution), - rustc_transmute::Answer::Yes => Ok((Certainty::Yes, ThinVec::new())), - rustc_transmute::Answer::If(cond) => { - let predicates = flatten_answer_tree(self.tcx, predicate, cond); - Ok((Certainty::Yes, predicates)) - } - } + rustc_transmute::Assume::from_const(self.tcx, assume) + .map(|assume| TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume)) + .ok_or(NoSolution) } fn obtain_canonicalizer_state(&self) -> CanonicalizerState { From 5b216e01a117532b30f061f3dff8a61408113c77 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 10:55:49 -0300 Subject: [PATCH 13/24] Uplift transmute Answer/Condition into type-ir --- Cargo.lock | 1 - compiler/rustc_next_trait_solver/Cargo.toml | 1 - .../rustc_next_trait_solver/src/delegate.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 2 +- .../src/solve/trait_goals.rs | 8 +- .../traits/fulfillment_errors.rs | 40 +++--- .../src/solve/delegate.rs | 3 +- .../src/traits/select/confirmation.rs | 2 +- compiler/rustc_transmute/src/lib.rs | 75 +--------- .../src/maybe_transmutable/mod.rs | 65 +-------- compiler/rustc_type_ir/src/lib.rs | 1 + compiler/rustc_type_ir/src/transmute.rs | 132 ++++++++++++++++++ 13 files changed, 165 insertions(+), 169 deletions(-) create mode 100644 compiler/rustc_type_ir/src/transmute.rs diff --git a/Cargo.lock b/Cargo.lock index 6799105a5361a..e11fd2189569c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4582,7 +4582,6 @@ dependencies = [ "rustc_data_structures", "rustc_index", "rustc_macros", - "rustc_transmute", "rustc_type_ir", "rustc_type_ir_macros", "thin-vec", diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 046294f9a5257..f151b880bb114 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -9,7 +9,6 @@ derive-where = "1.2.7" rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } thin-vec = "0.2.21" diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 241002257f3fe..630e1dd68e041 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,11 +1,11 @@ use std::fmt::Debug; use std::ops::Deref; -use rustc_transmute::Answer; use rustc_type_ir::solve::{ ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck, }; +use rustc_type_ir::transmute::Answer; use rustc_type_ir::{ self as ty, CanonicalizerState, Const, InferCtxtLike, Interner, Region, TypeFoldable, }; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 31bf7cc0519ee..3b372876f574b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -3,7 +3,6 @@ use std::ops::ControlFlow; #[cfg(feature = "nightly")] use rustc_macros::StableHash; -use rustc_transmute::Answer; use rustc_type_ir::data_structures::HashSet; use rustc_type_ir::inherent::*; use rustc_type_ir::region_constraint::RegionConstraint; @@ -17,6 +16,7 @@ use rustc_type_ir::solve::{ NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunCondition, RerunNonErased, RerunReason, RerunResultExt, SmallCopySet, TyOrConstInferVar, }; +use rustc_type_ir::transmute::Answer; use rustc_type_ir::{ self as ty, ClauseKind, Const, InferCtxtLike, Interner, MayBeErased, OpaqueTypeKey, PredicateKind, PredicateProxy, Region, RegionVid, TypeFoldable, TypeSuperVisitable, diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index bd9e0604c364c..c9da77eced6d3 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -21,10 +21,10 @@ mod search_graph; mod trait_goals; use derive_where::derive_where; -use rustc_transmute::Condition; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::SolverTraitLangItem; pub use rustc_type_ir::solve::*; +use rustc_type_ir::transmute::Condition; use rustc_type_ir::{self as ty, Const, Interner, Region, TraitClause, TypeVisitableExt, Upcast}; use thin_vec::{ThinVec, thin_vec}; 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 e1f8b55455df9..ffa06f38a66c5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -656,6 +656,8 @@ where ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolutionOrRerunNonErased> { + use rustc_type_ir::transmute::Answer; + if goal.predicate.polarity != ty::ClausePolarity::Positive { return Err(NoSolution.into()); } @@ -685,9 +687,9 @@ where )?; let certainty = match answer { - rustc_transmute::Answer::No(_) => return Err(NoSolution.into()), - rustc_transmute::Answer::Yes => Certainty::Yes, - rustc_transmute::Answer::If(cond) => { + Answer::No(_) => return Err(NoSolution.into()), + Answer::Yes => Certainty::Yes, + Answer::If(cond) => { let tcx = ecx.cx(); ecx.add_goals( GoalSource::Misc, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 47d1f1b22c090..4a1b674155795 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -31,6 +31,7 @@ use rustc_middle::ty::print::{ PrintPolyTraitClauseExt, PrintPolyTraitRefExt as _, PrintTraitClauseExt as _, PrintTraitRefExt as _, with_forced_trimmed_paths, }; +use rustc_middle::ty::transmute::{Answer, Reason}; use rustc_middle::ty::{ self, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast, @@ -3253,7 +3254,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_ref.args.type_at(0), assume, ), - rustc_transmute::Answer::Yes, + Answer::Yes, ); // If the normalized check unexpectedly passes, fall back to root obligation for reporting. @@ -3274,7 +3275,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitClause<'tcx>, span: Span, ) -> GetSafeTransmuteErrorAndReason { - use rustc_transmute::Answer; self.probe(|_| { // We don't assemble a transmutability candidate for types that are generic // and we should have ambiguity for types that still have non-region infer. @@ -3311,69 +3311,61 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { Answer::No(reason) => { let safe_transmute_explanation = match reason { - rustc_transmute::Reason::SrcIsNotYetSupported => { + Reason::SrcIsNotYetSupported => { format!("analyzing the transmutability of `{src}` is not yet supported") } - rustc_transmute::Reason::DstIsNotYetSupported => { + Reason::DstIsNotYetSupported => { format!("analyzing the transmutability of `{dst}` is not yet supported") } - rustc_transmute::Reason::DstIsBitIncompatible => { + Reason::DstIsBitIncompatible => { format!( "at least one value of `{src}` isn't a bit-valid value of `{dst}`" ) } - rustc_transmute::Reason::DstUninhabited => { + Reason::DstUninhabited => { format!("`{dst}` is uninhabited") } - rustc_transmute::Reason::DstMayHaveSafetyInvariants => { + Reason::DstMayHaveSafetyInvariants => { format!("`{dst}` may carry safety invariants") } - rustc_transmute::Reason::DstIsTooBig => { + Reason::DstIsTooBig => { format!("the size of `{src}` is smaller than the size of `{dst}`") } - rustc_transmute::Reason::DstRefIsTooBig { - src, - src_size, - dst, - dst_size, - } => { + Reason::DstRefIsTooBig { src, src_size, dst, dst_size } => { format!( "the size of `{src}` ({src_size} bytes) \ is smaller than that of `{dst}` ({dst_size} bytes)" ) } - rustc_transmute::Reason::SrcSizeOverflow => { + Reason::SrcSizeOverflow => { format!( "values of the type `{src}` are too big for the target architecture" ) } - rustc_transmute::Reason::DstSizeOverflow => { + Reason::DstSizeOverflow => { format!( "values of the type `{dst}` are too big for the target architecture" ) } - rustc_transmute::Reason::DstHasStricterAlignment { - src_min_align, - dst_min_align, - } => { + Reason::DstHasStricterAlignment { src_min_align, dst_min_align } => { format!( "the minimum alignment of `{src}` ({src_min_align}) should be \ greater than that of `{dst}` ({dst_min_align})" ) } - rustc_transmute::Reason::DstIsMoreUnique => { + Reason::DstIsMoreUnique => { format!( "`{src}` is a shared reference, but `{dst}` is a unique reference" ) } // Already reported by rustc - rustc_transmute::Reason::TypeError => { + Reason::TypeError => { return GetSafeTransmuteErrorAndReason::Silent; } - rustc_transmute::Reason::SrcLayoutUnknown => { + Reason::SrcLayoutUnknown => { format!("`{src}` has an unknown layout") } - rustc_transmute::Reason::DstLayoutUnknown => { + Reason::DstLayoutUnknown => { format!("`{dst}` has an unknown layout") } }; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index ad20826eed862..2335868a17b40 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -21,6 +21,7 @@ use rustc_lint_defs::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::MaybeInfo; use rustc_middle::ty::print::{FmtPrinter, Print}; +use rustc_middle::ty::transmute::Answer; use rustc_middle::ty::{ self, CanonicalizerState, MayBeErased, Region, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, @@ -28,7 +29,7 @@ use rustc_middle::ty::{ use rustc_next_trait_solver::solve::{GoalStalledOn, GoalStalledOnOpaques, TyOrConstInferVar}; use rustc_span::{DUMMY_SP, Span}; use rustc_structures::Limit; -use rustc_transmute::{Answer, TransmuteTypeEnv}; +use rustc_transmute::TransmuteTypeEnv; use thin_vec::{ThinVec, thin_vec}; use super::inspect::InferCtxtProofTreeExt; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 1f72a7c02c942..6d5cddde61076 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -284,7 +284,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result, SelectionError<'tcx>> { - use rustc_transmute::Answer; + use rustc_middle::ty::transmute::Answer; let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index a7b07529f0bd1..dfc0039aa53ff 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -28,82 +28,11 @@ pub struct Assume { pub validity: bool, } -/// The result of a transmutability query under the supplied [`Assume`] options. -#[derive(Debug, Hash, Eq, PartialEq, Clone)] -pub enum Answer { - /// The analysis requires no further conditions. - Yes, - /// The analysis could not establish transmutability. - No(Reason), - /// Transmutability depends on conditions that the trait solver must discharge. - If(Condition), -} - -/// A condition which must hold for safe transmutation to be possible. -#[derive(Debug, Hash, Eq, PartialEq, Clone)] -pub enum Condition { - /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`. - Transmutable { src: T, dst: T }, - - /// The region `long` must outlive `short`. - Outlives { long: R, short: R }, - - /// The type `ty` must satisfy `Freeze`. - Immutable { ty: T }, - - /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met. - IfAll(Vec>), - - /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met. - IfAny(Vec>), -} - -/// Answers "why wasn't the source type transmutable into the destination type?" -#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)] -pub enum Reason { - /// The layout of the source type is not yet supported. - SrcIsNotYetSupported, - /// The layout of the destination type is not yet supported. - DstIsNotYetSupported, - /// The layout of the destination type is bit-incompatible with the source type. - DstIsBitIncompatible, - /// The destination type is uninhabited. - DstUninhabited, - /// The destination type may carry safety invariants. - DstMayHaveSafetyInvariants, - /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized. - DstIsTooBig, - /// The destination referent is larger than the source referent. - DstRefIsTooBig { - /// The referent of the source type. - src: T, - /// The size of the source type's referent. - src_size: usize, - /// The too-large referent of the destination type. - dst: T, - /// The size of the destination type's referent. - dst_size: usize, - }, - /// The destination referent requires stricter alignment than the source referent. - DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize }, - /// Can't go from shared pointer to unique pointer - DstIsMoreUnique, - /// Encountered a type error - TypeError, - /// The layout of src is unknown - SrcLayoutUnknown, - /// The layout of dst is unknown - DstLayoutUnknown, - /// The size of src is overflow - SrcSizeOverflow, - /// The size of dst is overflow - DstSizeOverflow, -} - #[cfg(feature = "rustc")] mod rustc { use rustc_attr_ir::lang_items::LangItem; use rustc_middle::ty::consts::ConstExt; + use rustc_middle::ty::transmute::Answer; use rustc_middle::ty::{Const, Region, Ty, TyCtxt}; use super::*; @@ -122,7 +51,7 @@ mod rustc { src: Ty<'tcx>, dst: Ty<'tcx>, assume: crate::Assume, - ) -> crate::Answer, Ty<'tcx>> { + ) -> Answer, Ty<'tcx>> { crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, self.tcx) .answer() } diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index e9351d4081b6e..be4b1a882d966 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -4,9 +4,11 @@ pub(crate) mod query_context; #[cfg(test)] mod tests; +use rustc_middle::ty::transmute::{Answer, Condition, Reason}; + +use crate::Map; use crate::layout::{self, Def, Dfa, Reference, Tree, dfa, union}; use crate::maybe_transmutable::query_context::QueryContext; -use crate::{Answer, Condition, Map, Reason}; pub(crate) struct MaybeTransmutableQuery where @@ -299,67 +301,6 @@ where } } -impl Answer { - /// Requires both answers, combining their conditions into a conjunction. - fn and(self, rhs: Answer) -> Answer { - let lhs = self; - match (lhs, rhs) { - // Prefer a specific reason over generic bit incompatibility; - // otherwise, retain the left-hand reason. - (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) - | (Answer::No(reason), Answer::No(_)) - // If either is an error, return it - | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason), - // If only one side has a condition, pass it along - (Answer::Yes, other) | (other, Answer::Yes) => other, - // If both sides have IfAll conditions, merge them - (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => { - lhs.append(rhs); - Answer::If(Condition::IfAll(lhs)) - } - // If only one side is an IfAll, add the other Condition to it - (Answer::If(cond), Answer::If(Condition::IfAll(mut conds))) - | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => { - conds.push(cond); - Answer::If(Condition::IfAll(conds)) - } - // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll - (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(vec![lhs, rhs])), - } - } - - /// Combines alternative answers and collects their conditions in an `IfAny`. - /// - /// Currently, combining `Yes` with `If` retains the condition. This differs - /// from Boolean disjunction, where unconditional success would suffice. - fn or(self, rhs: Answer) -> Answer { - let lhs = self; - match (lhs, rhs) { - // Prefer a specific reason over generic bit incompatibility; - // otherwise, retain the left-hand reason. - (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) - | (Answer::No(reason), Answer::No(_)) => Answer::No(reason), - // Otherwise, errors can be ignored for the rest of the pattern matching - (Answer::No(_), other) | (other, Answer::No(_)) => other.or(Answer::Yes), - // If only one side has a condition, pass it along - (Answer::Yes, other) | (other, Answer::Yes) => other, - // If both sides have IfAny conditions, merge them - (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => { - lhs.append(rhs); - Answer::If(Condition::IfAny(lhs)) - } - // If only one side is an IfAny, add the other Condition to it - (Answer::If(cond), Answer::If(Condition::IfAny(mut conds))) - | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => { - conds.push(cond); - Answer::If(Condition::IfAny(conds)) - } - // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny - (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(vec![lhs, rhs])), - } - } -} - enum Quantifier { ThereExists, ForAll, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 0be6a2c4152dc..eab69fa224d92 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -61,6 +61,7 @@ pub mod relate; pub mod search_graph; pub mod solve; pub mod sty; +pub mod transmute; pub mod walk; // These modules are not `pub` since they are glob-imported. diff --git a/compiler/rustc_type_ir/src/transmute.rs b/compiler/rustc_type_ir/src/transmute.rs new file mode 100644 index 0000000000000..6da68e8c4ed89 --- /dev/null +++ b/compiler/rustc_type_ir/src/transmute.rs @@ -0,0 +1,132 @@ +/// The result of a transmutability query under the supplied [`Assume`] options. +#[derive(Debug, Hash, Eq, PartialEq, Clone)] +pub enum Answer { + /// The analysis requires no further conditions. + Yes, + /// The analysis could not establish transmutability. + No(Reason), + /// Transmutability depends on conditions that the trait solver must discharge. + If(Condition), +} + +/// A condition which must hold for safe transmutation to be possible. +#[derive(Debug, Hash, Eq, PartialEq, Clone)] +pub enum Condition { + /// `Src` is transmutable into `Dst`, if `src` is transmutable into `dst`. + Transmutable { src: T, dst: T }, + + /// The region `long` must outlive `short`. + Outlives { long: R, short: R }, + + /// The type `ty` must satisfy `Freeze`. + Immutable { ty: T }, + + /// `Src` is transmutable into `Dst`, if all of the enclosed requirements are met. + IfAll(Vec>), + + /// `Src` is transmutable into `Dst` if any of the enclosed requirements are met. + IfAny(Vec>), +} + +/// Answers "why wasn't the source type transmutable into the destination type?" +#[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)] +pub enum Reason { + /// The layout of the source type is not yet supported. + SrcIsNotYetSupported, + /// The layout of the destination type is not yet supported. + DstIsNotYetSupported, + /// The layout of the destination type is bit-incompatible with the source type. + DstIsBitIncompatible, + /// The destination type is uninhabited. + DstUninhabited, + /// The destination type may carry safety invariants. + DstMayHaveSafetyInvariants, + /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized. + DstIsTooBig, + /// The destination referent is larger than the source referent. + DstRefIsTooBig { + /// The referent of the source type. + src: T, + /// The size of the source type's referent. + src_size: usize, + /// The too-large referent of the destination type. + dst: T, + /// The size of the destination type's referent. + dst_size: usize, + }, + /// The destination referent requires stricter alignment than the source referent. + DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize }, + /// Can't go from shared pointer to unique pointer + DstIsMoreUnique, + /// Encountered a type error + TypeError, + /// The layout of src is unknown + SrcLayoutUnknown, + /// The layout of dst is unknown + DstLayoutUnknown, + /// The size of src is overflow + SrcSizeOverflow, + /// The size of dst is overflow + DstSizeOverflow, +} + +impl Answer { + /// Requires both answers, combining their conditions into a conjunction. + pub fn and(self, rhs: Answer) -> Answer { + let lhs = self; + match (lhs, rhs) { + // Prefer a specific reason over generic bit incompatibility; + // otherwise, retain the left-hand reason. + (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) + | (Answer::No(reason), Answer::No(_)) + // If either is an error, return it + | (Answer::No(reason), _) | (_, Answer::No(reason)) => Answer::No(reason), + // If only one side has a condition, pass it along + (Answer::Yes, other) | (other, Answer::Yes) => other, + // If both sides have IfAll conditions, merge them + (Answer::If(Condition::IfAll(mut lhs)), Answer::If(Condition::IfAll(ref mut rhs))) => { + lhs.append(rhs); + Answer::If(Condition::IfAll(lhs)) + } + // If only one side is an IfAll, add the other Condition to it + (Answer::If(cond), Answer::If(Condition::IfAll(mut conds))) + | (Answer::If(Condition::IfAll(mut conds)), Answer::If(cond)) => { + conds.push(cond); + Answer::If(Condition::IfAll(conds)) + } + // Otherwise, both lhs and rhs conditions can be combined in a parent IfAll + (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAll(vec![lhs, rhs])), + } + } + + /// Combines alternative answers and collects their conditions in an `IfAny`. + /// + /// Currently, combining `Yes` with `If` retains the condition. This differs + /// from Boolean disjunction, where unconditional success would suffice. + pub fn or(self, rhs: Answer) -> Answer { + let lhs = self; + match (lhs, rhs) { + // Prefer a specific reason over generic bit incompatibility; + // otherwise, retain the left-hand reason. + (Answer::No(Reason::DstIsBitIncompatible), Answer::No(reason)) + | (Answer::No(reason), Answer::No(_)) => Answer::No(reason), + // Otherwise, errors can be ignored for the rest of the pattern matching + (Answer::No(_), other) | (other, Answer::No(_)) => other.or(Answer::Yes), + // If only one side has a condition, pass it along + (Answer::Yes, other) | (other, Answer::Yes) => other, + // If both sides have IfAny conditions, merge them + (Answer::If(Condition::IfAny(mut lhs)), Answer::If(Condition::IfAny(ref mut rhs))) => { + lhs.append(rhs); + Answer::If(Condition::IfAny(lhs)) + } + // If only one side is an IfAny, add the other Condition to it + (Answer::If(cond), Answer::If(Condition::IfAny(mut conds))) + | (Answer::If(Condition::IfAny(mut conds)), Answer::If(cond)) => { + conds.push(cond); + Answer::If(Condition::IfAny(conds)) + } + // Otherwise, both lhs and rhs conditions can be combined in a parent IfAny + (Answer::If(lhs), Answer::If(rhs)) => Answer::If(Condition::IfAny(vec![lhs, rhs])), + } + } +} From ae3df03a08c70330e6a7ab290397b5b05db110bf Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 11:28:50 -0300 Subject: [PATCH 14/24] Make transmute test suite next-solver --- .../ui/transmute/ambiguity-in-closure-arg.rs | 2 +- tests/ui/transmute/diverging-fn-transmute.rs | 2 +- tests/ui/transmute/lifetimes.rs | 2 +- tests/ui/transmute/main.rs | 2 +- tests/ui/transmute/recursive-size-skeleton.rs | 2 +- .../ui/transmute/transmute-array-to-scalar.rs | 2 +- .../transmute-associated-type-to-slice.rs | 2 +- tests/ui/transmute/transmute-bool-u8.rs | 1 + .../ui/transmute/transmute-different-sizes.rs | 2 +- tests/ui/transmute/transmute-fat-pointers.rs | 2 +- .../transmute-from-fn-item-types-error.rs | 1 + .../transmute-from-fn-item-types-error.stderr | 18 ++-- tests/ui/transmute/transmute-impl.rs | 2 +- tests/ui/transmute/transmute-imut-to-mut.rs | 2 +- tests/ui/transmute/transmute-in-async-fn.rs | 3 +- .../ui/transmute/transmute-in-async-fn.stderr | 4 +- .../transmute-same-associated-type.rs | 2 +- tests/ui/transmute/transmute-slice-to-dst.rs | 1 + .../ui/transmute/transmute-type-parameters.rs | 2 +- tests/ui/transmute/transmute-zst-generics.rs | 2 +- .../transmute/unnecessary-transmutation.fixed | 1 + .../ui/transmute/unnecessary-transmutation.rs | 1 + .../unnecessary-transmutation.stderr | 82 +++++++++---------- ...cessary-transmute-path-remap-ice-140277.rs | 1 + 24 files changed, 74 insertions(+), 67 deletions(-) diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.rs b/tests/ui/transmute/ambiguity-in-closure-arg.rs index 4c2d1ce2ad463..b8d351e94bbde 100644 --- a/tests/ui/transmute/ambiguity-in-closure-arg.rs +++ b/tests/ui/transmute/ambiguity-in-closure-arg.rs @@ -1,5 +1,5 @@ // Minimized test for . - +//@ compile-flags: -Znext-solver=globally struct Unconstrained(T); fn main() { diff --git a/tests/ui/transmute/diverging-fn-transmute.rs b/tests/ui/transmute/diverging-fn-transmute.rs index aca82037a0c2c..6410c333ac77e 100644 --- a/tests/ui/transmute/diverging-fn-transmute.rs +++ b/tests/ui/transmute/diverging-fn-transmute.rs @@ -1,5 +1,5 @@ //! Regression test for issue #35849: transmute with panic in diverging function - +//@ compile-flags: -Znext-solver=globally fn assert_sizeof() -> ! { unsafe { ::std::mem::transmute::(panic!()) diff --git a/tests/ui/transmute/lifetimes.rs b/tests/ui/transmute/lifetimes.rs index 0114e6205bb38..0cd7856b28862 100644 --- a/tests/ui/transmute/lifetimes.rs +++ b/tests/ui/transmute/lifetimes.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver=globally use std::ptr::NonNull; struct Foo<'a, T: ?Sized>(&'a (), NonNull); diff --git a/tests/ui/transmute/main.rs b/tests/ui/transmute/main.rs index e4a5f9103cd79..8dd2b839dfc23 100644 --- a/tests/ui/transmute/main.rs +++ b/tests/ui/transmute/main.rs @@ -1,6 +1,6 @@ //@ normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)" //@ normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)" - +//@ compile-flags: -Znext-solver=globally use std::mem::transmute; pub trait TypeConstructor<'a> { diff --git a/tests/ui/transmute/recursive-size-skeleton.rs b/tests/ui/transmute/recursive-size-skeleton.rs index b2395a8f5aa4b..c3a68cb226806 100644 --- a/tests/ui/transmute/recursive-size-skeleton.rs +++ b/tests/ui/transmute/recursive-size-skeleton.rs @@ -3,7 +3,7 @@ // through a normalizing type alias used to recurse without bound and // blow the stack. We now bail out via the recursion limit and emit a // regular error instead of ICE-ing. - +//@ compile-flags: -Znext-solver=globally use std::mem::transmute; trait Trait { diff --git a/tests/ui/transmute/transmute-array-to-scalar.rs b/tests/ui/transmute/transmute-array-to-scalar.rs index cd6dbb040c8bb..70b7046b5bf7b 100644 --- a/tests/ui/transmute/transmute-array-to-scalar.rs +++ b/tests/ui/transmute/transmute-array-to-scalar.rs @@ -1,7 +1,7 @@ //! Verify transmuting from a single-element array to a scalar is allowed. //! //! Regression test: - +//@ compile-flags: -Znext-solver=globally //@ run-pass pub fn main() { diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.rs b/tests/ui/transmute/transmute-associated-type-to-slice.rs index 9521a944391cc..b23436a0eb57e 100644 --- a/tests/ui/transmute/transmute-associated-type-to-slice.rs +++ b/tests/ui/transmute/transmute-associated-type-to-slice.rs @@ -1,6 +1,6 @@ //! regression test for //@ normalize-stderr: "\d+ bits" -> "N bits" - +//@ compile-flags: -Znext-solver=globally trait MyTrait { type MyType; } diff --git a/tests/ui/transmute/transmute-bool-u8.rs b/tests/ui/transmute/transmute-bool-u8.rs index 502683b6d1366..ccbcce66bdcb2 100644 --- a/tests/ui/transmute/transmute-bool-u8.rs +++ b/tests/ui/transmute/transmute-bool-u8.rs @@ -1,4 +1,5 @@ //! regression test for +//@ compile-flags: -Znext-solver=globally //@ build-pass #![allow(unnecessary_transmutes)] use std::mem::transmute; diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs index 4f1f758677145..c327004f36518 100644 --- a/tests/ui/transmute/transmute-different-sizes.rs +++ b/tests/ui/transmute/transmute-different-sizes.rs @@ -1,5 +1,5 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" - +//@ compile-flags: -Znext-solver=globally // Tests that `transmute` cannot be called on types of different size. #![allow(warnings)] diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs index c03d0d34feb1b..48d2375443ef7 100644 --- a/tests/ui/transmute/transmute-fat-pointers.rs +++ b/tests/ui/transmute/transmute-fat-pointers.rs @@ -1,5 +1,5 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" - +//@ compile-flags: -Znext-solver=globally // Tests that are conservative around thin/fat pointer mismatches. #![allow(dead_code)] diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.rs b/tests/ui/transmute/transmute-from-fn-item-types-error.rs index f858a199e48e3..7be9dafcfccab 100644 --- a/tests/ui/transmute/transmute-from-fn-item-types-error.rs +++ b/tests/ui/transmute/transmute-from-fn-item-types-error.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver=globally use std::mem; unsafe fn foo() -> (i8, *const (), Option) { diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.stderr b/tests/ui/transmute/transmute-from-fn-item-types-error.stderr index aefe3fb8e25fd..35b07efd0f6df 100644 --- a/tests/ui/transmute/transmute-from-fn-item-types-error.stderr +++ b/tests/ui/transmute/transmute-from-fn-item-types-error.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-from-fn-item-types-error.rs:4:13 + --> $DIR/transmute-from-fn-item-types-error.rs:5:13 | LL | let i = mem::transmute(bar); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let i = mem::transmute(bar); = note: target type: `i8` (8 bits) error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:8:13 + --> $DIR/transmute-from-fn-item-types-error.rs:9:13 | LL | let p = mem::transmute(foo); | ^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let p = mem::transmute(foo); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:12:14 + --> $DIR/transmute-from-fn-item-types-error.rs:13:14 | LL | let of = mem::transmute(main); | ^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let of = mem::transmute(main); = help: cast with `as` to a pointer instead error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-from-fn-item-types-error.rs:21:5 + --> $DIR/transmute-from-fn-item-types-error.rs:22:5 | LL | mem::transmute::<_, u8>(main); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | mem::transmute::<_, u8>(main); = note: target type: `u8` (8 bits) error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:25:5 + --> $DIR/transmute-from-fn-item-types-error.rs:26:5 | LL | mem::transmute::<_, *mut ()>(foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | mem::transmute::<_, *mut ()>(foo); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:29:5 + --> $DIR/transmute-from-fn-item-types-error.rs:30:5 | LL | mem::transmute::<_, fn()>(bar); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | mem::transmute::<_, fn()>(bar); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:38:5 + --> $DIR/transmute-from-fn-item-types-error.rs:39:5 | LL | mem::transmute::<_, *mut ()>(Some(foo)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | mem::transmute::<_, *mut ()>(Some(foo)); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:42:5 + --> $DIR/transmute-from-fn-item-types-error.rs:43:5 | LL | mem::transmute::<_, fn()>(Some(bar)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | mem::transmute::<_, fn()>(Some(bar)); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:46:5 + --> $DIR/transmute-from-fn-item-types-error.rs:47:5 | LL | mem::transmute::<_, Option>(Some(baz)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs index 84951a0ee6035..1c85249645c39 100644 --- a/tests/ui/transmute/transmute-impl.rs +++ b/tests/ui/transmute/transmute-impl.rs @@ -1,5 +1,5 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" - +//@ compile-flags: -Znext-solver=globally // Tests that are conservative around thin/fat pointer mismatches. #![allow(dead_code)] diff --git a/tests/ui/transmute/transmute-imut-to-mut.rs b/tests/ui/transmute/transmute-imut-to-mut.rs index 9f3f76c1ef3e0..d5299fa40f202 100644 --- a/tests/ui/transmute/transmute-imut-to-mut.rs +++ b/tests/ui/transmute/transmute-imut-to-mut.rs @@ -1,5 +1,5 @@ // Tests that transmuting from &T to &mut T is Undefined Behavior. - +//@ compile-flags: -Znext-solver=globally use std::mem::transmute; fn main() { diff --git a/tests/ui/transmute/transmute-in-async-fn.rs b/tests/ui/transmute/transmute-in-async-fn.rs index 83574ee5b8bde..025e29017a93e 100644 --- a/tests/ui/transmute/transmute-in-async-fn.rs +++ b/tests/ui/transmute/transmute-in-async-fn.rs @@ -1,4 +1,5 @@ -//@compile-flags: -Zmir-enable-passes=+DataflowConstProp --crate-type lib +//@ compile-flags: -Zmir-enable-passes=+DataflowConstProp --crate-type lib +//@ compile-flags: -Znext-solver=globally //@ edition:2021 pub async fn a() -> u32 { unsafe { std::mem::transmute(1u64) } diff --git a/tests/ui/transmute/transmute-in-async-fn.stderr b/tests/ui/transmute/transmute-in-async-fn.stderr index 2f5e471302b51..f24f236d8d225 100644 --- a/tests/ui/transmute/transmute-in-async-fn.stderr +++ b/tests/ui/transmute/transmute-in-async-fn.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-in-async-fn.rs:4:14 + --> $DIR/transmute-in-async-fn.rs:5:14 | LL | unsafe { std::mem::transmute(1u64) } | ^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | unsafe { std::mem::transmute(1u64) } = note: target type: `u32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-in-async-fn.rs:9:31 + --> $DIR/transmute-in-async-fn.rs:10:31 | LL | let closure = || unsafe { std::mem::transmute(1u64) }; | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-same-associated-type.rs b/tests/ui/transmute/transmute-same-associated-type.rs index 8bc452c6df4f6..061b8edc0d07e 100644 --- a/tests/ui/transmute/transmute-same-associated-type.rs +++ b/tests/ui/transmute/transmute-same-associated-type.rs @@ -1,5 +1,5 @@ //! Verify transmuting is allowed when `Src` and `Dst` are the same associated type. - +//@ compile-flags: -Znext-solver=globally //@ check-pass trait Foo { diff --git a/tests/ui/transmute/transmute-slice-to-dst.rs b/tests/ui/transmute/transmute-slice-to-dst.rs index c1f77bee284dd..8cc0471c4d780 100644 --- a/tests/ui/transmute/transmute-slice-to-dst.rs +++ b/tests/ui/transmute/transmute-slice-to-dst.rs @@ -1,5 +1,6 @@ //! regression test for //@ build-pass +//@ compile-flags: -Znext-solver=globally //@ compile-flags: -g pub struct Dst { diff --git a/tests/ui/transmute/transmute-type-parameters.rs b/tests/ui/transmute/transmute-type-parameters.rs index 5f44b2d0f0163..afbe3f594719d 100644 --- a/tests/ui/transmute/transmute-type-parameters.rs +++ b/tests/ui/transmute/transmute-type-parameters.rs @@ -1,5 +1,5 @@ // Tests that `transmute` cannot be called on type parameters. - +//@ compile-flags: -Znext-solver=globally use std::mem::transmute; unsafe fn f(x: T) { diff --git a/tests/ui/transmute/transmute-zst-generics.rs b/tests/ui/transmute/transmute-zst-generics.rs index b80ec794f83f9..bc58591be6a48 100644 --- a/tests/ui/transmute/transmute-zst-generics.rs +++ b/tests/ui/transmute/transmute-zst-generics.rs @@ -1,5 +1,5 @@ //@ run-pass - +//@ compile-flags: -Znext-solver=globally // Transmuting to/from ZSTs that contain generics. #![feature(transmute_generic_consts)] diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed index 08010ec8b84e4..4b520905f0f5d 100644 --- a/tests/ui/transmute/unnecessary-transmutation.fixed +++ b/tests/ui/transmute/unnecessary-transmutation.fixed @@ -1,4 +1,5 @@ //@ run-rustfix +//@ compile-flags: -Znext-solver=globally #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] use std::mem::transmute; diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs index 43eefb97dc28f..607c1117361a6 100644 --- a/tests/ui/transmute/unnecessary-transmutation.rs +++ b/tests/ui/transmute/unnecessary-transmutation.rs @@ -1,4 +1,5 @@ //@ run-rustfix +//@ compile-flags: -Znext-solver=globally #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] use std::mem::transmute; diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr index 8399f760ceb37..5f94e3aaaf657 100644 --- a/tests/ui/transmute/unnecessary-transmutation.stderr +++ b/tests/ui/transmute/unnecessary-transmutation.stderr @@ -1,12 +1,12 @@ error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:7:14 + --> $DIR/unnecessary-transmutation.rs:8:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ | = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order note: the lint level is defined here - --> $DIR/unnecessary-transmutation.rs:2:9 + --> $DIR/unnecessary-transmutation.rs:3:9 | LL | #![deny(unnecessary_transmutes)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + unsafe { u32::to_ne_bytes(x) } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:12:14 + --> $DIR/unnecessary-transmutation.rs:13:14 | LL | unsafe { transmute(from) } | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL + unsafe { (from) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:16:29 + --> $DIR/unnecessary-transmutation.rs:17:29 | LL | pub static X: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL + pub static X: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:18:28 + --> $DIR/unnecessary-transmutation.rs:19:28 | LL | pub const Y: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + pub const Y: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:24:18 + --> $DIR/unnecessary-transmutation.rs:25:18 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL + unsafe { (x) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:30:22 + --> $DIR/unnecessary-transmutation.rs:31:22 | LL | const { unsafe { transmute::<_, u8>(true) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL + const { unsafe { (true) as u8 } }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:33:22 + --> $DIR/unnecessary-transmutation.rs:34:22 | LL | let x: u16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL + let x: u16 = u16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:35:26 + --> $DIR/unnecessary-transmutation.rs:36:26 | LL | let x: [u8; 2] = transmute(x); | ^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL + let x: [u8; 2] = u16::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:37:22 + --> $DIR/unnecessary-transmutation.rs:38:22 | LL | let x: u32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL + let x: u32 = u32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:39:26 + --> $DIR/unnecessary-transmutation.rs:40:26 | LL | let x: [u8; 4] = transmute(x); | ^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL + let x: [u8; 4] = u32::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:41:22 + --> $DIR/unnecessary-transmutation.rs:42:22 | LL | let x: u64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL + let x: u64 = u64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:43:26 + --> $DIR/unnecessary-transmutation.rs:44:26 | LL | let x: [u8; 8] = transmute(x); | ^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let x: [u8; 8] = u64::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:46:22 + --> $DIR/unnecessary-transmutation.rs:47:22 | LL | let y: i16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + let y: i16 = i16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:48:26 + --> $DIR/unnecessary-transmutation.rs:49:26 | LL | let y: [u8; 2] = transmute(y); | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + let y: [u8; 2] = i16::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:50:22 + --> $DIR/unnecessary-transmutation.rs:51:22 | LL | let y: i32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL + let y: i32 = i32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:52:26 + --> $DIR/unnecessary-transmutation.rs:53:26 | LL | let y: [u8; 4] = transmute(y); | ^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let y: [u8; 4] = i32::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:54:22 + --> $DIR/unnecessary-transmutation.rs:55:22 | LL | let y: i64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL + let y: i64 = i64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:56:26 + --> $DIR/unnecessary-transmutation.rs:57:26 | LL | let y: [u8; 8] = transmute(y); | ^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL + let y: [u8; 8] = i64::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:59:22 + --> $DIR/unnecessary-transmutation.rs:60:22 | LL | let z: f32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -246,7 +246,7 @@ LL + let z: f32 = f32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:61:26 + --> $DIR/unnecessary-transmutation.rs:62:26 | LL | let z: [u8; 4] = transmute(z); | ^^^^^^^^^^^^ @@ -259,7 +259,7 @@ LL + let z: [u8; 4] = f32::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:63:22 + --> $DIR/unnecessary-transmutation.rs:64:22 | LL | let z: f64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + let z: f64 = f64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:65:26 + --> $DIR/unnecessary-transmutation.rs:66:26 | LL | let z: [u8; 8] = transmute(z); | ^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL + let z: [u8; 8] = f64::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:68:22 + --> $DIR/unnecessary-transmutation.rs:69:22 | LL | let y: u32 = transmute('🦀'); | ^^^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + let y: u32 = u32::from('🦀'); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:70:23 + --> $DIR/unnecessary-transmutation.rs:71:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL + let y: char = char::from_u32_unchecked(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:72:22 + --> $DIR/unnecessary-transmutation.rs:73:22 | LL | let y: i32 = transmute('🐱'); | ^^^^^^^^^^^^^^^ @@ -322,7 +322,7 @@ LL + let y: i32 = u32::from('🐱').cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:74:23 + --> $DIR/unnecessary-transmutation.rs:75:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:77:22 + --> $DIR/unnecessary-transmutation.rs:78:22 | LL | let x: u16 = transmute(8i16); | ^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL + let x: u16 = i16::cast_unsigned(8i16); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:79:22 + --> $DIR/unnecessary-transmutation.rs:80:22 | LL | let x: i16 = transmute(x); | ^^^^^^^^^^^^ @@ -359,7 +359,7 @@ LL + let x: i16 = u16::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:81:22 + --> $DIR/unnecessary-transmutation.rs:82:22 | LL | let x: u32 = transmute(4i32); | ^^^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL + let x: u32 = i32::cast_unsigned(4i32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:83:22 + --> $DIR/unnecessary-transmutation.rs:84:22 | LL | let x: i32 = transmute(x); | ^^^^^^^^^^^^ @@ -383,7 +383,7 @@ LL + let x: i32 = u32::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:85:22 + --> $DIR/unnecessary-transmutation.rs:86:22 | LL | let x: u64 = transmute(7i64); | ^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ LL + let x: u64 = i64::cast_unsigned(7i64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:87:22 + --> $DIR/unnecessary-transmutation.rs:88:22 | LL | let x: i64 = transmute(x); | ^^^^^^^^^^^^ @@ -407,7 +407,7 @@ LL + let x: i64 = u64::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:90:22 + --> $DIR/unnecessary-transmutation.rs:91:22 | LL | let y: f32 = transmute(1u32); | ^^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL + let y: f32 = f32::from_bits(1u32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:92:22 + --> $DIR/unnecessary-transmutation.rs:93:22 | LL | let y: u32 = transmute(y); | ^^^^^^^^^^^^ @@ -431,7 +431,7 @@ LL + let y: u32 = f32::to_bits(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:94:22 + --> $DIR/unnecessary-transmutation.rs:95:22 | LL | let y: f64 = transmute(3u64); | ^^^^^^^^^^^^^^^ @@ -443,7 +443,7 @@ LL + let y: f64 = f64::from_bits(3u64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:96:22 + --> $DIR/unnecessary-transmutation.rs:97:22 | LL | let y: u64 = transmute(2.0); | ^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL + let y: u64 = f64::to_bits(2.0); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:99:22 + --> $DIR/unnecessary-transmutation.rs:100:22 | LL | let y: f64 = transmute(1i64); | ^^^^^^^^^^^^^^^ @@ -467,7 +467,7 @@ LL + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:101:22 + --> $DIR/unnecessary-transmutation.rs:102:22 | LL | let y: i64 = transmute(1f64); | ^^^^^^^^^^^^^^^ @@ -479,7 +479,7 @@ LL + let y: i64 = f64::to_bits(1f64).cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:106:21 + --> $DIR/unnecessary-transmutation.rs:107:21 | LL | let z: u8 = transmute(z); | ^^^^^^^^^^^^ @@ -491,7 +491,7 @@ LL + let z: u8 = u8::from(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:111:21 + --> $DIR/unnecessary-transmutation.rs:112:21 | LL | let z: i8 = transmute(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs b/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs index 756ce7b3d5074..b9a095fe64b22 100644 --- a/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs +++ b/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs @@ -1,4 +1,5 @@ //@ aux-crate: zerocopy=unnecessary-transmute-path-remap-ice-140277-trans.rs +//@ compile-flags: -Znext-solver=globally //@ check-pass // tests for a regression in linting for unnecessary transmutes // where a span was inacessible for snippet procuring, From 0f13998ff8a3b559ddcbfed3832de5ff700b1c4f Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 12:33:54 -0300 Subject: [PATCH 15/24] Fix test imports for moved transmute --- compiler/rustc_transmute/src/lib.rs | 4 ++-- .../src/maybe_transmutable/tests.rs | 24 ++++++++++++------- compiler/rustc_type_ir/src/transmute.rs | 2 +- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index dfc0039aa53ff..87f00c628435e 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -3,8 +3,8 @@ //! The analysis converts compiler layouts into trees of bytes, references, and //! definition markers. It prunes destination paths that may carry safety invariants unless //! safety is assumed, then converts the trees into deterministic finite automata. -//! Comparing the automata produces an [`Answer`]; reference transitions can leave -//! [`Condition`]s for the trait solver to discharge. +//! Comparing the automata produces an `Answer`; reference transitions can leave +//! `Condition`s for the trait solver to discharge. // tidy-alphabetical-start #![cfg_attr(test, feature(test))] diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index 371a362c09ff3..ec561a4109ca9 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -1,9 +1,10 @@ extern crate test; use itertools::Itertools; +use rustc_middle::ty::transmute::{Answer, Condition, Reason}; use super::query_context::test::{Def, UltraMinimal}; -use crate::{Answer, Assume, Condition, Reason, layout}; +use crate::{Assume, layout}; type Tree = layout::Tree; type Dfa = layout::Dfa; @@ -40,17 +41,18 @@ fn is_transmutable( src: &R, dst: &R, assume: Assume, -) -> crate::Answer { +) -> rustc_middle::ty::transmute::Answer { let src = src.clone(); let dst = dst.clone(); R::is_transmutable(src, dst, assume) } mod answers { + use rustc_middle::ty::transmute::{Condition, Reason}; + use crate::maybe_transmutable::Quantifier; - use crate::{Condition, Reason}; - type Answer = crate::Answer; + type Answer = rustc_middle::ty::transmute::Answer; const OUTLIVES: Condition = Condition::Outlives { long: 1, short: 0 }; const IMMUTABLE: Condition = Condition::Immutable { ty: () }; @@ -141,11 +143,11 @@ mod answers { } mod safety { + use rustc_middle::ty::transmute::{Answer, Reason}; + use super::*; - use crate::Answer; - const DST_HAS_SAFETY_INVARIANTS: Answer = - Answer::No(crate::Reason::DstMayHaveSafetyInvariants); + const DST_HAS_SAFETY_INVARIANTS: Answer = Answer::No(Reason::DstMayHaveSafetyInvariants); #[test] fn src_safe_dst_safe() { @@ -353,8 +355,9 @@ mod uninit { } mod alt { + use rustc_middle::ty::transmute::Answer; + use super::*; - use crate::Answer; #[test] fn should_permit_identity_transmutation() { @@ -405,6 +408,8 @@ mod union { } mod char { + use rustc_middle::ty::transmute::Answer; + use super::*; use crate::layout::tree::Endian; @@ -444,8 +449,9 @@ mod char { } mod nonzero { + use rustc_middle::ty::transmute::{Answer, Reason}; + use super::*; - use crate::{Answer, Reason}; const NONZERO_BYTE_WIDTHS: [u64; 5] = [1, 2, 4, 8, 16]; diff --git a/compiler/rustc_type_ir/src/transmute.rs b/compiler/rustc_type_ir/src/transmute.rs index 6da68e8c4ed89..f74bd3b954d1a 100644 --- a/compiler/rustc_type_ir/src/transmute.rs +++ b/compiler/rustc_type_ir/src/transmute.rs @@ -1,4 +1,4 @@ -/// The result of a transmutability query under the supplied [`Assume`] options. +/// The result of a transmutability query under the supplied `Assume` options. #[derive(Debug, Hash, Eq, PartialEq, Clone)] pub enum Answer { /// The analysis requires no further conditions. From 2c21fc5382ae217a33148767c402679eb4b3c786 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Fri, 9 Oct 2026 18:51:30 -0300 Subject: [PATCH 16/24] Add test that checks add_goals for flattened goals --- .../transmutability/with-condition-nested-goals.rs | 12 ++++++++++++ .../with-condition-nested-goals.stderr | 13 +++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/ui/transmutability/with-condition-nested-goals.rs create mode 100644 tests/ui/transmutability/with-condition-nested-goals.stderr diff --git a/tests/ui/transmutability/with-condition-nested-goals.rs b/tests/ui/transmutability/with-condition-nested-goals.rs new file mode 100644 index 0000000000000..c09cb1f8df841 --- /dev/null +++ b/tests/ui/transmutability/with-condition-nested-goals.rs @@ -0,0 +1,12 @@ +//@ compile-flags: -Znext-solver=globally +//@ check-fail + +#![feature(transmutability)] +use std::mem::TransmuteFrom; + +struct NewType(u8); + +fn main() { + let bytes: &[NewType; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; + //~^ ERROR `&i32` cannot be safely transmuted into `&[NewType; 4]` +} diff --git a/tests/ui/transmutability/with-condition-nested-goals.stderr b/tests/ui/transmutability/with-condition-nested-goals.stderr new file mode 100644 index 0000000000000..d808160c39f3c --- /dev/null +++ b/tests/ui/transmutability/with-condition-nested-goals.stderr @@ -0,0 +1,13 @@ +error[E0277]: `&i32` cannot be safely transmuted into `&[NewType; 4]` + --> $DIR/with-condition-nested-goals.rs:10:74 + | +LL | let bytes: &[NewType; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; + | -------------------------------- ^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | + = help: the nightly-only, unstable trait `TransmuteFrom<&i32, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `&[NewType; 4]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From cf94b149f4b474eb1c63dc97a15b985051274973 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Sat, 10 Oct 2026 13:56:54 -0300 Subject: [PATCH 17/24] Mark fixed transmutability tests as fixed --- .../alignment/align-pass.next.stderr | 29 ---- .../transmutability/alignment/align-pass.rs | 2 +- ...cept_assume_lifetime_extension.next.stderr | 138 ------------------ .../accept_assume_lifetime_extension.rs | 2 +- ...e-wrapper-types-bit-compatible.next.stderr | 24 --- .../recursive-wrapper-types-bit-compatible.rs | 2 +- .../recursive-wrapper-types.next.stderr | 45 ------ .../references/recursive-wrapper-types.rs | 2 +- .../references/u8-to-unit.next.stderr | 29 ---- .../transmutability/references/u8-to-unit.rs | 2 +- .../references/unit-to-itself.next.stderr | 29 ---- .../references/unit-to-itself.rs | 2 +- ...f_ref_src_has_safety_invariant.next.stderr | 18 --- ..._accept_if_ref_src_has_safety_invariant.rs | 2 +- .../transmute-higher-ranked.next.stderr | 18 --- .../transmute-higher-ranked.rs | 2 +- 16 files changed, 8 insertions(+), 338 deletions(-) delete mode 100644 tests/ui/transmutability/alignment/align-pass.next.stderr delete mode 100644 tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr delete mode 100644 tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.next.stderr delete mode 100644 tests/ui/transmutability/references/recursive-wrapper-types.next.stderr delete mode 100644 tests/ui/transmutability/references/u8-to-unit.next.stderr delete mode 100644 tests/ui/transmutability/references/unit-to-itself.next.stderr delete mode 100644 tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.next.stderr delete mode 100644 tests/ui/transmutability/transmute-higher-ranked.next.stderr diff --git a/tests/ui/transmutability/alignment/align-pass.next.stderr b/tests/ui/transmutability/alignment/align-pass.next.stderr deleted file mode 100644 index 2095e97cc3915..0000000000000 --- a/tests/ui/transmutability/alignment/align-pass.next.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: `&[u16; 0]` cannot be safely transmuted into `&[u8; 0]` - --> $DIR/align-pass.rs:25:56 - | -LL | assert::is_maybe_transmutable::<&'static [u16; 0], &'static [u8; 0]>(); - | ^^^^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static [u16; 0], Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'static [u8; 0]` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/align-pass.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` -help: consider removing the leading `&`-reference - | -LL - assert::is_maybe_transmutable::<&'static [u16; 0], &'static [u8; 0]>(); -LL + assert::is_maybe_transmutable::<&'static [u16; 0], [u8; 0]>(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/alignment/align-pass.rs b/tests/ui/transmutability/alignment/align-pass.rs index fa40c3a3ade43..21596fe01073f 100644 --- a/tests/ui/transmutability/alignment/align-pass.rs +++ b/tests/ui/transmutability/alignment/align-pass.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr b/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr deleted file mode 100644 index 4c469fd2222e3..0000000000000 --- a/tests/ui/transmutability/references/accept_assume_lifetime_extension.next.stderr +++ /dev/null @@ -1,138 +0,0 @@ -error[E0277]: `&u8` cannot be safely transmuted into `&u8` - --> $DIR/accept_assume_lifetime_extension.rs:24:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `std::mem::TransmuteFrom<&u8, std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `&u8` -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `&&u8` cannot be safely transmuted into `&&u8` - --> $DIR/accept_assume_lifetime_extension.rs:32:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `std::mem::TransmuteFrom<&&u8, std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `&&u8` -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `(&u8,)` cannot be safely transmuted into `(&u8,)` - --> $DIR/accept_assume_lifetime_extension.rs:40:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `std::mem::TransmuteFrom<(&u8,), std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `(&u8,)` -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `(&u8, u8)` cannot be safely transmuted into `(&u8, u8)` - --> $DIR/accept_assume_lifetime_extension.rs:44:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `std::mem::TransmuteFrom<(&u8, u8), std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `(&u8, u8)` -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `r#struct::Struct<'_>` cannot be safely transmuted into `r#struct::Struct<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:54:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | -help: the nightly-only, unstable trait `std::mem::TransmuteFrom, std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `r#struct::Struct<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:51:5 - | -LL | struct Struct<'a>(&'a u8); - | ^^^^^^^^^^^^^^^^^ -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `Single<'_>` cannot be safely transmuted into `Single<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:66:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | -help: the nightly-only, unstable trait `std::mem::TransmuteFrom, std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `Single<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:61:5 - | -LL | enum Single<'a> { - | ^^^^^^^^^^^^^^^ -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `Multi<'_>` cannot be safely transmuted into `Multi<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:76:18 - | -LL | unsafe { transmute(src) } - | ^^^^^^^^^^^^^^ unsatisfied trait bound - | -help: the nightly-only, unstable trait `std::mem::TransmuteFrom, std::mem::Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `Multi<'_>` - --> $DIR/accept_assume_lifetime_extension.rs:69:5 - | -LL | enum Multi<'a> { - | ^^^^^^^^^^^^^^ -note: required by a bound in `transmute` - --> $DIR/accept_assume_lifetime_extension.rs:15:10 - | -LL | unsafe fn transmute(src: Src) -> Dst -LL | where -LL | Dst: TransmuteFrom, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error[E0277]: `&u8` cannot be safely transmuted into `&u8` - --> $DIR/accept_assume_lifetime_extension.rs:84:18 - | -LL | unsafe { extend_hrtb(src) } - | ^^^^^^^^^^^^---^ - | | | - | | `&u8` doesn't satisfy the trait bound - | unsatisfied trait bound - | - = help: the nightly-only, unstable trait `for<'b> std::mem::TransmuteFrom<&u8, std::mem::Assume { alignment: false, lifetimes: true, safety: false, validity: false }>` is not implemented for `&'b u8` -note: required by a bound in `extend_hrtb` - --> $DIR/accept_assume_lifetime_extension.rs:89:25 - | -LL | unsafe fn extend_hrtb<'a>(src: &'a u8) -> &'static u8 -LL | where -LL | for<'b> &'b u8: TransmuteFrom<&'a u8, { Assume::LIFETIMES }>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `extend_hrtb` - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs index 86feb3c40eb7d..b24e8eab618e3 100644 --- a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs +++ b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass //! Accept lifetime extensions with `Assume::LIFETIMES`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.next.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.next.stderr deleted file mode 100644 index 32156298a1f6f..0000000000000 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.next.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: `&A` cannot be safely transmuted into `&B` - --> $DIR/recursive-wrapper-types-bit-compatible.rs:27:49 - | -LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); - | ^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static A, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'static B` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/recursive-wrapper-types-bit-compatible.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs index f1bb503549968..aa628e0515200 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.next.stderr b/tests/ui/transmutability/references/recursive-wrapper-types.next.stderr deleted file mode 100644 index 8ea346d7c08b5..0000000000000 --- a/tests/ui/transmutability/references/recursive-wrapper-types.next.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error[E0277]: `&A` cannot be safely transmuted into `&B` - --> $DIR/recursive-wrapper-types.rs:27:49 - | -LL | assert::is_maybe_transmutable::<&'static A, &'static B>(); - | ^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static A, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'static B` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/recursive-wrapper-types.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `&B` cannot be safely transmuted into `&A` - --> $DIR/recursive-wrapper-types.rs:28:49 - | -LL | assert::is_maybe_transmutable::<&'static B, &'static A>(); - | ^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static B, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'static A` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/recursive-wrapper-types.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs index 7ff458aa2512b..12ce29f079cdf 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/references/u8-to-unit.next.stderr b/tests/ui/transmutability/references/u8-to-unit.next.stderr deleted file mode 100644 index 0897833202826..0000000000000 --- a/tests/ui/transmutability/references/u8-to-unit.next.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: `&u8` cannot be safely transmuted into `&Unit` - --> $DIR/u8-to-unit.rs:26:50 - | -LL | assert::is_maybe_transmutable::<&'static u8, &'static Unit>(); - | ^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static u8, Assume { alignment: false, lifetimes: true, safety: true, validity: false }>` is not implemented for `&'static Unit` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/u8-to-unit.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` -help: consider removing the leading `&`-reference - | -LL - assert::is_maybe_transmutable::<&'static u8, &'static Unit>(); -LL + assert::is_maybe_transmutable::<&'static u8, Unit>(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/u8-to-unit.rs b/tests/ui/transmutability/references/u8-to-unit.rs index df124cafda3d6..4b5a04dce50e5 100644 --- a/tests/ui/transmutability/references/u8-to-unit.rs +++ b/tests/ui/transmutability/references/u8-to-unit.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/references/unit-to-itself.next.stderr b/tests/ui/transmutability/references/unit-to-itself.next.stderr deleted file mode 100644 index 4a15b3b3d5c30..0000000000000 --- a/tests/ui/transmutability/references/unit-to-itself.next.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` - --> $DIR/unit-to-itself.rs:26:52 - | -LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&'static Unit, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>` is not implemented for `&'static Unit` -note: required by a bound in `is_maybe_transmutable` - --> $DIR/unit-to-itself.rs:13:14 - | -LL | pub fn is_maybe_transmutable() -LL | where -LL | Dst: TransmuteFrom - | |__________^ required by this bound in `is_maybe_transmutable` -help: consider removing the leading `&`-reference - | -LL - assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); -LL + assert::is_maybe_transmutable::<&'static Unit, Unit>(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/unit-to-itself.rs b/tests/ui/transmutability/references/unit-to-itself.rs index 87d001222f96e..e585d21f02b6e 100644 --- a/tests/ui/transmutability/references/unit-to-itself.rs +++ b/tests/ui/transmutability/references/unit-to-itself.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] mod assert { diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.next.stderr b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.next.stderr deleted file mode 100644 index 2cbaa71262cea..0000000000000 --- a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.next.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: `&mut Src` cannot be safely transmuted into `&mut u8` - --> $DIR/should_accept_if_ref_src_has_safety_invariant.rs:29:41 - | -LL | assert::is_transmutable::<&mut Src, &mut Dst>(); - | ^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `TransmuteFrom<&mut Src, Assume { alignment: false, lifetimes: false, safety: true, validity: false }>` is not implemented for `&mut u8` -note: required by a bound in `is_transmutable` - --> $DIR/should_accept_if_ref_src_has_safety_invariant.rs:19:14 - | -LL | pub fn is_transmutable() -LL | where -LL | Dst: TransmuteFrom - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs index 32d70c3298eda..b26e2992af977 100644 --- a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs +++ b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass //! When safety is assumed, a transmutation over exclusive references should be //! accepted if the source type potentially carries safety invariants. diff --git a/tests/ui/transmutability/transmute-higher-ranked.next.stderr b/tests/ui/transmutability/transmute-higher-ranked.next.stderr deleted file mode 100644 index 9d86559f62bcc..0000000000000 --- a/tests/ui/transmutability/transmute-higher-ranked.next.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: `&&u32` cannot be safely transmuted into `&&i32` - --> $DIR/transmute-higher-ranked.rs:21:5 - | -LL | transmute(); - | ^^^^^^^^^^^ unsatisfied trait bound - | - = help: the nightly-only, unstable trait `for<'a> TransmuteFrom<&'a &'a u32, Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `&'a &'a i32` -note: required by a bound in `transmute` - --> $DIR/transmute-higher-ranked.rs:16:26 - | -LL | pub fn transmute() -LL | where -LL | for<'a> &'a &'a i32: TransmuteFrom<&'a &'a u32>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `transmute` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/transmute-higher-ranked.rs b/tests/ui/transmutability/transmute-higher-ranked.rs index fc0753942906a..d1e4778636df4 100644 --- a/tests/ui/transmutability/transmute-higher-ranked.rs +++ b/tests/ui/transmutability/transmute-higher-ranked.rs @@ -5,7 +5,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: trait-system-refactor-initiative#152 -//@[old] check-pass +//@ check-pass #![feature(transmutability)] From 10d2bb9d8f7c35c17b2a7f94ff3da046f7540fd5 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Sat, 10 Oct 2026 14:15:28 -0300 Subject: [PATCH 18/24] Fix an needless import and needless full path --- compiler/rustc_transmute/src/maybe_transmutable/tests.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index ec561a4109ca9..2f242871de6ce 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -37,11 +37,7 @@ impl Representation for Dfa { } } -fn is_transmutable( - src: &R, - dst: &R, - assume: Assume, -) -> rustc_middle::ty::transmute::Answer { +fn is_transmutable(src: &R, dst: &R, assume: Assume) -> Answer { let src = src.clone(); let dst = dst.clone(); R::is_transmutable(src, dst, assume) @@ -355,8 +351,6 @@ mod uninit { } mod alt { - use rustc_middle::ty::transmute::Answer; - use super::*; #[test] From 7c7546802b6a6f135dcd1d44fadf50ce07c88983 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Sat, 10 Oct 2026 14:20:39 -0300 Subject: [PATCH 19/24] Add revision to a couple of tests --- .../with-condition-nested-goals.current.stderr | 11 +++++++++++ ...stderr => with-condition-nested-goals.next.stderr} | 2 +- .../ui/transmutability/with-condition-nested-goals.rs | 11 +++++++++-- ...stderr => ambiguity-in-closure-arg.current.stderr} | 2 +- .../ui/transmute/ambiguity-in-closure-arg.next.stderr | 9 +++++++++ tests/ui/transmute/ambiguity-in-closure-arg.rs | 9 +++++++-- 6 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/ui/transmutability/with-condition-nested-goals.current.stderr rename tests/ui/transmutability/{with-condition-nested-goals.stderr => with-condition-nested-goals.next.stderr} (93%) rename tests/ui/transmute/{ambiguity-in-closure-arg.stderr => ambiguity-in-closure-arg.current.stderr} (87%) create mode 100644 tests/ui/transmute/ambiguity-in-closure-arg.next.stderr diff --git a/tests/ui/transmutability/with-condition-nested-goals.current.stderr b/tests/ui/transmutability/with-condition-nested-goals.current.stderr new file mode 100644 index 0000000000000..27fbf8e92e811 --- /dev/null +++ b/tests/ui/transmutability/with-condition-nested-goals.current.stderr @@ -0,0 +1,11 @@ +error[E0277]: `i32` cannot be safely transmuted into `[NewType; 4]` + --> $DIR/with-condition-nested-goals.rs:16:74 + | +LL | let bytes: &[NewType; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; + | -------------------------------- ^^^^^ `[NewType; 4]` may carry safety invariants + | | + | required by a bound introduced by this call + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/with-condition-nested-goals.stderr b/tests/ui/transmutability/with-condition-nested-goals.next.stderr similarity index 93% rename from tests/ui/transmutability/with-condition-nested-goals.stderr rename to tests/ui/transmutability/with-condition-nested-goals.next.stderr index d808160c39f3c..dbb0747c3ff63 100644 --- a/tests/ui/transmutability/with-condition-nested-goals.stderr +++ b/tests/ui/transmutability/with-condition-nested-goals.next.stderr @@ -1,5 +1,5 @@ error[E0277]: `&i32` cannot be safely transmuted into `&[NewType; 4]` - --> $DIR/with-condition-nested-goals.rs:10:74 + --> $DIR/with-condition-nested-goals.rs:16:74 | LL | let bytes: &[NewType; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; | -------------------------------- ^^^^^ unsatisfied trait bound diff --git a/tests/ui/transmutability/with-condition-nested-goals.rs b/tests/ui/transmutability/with-condition-nested-goals.rs index c09cb1f8df841..1561a0a20fe55 100644 --- a/tests/ui/transmutability/with-condition-nested-goals.rs +++ b/tests/ui/transmutability/with-condition-nested-goals.rs @@ -1,4 +1,10 @@ -//@ compile-flags: -Znext-solver=globally +//! This UI test ensures that transmutability check tests nested goals. +//! If the nested goals regarding the NewType implementing the trait +//! was not being tested, this transmute call would compile. +// +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-fail #![feature(transmutability)] @@ -8,5 +14,6 @@ struct NewType(u8); fn main() { let bytes: &[NewType; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; - //~^ ERROR `&i32` cannot be safely transmuted into `&[NewType; 4]` + //[current]~^ ERROR `i32` cannot be safely transmuted into `[NewType; 4]` + //[next]~^^ ERROR `&i32` cannot be safely transmuted into `&[NewType; 4]` } diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.stderr b/tests/ui/transmute/ambiguity-in-closure-arg.current.stderr similarity index 87% rename from tests/ui/transmute/ambiguity-in-closure-arg.stderr rename to tests/ui/transmute/ambiguity-in-closure-arg.current.stderr index 24a10a6d210b4..3a38bb35ac793 100644 --- a/tests/ui/transmute/ambiguity-in-closure-arg.stderr +++ b/tests/ui/transmute/ambiguity-in-closure-arg.current.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/ambiguity-in-closure-arg.rs:6:44 + --> $DIR/ambiguity-in-closure-arg.rs:11:44 | LL | unsafe { std::mem::transmute::<_, ()>(|o_b: Unconstrained<_>| {}) }; | ^^^^^^^^^^^^^^^^^^^^^ cannot infer type diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.next.stderr b/tests/ui/transmute/ambiguity-in-closure-arg.next.stderr new file mode 100644 index 0000000000000..3a38bb35ac793 --- /dev/null +++ b/tests/ui/transmute/ambiguity-in-closure-arg.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguity-in-closure-arg.rs:11:44 + | +LL | unsafe { std::mem::transmute::<_, ()>(|o_b: Unconstrained<_>| {}) }; + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/transmute/ambiguity-in-closure-arg.rs b/tests/ui/transmute/ambiguity-in-closure-arg.rs index b8d351e94bbde..1926fb15f7b2d 100644 --- a/tests/ui/transmute/ambiguity-in-closure-arg.rs +++ b/tests/ui/transmute/ambiguity-in-closure-arg.rs @@ -1,5 +1,10 @@ -// Minimized test for . -//@ compile-flags: -Znext-solver=globally +//! Minimized test for . + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver +//@ check-fail + struct Unconstrained(T); fn main() { From 71f84bde3d8d454bba1c0c99f14585aad4bb9c87 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Sat, 10 Oct 2026 14:28:10 -0300 Subject: [PATCH 20/24] Fix a couple of type references in doc (what was I thinking) --- compiler/rustc_transmute/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 87f00c628435e..c0ffc8babc723 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -3,8 +3,8 @@ //! The analysis converts compiler layouts into trees of bytes, references, and //! definition markers. It prunes destination paths that may carry safety invariants unless //! safety is assumed, then converts the trees into deterministic finite automata. -//! Comparing the automata produces an `Answer`; reference transitions can leave -//! `Condition`s for the trait solver to discharge. +//! Comparing the automata produces an [`rustc_middle::ty::transmute::Answer`]; reference transitions can leave +//! [`rustc_middle::ty::transmute::Condition`]s for the trait solver to discharge. // tidy-alphabetical-start #![cfg_attr(test, feature(test))] From 3e780c40345086552c85dbfd7bdce9a3b6a68e36 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Sat, 10 Oct 2026 14:36:16 -0300 Subject: [PATCH 21/24] Add revisions to all previously edited tests --- .../pointer-aligned-to-next-solver.rs | 4 +- .../transmute-from-next-solver.rs | 4 +- .../vec-recycle-next-solver.rs | 4 +- ... => diverging-fn-transmute.current.stderr} | 2 +- .../diverging-fn-transmute.next.stderr | 15 + tests/ui/transmute/diverging-fn-transmute.rs | 4 +- tests/ui/transmute/lifetimes.rs | 4 +- .../{main.stderr => main.current.stderr} | 6 +- tests/ui/transmute/main.next.stderr | 30 ++ tests/ui/transmute/main.rs | 4 +- ...=> recursive-size-skeleton.current.stderr} | 4 +- .../recursive-size-skeleton.next.stderr | 20 + tests/ui/transmute/recursive-size-skeleton.rs | 4 +- .../ui/transmute/transmute-array-to-scalar.rs | 4 +- ...e-associated-type-to-slice.current.stderr} | 2 +- ...smute-associated-type-to-slice.next.stderr | 12 + .../transmute-associated-type-to-slice.rs | 4 +- tests/ui/transmute/transmute-bool-u8.rs | 4 +- ... transmute-different-sizes.current.stderr} | 16 +- .../transmute-different-sizes.next.stderr | 75 +++ .../ui/transmute/transmute-different-sizes.rs | 4 +- ... => transmute-fat-pointers.current.stderr} | 8 +- .../transmute-fat-pointers.next.stderr | 39 ++ tests/ui/transmute/transmute-fat-pointers.rs | 4 +- ...e-from-fn-item-types-error.current.stderr} | 18 +- ...smute-from-fn-item-types-error.next.stderr | 92 ++++ .../transmute-from-fn-item-types-error.rs | 4 +- ...l.stderr => transmute-impl.current.stderr} | 2 +- tests/ui/transmute/transmute-impl.next.stderr | 12 + tests/ui/transmute/transmute-impl.rs | 4 +- ...r => transmute-imut-to-mut.current.stderr} | 2 +- .../transmute-imut-to-mut.next.stderr | 10 + tests/ui/transmute/transmute-imut-to-mut.rs | 4 +- ...r => transmute-in-async-fn.current.stderr} | 4 +- .../transmute-in-async-fn.next.stderr | 21 + tests/ui/transmute/transmute-in-async-fn.rs | 4 +- .../transmute-same-associated-type.rs | 4 +- tests/ui/transmute/transmute-slice-to-dst.rs | 4 +- ... transmute-type-parameters.current.stderr} | 12 +- .../transmute-type-parameters.next.stderr | 57 ++ .../ui/transmute/transmute-type-parameters.rs | 4 +- tests/ui/transmute/transmute-zst-generics.rs | 4 +- ...> unnecessary-transmutation.current.fixed} | 6 +- ... unnecessary-transmutation.current.stderr} | 82 +-- .../unnecessary-transmutation.next.fixed | 119 ++++ .../unnecessary-transmutation.next.stderr | 506 ++++++++++++++++++ .../ui/transmute/unnecessary-transmutation.rs | 6 +- ...cessary-transmute-path-remap-ice-140277.rs | 4 +- 48 files changed, 1160 insertions(+), 102 deletions(-) rename tests/ui/transmute/{diverging-fn-transmute.stderr => diverging-fn-transmute.current.stderr} (92%) create mode 100644 tests/ui/transmute/diverging-fn-transmute.next.stderr rename tests/ui/transmute/{main.stderr => main.current.stderr} (92%) create mode 100644 tests/ui/transmute/main.next.stderr rename tests/ui/transmute/{recursive-size-skeleton.stderr => recursive-size-skeleton.current.stderr} (88%) create mode 100644 tests/ui/transmute/recursive-size-skeleton.next.stderr rename tests/ui/transmute/{transmute-associated-type-to-slice.stderr => transmute-associated-type-to-slice.current.stderr} (87%) create mode 100644 tests/ui/transmute/transmute-associated-type-to-slice.next.stderr rename tests/ui/transmute/{transmute-different-sizes.stderr => transmute-different-sizes.current.stderr} (86%) create mode 100644 tests/ui/transmute/transmute-different-sizes.next.stderr rename tests/ui/transmute/{transmute-fat-pointers.stderr => transmute-fat-pointers.current.stderr} (86%) create mode 100644 tests/ui/transmute/transmute-fat-pointers.next.stderr rename tests/ui/transmute/{transmute-from-fn-item-types-error.stderr => transmute-from-fn-item-types-error.current.stderr} (84%) create mode 100644 tests/ui/transmute/transmute-from-fn-item-types-error.next.stderr rename tests/ui/transmute/{transmute-impl.stderr => transmute-impl.current.stderr} (91%) create mode 100644 tests/ui/transmute/transmute-impl.next.stderr rename tests/ui/transmute/{transmute-imut-to-mut.stderr => transmute-imut-to-mut.current.stderr} (89%) create mode 100644 tests/ui/transmute/transmute-imut-to-mut.next.stderr rename tests/ui/transmute/{transmute-in-async-fn.stderr => transmute-in-async-fn.current.stderr} (89%) create mode 100644 tests/ui/transmute/transmute-in-async-fn.next.stderr rename tests/ui/transmute/{transmute-type-parameters.stderr => transmute-type-parameters.current.stderr} (86%) create mode 100644 tests/ui/transmute/transmute-type-parameters.next.stderr rename tests/ui/transmute/{unnecessary-transmutation.fixed => unnecessary-transmutation.current.fixed} (95%) rename tests/ui/transmute/{unnecessary-transmutation.stderr => unnecessary-transmutation.current.stderr} (92%) create mode 100644 tests/ui/transmute/unnecessary-transmutation.next.fixed create mode 100644 tests/ui/transmute/unnecessary-transmutation.next.stderr diff --git a/tests/ui/transmutability/pointer-aligned-to-next-solver.rs b/tests/ui/transmutability/pointer-aligned-to-next-solver.rs index 6c628b697708d..592ed5a6c2c50 100644 --- a/tests/ui/transmutability/pointer-aligned-to-next-solver.rs +++ b/tests/ui/transmutability/pointer-aligned-to-next-solver.rs @@ -1,5 +1,7 @@ //! Regression test for . -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-pass #![feature(pointer_is_aligned_to, transmutability)] diff --git a/tests/ui/transmutability/transmute-from-next-solver.rs b/tests/ui/transmutability/transmute-from-next-solver.rs index 9b86e4c66a4ff..b2bdaffb32456 100644 --- a/tests/ui/transmutability/transmute-from-next-solver.rs +++ b/tests/ui/transmutability/transmute-from-next-solver.rs @@ -1,5 +1,7 @@ //! Regression test for . -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/vec-recycle-next-solver.rs b/tests/ui/transmutability/vec-recycle-next-solver.rs index 0d1fc6cf7675c..ba68a31cea624 100644 --- a/tests/ui/transmutability/vec-recycle-next-solver.rs +++ b/tests/ui/transmutability/vec-recycle-next-solver.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-pass #![feature(vec_recycle, transmutability)] diff --git a/tests/ui/transmute/diverging-fn-transmute.stderr b/tests/ui/transmute/diverging-fn-transmute.current.stderr similarity index 92% rename from tests/ui/transmute/diverging-fn-transmute.stderr rename to tests/ui/transmute/diverging-fn-transmute.current.stderr index b9aeae7ed62b1..37b13e17a70e8 100644 --- a/tests/ui/transmute/diverging-fn-transmute.stderr +++ b/tests/ui/transmute/diverging-fn-transmute.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/diverging-fn-transmute.rs:5:9 + --> $DIR/diverging-fn-transmute.rs:7:9 | LL | fn assert_sizeof() -> ! { | - expected `!` because of return type diff --git a/tests/ui/transmute/diverging-fn-transmute.next.stderr b/tests/ui/transmute/diverging-fn-transmute.next.stderr new file mode 100644 index 0000000000000..37b13e17a70e8 --- /dev/null +++ b/tests/ui/transmute/diverging-fn-transmute.next.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/diverging-fn-transmute.rs:7:9 + | +LL | fn assert_sizeof() -> ! { + | - expected `!` because of return type +LL | unsafe { +LL | ::std::mem::transmute::(panic!()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `!`, found `[u8; 8]` + | + = note: expected type `!` + found array `[u8; 8]` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/transmute/diverging-fn-transmute.rs b/tests/ui/transmute/diverging-fn-transmute.rs index 6410c333ac77e..aedd3c53514c2 100644 --- a/tests/ui/transmute/diverging-fn-transmute.rs +++ b/tests/ui/transmute/diverging-fn-transmute.rs @@ -1,5 +1,7 @@ //! Regression test for issue #35849: transmute with panic in diverging function -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver fn assert_sizeof() -> ! { unsafe { ::std::mem::transmute::(panic!()) diff --git a/tests/ui/transmute/lifetimes.rs b/tests/ui/transmute/lifetimes.rs index 0cd7856b28862..926d2129821f7 100644 --- a/tests/ui/transmute/lifetimes.rs +++ b/tests/ui/transmute/lifetimes.rs @@ -1,5 +1,7 @@ //@ check-pass -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::ptr::NonNull; struct Foo<'a, T: ?Sized>(&'a (), NonNull); diff --git a/tests/ui/transmute/main.stderr b/tests/ui/transmute/main.current.stderr similarity index 92% rename from tests/ui/transmute/main.stderr rename to tests/ui/transmute/main.current.stderr index 6cb0d7f67e085..2a8a131a5e53c 100644 --- a/tests/ui/transmute/main.stderr +++ b/tests/ui/transmute/main.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:17:17 + --> $DIR/main.rs:19:17 | LL | let x: u8 = transmute(10u16); | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let x: u8 = transmute(10u16); = note: target type: `u8` (8 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:21:17 + --> $DIR/main.rs:23:17 | LL | let x: u8 = transmute("test"); | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let x: u8 = transmute("test"); = note: target type: `u8` (8 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/main.rs:26:18 + --> $DIR/main.rs:28:18 | LL | let x: Foo = transmute(10); | ^^^^^^^^^ diff --git a/tests/ui/transmute/main.next.stderr b/tests/ui/transmute/main.next.stderr new file mode 100644 index 0000000000000..2a8a131a5e53c --- /dev/null +++ b/tests/ui/transmute/main.next.stderr @@ -0,0 +1,30 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:19:17 + | +LL | let x: u8 = transmute(10u16); + | ^^^^^^^^^ + | + = note: source type: `u16` (16 bits) + = note: target type: `u8` (8 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:23:17 + | +LL | let x: u8 = transmute("test"); + | ^^^^^^^^^ + | + = note: source type: `&str` ($STR bits) + = note: target type: `u8` (8 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/main.rs:28:18 + | +LL | let x: Foo = transmute(10); + | ^^^^^^^^^ + | + = note: source type: `i32` (32 bits) + = note: target type: `Foo` (0 bits) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/main.rs b/tests/ui/transmute/main.rs index 8dd2b839dfc23..941944f749466 100644 --- a/tests/ui/transmute/main.rs +++ b/tests/ui/transmute/main.rs @@ -1,6 +1,8 @@ //@ normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)" //@ normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)" -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::mem::transmute; pub trait TypeConstructor<'a> { diff --git a/tests/ui/transmute/recursive-size-skeleton.stderr b/tests/ui/transmute/recursive-size-skeleton.current.stderr similarity index 88% rename from tests/ui/transmute/recursive-size-skeleton.stderr rename to tests/ui/transmute/recursive-size-skeleton.current.stderr index 05bdf6ae49905..a1a61480b8e26 100644 --- a/tests/ui/transmute/recursive-size-skeleton.stderr +++ b/tests/ui/transmute/recursive-size-skeleton.current.stderr @@ -1,5 +1,5 @@ error: reached the recursion limit while computing the size of `Thing` - --> $DIR/recursive-size-skeleton.rs:20:27 + --> $DIR/recursive-size-skeleton.rs:22:27 | LL | let _: i32 = unsafe { transmute(value) }; | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | let _: i32 = unsafe { transmute(value) }; = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/recursive-size-skeleton.rs:20:27 + --> $DIR/recursive-size-skeleton.rs:22:27 | LL | let _: i32 = unsafe { transmute(value) }; | ^^^^^^^^^ diff --git a/tests/ui/transmute/recursive-size-skeleton.next.stderr b/tests/ui/transmute/recursive-size-skeleton.next.stderr new file mode 100644 index 0000000000000..a1a61480b8e26 --- /dev/null +++ b/tests/ui/transmute/recursive-size-skeleton.next.stderr @@ -0,0 +1,20 @@ +error: reached the recursion limit while computing the size of `Thing` + --> $DIR/recursive-size-skeleton.rs:22:27 + | +LL | let _: i32 = unsafe { transmute(value) }; + | ^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/recursive-size-skeleton.rs:22:27 + | +LL | let _: i32 = unsafe { transmute(value) }; + | ^^^^^^^^^ + | + = note: source type: `Thing` (the type has an unknown layout) + = note: target type: `i32` (32 bits) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/recursive-size-skeleton.rs b/tests/ui/transmute/recursive-size-skeleton.rs index c3a68cb226806..138bc0eb34324 100644 --- a/tests/ui/transmute/recursive-size-skeleton.rs +++ b/tests/ui/transmute/recursive-size-skeleton.rs @@ -3,7 +3,9 @@ // through a normalizing type alias used to recurse without bound and // blow the stack. We now bail out via the recursion limit and emit a // regular error instead of ICE-ing. -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::mem::transmute; trait Trait { diff --git a/tests/ui/transmute/transmute-array-to-scalar.rs b/tests/ui/transmute/transmute-array-to-scalar.rs index 70b7046b5bf7b..c80d13fa7db03 100644 --- a/tests/ui/transmute/transmute-array-to-scalar.rs +++ b/tests/ui/transmute/transmute-array-to-scalar.rs @@ -1,7 +1,9 @@ //! Verify transmuting from a single-element array to a scalar is allowed. //! //! Regression test: -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ run-pass pub fn main() { diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.stderr b/tests/ui/transmute/transmute-associated-type-to-slice.current.stderr similarity index 87% rename from tests/ui/transmute/transmute-associated-type-to-slice.stderr rename to tests/ui/transmute/transmute-associated-type-to-slice.current.stderr index ada3153165e57..ac59b0c70be65 100644 --- a/tests/ui/transmute/transmute-associated-type-to-slice.stderr +++ b/tests/ui/transmute/transmute-associated-type-to-slice.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-associated-type-to-slice.rs:13:14 + --> $DIR/transmute-associated-type-to-slice.rs:15:14 | LL | unsafe { std::mem::transmute(a) } | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.next.stderr b/tests/ui/transmute/transmute-associated-type-to-slice.next.stderr new file mode 100644 index 0000000000000..ac59b0c70be65 --- /dev/null +++ b/tests/ui/transmute/transmute-associated-type-to-slice.next.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-associated-type-to-slice.rs:15:14 + | +LL | unsafe { std::mem::transmute(a) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `&ArrayPeano` (N bits) + = note: target type: `&[T]` (N bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-associated-type-to-slice.rs b/tests/ui/transmute/transmute-associated-type-to-slice.rs index b23436a0eb57e..5b56c541143a8 100644 --- a/tests/ui/transmute/transmute-associated-type-to-slice.rs +++ b/tests/ui/transmute/transmute-associated-type-to-slice.rs @@ -1,6 +1,8 @@ //! regression test for //@ normalize-stderr: "\d+ bits" -> "N bits" -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver trait MyTrait { type MyType; } diff --git a/tests/ui/transmute/transmute-bool-u8.rs b/tests/ui/transmute/transmute-bool-u8.rs index ccbcce66bdcb2..9bd4ac212d399 100644 --- a/tests/ui/transmute/transmute-bool-u8.rs +++ b/tests/ui/transmute/transmute-bool-u8.rs @@ -1,5 +1,7 @@ //! regression test for -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ build-pass #![allow(unnecessary_transmutes)] use std::mem::transmute; diff --git a/tests/ui/transmute/transmute-different-sizes.stderr b/tests/ui/transmute/transmute-different-sizes.current.stderr similarity index 86% rename from tests/ui/transmute/transmute-different-sizes.stderr rename to tests/ui/transmute/transmute-different-sizes.current.stderr index fe611f7ba18d1..d8b1898b25e91 100644 --- a/tests/ui/transmute/transmute-different-sizes.stderr +++ b/tests/ui/transmute/transmute-different-sizes.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:11:17 + --> $DIR/transmute-different-sizes.rs:13:17 | LL | let _: i8 = transmute(16i16); | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _: i8 = transmute(16i16); = note: target type: `i8` (N bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:16:17 + --> $DIR/transmute-different-sizes.rs:18:17 | LL | let _: i8 = transmute(x); | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _: i8 = transmute(x); = note: target type: `i8` (N bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:27:5 + --> $DIR/transmute-different-sizes.rs:29:5 | LL | transmute(x) | ^^^^^^^^^ @@ -26,7 +26,7 @@ LL | transmute(x) = note: target type: `::Output` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:38:5 + --> $DIR/transmute-different-sizes.rs:40:5 | LL | transmute(from) | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | transmute(from) = note: target type: `PtrAndOverAlignZST` (size can vary because of ::Metadata) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:47:5 + --> $DIR/transmute-different-sizes.rs:49:5 | LL | std::mem::transmute(from) | ^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | std::mem::transmute(from) = note: target type: `PtrAndEmptyArray` (size can vary because of ::Metadata) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:55:14 + --> $DIR/transmute-different-sizes.rs:57:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ @@ -53,7 +53,7 @@ LL | unsafe { transmute(x) } = note: target type: `*const T` (pointer to `T`) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:66:14 + --> $DIR/transmute-different-sizes.rs:68:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ @@ -62,7 +62,7 @@ LL | unsafe { transmute(x) } = note: target type: `NotANewtype<&T>` (size can vary because of ::Metadata) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-different-sizes.rs:79:14 + --> $DIR/transmute-different-sizes.rs:81:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-different-sizes.next.stderr b/tests/ui/transmute/transmute-different-sizes.next.stderr new file mode 100644 index 0000000000000..d8b1898b25e91 --- /dev/null +++ b/tests/ui/transmute/transmute-different-sizes.next.stderr @@ -0,0 +1,75 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:13:17 + | +LL | let _: i8 = transmute(16i16); + | ^^^^^^^^^ + | + = note: source type: `i16` (N bits) + = note: target type: `i8` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:18:17 + | +LL | let _: i8 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `&T` (N bits) + = note: target type: `i8` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:29:5 + | +LL | transmute(x) + | ^^^^^^^^^ + | + = note: source type: `u16` (N bits) + = note: target type: `::Output` (this type does not have a fixed size) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:40:5 + | +LL | transmute(from) + | ^^^^^^^^^ + | + = note: source type: `*mut T` (pointer to `T`) + = note: target type: `PtrAndOverAlignZST` (size can vary because of ::Metadata) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:49:5 + | +LL | std::mem::transmute(from) + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `*mut T` (pointer to `T`) + = note: target type: `PtrAndEmptyArray` (size can vary because of ::Metadata) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:57:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `OverAlignWrap<*const T>` (size can vary because of ::Metadata) + = note: target type: `*const T` (pointer to `T`) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:68:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `NotANewtype<&T>` (size can vary because of ::Metadata) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-different-sizes.rs:81:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `NotNullPointerOptimized<&T>` (size can vary because of ::Metadata) + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs index c327004f36518..c269b571d9e31 100644 --- a/tests/ui/transmute/transmute-different-sizes.rs +++ b/tests/ui/transmute/transmute-different-sizes.rs @@ -1,5 +1,7 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver // Tests that `transmute` cannot be called on types of different size. #![allow(warnings)] diff --git a/tests/ui/transmute/transmute-fat-pointers.stderr b/tests/ui/transmute/transmute-fat-pointers.current.stderr similarity index 86% rename from tests/ui/transmute/transmute-fat-pointers.stderr rename to tests/ui/transmute/transmute-fat-pointers.current.stderr index 56a4f7f33d152..e94ff321e9197 100644 --- a/tests/ui/transmute/transmute-fat-pointers.stderr +++ b/tests/ui/transmute/transmute-fat-pointers.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fat-pointers.rs:11:14 + --> $DIR/transmute-fat-pointers.rs:13:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | unsafe { transmute(x) } = note: target type: `&U` (pointer to `U`) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fat-pointers.rs:15:14 + --> $DIR/transmute-fat-pointers.rs:17:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe { transmute(x) } = note: target type: `&U` (pointer to `U`) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fat-pointers.rs:27:14 + --> $DIR/transmute-fat-pointers.rs:29:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ @@ -26,7 +26,7 @@ LL | unsafe { transmute(x) } = note: target type: `&U` (N bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fat-pointers.rs:31:14 + --> $DIR/transmute-fat-pointers.rs:33:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-fat-pointers.next.stderr b/tests/ui/transmute/transmute-fat-pointers.next.stderr new file mode 100644 index 0000000000000..e94ff321e9197 --- /dev/null +++ b/tests/ui/transmute/transmute-fat-pointers.next.stderr @@ -0,0 +1,39 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:13:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&[T]` (N bits) + = note: target type: `&U` (pointer to `U`) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:17:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&U` (pointer to `U`) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:29:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&U` (N bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-fat-pointers.rs:33:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (N bits) + = note: target type: `&U` (pointer to `U`) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs index 48d2375443ef7..eba750d9229a6 100644 --- a/tests/ui/transmute/transmute-fat-pointers.rs +++ b/tests/ui/transmute/transmute-fat-pointers.rs @@ -1,5 +1,7 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver // Tests that are conservative around thin/fat pointer mismatches. #![allow(dead_code)] diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.stderr b/tests/ui/transmute/transmute-from-fn-item-types-error.current.stderr similarity index 84% rename from tests/ui/transmute/transmute-from-fn-item-types-error.stderr rename to tests/ui/transmute/transmute-from-fn-item-types-error.current.stderr index 35b07efd0f6df..c77725b1c4eb0 100644 --- a/tests/ui/transmute/transmute-from-fn-item-types-error.stderr +++ b/tests/ui/transmute/transmute-from-fn-item-types-error.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-from-fn-item-types-error.rs:5:13 + --> $DIR/transmute-from-fn-item-types-error.rs:7:13 | LL | let i = mem::transmute(bar); | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let i = mem::transmute(bar); = note: target type: `i8` (8 bits) error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:9:13 + --> $DIR/transmute-from-fn-item-types-error.rs:11:13 | LL | let p = mem::transmute(foo); | ^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let p = mem::transmute(foo); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:13:14 + --> $DIR/transmute-from-fn-item-types-error.rs:15:14 | LL | let of = mem::transmute(main); | ^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let of = mem::transmute(main); = help: cast with `as` to a pointer instead error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-from-fn-item-types-error.rs:22:5 + --> $DIR/transmute-from-fn-item-types-error.rs:24:5 | LL | mem::transmute::<_, u8>(main); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | mem::transmute::<_, u8>(main); = note: target type: `u8` (8 bits) error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:26:5 + --> $DIR/transmute-from-fn-item-types-error.rs:28:5 | LL | mem::transmute::<_, *mut ()>(foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | mem::transmute::<_, *mut ()>(foo); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:30:5 + --> $DIR/transmute-from-fn-item-types-error.rs:32:5 | LL | mem::transmute::<_, fn()>(bar); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | mem::transmute::<_, fn()>(bar); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:39:5 + --> $DIR/transmute-from-fn-item-types-error.rs:41:5 | LL | mem::transmute::<_, *mut ()>(Some(foo)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | mem::transmute::<_, *mut ()>(Some(foo)); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:43:5 + --> $DIR/transmute-from-fn-item-types-error.rs:45:5 | LL | mem::transmute::<_, fn()>(Some(bar)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | mem::transmute::<_, fn()>(Some(bar)); = help: cast with `as` to a pointer instead error[E0591]: can't transmute zero-sized type - --> $DIR/transmute-from-fn-item-types-error.rs:47:5 + --> $DIR/transmute-from-fn-item-types-error.rs:49:5 | LL | mem::transmute::<_, Option>(Some(baz)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.next.stderr b/tests/ui/transmute/transmute-from-fn-item-types-error.next.stderr new file mode 100644 index 0000000000000..c77725b1c4eb0 --- /dev/null +++ b/tests/ui/transmute/transmute-from-fn-item-types-error.next.stderr @@ -0,0 +1,92 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-from-fn-item-types-error.rs:7:13 + | +LL | let i = mem::transmute(bar); + | ^^^^^^^^^^^^^^ + | + = note: source type: `unsafe fn() {bar}` (0 bits) + = note: target type: `i8` (8 bits) + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:11:13 + | +LL | let p = mem::transmute(foo); + | ^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option) {foo} + = note: target type: *const () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:15:14 + | +LL | let of = mem::transmute(main); + | ^^^^^^^^^^^^^^ + | + = note: source type: fn() {main} + = note: target type: Option + = help: cast with `as` to a pointer instead + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-from-fn-item-types-error.rs:24:5 + | +LL | mem::transmute::<_, u8>(main); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `fn() {main}` (0 bits) + = note: target type: `u8` (8 bits) + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:28:5 + | +LL | mem::transmute::<_, *mut ()>(foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option) {foo} + = note: target type: *mut () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:32:5 + | +LL | mem::transmute::<_, fn()>(bar); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {bar} + = note: target type: fn() + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:41:5 + | +LL | mem::transmute::<_, *mut ()>(Some(foo)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() -> (i8, *const (), Option) {foo} + = note: target type: *mut () + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:45:5 + | +LL | mem::transmute::<_, fn()>(Some(bar)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {bar} + = note: target type: fn() + = help: cast with `as` to a pointer instead + +error[E0591]: can't transmute zero-sized type + --> $DIR/transmute-from-fn-item-types-error.rs:49:5 + | +LL | mem::transmute::<_, Option>(Some(baz)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: unsafe fn() {baz} + = note: target type: Option + = help: cast with `as` to a pointer instead + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0512, E0591. +For more information about an error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-from-fn-item-types-error.rs b/tests/ui/transmute/transmute-from-fn-item-types-error.rs index 7be9dafcfccab..c1161305406d1 100644 --- a/tests/ui/transmute/transmute-from-fn-item-types-error.rs +++ b/tests/ui/transmute/transmute-from-fn-item-types-error.rs @@ -1,4 +1,6 @@ -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::mem; unsafe fn foo() -> (i8, *const (), Option) { diff --git a/tests/ui/transmute/transmute-impl.stderr b/tests/ui/transmute/transmute-impl.current.stderr similarity index 91% rename from tests/ui/transmute/transmute-impl.stderr rename to tests/ui/transmute/transmute-impl.current.stderr index 6ed1cd6cec455..598f43cddced0 100644 --- a/tests/ui/transmute/transmute-impl.stderr +++ b/tests/ui/transmute/transmute-impl.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-impl.rs:21:18 + --> $DIR/transmute-impl.rs:23:18 | LL | unsafe { transmute(x) } | ^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-impl.next.stderr b/tests/ui/transmute/transmute-impl.next.stderr new file mode 100644 index 0000000000000..598f43cddced0 --- /dev/null +++ b/tests/ui/transmute/transmute-impl.next.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-impl.rs:23:18 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^ + | + = note: source type: `&T` (pointer to `T`) + = note: target type: `&isize` (N bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs index 1c85249645c39..1e5cf6509f6ba 100644 --- a/tests/ui/transmute/transmute-impl.rs +++ b/tests/ui/transmute/transmute-impl.rs @@ -1,5 +1,7 @@ //@ normalize-stderr: "\d+ bits" -> "N bits" -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver // Tests that are conservative around thin/fat pointer mismatches. #![allow(dead_code)] diff --git a/tests/ui/transmute/transmute-imut-to-mut.stderr b/tests/ui/transmute/transmute-imut-to-mut.current.stderr similarity index 89% rename from tests/ui/transmute/transmute-imut-to-mut.stderr rename to tests/ui/transmute/transmute-imut-to-mut.current.stderr index d37050fa58af6..265426641d57e 100644 --- a/tests/ui/transmute/transmute-imut-to-mut.stderr +++ b/tests/ui/transmute/transmute-imut-to-mut.current.stderr @@ -1,5 +1,5 @@ error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell - --> $DIR/transmute-imut-to-mut.rs:6:32 + --> $DIR/transmute-imut-to-mut.rs:8:32 | LL | let _a: &mut u8 = unsafe { transmute(&1u8) }; | ^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-imut-to-mut.next.stderr b/tests/ui/transmute/transmute-imut-to-mut.next.stderr new file mode 100644 index 0000000000000..265426641d57e --- /dev/null +++ b/tests/ui/transmute/transmute-imut-to-mut.next.stderr @@ -0,0 +1,10 @@ +error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell + --> $DIR/transmute-imut-to-mut.rs:8:32 + | +LL | let _a: &mut u8 = unsafe { transmute(&1u8) }; + | ^^^^^^^^^ + | + = note: `#[deny(mutable_transmutes)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/transmute/transmute-imut-to-mut.rs b/tests/ui/transmute/transmute-imut-to-mut.rs index d5299fa40f202..85c067366e549 100644 --- a/tests/ui/transmute/transmute-imut-to-mut.rs +++ b/tests/ui/transmute/transmute-imut-to-mut.rs @@ -1,5 +1,7 @@ // Tests that transmuting from &T to &mut T is Undefined Behavior. -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::mem::transmute; fn main() { diff --git a/tests/ui/transmute/transmute-in-async-fn.stderr b/tests/ui/transmute/transmute-in-async-fn.current.stderr similarity index 89% rename from tests/ui/transmute/transmute-in-async-fn.stderr rename to tests/ui/transmute/transmute-in-async-fn.current.stderr index f24f236d8d225..730e9550f9927 100644 --- a/tests/ui/transmute/transmute-in-async-fn.stderr +++ b/tests/ui/transmute/transmute-in-async-fn.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-in-async-fn.rs:5:14 + --> $DIR/transmute-in-async-fn.rs:7:14 | LL | unsafe { std::mem::transmute(1u64) } | ^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | unsafe { std::mem::transmute(1u64) } = note: target type: `u32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-in-async-fn.rs:10:31 + --> $DIR/transmute-in-async-fn.rs:12:31 | LL | let closure = || unsafe { std::mem::transmute(1u64) }; | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-in-async-fn.next.stderr b/tests/ui/transmute/transmute-in-async-fn.next.stderr new file mode 100644 index 0000000000000..730e9550f9927 --- /dev/null +++ b/tests/ui/transmute/transmute-in-async-fn.next.stderr @@ -0,0 +1,21 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-in-async-fn.rs:7:14 + | +LL | unsafe { std::mem::transmute(1u64) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u64` (64 bits) + = note: target type: `u32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-in-async-fn.rs:12:31 + | +LL | let closure = || unsafe { std::mem::transmute(1u64) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u64` (64 bits) + = note: target type: `u32` (32 bits) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-in-async-fn.rs b/tests/ui/transmute/transmute-in-async-fn.rs index 025e29017a93e..49270406315ec 100644 --- a/tests/ui/transmute/transmute-in-async-fn.rs +++ b/tests/ui/transmute/transmute-in-async-fn.rs @@ -1,5 +1,7 @@ //@ compile-flags: -Zmir-enable-passes=+DataflowConstProp --crate-type lib -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ edition:2021 pub async fn a() -> u32 { unsafe { std::mem::transmute(1u64) } diff --git a/tests/ui/transmute/transmute-same-associated-type.rs b/tests/ui/transmute/transmute-same-associated-type.rs index 061b8edc0d07e..0ea1b799b412a 100644 --- a/tests/ui/transmute/transmute-same-associated-type.rs +++ b/tests/ui/transmute/transmute-same-associated-type.rs @@ -1,5 +1,7 @@ //! Verify transmuting is allowed when `Src` and `Dst` are the same associated type. -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-pass trait Foo { diff --git a/tests/ui/transmute/transmute-slice-to-dst.rs b/tests/ui/transmute/transmute-slice-to-dst.rs index 8cc0471c4d780..60386af186b6b 100644 --- a/tests/ui/transmute/transmute-slice-to-dst.rs +++ b/tests/ui/transmute/transmute-slice-to-dst.rs @@ -1,6 +1,8 @@ //! regression test for //@ build-pass -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ compile-flags: -g pub struct Dst { diff --git a/tests/ui/transmute/transmute-type-parameters.stderr b/tests/ui/transmute/transmute-type-parameters.current.stderr similarity index 86% rename from tests/ui/transmute/transmute-type-parameters.stderr rename to tests/ui/transmute/transmute-type-parameters.current.stderr index 220b929d4fd2e..e1c3bca593af4 100644 --- a/tests/ui/transmute/transmute-type-parameters.stderr +++ b/tests/ui/transmute/transmute-type-parameters.current.stderr @@ -1,5 +1,5 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:6:18 + --> $DIR/transmute-type-parameters.rs:8:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _: i32 = transmute(x); = note: target type: `i32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:11:18 + --> $DIR/transmute-type-parameters.rs:13:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _: i32 = transmute(x); = note: target type: `i32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:16:18 + --> $DIR/transmute-type-parameters.rs:18:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _: i32 = transmute(x); = note: target type: `i32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:25:18 + --> $DIR/transmute-type-parameters.rs:27:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | let _: i32 = transmute(x); = note: target type: `i32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:35:18 + --> $DIR/transmute-type-parameters.rs:37:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _: i32 = transmute(x); = note: target type: `i32` (32 bits) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-type-parameters.rs:40:18 + --> $DIR/transmute-type-parameters.rs:42:18 | LL | let _: i32 = transmute(x); | ^^^^^^^^^ diff --git a/tests/ui/transmute/transmute-type-parameters.next.stderr b/tests/ui/transmute/transmute-type-parameters.next.stderr new file mode 100644 index 0000000000000..e1c3bca593af4 --- /dev/null +++ b/tests/ui/transmute/transmute-type-parameters.next.stderr @@ -0,0 +1,57 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:8:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `T` (this type does not have a fixed size) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:13:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `(T, i32)` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:18:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `[T; 10]` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:27:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Bad` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:37:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Worse` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-type-parameters.rs:42:18 + | +LL | let _: i32 = transmute(x); + | ^^^^^^^^^ + | + = note: source type: `Option` (size can vary because of T) + = note: target type: `i32` (32 bits) + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/transmute/transmute-type-parameters.rs b/tests/ui/transmute/transmute-type-parameters.rs index afbe3f594719d..cb9fc3cbb86a0 100644 --- a/tests/ui/transmute/transmute-type-parameters.rs +++ b/tests/ui/transmute/transmute-type-parameters.rs @@ -1,5 +1,7 @@ // Tests that `transmute` cannot be called on type parameters. -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver use std::mem::transmute; unsafe fn f(x: T) { diff --git a/tests/ui/transmute/transmute-zst-generics.rs b/tests/ui/transmute/transmute-zst-generics.rs index bc58591be6a48..31ee48bac3687 100644 --- a/tests/ui/transmute/transmute-zst-generics.rs +++ b/tests/ui/transmute/transmute-zst-generics.rs @@ -1,5 +1,7 @@ //@ run-pass -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver // Transmuting to/from ZSTs that contain generics. #![feature(transmute_generic_consts)] diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.current.fixed similarity index 95% rename from tests/ui/transmute/unnecessary-transmutation.fixed rename to tests/ui/transmute/unnecessary-transmutation.current.fixed index 4b520905f0f5d..52684c920ee88 100644 --- a/tests/ui/transmute/unnecessary-transmutation.fixed +++ b/tests/ui/transmute/unnecessary-transmutation.current.fixed @@ -1,5 +1,9 @@ //@ run-rustfix -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver +//@ check-fail + #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] use std::mem::transmute; diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.current.stderr similarity index 92% rename from tests/ui/transmute/unnecessary-transmutation.stderr rename to tests/ui/transmute/unnecessary-transmutation.current.stderr index 5f94e3aaaf657..ca8cf6f7d9634 100644 --- a/tests/ui/transmute/unnecessary-transmutation.stderr +++ b/tests/ui/transmute/unnecessary-transmutation.current.stderr @@ -1,12 +1,12 @@ error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:8:14 + --> $DIR/unnecessary-transmutation.rs:12:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ | = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order note: the lint level is defined here - --> $DIR/unnecessary-transmutation.rs:3:9 + --> $DIR/unnecessary-transmutation.rs:7:9 | LL | #![deny(unnecessary_transmutes)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + unsafe { u32::to_ne_bytes(x) } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:13:14 + --> $DIR/unnecessary-transmutation.rs:17:14 | LL | unsafe { transmute(from) } | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL + unsafe { (from) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:17:29 + --> $DIR/unnecessary-transmutation.rs:21:29 | LL | pub static X: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL + pub static X: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:19:28 + --> $DIR/unnecessary-transmutation.rs:23:28 | LL | pub const Y: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + pub const Y: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:25:18 + --> $DIR/unnecessary-transmutation.rs:29:18 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL + unsafe { (x) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:31:22 + --> $DIR/unnecessary-transmutation.rs:35:22 | LL | const { unsafe { transmute::<_, u8>(true) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL + const { unsafe { (true) as u8 } }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:34:22 + --> $DIR/unnecessary-transmutation.rs:38:22 | LL | let x: u16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL + let x: u16 = u16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:36:26 + --> $DIR/unnecessary-transmutation.rs:40:26 | LL | let x: [u8; 2] = transmute(x); | ^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL + let x: [u8; 2] = u16::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:38:22 + --> $DIR/unnecessary-transmutation.rs:42:22 | LL | let x: u32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL + let x: u32 = u32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:40:26 + --> $DIR/unnecessary-transmutation.rs:44:26 | LL | let x: [u8; 4] = transmute(x); | ^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL + let x: [u8; 4] = u32::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:42:22 + --> $DIR/unnecessary-transmutation.rs:46:22 | LL | let x: u64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL + let x: u64 = u64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:44:26 + --> $DIR/unnecessary-transmutation.rs:48:26 | LL | let x: [u8; 8] = transmute(x); | ^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let x: [u8; 8] = u64::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:47:22 + --> $DIR/unnecessary-transmutation.rs:51:22 | LL | let y: i16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + let y: i16 = i16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:49:26 + --> $DIR/unnecessary-transmutation.rs:53:26 | LL | let y: [u8; 2] = transmute(y); | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + let y: [u8; 2] = i16::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:51:22 + --> $DIR/unnecessary-transmutation.rs:55:22 | LL | let y: i32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL + let y: i32 = i32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:53:26 + --> $DIR/unnecessary-transmutation.rs:57:26 | LL | let y: [u8; 4] = transmute(y); | ^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let y: [u8; 4] = i32::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:55:22 + --> $DIR/unnecessary-transmutation.rs:59:22 | LL | let y: i64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL + let y: i64 = i64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:57:26 + --> $DIR/unnecessary-transmutation.rs:61:26 | LL | let y: [u8; 8] = transmute(y); | ^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL + let y: [u8; 8] = i64::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:60:22 + --> $DIR/unnecessary-transmutation.rs:64:22 | LL | let z: f32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -246,7 +246,7 @@ LL + let z: f32 = f32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:62:26 + --> $DIR/unnecessary-transmutation.rs:66:26 | LL | let z: [u8; 4] = transmute(z); | ^^^^^^^^^^^^ @@ -259,7 +259,7 @@ LL + let z: [u8; 4] = f32::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:64:22 + --> $DIR/unnecessary-transmutation.rs:68:22 | LL | let z: f64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + let z: f64 = f64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:66:26 + --> $DIR/unnecessary-transmutation.rs:70:26 | LL | let z: [u8; 8] = transmute(z); | ^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL + let z: [u8; 8] = f64::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:69:22 + --> $DIR/unnecessary-transmutation.rs:73:22 | LL | let y: u32 = transmute('🦀'); | ^^^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + let y: u32 = u32::from('🦀'); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:71:23 + --> $DIR/unnecessary-transmutation.rs:75:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL + let y: char = char::from_u32_unchecked(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:73:22 + --> $DIR/unnecessary-transmutation.rs:77:22 | LL | let y: i32 = transmute('🐱'); | ^^^^^^^^^^^^^^^ @@ -322,7 +322,7 @@ LL + let y: i32 = u32::from('🐱').cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:75:23 + --> $DIR/unnecessary-transmutation.rs:79:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:78:22 + --> $DIR/unnecessary-transmutation.rs:82:22 | LL | let x: u16 = transmute(8i16); | ^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL + let x: u16 = i16::cast_unsigned(8i16); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:80:22 + --> $DIR/unnecessary-transmutation.rs:84:22 | LL | let x: i16 = transmute(x); | ^^^^^^^^^^^^ @@ -359,7 +359,7 @@ LL + let x: i16 = u16::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:82:22 + --> $DIR/unnecessary-transmutation.rs:86:22 | LL | let x: u32 = transmute(4i32); | ^^^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL + let x: u32 = i32::cast_unsigned(4i32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:84:22 + --> $DIR/unnecessary-transmutation.rs:88:22 | LL | let x: i32 = transmute(x); | ^^^^^^^^^^^^ @@ -383,7 +383,7 @@ LL + let x: i32 = u32::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:86:22 + --> $DIR/unnecessary-transmutation.rs:90:22 | LL | let x: u64 = transmute(7i64); | ^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ LL + let x: u64 = i64::cast_unsigned(7i64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:88:22 + --> $DIR/unnecessary-transmutation.rs:92:22 | LL | let x: i64 = transmute(x); | ^^^^^^^^^^^^ @@ -407,7 +407,7 @@ LL + let x: i64 = u64::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:91:22 + --> $DIR/unnecessary-transmutation.rs:95:22 | LL | let y: f32 = transmute(1u32); | ^^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL + let y: f32 = f32::from_bits(1u32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:93:22 + --> $DIR/unnecessary-transmutation.rs:97:22 | LL | let y: u32 = transmute(y); | ^^^^^^^^^^^^ @@ -431,7 +431,7 @@ LL + let y: u32 = f32::to_bits(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:95:22 + --> $DIR/unnecessary-transmutation.rs:99:22 | LL | let y: f64 = transmute(3u64); | ^^^^^^^^^^^^^^^ @@ -443,7 +443,7 @@ LL + let y: f64 = f64::from_bits(3u64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:97:22 + --> $DIR/unnecessary-transmutation.rs:101:22 | LL | let y: u64 = transmute(2.0); | ^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL + let y: u64 = f64::to_bits(2.0); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:100:22 + --> $DIR/unnecessary-transmutation.rs:104:22 | LL | let y: f64 = transmute(1i64); | ^^^^^^^^^^^^^^^ @@ -467,7 +467,7 @@ LL + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:102:22 + --> $DIR/unnecessary-transmutation.rs:106:22 | LL | let y: i64 = transmute(1f64); | ^^^^^^^^^^^^^^^ @@ -479,7 +479,7 @@ LL + let y: i64 = f64::to_bits(1f64).cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:107:21 + --> $DIR/unnecessary-transmutation.rs:111:21 | LL | let z: u8 = transmute(z); | ^^^^^^^^^^^^ @@ -491,7 +491,7 @@ LL + let z: u8 = u8::from(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:112:21 + --> $DIR/unnecessary-transmutation.rs:116:21 | LL | let z: i8 = transmute(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/transmute/unnecessary-transmutation.next.fixed b/tests/ui/transmute/unnecessary-transmutation.next.fixed new file mode 100644 index 0000000000000..52684c920ee88 --- /dev/null +++ b/tests/ui/transmute/unnecessary-transmutation.next.fixed @@ -0,0 +1,119 @@ +//@ run-rustfix +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver +//@ check-fail + +#![deny(unnecessary_transmutes)] +#![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] +use std::mem::transmute; + +pub fn bytes_at_home(x: u32) -> [u8; 4] { + unsafe { u32::to_ne_bytes(x) } + //~^ ERROR +} + +pub const fn intinator_const(from: bool) -> u8 { + unsafe { (from) as u8 } + //~^ ERROR +} + +pub static X: u8 = unsafe { (true) as u8 }; +//~^ ERROR +pub const Y: u8 = unsafe { (true) as u8 }; +//~^ ERROR + +pub struct Z {} +impl Z { + pub const fn intinator_assoc(x: bool) -> u8 { + unsafe { (x) as u8 } + //~^ ERROR + } +} + +fn main() { + const { unsafe { (true) as u8 } }; + //~^ ERROR + unsafe { + let x: u16 = u16::from_ne_bytes(*b"01"); + //~^ ERROR + let x: [u8; 2] = u16::to_ne_bytes(x); + //~^ ERROR + let x: u32 = u32::from_ne_bytes(*b"0123"); + //~^ ERROR + let x: [u8; 4] = u32::to_ne_bytes(x); + //~^ ERROR + let x: u64 = u64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let x: [u8; 8] = u64::to_ne_bytes(x); + //~^ ERROR + + let y: i16 = i16::from_ne_bytes(*b"01"); + //~^ ERROR + let y: [u8; 2] = i16::to_ne_bytes(y); + //~^ ERROR + let y: i32 = i32::from_ne_bytes(*b"0123"); + //~^ ERROR + let y: [u8; 4] = i32::to_ne_bytes(y); + //~^ ERROR + let y: i64 = i64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let y: [u8; 8] = i64::to_ne_bytes(y); + //~^ ERROR + + let z: f32 = f32::from_ne_bytes(*b"0123"); + //~^ ERROR + let z: [u8; 4] = f32::to_ne_bytes(z); + //~^ ERROR + let z: f64 = f64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let z: [u8; 8] = f64::to_ne_bytes(z); + //~^ ERROR + + let y: u32 = u32::from('🦀'); + //~^ ERROR + let y: char = char::from_u32_unchecked(y); + //~^ ERROR + let y: i32 = u32::from('🐱').cast_signed(); + //~^ ERROR + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); + //~^ ERROR + + let x: u16 = i16::cast_unsigned(8i16); + //~^ ERROR + let x: i16 = u16::cast_signed(x); + //~^ ERROR + let x: u32 = i32::cast_unsigned(4i32); + //~^ ERROR + let x: i32 = u32::cast_signed(x); + //~^ ERROR + let x: u64 = i64::cast_unsigned(7i64); + //~^ ERROR + let x: i64 = u64::cast_signed(x); + //~^ ERROR + + let y: f32 = f32::from_bits(1u32); + //~^ ERROR + let y: u32 = f32::to_bits(y); + //~^ ERROR + let y: f64 = f64::from_bits(3u64); + //~^ ERROR + let y: u64 = f64::to_bits(2.0); + //~^ ERROR + + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); + //~^ ERROR + let y: i64 = f64::to_bits(1f64).cast_signed(); + //~^ ERROR + + let z: bool = transmute(1u8); + // clippy + let z: u8 = u8::from(z); + //~^ ERROR + + let z: bool = transmute(1i8); + // clippy + let z: i8 = i8::from(z); + //~^ ERROR + } +} diff --git a/tests/ui/transmute/unnecessary-transmutation.next.stderr b/tests/ui/transmute/unnecessary-transmutation.next.stderr new file mode 100644 index 0000000000000..ca8cf6f7d9634 --- /dev/null +++ b/tests/ui/transmute/unnecessary-transmutation.next.stderr @@ -0,0 +1,506 @@ +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:12:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +note: the lint level is defined here + --> $DIR/unnecessary-transmutation.rs:7:9 + | +LL | #![deny(unnecessary_transmutes)] + | ^^^^^^^^^^^^^^^^^^^^^^ +help: replace this with + | +LL - unsafe { transmute(x) } +LL + unsafe { u32::to_ne_bytes(x) } + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:17:14 + | +LL | unsafe { transmute(from) } + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - unsafe { transmute(from) } +LL + unsafe { (from) as u8 } + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:21:29 + | +LL | pub static X: u8 = unsafe { transmute(true) }; + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - pub static X: u8 = unsafe { transmute(true) }; +LL + pub static X: u8 = unsafe { (true) as u8 }; + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:23:28 + | +LL | pub const Y: u8 = unsafe { transmute(true) }; + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - pub const Y: u8 = unsafe { transmute(true) }; +LL + pub const Y: u8 = unsafe { (true) as u8 }; + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:29:18 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - unsafe { transmute(x) } +LL + unsafe { (x) as u8 } + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:35:22 + | +LL | const { unsafe { transmute::<_, u8>(true) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - const { unsafe { transmute::<_, u8>(true) } }; +LL + const { unsafe { (true) as u8 } }; + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:38:22 + | +LL | let x: u16 = transmute(*b"01"); + | ^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: u16 = transmute(*b"01"); +LL + let x: u16 = u16::from_ne_bytes(*b"01"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:40:26 + | +LL | let x: [u8; 2] = transmute(x); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: [u8; 2] = transmute(x); +LL + let x: [u8; 2] = u16::to_ne_bytes(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:42:22 + | +LL | let x: u32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: u32 = transmute(*b"0123"); +LL + let x: u32 = u32::from_ne_bytes(*b"0123"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:44:26 + | +LL | let x: [u8; 4] = transmute(x); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: [u8; 4] = transmute(x); +LL + let x: [u8; 4] = u32::to_ne_bytes(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:46:22 + | +LL | let x: u64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: u64 = transmute(*b"feriscat"); +LL + let x: u64 = u64::from_ne_bytes(*b"feriscat"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:48:26 + | +LL | let x: [u8; 8] = transmute(x); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let x: [u8; 8] = transmute(x); +LL + let x: [u8; 8] = u64::to_ne_bytes(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:51:22 + | +LL | let y: i16 = transmute(*b"01"); + | ^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: i16 = transmute(*b"01"); +LL + let y: i16 = i16::from_ne_bytes(*b"01"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:53:26 + | +LL | let y: [u8; 2] = transmute(y); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: [u8; 2] = transmute(y); +LL + let y: [u8; 2] = i16::to_ne_bytes(y); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:55:22 + | +LL | let y: i32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: i32 = transmute(*b"0123"); +LL + let y: i32 = i32::from_ne_bytes(*b"0123"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:57:26 + | +LL | let y: [u8; 4] = transmute(y); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: [u8; 4] = transmute(y); +LL + let y: [u8; 4] = i32::to_ne_bytes(y); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:59:22 + | +LL | let y: i64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: i64 = transmute(*b"feriscat"); +LL + let y: i64 = i64::from_ne_bytes(*b"feriscat"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:61:26 + | +LL | let y: [u8; 8] = transmute(y); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let y: [u8; 8] = transmute(y); +LL + let y: [u8; 8] = i64::to_ne_bytes(y); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:64:22 + | +LL | let z: f32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let z: f32 = transmute(*b"0123"); +LL + let z: f32 = f32::from_ne_bytes(*b"0123"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:66:26 + | +LL | let z: [u8; 4] = transmute(z); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let z: [u8; 4] = transmute(z); +LL + let z: [u8; 4] = f32::to_ne_bytes(z); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:68:22 + | +LL | let z: f64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let z: f64 = transmute(*b"feriscat"); +LL + let z: f64 = f64::from_ne_bytes(*b"feriscat"); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:70:26 + | +LL | let z: [u8; 8] = transmute(z); + | ^^^^^^^^^^^^ + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +help: replace this with + | +LL - let z: [u8; 8] = transmute(z); +LL + let z: [u8; 8] = f64::to_ne_bytes(z); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:73:22 + | +LL | let y: u32 = transmute('🦀'); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: u32 = transmute('🦀'); +LL + let y: u32 = u32::from('🦀'); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:75:23 + | +LL | let y: char = transmute(y); + | ^^^^^^^^^^^^ + | + = help: consider using `char::from_u32(…).unwrap()` +help: replace this with + | +LL - let y: char = transmute(y); +LL + let y: char = char::from_u32_unchecked(y); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:77:22 + | +LL | let y: i32 = transmute('🐱'); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: i32 = transmute('🐱'); +LL + let y: i32 = u32::from('🐱').cast_signed(); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:79:23 + | +LL | let y: char = transmute(y); + | ^^^^^^^^^^^^ + | + = help: consider using `char::from_u32(i32::cast_unsigned(…)).unwrap()` +help: replace this with + | +LL - let y: char = transmute(y); +LL + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:82:22 + | +LL | let x: u16 = transmute(8i16); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: u16 = transmute(8i16); +LL + let x: u16 = i16::cast_unsigned(8i16); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:84:22 + | +LL | let x: i16 = transmute(x); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: i16 = transmute(x); +LL + let x: i16 = u16::cast_signed(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:86:22 + | +LL | let x: u32 = transmute(4i32); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: u32 = transmute(4i32); +LL + let x: u32 = i32::cast_unsigned(4i32); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:88:22 + | +LL | let x: i32 = transmute(x); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: i32 = transmute(x); +LL + let x: i32 = u32::cast_signed(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:90:22 + | +LL | let x: u64 = transmute(7i64); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: u64 = transmute(7i64); +LL + let x: u64 = i64::cast_unsigned(7i64); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:92:22 + | +LL | let x: i64 = transmute(x); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let x: i64 = transmute(x); +LL + let x: i64 = u64::cast_signed(x); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:95:22 + | +LL | let y: f32 = transmute(1u32); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: f32 = transmute(1u32); +LL + let y: f32 = f32::from_bits(1u32); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:97:22 + | +LL | let y: u32 = transmute(y); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: u32 = transmute(y); +LL + let y: u32 = f32::to_bits(y); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:99:22 + | +LL | let y: f64 = transmute(3u64); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: f64 = transmute(3u64); +LL + let y: f64 = f64::from_bits(3u64); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:101:22 + | +LL | let y: u64 = transmute(2.0); + | ^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: u64 = transmute(2.0); +LL + let y: u64 = f64::to_bits(2.0); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:104:22 + | +LL | let y: f64 = transmute(1i64); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: f64 = transmute(1i64); +LL + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:106:22 + | +LL | let y: i64 = transmute(1f64); + | ^^^^^^^^^^^^^^^ + | +help: replace this with + | +LL - let y: i64 = transmute(1f64); +LL + let y: i64 = f64::to_bits(1f64).cast_signed(); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:111:21 + | +LL | let z: u8 = transmute(z); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let z: u8 = transmute(z); +LL + let z: u8 = u8::from(z); + | + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:116:21 + | +LL | let z: i8 = transmute(z); + | ^^^^^^^^^^^^ + | +help: replace this with + | +LL - let z: i8 = transmute(z); +LL + let z: i8 = i8::from(z); + | + +error: aborting due to 40 previous errors + diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs index 607c1117361a6..f211956b648d2 100644 --- a/tests/ui/transmute/unnecessary-transmutation.rs +++ b/tests/ui/transmute/unnecessary-transmutation.rs @@ -1,5 +1,9 @@ //@ run-rustfix -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver +//@ check-fail + #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] use std::mem::transmute; diff --git a/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs b/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs index b9a095fe64b22..5f7ce0005bd0e 100644 --- a/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs +++ b/tests/ui/transmute/unnecessary-transmute-path-remap-ice-140277.rs @@ -1,5 +1,7 @@ //@ aux-crate: zerocopy=unnecessary-transmute-path-remap-ice-140277-trans.rs -//@ compile-flags: -Znext-solver=globally +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver //@ check-pass // tests for a regression in linting for unnecessary transmutes // where a span was inacessible for snippet procuring, From 7c32373d3a86654af6f9da6f9c3818cf5c996598 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Mon, 12 Oct 2026 06:46:02 -0300 Subject: [PATCH 22/24] Remove couple more unused imports --- compiler/rustc_transmute/src/maybe_transmutable/tests.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index 2f242871de6ce..56d31cb83f57f 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -402,8 +402,6 @@ mod union { } mod char { - use rustc_middle::ty::transmute::Answer; - use super::*; use crate::layout::tree::Endian; @@ -443,8 +441,6 @@ mod char { } mod nonzero { - use rustc_middle::ty::transmute::{Answer, Reason}; - use super::*; const NONZERO_BYTE_WIDTHS: [u64; 5] = [1, 2, 4, 8, 16]; From 2cee0dcde1d222886154000edf3ea0bfedafa5d3 Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Mon, 12 Oct 2026 07:50:53 -0300 Subject: [PATCH 23/24] trait-system-refactor-initiative#152 is not a bug anymore --- tests/ui/transmutability/alignment/align-pass.rs | 1 - .../references/accept_assume_lifetime_extension.rs | 1 - .../references/recursive-wrapper-types-bit-compatible.rs | 1 - tests/ui/transmutability/references/recursive-wrapper-types.rs | 1 - tests/ui/transmutability/references/u8-to-unit.rs | 1 - tests/ui/transmutability/references/unit-to-itself.rs | 1 - .../assume/should_accept_if_ref_src_has_safety_invariant.rs | 1 - tests/ui/transmutability/transmute-higher-ranked.rs | 1 - 8 files changed, 8 deletions(-) diff --git a/tests/ui/transmutability/alignment/align-pass.rs b/tests/ui/transmutability/alignment/align-pass.rs index 21596fe01073f..a87f1db089c16 100644 --- a/tests/ui/transmutability/alignment/align-pass.rs +++ b/tests/ui/transmutability/alignment/align-pass.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs index b24e8eab618e3..fea6675d751c9 100644 --- a/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs +++ b/tests/ui/transmutability/references/accept_assume_lifetime_extension.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass //! Accept lifetime extensions with `Assume::LIFETIMES`. diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs index aa628e0515200..e3fad55910e92 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs index 12ce29f079cdf..b1626d21e9731 100644 --- a/tests/ui/transmutability/references/recursive-wrapper-types.rs +++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/references/u8-to-unit.rs b/tests/ui/transmutability/references/u8-to-unit.rs index 4b5a04dce50e5..09f1a5d64bb45 100644 --- a/tests/ui/transmutability/references/u8-to-unit.rs +++ b/tests/ui/transmutability/references/u8-to-unit.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/references/unit-to-itself.rs b/tests/ui/transmutability/references/unit-to-itself.rs index e585d21f02b6e..5e001432caec9 100644 --- a/tests/ui/transmutability/references/unit-to-itself.rs +++ b/tests/ui/transmutability/references/unit-to-itself.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] diff --git a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs index b26e2992af977..ed89ad3c3a679 100644 --- a/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs +++ b/tests/ui/transmutability/safety/assume/should_accept_if_ref_src_has_safety_invariant.rs @@ -1,7 +1,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass //! When safety is assumed, a transmutation over exclusive references should be diff --git a/tests/ui/transmutability/transmute-higher-ranked.rs b/tests/ui/transmutability/transmute-higher-ranked.rs index d1e4778636df4..43c417daa2637 100644 --- a/tests/ui/transmutability/transmute-higher-ranked.rs +++ b/tests/ui/transmutability/transmute-higher-ranked.rs @@ -4,7 +4,6 @@ //@ revisions: old next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[next] known-bug: trait-system-refactor-initiative#152 //@ check-pass #![feature(transmutability)] From 13694b690e21cbc8c098813150d0772ca44146ad Mon Sep 17 00:00:00 2001 From: Lucas Sunsi Abreu Date: Mon, 12 Oct 2026 09:34:33 -0300 Subject: [PATCH 24/24] Drop two repeated tests and an unecessary directive --- .../pointer-aligned-to-next-solver.rs | 20 ----- .../transmute-from-next-solver.rs | 12 --- .../unnecessary-transmutation.current.fixed | 1 - .../unnecessary-transmutation.current.stderr | 82 +++++++++---------- .../unnecessary-transmutation.next.fixed | 1 - .../unnecessary-transmutation.next.stderr | 82 +++++++++---------- .../ui/transmute/unnecessary-transmutation.rs | 1 - 7 files changed, 82 insertions(+), 117 deletions(-) delete mode 100644 tests/ui/transmutability/pointer-aligned-to-next-solver.rs delete mode 100644 tests/ui/transmutability/transmute-from-next-solver.rs diff --git a/tests/ui/transmutability/pointer-aligned-to-next-solver.rs b/tests/ui/transmutability/pointer-aligned-to-next-solver.rs deleted file mode 100644 index 592ed5a6c2c50..0000000000000 --- a/tests/ui/transmutability/pointer-aligned-to-next-solver.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Regression test for . -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@ [next] compile-flags: -Znext-solver -//@ check-pass - -#![feature(pointer_is_aligned_to, transmutability)] -use std::mem::{Assume, TransmuteFrom}; - -fn main() { - let src: &[u8; 2] = &[0xFF, 0xFF]; - - let maybe_dst: Option<&u16> = if <*const _>::is_aligned_to(src, align_of::()) { - Some(unsafe { - <_ as TransmuteFrom<_, { Assume::ALIGNMENT }>>::transmute(src) - }) - } else { - None - }; -} diff --git a/tests/ui/transmutability/transmute-from-next-solver.rs b/tests/ui/transmutability/transmute-from-next-solver.rs deleted file mode 100644 index b2bdaffb32456..0000000000000 --- a/tests/ui/transmutability/transmute-from-next-solver.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Regression test for . -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@ [next] compile-flags: -Znext-solver -//@ check-pass - -#![feature(transmutability)] -use std::mem::TransmuteFrom; - -fn main() { - let bytes: &[u8; 4] = unsafe { TransmuteFrom::<&i32>::transmute(&1i32) }; -} diff --git a/tests/ui/transmute/unnecessary-transmutation.current.fixed b/tests/ui/transmute/unnecessary-transmutation.current.fixed index 52684c920ee88..567507f7dc54d 100644 --- a/tests/ui/transmute/unnecessary-transmutation.current.fixed +++ b/tests/ui/transmute/unnecessary-transmutation.current.fixed @@ -2,7 +2,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@ [next] compile-flags: -Znext-solver -//@ check-fail #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] diff --git a/tests/ui/transmute/unnecessary-transmutation.current.stderr b/tests/ui/transmute/unnecessary-transmutation.current.stderr index ca8cf6f7d9634..84532449c5dc8 100644 --- a/tests/ui/transmute/unnecessary-transmutation.current.stderr +++ b/tests/ui/transmute/unnecessary-transmutation.current.stderr @@ -1,12 +1,12 @@ error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:12:14 + --> $DIR/unnecessary-transmutation.rs:11:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ | = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order note: the lint level is defined here - --> $DIR/unnecessary-transmutation.rs:7:9 + --> $DIR/unnecessary-transmutation.rs:6:9 | LL | #![deny(unnecessary_transmutes)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + unsafe { u32::to_ne_bytes(x) } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:17:14 + --> $DIR/unnecessary-transmutation.rs:16:14 | LL | unsafe { transmute(from) } | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL + unsafe { (from) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:21:29 + --> $DIR/unnecessary-transmutation.rs:20:29 | LL | pub static X: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL + pub static X: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:23:28 + --> $DIR/unnecessary-transmutation.rs:22:28 | LL | pub const Y: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + pub const Y: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:29:18 + --> $DIR/unnecessary-transmutation.rs:28:18 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL + unsafe { (x) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:35:22 + --> $DIR/unnecessary-transmutation.rs:34:22 | LL | const { unsafe { transmute::<_, u8>(true) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL + const { unsafe { (true) as u8 } }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:38:22 + --> $DIR/unnecessary-transmutation.rs:37:22 | LL | let x: u16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL + let x: u16 = u16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:40:26 + --> $DIR/unnecessary-transmutation.rs:39:26 | LL | let x: [u8; 2] = transmute(x); | ^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL + let x: [u8; 2] = u16::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:42:22 + --> $DIR/unnecessary-transmutation.rs:41:22 | LL | let x: u32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL + let x: u32 = u32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:44:26 + --> $DIR/unnecessary-transmutation.rs:43:26 | LL | let x: [u8; 4] = transmute(x); | ^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL + let x: [u8; 4] = u32::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:46:22 + --> $DIR/unnecessary-transmutation.rs:45:22 | LL | let x: u64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL + let x: u64 = u64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:48:26 + --> $DIR/unnecessary-transmutation.rs:47:26 | LL | let x: [u8; 8] = transmute(x); | ^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let x: [u8; 8] = u64::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:51:22 + --> $DIR/unnecessary-transmutation.rs:50:22 | LL | let y: i16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + let y: i16 = i16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:53:26 + --> $DIR/unnecessary-transmutation.rs:52:26 | LL | let y: [u8; 2] = transmute(y); | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + let y: [u8; 2] = i16::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:55:22 + --> $DIR/unnecessary-transmutation.rs:54:22 | LL | let y: i32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL + let y: i32 = i32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:57:26 + --> $DIR/unnecessary-transmutation.rs:56:26 | LL | let y: [u8; 4] = transmute(y); | ^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let y: [u8; 4] = i32::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:59:22 + --> $DIR/unnecessary-transmutation.rs:58:22 | LL | let y: i64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL + let y: i64 = i64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:61:26 + --> $DIR/unnecessary-transmutation.rs:60:26 | LL | let y: [u8; 8] = transmute(y); | ^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL + let y: [u8; 8] = i64::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:64:22 + --> $DIR/unnecessary-transmutation.rs:63:22 | LL | let z: f32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -246,7 +246,7 @@ LL + let z: f32 = f32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:66:26 + --> $DIR/unnecessary-transmutation.rs:65:26 | LL | let z: [u8; 4] = transmute(z); | ^^^^^^^^^^^^ @@ -259,7 +259,7 @@ LL + let z: [u8; 4] = f32::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:68:22 + --> $DIR/unnecessary-transmutation.rs:67:22 | LL | let z: f64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + let z: f64 = f64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:70:26 + --> $DIR/unnecessary-transmutation.rs:69:26 | LL | let z: [u8; 8] = transmute(z); | ^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL + let z: [u8; 8] = f64::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:73:22 + --> $DIR/unnecessary-transmutation.rs:72:22 | LL | let y: u32 = transmute('🦀'); | ^^^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + let y: u32 = u32::from('🦀'); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:75:23 + --> $DIR/unnecessary-transmutation.rs:74:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL + let y: char = char::from_u32_unchecked(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:77:22 + --> $DIR/unnecessary-transmutation.rs:76:22 | LL | let y: i32 = transmute('🐱'); | ^^^^^^^^^^^^^^^ @@ -322,7 +322,7 @@ LL + let y: i32 = u32::from('🐱').cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:79:23 + --> $DIR/unnecessary-transmutation.rs:78:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:82:22 + --> $DIR/unnecessary-transmutation.rs:81:22 | LL | let x: u16 = transmute(8i16); | ^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL + let x: u16 = i16::cast_unsigned(8i16); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:84:22 + --> $DIR/unnecessary-transmutation.rs:83:22 | LL | let x: i16 = transmute(x); | ^^^^^^^^^^^^ @@ -359,7 +359,7 @@ LL + let x: i16 = u16::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:86:22 + --> $DIR/unnecessary-transmutation.rs:85:22 | LL | let x: u32 = transmute(4i32); | ^^^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL + let x: u32 = i32::cast_unsigned(4i32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:88:22 + --> $DIR/unnecessary-transmutation.rs:87:22 | LL | let x: i32 = transmute(x); | ^^^^^^^^^^^^ @@ -383,7 +383,7 @@ LL + let x: i32 = u32::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:90:22 + --> $DIR/unnecessary-transmutation.rs:89:22 | LL | let x: u64 = transmute(7i64); | ^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ LL + let x: u64 = i64::cast_unsigned(7i64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:92:22 + --> $DIR/unnecessary-transmutation.rs:91:22 | LL | let x: i64 = transmute(x); | ^^^^^^^^^^^^ @@ -407,7 +407,7 @@ LL + let x: i64 = u64::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:95:22 + --> $DIR/unnecessary-transmutation.rs:94:22 | LL | let y: f32 = transmute(1u32); | ^^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL + let y: f32 = f32::from_bits(1u32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:97:22 + --> $DIR/unnecessary-transmutation.rs:96:22 | LL | let y: u32 = transmute(y); | ^^^^^^^^^^^^ @@ -431,7 +431,7 @@ LL + let y: u32 = f32::to_bits(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:99:22 + --> $DIR/unnecessary-transmutation.rs:98:22 | LL | let y: f64 = transmute(3u64); | ^^^^^^^^^^^^^^^ @@ -443,7 +443,7 @@ LL + let y: f64 = f64::from_bits(3u64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:101:22 + --> $DIR/unnecessary-transmutation.rs:100:22 | LL | let y: u64 = transmute(2.0); | ^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL + let y: u64 = f64::to_bits(2.0); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:104:22 + --> $DIR/unnecessary-transmutation.rs:103:22 | LL | let y: f64 = transmute(1i64); | ^^^^^^^^^^^^^^^ @@ -467,7 +467,7 @@ LL + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:106:22 + --> $DIR/unnecessary-transmutation.rs:105:22 | LL | let y: i64 = transmute(1f64); | ^^^^^^^^^^^^^^^ @@ -479,7 +479,7 @@ LL + let y: i64 = f64::to_bits(1f64).cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:111:21 + --> $DIR/unnecessary-transmutation.rs:110:21 | LL | let z: u8 = transmute(z); | ^^^^^^^^^^^^ @@ -491,7 +491,7 @@ LL + let z: u8 = u8::from(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:116:21 + --> $DIR/unnecessary-transmutation.rs:115:21 | LL | let z: i8 = transmute(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/transmute/unnecessary-transmutation.next.fixed b/tests/ui/transmute/unnecessary-transmutation.next.fixed index 52684c920ee88..567507f7dc54d 100644 --- a/tests/ui/transmute/unnecessary-transmutation.next.fixed +++ b/tests/ui/transmute/unnecessary-transmutation.next.fixed @@ -2,7 +2,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@ [next] compile-flags: -Znext-solver -//@ check-fail #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] diff --git a/tests/ui/transmute/unnecessary-transmutation.next.stderr b/tests/ui/transmute/unnecessary-transmutation.next.stderr index ca8cf6f7d9634..84532449c5dc8 100644 --- a/tests/ui/transmute/unnecessary-transmutation.next.stderr +++ b/tests/ui/transmute/unnecessary-transmutation.next.stderr @@ -1,12 +1,12 @@ error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:12:14 + --> $DIR/unnecessary-transmutation.rs:11:14 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ | = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order note: the lint level is defined here - --> $DIR/unnecessary-transmutation.rs:7:9 + --> $DIR/unnecessary-transmutation.rs:6:9 | LL | #![deny(unnecessary_transmutes)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + unsafe { u32::to_ne_bytes(x) } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:17:14 + --> $DIR/unnecessary-transmutation.rs:16:14 | LL | unsafe { transmute(from) } | ^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL + unsafe { (from) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:21:29 + --> $DIR/unnecessary-transmutation.rs:20:29 | LL | pub static X: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL + pub static X: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:23:28 + --> $DIR/unnecessary-transmutation.rs:22:28 | LL | pub const Y: u8 = unsafe { transmute(true) }; | ^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL + pub const Y: u8 = unsafe { (true) as u8 }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:29:18 + --> $DIR/unnecessary-transmutation.rs:28:18 | LL | unsafe { transmute(x) } | ^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL + unsafe { (x) as u8 } | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:35:22 + --> $DIR/unnecessary-transmutation.rs:34:22 | LL | const { unsafe { transmute::<_, u8>(true) } }; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL + const { unsafe { (true) as u8 } }; | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:38:22 + --> $DIR/unnecessary-transmutation.rs:37:22 | LL | let x: u16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL + let x: u16 = u16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:40:26 + --> $DIR/unnecessary-transmutation.rs:39:26 | LL | let x: [u8; 2] = transmute(x); | ^^^^^^^^^^^^ @@ -103,7 +103,7 @@ LL + let x: [u8; 2] = u16::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:42:22 + --> $DIR/unnecessary-transmutation.rs:41:22 | LL | let x: u32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -116,7 +116,7 @@ LL + let x: u32 = u32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:44:26 + --> $DIR/unnecessary-transmutation.rs:43:26 | LL | let x: [u8; 4] = transmute(x); | ^^^^^^^^^^^^ @@ -129,7 +129,7 @@ LL + let x: [u8; 4] = u32::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:46:22 + --> $DIR/unnecessary-transmutation.rs:45:22 | LL | let x: u64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL + let x: u64 = u64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:48:26 + --> $DIR/unnecessary-transmutation.rs:47:26 | LL | let x: [u8; 8] = transmute(x); | ^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let x: [u8; 8] = u64::to_ne_bytes(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:51:22 + --> $DIR/unnecessary-transmutation.rs:50:22 | LL | let y: i16 = transmute(*b"01"); | ^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL + let y: i16 = i16::from_ne_bytes(*b"01"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:53:26 + --> $DIR/unnecessary-transmutation.rs:52:26 | LL | let y: [u8; 2] = transmute(y); | ^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL + let y: [u8; 2] = i16::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:55:22 + --> $DIR/unnecessary-transmutation.rs:54:22 | LL | let y: i32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL + let y: i32 = i32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:57:26 + --> $DIR/unnecessary-transmutation.rs:56:26 | LL | let y: [u8; 4] = transmute(y); | ^^^^^^^^^^^^ @@ -207,7 +207,7 @@ LL + let y: [u8; 4] = i32::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:59:22 + --> $DIR/unnecessary-transmutation.rs:58:22 | LL | let y: i64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL + let y: i64 = i64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:61:26 + --> $DIR/unnecessary-transmutation.rs:60:26 | LL | let y: [u8; 8] = transmute(y); | ^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL + let y: [u8; 8] = i64::to_ne_bytes(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:64:22 + --> $DIR/unnecessary-transmutation.rs:63:22 | LL | let z: f32 = transmute(*b"0123"); | ^^^^^^^^^^^^^^^^^^^ @@ -246,7 +246,7 @@ LL + let z: f32 = f32::from_ne_bytes(*b"0123"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:66:26 + --> $DIR/unnecessary-transmutation.rs:65:26 | LL | let z: [u8; 4] = transmute(z); | ^^^^^^^^^^^^ @@ -259,7 +259,7 @@ LL + let z: [u8; 4] = f32::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:68:22 + --> $DIR/unnecessary-transmutation.rs:67:22 | LL | let z: f64 = transmute(*b"feriscat"); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + let z: f64 = f64::from_ne_bytes(*b"feriscat"); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:70:26 + --> $DIR/unnecessary-transmutation.rs:69:26 | LL | let z: [u8; 8] = transmute(z); | ^^^^^^^^^^^^ @@ -285,7 +285,7 @@ LL + let z: [u8; 8] = f64::to_ne_bytes(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:73:22 + --> $DIR/unnecessary-transmutation.rs:72:22 | LL | let y: u32 = transmute('🦀'); | ^^^^^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + let y: u32 = u32::from('🦀'); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:75:23 + --> $DIR/unnecessary-transmutation.rs:74:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -310,7 +310,7 @@ LL + let y: char = char::from_u32_unchecked(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:77:22 + --> $DIR/unnecessary-transmutation.rs:76:22 | LL | let y: i32 = transmute('🐱'); | ^^^^^^^^^^^^^^^ @@ -322,7 +322,7 @@ LL + let y: i32 = u32::from('🐱').cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:79:23 + --> $DIR/unnecessary-transmutation.rs:78:23 | LL | let y: char = transmute(y); | ^^^^^^^^^^^^ @@ -335,7 +335,7 @@ LL + let y: char = char::from_u32_unchecked(i32::cast_unsigned(y)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:82:22 + --> $DIR/unnecessary-transmutation.rs:81:22 | LL | let x: u16 = transmute(8i16); | ^^^^^^^^^^^^^^^ @@ -347,7 +347,7 @@ LL + let x: u16 = i16::cast_unsigned(8i16); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:84:22 + --> $DIR/unnecessary-transmutation.rs:83:22 | LL | let x: i16 = transmute(x); | ^^^^^^^^^^^^ @@ -359,7 +359,7 @@ LL + let x: i16 = u16::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:86:22 + --> $DIR/unnecessary-transmutation.rs:85:22 | LL | let x: u32 = transmute(4i32); | ^^^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL + let x: u32 = i32::cast_unsigned(4i32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:88:22 + --> $DIR/unnecessary-transmutation.rs:87:22 | LL | let x: i32 = transmute(x); | ^^^^^^^^^^^^ @@ -383,7 +383,7 @@ LL + let x: i32 = u32::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:90:22 + --> $DIR/unnecessary-transmutation.rs:89:22 | LL | let x: u64 = transmute(7i64); | ^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ LL + let x: u64 = i64::cast_unsigned(7i64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:92:22 + --> $DIR/unnecessary-transmutation.rs:91:22 | LL | let x: i64 = transmute(x); | ^^^^^^^^^^^^ @@ -407,7 +407,7 @@ LL + let x: i64 = u64::cast_signed(x); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:95:22 + --> $DIR/unnecessary-transmutation.rs:94:22 | LL | let y: f32 = transmute(1u32); | ^^^^^^^^^^^^^^^ @@ -419,7 +419,7 @@ LL + let y: f32 = f32::from_bits(1u32); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:97:22 + --> $DIR/unnecessary-transmutation.rs:96:22 | LL | let y: u32 = transmute(y); | ^^^^^^^^^^^^ @@ -431,7 +431,7 @@ LL + let y: u32 = f32::to_bits(y); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:99:22 + --> $DIR/unnecessary-transmutation.rs:98:22 | LL | let y: f64 = transmute(3u64); | ^^^^^^^^^^^^^^^ @@ -443,7 +443,7 @@ LL + let y: f64 = f64::from_bits(3u64); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:101:22 + --> $DIR/unnecessary-transmutation.rs:100:22 | LL | let y: u64 = transmute(2.0); | ^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ LL + let y: u64 = f64::to_bits(2.0); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:104:22 + --> $DIR/unnecessary-transmutation.rs:103:22 | LL | let y: f64 = transmute(1i64); | ^^^^^^^^^^^^^^^ @@ -467,7 +467,7 @@ LL + let y: f64 = f64::from_bits(i64::cast_unsigned(1i64)); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:106:22 + --> $DIR/unnecessary-transmutation.rs:105:22 | LL | let y: i64 = transmute(1f64); | ^^^^^^^^^^^^^^^ @@ -479,7 +479,7 @@ LL + let y: i64 = f64::to_bits(1f64).cast_signed(); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:111:21 + --> $DIR/unnecessary-transmutation.rs:110:21 | LL | let z: u8 = transmute(z); | ^^^^^^^^^^^^ @@ -491,7 +491,7 @@ LL + let z: u8 = u8::from(z); | error: unnecessary transmute - --> $DIR/unnecessary-transmutation.rs:116:21 + --> $DIR/unnecessary-transmutation.rs:115:21 | LL | let z: i8 = transmute(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs index f211956b648d2..273529f5e5d78 100644 --- a/tests/ui/transmute/unnecessary-transmutation.rs +++ b/tests/ui/transmute/unnecessary-transmutation.rs @@ -2,7 +2,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@ [next] compile-flags: -Znext-solver -//@ check-fail #![deny(unnecessary_transmutes)] #![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)]