diff options
| author | David Wood <david@davidtw.co> | 2020-06-11 22:53:32 +0100 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2020-06-19 10:10:54 +0100 |
| commit | d5b07373cef98dec5672cd94bf14609eec65aa03 (patch) | |
| tree | 695583d2fb9a40679893f2b08dc83557b2a3859c | |
| parent | a39c7787ba246353178e099373b9240be0d9e603 (diff) | |
| download | rust-d5b07373cef98dec5672cd94bf14609eec65aa03.tar.gz rust-d5b07373cef98dec5672cd94bf14609eec65aa03.zip | |
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>
| -rw-r--r-- | src/librustc_middle/ty/mod.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/lint/lint-ctypes-73249-1.rs | 21 | ||||
| -rw-r--r-- | src/test/ui/lint/lint-ctypes-73249.rs | 21 |
3 files changed, 50 insertions, 4 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 93ef7317199..1f94c28b357 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -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); } diff --git a/src/test/ui/lint/lint-ctypes-73249-1.rs b/src/test/ui/lint/lint-ctypes-73249-1.rs new file mode 100644 index 00000000000..cf416c3fe8b --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-73249-1.rs @@ -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() {} diff --git a/src/test/ui/lint/lint-ctypes-73249.rs b/src/test/ui/lint/lint-ctypes-73249.rs new file mode 100644 index 00000000000..5b48fa9b737 --- /dev/null +++ b/src/test/ui/lint/lint-ctypes-73249.rs @@ -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() {} |
