Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
match self.get_safe_transmute_error_and_reason(
obligation.clone(),
main_trait_predicate,
root_obligation,
span,
) {
GetSafeTransmuteErrorAndReason::Silent => {
Expand Down Expand Up @@ -2797,6 +2798,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&self,
obligation: PredicateObligation<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
root_obligation: &PredicateObligation<'tcx>,
span: Span,
) -> GetSafeTransmuteErrorAndReason {
use rustc_transmute::Answer;
Expand Down Expand Up @@ -2913,11 +2915,28 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
safe_transmute_explanation: Some(safe_transmute_explanation),
}
}
// Should never get a Yes at this point! We already ran it before, and did not get a Yes.
Answer::Yes => span_bug!(
span,
"Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
),
// The normalized types pass, but the original check failed.
// This can happen when type aliases were normalized for diagnostics.
// Retry with root_obligation's types to get the real error.
Answer::Yes => {
if obligation.predicate != root_obligation.predicate {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(root_pred)) =
root_obligation.predicate.kind().skip_binder()
&& root_pred.def_id() == trait_pred.trait_ref.def_id
Comment on lines +2922 to +2925
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if obligation.predicate != root_obligation.predicate {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(root_pred)) =
root_obligation.predicate.kind().skip_binder()
&& root_pred.def_id() == trait_pred.trait_ref.def_id
if obligation.predicate != root_obligation.predicate
&& let ty::PredicateKind::Clause(ty::ClauseKind::Trait(root_pred)) =
root_obligation.predicate.kind().skip_binder()
&& root_pred.def_id() == trait_pred.trait_ref.def_id

{
return self.get_safe_transmute_error_and_reason(
root_obligation.clone(),
root_obligation.predicate.kind().rebind(root_pred),
root_obligation,
span,
);
}
}
span_bug!(
span,
"Inconsistent rustc_transmute::is_transmutable(...) result, got Yes",
)
}
// Reached when a different obligation (namely `Freeze`) causes the
// transmutability analysis to fail. In this case, silence the
// transmutability error message in favor of that more specific
Expand Down
31 changes: 31 additions & 0 deletions tests/ui/transmutability/type-alias-normalization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//! regression test for https://github.com/rust-lang/rust/issues/151462
//@compile-flags: -Znext-solver=globally
#![feature(lazy_type_alias, transmutability)]
#![allow(incomplete_features)]
mod assert {
use std::mem::{Assume, TransmuteFrom};

pub fn is_maybe_transmutable<Src, Dst>()
where
Src: TransmuteFrom<
Src,
{
Assume {
alignment: true,
lifetimes: true,
safety: true,
validity: true,
}
},
>,
{
}
}

fn test() {
type JustUnit = ();
assert::is_maybe_transmutable::<JustUnit, ()>();
//~^ ERROR `JustUnit` cannot be safely transmuted into `JustUnit`
}

fn main() {}
29 changes: 29 additions & 0 deletions tests/ui/transmutability/type-alias-normalization.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0277]: `JustUnit` cannot be safely transmuted into `JustUnit`
--> $DIR/type-alias-normalization.rs:27:37
|
LL | assert::is_maybe_transmutable::<JustUnit, ()>();
| ^^^^^^^^ analyzing the transmutability of `JustUnit` is not yet supported
|
note: required by a bound in `is_maybe_transmutable`
--> $DIR/type-alias-normalization.rs:10:14
|
LL | pub fn is_maybe_transmutable<Src, Dst>()
| --------------------- required by a bound in this function
LL | where
LL | Src: TransmuteFrom<
| ______________^
LL | | Src,
LL | | {
LL | | Assume {
... |
LL | | },
LL | | >,
| |_________^ required by this bound in `is_maybe_transmutable`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn test() where (): TransmuteFrom<(), Assume { alignment: true, lifetimes: true, safety: true, validity: true }> {
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Loading