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 <david@davidtw.co>
This commit is contained in:
David Wood 2020-06-11 22:53:32 +01:00
parent a39c7787ba
commit d5b07373ce
No known key found for this signature in database
GPG key ID: 2592E76C87381FD9
3 changed files with 50 additions and 4 deletions

View file

@ -2387,11 +2387,15 @@ impl<'tcx> AdtDef {
assert!(self.is_struct() && self.repr.transparent());
for field in &self.non_enum_variant().fields {
let field_ty = tcx.normalize_erasing_regions(
param_env,
field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did)),
);
let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did));
// `normalize_erasing_regions` will fail for projections that contain generic
// parameters, so check these before normalizing.
if field_ty.has_projections() && field_ty.needs_subst() {
return Some(field);
}
let field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
if !field_ty.is_zst(tcx, self.did) {
return Some(field);
}

View file

@ -0,0 +1,21 @@
// check-pass
#![deny(improper_ctypes)]
pub trait Foo {
type Assoc: 'static;
}
impl Foo for () {
type Assoc = u32;
}
extern "C" {
pub fn lint_me(x: Bar<()>);
}
#[repr(transparent)]
pub struct Bar<T: Foo> {
value: &'static <T as Foo>::Assoc,
}
fn main() {}

View file

@ -0,0 +1,21 @@
// check-pass
#![deny(improper_ctypes)]
pub trait Foo {
type Assoc;
}
impl Foo for () {
type Assoc = u32;
}
extern "C" {
pub fn lint_me(x: Bar<()>);
}
#[repr(transparent)]
pub struct Bar<T: Foo> {
value: <T as Foo>::Assoc,
}
fn main() {}