Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 641a43d

Browse files
committedJul 26, 2023
Safe Transmute: Return ambiguity instead of an error, when necessary
This patch updates a couple spots in the trait selection (in both solvers) to return ambiguity instead of an error.
1 parent 98ddc0f commit 641a43d

File tree

8 files changed

+32
-21
lines changed

8 files changed

+32
-21
lines changed
 

‎compiler/rustc_trait_selection/src/solve/trait_goals.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
602602
let maybe_assume =
603603
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(3));
604604
let assume = match maybe_assume {
605-
Some(Ok(assume)) => assume,
606-
Some(Err(_guar)) => return Err(NoSolution),
607-
None => return Err(NoSolution),
605+
Ok(Some(assume)) => assume,
606+
Ok(None) => {
607+
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
608+
}
609+
Err(_guar) => return Err(NoSolution),
608610
};
609611

610612
let certainty = ecx.is_transmutable(

‎compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,9 +2897,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
28972897
);
28982898

28992899
let assume = match maybe_assume {
2900-
Some(Ok(assume)) => assume,
2901-
Some(Err(guar)) => return GetSafeTransmuteErrorAndReason::ErrorGuaranteed(guar),
2902-
None => return GetSafeTransmuteErrorAndReason::Ambiguous,
2900+
Ok(Some(assume)) => assume,
2901+
Ok(None) => return GetSafeTransmuteErrorAndReason::Ambiguous,
2902+
Err(guar) => return GetSafeTransmuteErrorAndReason::ErrorGuaranteed(guar),
29032903
};
29042904

29052905
match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
@@ -2945,7 +2945,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
29452945
format!("`{src}` is a shared reference, but `{dst}` is a unique reference")
29462946
}
29472947
// Already reported by rustc
2948-
rustc_transmute::Reason::TypeError(guar) => {
2948+
rustc_transmute::Reason::ErrorGuaranteed(guar) => {
29492949
return GetSafeTransmuteErrorAndReason::ErrorGuaranteed(guar);
29502950
}
29512951
rustc_transmute::Reason::SrcLayoutUnknown => {

‎compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
340340
let predicate =
341341
self.tcx().erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate));
342342

343-
let Some(Ok(assume)) = rustc_transmute::Assume::from_const(
343+
let assume = match rustc_transmute::Assume::from_const(
344344
self.infcx.tcx,
345345
obligation.param_env,
346346
predicate.trait_ref.args.const_at(3),
347-
) else {
348-
return Err(Unimplemented);
347+
) {
348+
Ok(Some(assume)) => assume,
349+
Ok(None) => return Ok(vec![]),
350+
Err(_guar) => return Err(Unimplemented),
349351
};
350352

351353
let dst = predicate.trait_ref.args.type_at(0);

‎compiler/rustc_transmute/src/lib.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub enum Reason {
5959
/// Can't go from shared pointer to unique pointer
6060
DstIsMoreUnique,
6161
/// Encountered a type error
62-
TypeError(ErrorGuaranteed),
62+
ErrorGuaranteed(ErrorGuaranteed),
6363
/// The layout of src is unknown
6464
SrcLayoutUnknown,
6565
/// The layout of dst is unknown
@@ -124,17 +124,20 @@ mod rustc {
124124
tcx: TyCtxt<'tcx>,
125125
param_env: ParamEnv<'tcx>,
126126
c: Const<'tcx>,
127-
) -> Option<Result<Self, ErrorGuaranteed>> {
127+
) -> Result<Option<Self>, ErrorGuaranteed> {
128128
use rustc_middle::ty::ScalarInt;
129129
use rustc_middle::ty::TypeVisitableExt;
130130
use rustc_span::symbol::sym;
131131

132132
let c = c.eval(tcx, param_env);
133133
if let Err(err) = c.error_reported() {
134-
return Some(Err(err));
134+
return Err(err);
135135
}
136136

137-
let adt_def = c.ty().ty_adt_def()?;
137+
let adt_def = match c.ty().ty_adt_def() {
138+
Some(adt_def) => adt_def,
139+
None => return Ok(None),
140+
};
138141

139142
assert_eq!(
140143
tcx.require_lang_item(LangItem::TransmuteOpts, None),
@@ -146,7 +149,7 @@ mod rustc {
146149
let variant = adt_def.non_enum_variant();
147150
let fields = match c.try_to_valtree() {
148151
Some(ValTree::Branch(branch)) => branch,
149-
_ => return None,
152+
_ => return Ok(None),
150153
};
151154

152155
let get_field = |name| {
@@ -159,7 +162,7 @@ mod rustc {
159162
fields[field_idx].unwrap_leaf() == ScalarInt::TRUE
160163
};
161164

162-
Some(Ok(Self {
165+
Ok(Some(Self {
163166
alignment: get_field(sym::alignment),
164167
lifetimes: get_field(sym::lifetimes),
165168
safety: get_field(sym::safety),
@@ -169,6 +172,9 @@ mod rustc {
169172
}
170173
}
171174

175+
// FIXME(bryangarza): This prevents `cargo build` from building.
176+
// Need to remove this dependency on `ErrorGuaranteed` so the crate can
177+
// build/test independently of rustc again.
172178
#[cfg(feature = "rustc")]
173179
pub use rustc::*;
174180
use rustc_span::ErrorGuaranteed;

‎compiler/rustc_transmute/src/maybe_transmutable/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ mod rustc {
7979

8080
match (src, dst) {
8181
(Err(Err::TypeError(guar)), _) | (_, Err(Err::TypeError(guar))) => {
82-
Answer::No(Reason::TypeError(guar))
82+
Answer::No(Reason::ErrorGuaranteed(guar))
8383
}
8484
(Err(Err::UnknownLayout), _) => Answer::No(Reason::SrcLayoutUnknown),
8585
(_, Err(Err::UnknownLayout)) => Answer::No(Reason::DstLayoutUnknown),

‎tests/ui/transmutability/issue-110969.current.stderr renamed to ‎tests/ui/transmutability/inconsistent-is-transmutable.current.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0308]: mismatched types
2-
--> $DIR/issue-110969.rs:26:74
2+
--> $DIR/inconsistent-is-transmutable.rs:27:74
33
|
44
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
55
| ^^ expected `Assume`, found `()`
66

77
error[E0308]: mismatched types
8-
--> $DIR/issue-110969.rs:26:29
8+
--> $DIR/inconsistent-is-transmutable.rs:27:29
99
|
1010
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`

‎tests/ui/transmutability/issue-110969.next.stderr renamed to ‎tests/ui/transmutability/inconsistent-is-transmutable.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0308]: mismatched types
2-
--> $DIR/issue-110969.rs:26:74
2+
--> $DIR/inconsistent-is-transmutable.rs:27:74
33
|
44
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
55
| ^^ expected `Assume`, found `()`
66

77
error[E0308]: mismatched types
8-
--> $DIR/issue-110969.rs:26:29
8+
--> $DIR/inconsistent-is-transmutable.rs:27:29
99
|
1010
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`

‎tests/ui/transmutability/issue-110969.rs renamed to ‎tests/ui/transmutability/inconsistent-is-transmutable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// check-fail
22
// revisions: current next
33
//[next] compile-flags: -Ztrait-solver=next
4+
// https://github.com/rust-lang/rust/issues/110969
45
#![feature(adt_const_params, generic_const_exprs, transmutability)]
56
#![allow(incomplete_features)]
67

0 commit comments

Comments
 (0)
Please sign in to comment.