Skip to content

Commit d5b0737

Browse files
committed
ty: projections in transparent_newtype_field
This commit modifies `transparent_newtype_field` so that it handles projections with generic parameters, where `normalize_erasing_regions` would ICE. Signed-off-by: David Wood <[email protected]>
1 parent a39c778 commit d5b0737

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/librustc_middle/ty/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,11 +2387,15 @@ impl<'tcx> AdtDef {
23872387
assert!(self.is_struct() && self.repr.transparent());
23882388

23892389
for field in &self.non_enum_variant().fields {
2390-
let field_ty = tcx.normalize_erasing_regions(
2391-
param_env,
2392-
field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did)),
2393-
);
2390+
let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did));
2391+
2392+
// `normalize_erasing_regions` will fail for projections that contain generic
2393+
// parameters, so check these before normalizing.
2394+
if field_ty.has_projections() && field_ty.needs_subst() {
2395+
return Some(field);
2396+
}
23942397

2398+
let field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
23952399
if !field_ty.is_zst(tcx, self.did) {
23962400
return Some(field);
23972401
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
#![deny(improper_ctypes)]
3+
4+
pub trait Foo {
5+
type Assoc: 'static;
6+
}
7+
8+
impl Foo for () {
9+
type Assoc = u32;
10+
}
11+
12+
extern "C" {
13+
pub fn lint_me(x: Bar<()>);
14+
}
15+
16+
#[repr(transparent)]
17+
pub struct Bar<T: Foo> {
18+
value: &'static <T as Foo>::Assoc,
19+
}
20+
21+
fn main() {}

src/test/ui/lint/lint-ctypes-73249.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
#![deny(improper_ctypes)]
3+
4+
pub trait Foo {
5+
type Assoc;
6+
}
7+
8+
impl Foo for () {
9+
type Assoc = u32;
10+
}
11+
12+
extern "C" {
13+
pub fn lint_me(x: Bar<()>);
14+
}
15+
16+
#[repr(transparent)]
17+
pub struct Bar<T: Foo> {
18+
value: <T as Foo>::Assoc,
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)