Fix transmute goal

This commit is contained in:
Michael Goulet 2024-09-27 14:24:31 -04:00
parent 38bbcc001e
commit 9453d2cfeb
9 changed files with 236 additions and 117 deletions

View file

@ -295,6 +295,37 @@ where
Ok(ty)
}
}
/// Normalize a const for when it is structurally matched on, or more likely
/// when it needs `.try_to_*` called on it (e.g. to turn it into a usize).
///
/// This function is necessary in nearly all cases before matching on a const.
/// Not doing so is likely to be incomplete and therefore unsound during
/// coherence.
#[instrument(level = "trace", skip(self, param_env), ret)]
fn structurally_normalize_const(
&mut self,
param_env: I::ParamEnv,
ct: I::Const,
) -> Result<I::Const, NoSolution> {
if let ty::ConstKind::Unevaluated(..) = ct.kind() {
let normalized_ct = self.next_const_infer();
let alias_relate_goal = Goal::new(
self.cx(),
param_env,
ty::PredicateKind::AliasRelate(
ct.into(),
normalized_ct.into(),
ty::AliasRelationDirection::Equate,
),
);
self.add_goal(GoalSource::Misc, alias_relate_goal);
self.try_evaluate_added_goals()?;
Ok(self.resolve_vars_if_possible(normalized_ct))
} else {
Ok(ct)
}
}
}
fn response_no_constraints_raw<I: Interner>(

View file

@ -627,11 +627,16 @@ where
}
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let assume = ecx.structurally_normalize_const(
goal.param_env,
goal.predicate.trait_ref.args.const_at(2),
)?;
let certainty = ecx.is_transmutable(
goal.param_env,
goal.predicate.trait_ref.args.type_at(0),
goal.predicate.trait_ref.args.type_at(1),
goal.predicate.trait_ref.args.const_at(2),
assume,
)?;
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
})