Fix transmute goal
This commit is contained in:
parent
fb6f4b4a6e
commit
6609501ca7
6 changed files with 59 additions and 39 deletions
|
@ -61,6 +61,10 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
|
||||||
self.region_at(i)
|
self.region_at(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn const_at(self, i: usize) -> ty::Const<'tcx> {
|
||||||
|
self.const_at(i)
|
||||||
|
}
|
||||||
|
|
||||||
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
|
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
|
||||||
GenericArgs::identity_for_item(tcx, def_id)
|
GenericArgs::identity_for_item(tcx, def_id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt::Debug;
|
||||||
|
|
||||||
use rustc_type_ir::fold::TypeFoldable;
|
use rustc_type_ir::fold::TypeFoldable;
|
||||||
use rustc_type_ir::relate::Relate;
|
use rustc_type_ir::relate::Relate;
|
||||||
use rustc_type_ir::solve::{Goal, NoSolution, SolverMode};
|
use rustc_type_ir::solve::{Certainty, Goal, NoSolution, SolverMode};
|
||||||
use rustc_type_ir::{self as ty, Interner};
|
use rustc_type_ir::{self as ty, Interner};
|
||||||
|
|
||||||
pub trait SolverDelegate: Sized {
|
pub trait SolverDelegate: Sized {
|
||||||
|
@ -194,4 +194,12 @@ pub trait SolverDelegate: Sized {
|
||||||
trait_assoc_def_id: <Self::Interner as Interner>::DefId,
|
trait_assoc_def_id: <Self::Interner as Interner>::DefId,
|
||||||
impl_def_id: <Self::Interner as Interner>::DefId,
|
impl_def_id: <Self::Interner as Interner>::DefId,
|
||||||
) -> Result<Option<<Self::Interner as Interner>::DefId>, NoSolution>;
|
) -> Result<Option<<Self::Interner as Interner>::DefId>, NoSolution>;
|
||||||
|
|
||||||
|
fn is_transmutable(
|
||||||
|
&self,
|
||||||
|
param_env: <Self::Interner as Interner>::ParamEnv,
|
||||||
|
dst: <Self::Interner as Interner>::Ty,
|
||||||
|
src: <Self::Interner as Interner>::Ty,
|
||||||
|
assume: <Self::Interner as Interner>::Const,
|
||||||
|
) -> Result<Certainty, NoSolution>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -890,25 +890,6 @@ where
|
||||||
self.infcx.well_formed_goals(param_env, arg)
|
self.infcx.well_formed_goals(param_env, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub(super) fn is_transmutable(
|
|
||||||
&self,
|
|
||||||
src_and_dst: rustc_transmute::Types<I>,
|
|
||||||
assume: rustc_transmute::Assume,
|
|
||||||
) -> Result<Certainty, NoSolution> {
|
|
||||||
use rustc_transmute::Answer;
|
|
||||||
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
|
|
||||||
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
|
|
||||||
ObligationCause::dummy(),
|
|
||||||
src_and_dst,
|
|
||||||
assume,
|
|
||||||
) {
|
|
||||||
Answer::Yes => Ok(Certainty::Yes),
|
|
||||||
Answer::No(_) | Answer::If(_) => Err(NoSolution),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub(super) fn trait_ref_is_knowable(
|
pub(super) fn trait_ref_is_knowable(
|
||||||
&mut self,
|
&mut self,
|
||||||
param_env: I::ParamEnv,
|
param_env: I::ParamEnv,
|
||||||
|
@ -1016,6 +997,16 @@ where
|
||||||
) -> Option<I::Const> {
|
) -> Option<I::Const> {
|
||||||
self.infcx.try_const_eval_resolve(param_env, unevaluated)
|
self.infcx.try_const_eval_resolve(param_env, unevaluated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn is_transmutable(
|
||||||
|
&mut self,
|
||||||
|
param_env: I::ParamEnv,
|
||||||
|
dst: I::Ty,
|
||||||
|
src: I::Ty,
|
||||||
|
assume: I::Const,
|
||||||
|
) -> Result<Certainty, NoSolution> {
|
||||||
|
self.infcx.is_transmutable(param_env, dst, src, assume)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`
|
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`
|
||||||
|
|
|
@ -601,12 +601,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_transmute_candidate(
|
fn consider_builtin_transmute_candidate(
|
||||||
_ecx: &mut EvalCtxt<'_, Infcx>,
|
ecx: &mut EvalCtxt<'_, Infcx>,
|
||||||
_goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
// TODO:
|
if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
||||||
todo!()
|
|
||||||
/* if goal.predicate.polarity != ty::PredicatePolarity::Positive {
|
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,26 +613,17 @@ where
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase regions because we compute layouts in `rustc_transmute`,
|
|
||||||
// which will ICE for region vars.
|
|
||||||
let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args);
|
|
||||||
|
|
||||||
let Some(assume) =
|
|
||||||
rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2))
|
|
||||||
else {
|
|
||||||
return Err(NoSolution);
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME: This actually should destructure the `Result` we get from transmutability and
|
// FIXME: This actually should destructure the `Result` we get from transmutability and
|
||||||
// register candiates. We probably need to register >1 since we may have an OR of ANDs.
|
// register candiates. We probably need to register >1 since we may have an OR of ANDs.
|
||||||
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
|
||||||
let certainty = ecx.is_transmutable(
|
let certainty = ecx.is_transmutable(
|
||||||
rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
|
goal.param_env,
|
||||||
assume,
|
goal.predicate.trait_ref.args.type_at(0),
|
||||||
|
goal.predicate.trait_ref.args.type_at(1),
|
||||||
|
goal.predicate.trait_ref.args.const_at(2),
|
||||||
)?;
|
)?;
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
|
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ```ignore (builtin impl example)
|
/// ```ignore (builtin impl example)
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
|
||||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||||
use rustc_type_ir::relate::Relate;
|
use rustc_type_ir::relate::Relate;
|
||||||
use rustc_type_ir::solve::{NoSolution, SolverMode};
|
use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode};
|
||||||
|
|
||||||
use crate::traits::coherence::trait_ref_is_knowable;
|
use crate::traits::coherence::trait_ref_is_knowable;
|
||||||
use crate::traits::specialization_graph;
|
use crate::traits::specialization_graph;
|
||||||
|
@ -406,4 +406,30 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc
|
||||||
// FIXME: Check for defaultness here may cause diagnostics problems.
|
// FIXME: Check for defaultness here may cause diagnostics problems.
|
||||||
if eligible { Ok(Some(node_item.item.def_id)) } else { Ok(None) }
|
if eligible { Ok(Some(node_item.item.def_id)) } else { Ok(None) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_transmutable(
|
||||||
|
&self,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
dst: Ty<'tcx>,
|
||||||
|
src: Ty<'tcx>,
|
||||||
|
assume: ty::Const<'tcx>,
|
||||||
|
) -> Result<Certainty, NoSolution> {
|
||||||
|
// Erase regions because we compute layouts in `rustc_transmute`,
|
||||||
|
// which will ICE for region vars.
|
||||||
|
let (dst, src) = self.tcx.erase_regions((dst, src));
|
||||||
|
|
||||||
|
let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, param_env, assume) else {
|
||||||
|
return Err(NoSolution);
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
|
||||||
|
match rustc_transmute::TransmuteTypeEnv::new(&self.0).is_transmutable(
|
||||||
|
ObligationCause::dummy(),
|
||||||
|
rustc_transmute::Types { src, dst },
|
||||||
|
assume,
|
||||||
|
) {
|
||||||
|
rustc_transmute::Answer::Yes => Ok(Certainty::Yes),
|
||||||
|
rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,6 +374,8 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
|
||||||
|
|
||||||
fn region_at(self, i: usize) -> I::Region;
|
fn region_at(self, i: usize) -> I::Region;
|
||||||
|
|
||||||
|
fn const_at(self, i: usize) -> I::Const;
|
||||||
|
|
||||||
fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
|
fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
|
||||||
|
|
||||||
fn extend_with_error(
|
fn extend_with_error(
|
||||||
|
|
Loading…
Add table
Reference in a new issue