Skip to content

Commit 06e3d9b

Browse files
Fix transmute goal
1 parent 69c29fa commit 06e3d9b

File tree

6 files changed

+59
-39
lines changed

6 files changed

+59
-39
lines changed

compiler/rustc_middle/src/ty/generic_args.rs

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
6161
self.region_at(i)
6262
}
6363

64+
fn const_at(self, i: usize) -> ty::Const<'tcx> {
65+
self.const_at(i)
66+
}
67+
6468
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
6569
GenericArgs::identity_for_item(tcx, def_id)
6670
}

compiler/rustc_next_trait_solver/src/infcx.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fmt::Debug;
22

33
use rustc_type_ir::fold::TypeFoldable;
44
use rustc_type_ir::relate::Relate;
5-
use rustc_type_ir::solve::{Goal, NoSolution, SolverMode};
5+
use rustc_type_ir::solve::{Certainty, Goal, NoSolution, SolverMode};
66
use rustc_type_ir::{self as ty, Interner};
77

88
pub trait SolverDelegate: Sized {
@@ -193,4 +193,12 @@ pub trait SolverDelegate: Sized {
193193
trait_assoc_def_id: <Self::Interner as Interner>::DefId,
194194
impl_def_id: <Self::Interner as Interner>::DefId,
195195
) -> Result<Option<<Self::Interner as Interner>::DefId>, NoSolution>;
196+
197+
fn is_transmutable(
198+
&self,
199+
param_env: <Self::Interner as Interner>::ParamEnv,
200+
dst: <Self::Interner as Interner>::Ty,
201+
src: <Self::Interner as Interner>::Ty,
202+
assume: <Self::Interner as Interner>::Const,
203+
) -> Result<Certainty, NoSolution>;
196204
}

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+10-19
Original file line numberDiff line numberDiff line change
@@ -888,25 +888,6 @@ where
888888
self.infcx.well_formed_goals(param_env, arg)
889889
}
890890

891-
/*
892-
pub(super) fn is_transmutable(
893-
&self,
894-
src_and_dst: rustc_transmute::Types<I>,
895-
assume: rustc_transmute::Assume,
896-
) -> Result<Certainty, NoSolution> {
897-
use rustc_transmute::Answer;
898-
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
899-
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
900-
ObligationCause::dummy(),
901-
src_and_dst,
902-
assume,
903-
) {
904-
Answer::Yes => Ok(Certainty::Yes),
905-
Answer::No(_) | Answer::If(_) => Err(NoSolution),
906-
}
907-
}
908-
*/
909-
910891
pub(super) fn trait_ref_is_knowable(
911892
&mut self,
912893
param_env: I::ParamEnv,
@@ -1014,6 +995,16 @@ where
1014995
) -> Option<I::Const> {
1015996
self.infcx.try_const_eval_resolve(param_env, unevaluated)
1016997
}
998+
999+
pub(super) fn is_transmutable(
1000+
&mut self,
1001+
param_env: I::ParamEnv,
1002+
dst: I::Ty,
1003+
src: I::Ty,
1004+
assume: I::Const,
1005+
) -> Result<Certainty, NoSolution> {
1006+
self.infcx.is_transmutable(param_env, dst, src, assume)
1007+
}
10171008
}
10181009

10191010
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+7-18
Original file line numberDiff line numberDiff line change
@@ -601,12 +601,10 @@ where
601601
}
602602

603603
fn consider_builtin_transmute_candidate(
604-
_ecx: &mut EvalCtxt<'_, Infcx>,
605-
_goal: Goal<I, Self>,
604+
ecx: &mut EvalCtxt<'_, Infcx>,
605+
goal: Goal<I, Self>,
606606
) -> Result<Candidate<I>, NoSolution> {
607-
// TODO:
608-
todo!()
609-
/* if goal.predicate.polarity != ty::PredicatePolarity::Positive {
607+
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
610608
return Err(NoSolution);
611609
}
612610

@@ -615,26 +613,17 @@ where
615613
return Err(NoSolution);
616614
}
617615

618-
// Erase regions because we compute layouts in `rustc_transmute`,
619-
// which will ICE for region vars.
620-
let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args);
621-
622-
let Some(assume) =
623-
rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2))
624-
else {
625-
return Err(NoSolution);
626-
};
627-
628616
// FIXME: This actually should destructure the `Result` we get from transmutability and
629617
// register candiates. We probably need to register >1 since we may have an OR of ANDs.
630618
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
631619
let certainty = ecx.is_transmutable(
632-
rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
633-
assume,
620+
goal.param_env,
621+
goal.predicate.trait_ref.args.type_at(0),
622+
goal.predicate.trait_ref.args.type_at(1),
623+
goal.predicate.trait_ref.args.const_at(2),
634624
)?;
635625
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
636626
})
637-
*/
638627
}
639628

640629
/// ```ignore (builtin impl example)

compiler/rustc_trait_selection/src/solve/infcx.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable;
1616
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
1717
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
1818
use rustc_type_ir::relate::Relate;
19-
use rustc_type_ir::solve::{NoSolution, SolverMode};
19+
use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode};
2020

2121
use crate::traits::coherence::trait_ref_is_knowable;
2222
use crate::traits::specialization_graph;
@@ -406,4 +406,30 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc
406406
// FIXME: Check for defaultness here may cause diagnostics problems.
407407
if eligible { Ok(Some(node_item.item.def_id)) } else { Ok(None) }
408408
}
409+
410+
fn is_transmutable(
411+
&self,
412+
param_env: ty::ParamEnv<'tcx>,
413+
dst: Ty<'tcx>,
414+
src: Ty<'tcx>,
415+
assume: ty::Const<'tcx>,
416+
) -> Result<Certainty, NoSolution> {
417+
// Erase regions because we compute layouts in `rustc_transmute`,
418+
// which will ICE for region vars.
419+
let (dst, src) = self.tcx.erase_regions((dst, src));
420+
421+
let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, param_env, assume) else {
422+
return Err(NoSolution);
423+
};
424+
425+
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
426+
match rustc_transmute::TransmuteTypeEnv::new(&self.0).is_transmutable(
427+
ObligationCause::dummy(),
428+
rustc_transmute::Types { src, dst },
429+
assume,
430+
) {
431+
rustc_transmute::Answer::Yes => Ok(Certainty::Yes),
432+
rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution),
433+
}
434+
}
409435
}

compiler/rustc_type_ir/src/inherent.rs

+2
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
374374

375375
fn region_at(self, i: usize) -> I::Region;
376376

377+
fn const_at(self, i: usize) -> I::Const;
378+
377379
fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
378380

379381
fn extend_with_error(

0 commit comments

Comments
 (0)