Skip to content

Commit 717f97c

Browse files
committed
Turn eager normalization errors to delayed errors
When normalizing `union`s with fields coming from associated types that don't satisfy trait bounds, avoid ICEing by using `delay_span_bug()` instead of `bug!()`. Fix #81199.
1 parent 958d788 commit 717f97c

9 files changed

+150
-2
lines changed

compiler/rustc_passes/src/stability.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,13 @@ impl Visitor<'tcx> for Checker<'tcx> {
835835
let ty = self.tcx.type_of(item.def_id);
836836
let (adt_def, substs) = match ty.kind() {
837837
ty::Adt(adt_def, substs) => (adt_def, substs),
838-
_ => bug!(),
838+
_ => {
839+
self.tcx.sess.delay_span_bug(
840+
item.span,
841+
&format!("unexpected type kind {:?} (`{:?}`)", ty, ty.kind()),
842+
);
843+
return;
844+
}
839845
};
840846

841847
// Non-`Copy` fields are unstable, except for `ManuallyDrop`.

compiler/rustc_traits/src/normalize_erasing_regions.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_infer::infer::TyCtxtInferExt;
22
use rustc_middle::traits::query::NoSolution;
33
use rustc_middle::ty::query::Providers;
44
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable};
5+
use rustc_span::DUMMY_SP;
56
use rustc_trait_selection::traits::query::normalize::AtExt;
67
use rustc_trait_selection::traits::{Normalized, ObligationCause};
78
use std::sync::atomic::Ordering;
@@ -51,7 +52,13 @@ fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Cop
5152
debug_assert!(!erased.needs_infer(), "{:?}", erased);
5253
erased
5354
}
54-
Err(NoSolution) => bug!("could not fully normalize `{:?}`", value),
55+
Err(NoSolution) => {
56+
infcx
57+
.tcx
58+
.sess
59+
.delay_span_bug(DUMMY_SP, &format!("could not fully normalize `{:?}`", value));
60+
value
61+
}
5562
}
5663
})
5764
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-rustfix
2+
#[allow(dead_code)]
3+
#[repr(C)]
4+
union PtrRepr<T: ?Sized + Pointee> {
5+
const_ptr: *const T,
6+
mut_ptr: *mut T,
7+
components: std::mem::ManuallyDrop<PtrComponents<T>>,
8+
//~^ ERROR the trait bound `T: Pointee` is not satisfied
9+
}
10+
11+
#[repr(C)]
12+
struct PtrComponents<T: Pointee + ?Sized> {
13+
data_address: *const (),
14+
metadata: <T as Pointee>::Metadata,
15+
}
16+
17+
pub trait Pointee {
18+
type Metadata;
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-rustfix
2+
#[allow(dead_code)]
3+
#[repr(C)]
4+
union PtrRepr<T: ?Sized> {
5+
const_ptr: *const T,
6+
mut_ptr: *mut T,
7+
components: std::mem::ManuallyDrop<PtrComponents<T>>,
8+
//~^ ERROR the trait bound `T: Pointee` is not satisfied
9+
}
10+
11+
#[repr(C)]
12+
struct PtrComponents<T: Pointee + ?Sized> {
13+
data_address: *const (),
14+
metadata: <T as Pointee>::Metadata,
15+
}
16+
17+
pub trait Pointee {
18+
type Metadata;
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0277]: the trait bound `T: Pointee` is not satisfied
2+
--> $DIR/normalization-failure-issue-81199-autofix.rs:7:40
3+
|
4+
LL | components: std::mem::ManuallyDrop<PtrComponents<T>>,
5+
| ^^^^^^^^^^^^^^^^ the trait `Pointee` is not implemented for `T`
6+
|
7+
note: required by a bound in `PtrComponents`
8+
--> $DIR/normalization-failure-issue-81199-autofix.rs:12:25
9+
|
10+
LL | struct PtrComponents<T: Pointee + ?Sized> {
11+
| ^^^^^^^ required by this bound in `PtrComponents`
12+
help: consider further restricting this bound
13+
|
14+
LL | union PtrRepr<T: ?Sized + Pointee> {
15+
| +++++++++
16+
17+
error: aborting due to previous error
18+
19+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
union PtrRepr<T: ?Sized> {
2+
const_ptr: *const T,
3+
mut_ptr: *mut T,
4+
components: <T as Pointee>::Metadata
5+
//~^ ERROR the trait bound `T: Pointee` is not satisfied
6+
}
7+
8+
pub trait Pointee {
9+
type Metadata;
10+
}
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0277]: the trait bound `T: Pointee` is not satisfied
2+
--> $DIR/normalization-failure-issue-81199-min.rs:4:17
3+
|
4+
LL | components: <T as Pointee>::Metadata
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pointee` is not implemented for `T`
6+
|
7+
help: consider further restricting this bound
8+
|
9+
LL | union PtrRepr<T: ?Sized + Pointee> {
10+
| +++++++++
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#[repr(C)]
2+
union PtrRepr<T: ?Sized> {
3+
const_ptr: *const T,
4+
mut_ptr: *mut T,
5+
components: PtrComponents<T>,
6+
//~^ ERROR the trait bound `T: Pointee` is not satisfied in `PtrComponents<T>`
7+
}
8+
9+
#[repr(C)]
10+
struct PtrComponents<T: Pointee + ?Sized> {
11+
data_address: *const (),
12+
metadata: <T as Pointee>::Metadata,
13+
}
14+
15+
pub trait Pointee {
16+
type Metadata;
17+
}
18+
19+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0277]: the trait bound `T: Pointee` is not satisfied in `PtrComponents<T>`
2+
--> $DIR/normalization-failure-issue-81199.rs:5:17
3+
|
4+
LL | components: PtrComponents<T>,
5+
| ^^^^^^^^^^^^^^^^ within `PtrComponents<T>`, the trait `Pointee` is not implemented for `T`
6+
|
7+
note: required because it appears within the type `PtrComponents<T>`
8+
--> $DIR/normalization-failure-issue-81199.rs:10:8
9+
|
10+
LL | struct PtrComponents<T: Pointee + ?Sized> {
11+
| ^^^^^^^^^^^^^
12+
= note: no field of a union may have a dynamically sized type
13+
= help: change the field's type to have a statically known size
14+
help: consider further restricting this bound
15+
|
16+
LL | union PtrRepr<T: ?Sized + Pointee> {
17+
| +++++++++
18+
help: borrowed types always have a statically known size
19+
|
20+
LL | components: &PtrComponents<T>,
21+
| +
22+
help: the `Box` type always has a statically known size and allocates its contents in the heap
23+
|
24+
LL | components: Box<PtrComponents<T>>,
25+
| ++++ +
26+
27+
error: aborting due to previous error
28+
29+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)