diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 70d85796d002..86fdc965e085 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -7,9 +7,9 @@ use rustc_attr as attr; use rustc_errors::{Applicability, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::Visitor; +use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::lang_items::LangItem; -use rustc_hir::{def::Res, ItemKind, Node, PathSegment}; +use rustc_hir::{def::DefKind, def::Res, ItemKind, Node, PathSegment}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_middle::ty::fold::TypeFoldable; @@ -414,7 +414,12 @@ pub(super) fn check_fn<'a, 'tcx>( } fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { + debug!("check_struct(def_id: {:?}, span: {:?})", def_id, span); + let def = tcx.adt_def(def_id); + + check_fields_for_opaque_types(tcx, def, def_id, span); + def.destructor(tcx); // force the destructor to be evaluated check_representable(tcx, span, def_id); @@ -426,8 +431,174 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { check_packed(tcx, span, def); } +fn check_fields_for_opaque_types( + tcx: TyCtxt<'tcx>, + adt_def: &ty::AdtDef, + def_id: LocalDefId, + span: Span, +) { + struct TyAliasFinder<'tcx> { + tcx: TyCtxt<'tcx>, + ty_alias_span: Option, + ty_alias_ident: Option, + field_ty_span: Option, + } + + impl TyAliasFinder<'_> { + fn new(tcx: TyCtxt<'tcx>) -> TyAliasFinder<'_> { + TyAliasFinder { tcx, ty_alias_span: None, ty_alias_ident: None, field_ty_span: None } + } + + fn get_collected_information(&self) -> (Option, Option, Option) { + (self.field_ty_span, self.ty_alias_ident, self.ty_alias_span) + } + } + + impl<'tcx> intravisit::Visitor<'tcx> for TyAliasFinder<'tcx> { + type Map = intravisit::ErasedMap<'tcx>; + + fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { + intravisit::NestedVisitorMap::None + } + + fn visit_ty(&mut self, t: &'tcx hir::Ty<'_>) { + if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = t.kind { + if let Res::Def(DefKind::TyAlias, ty_alias_def_id) = path.res { + let span = path.span; + if let Some(ty_alias_local_id) = ty_alias_def_id.as_local() { + let ty_alias_hir_id = + self.tcx.hir().local_def_id_to_hir_id(ty_alias_local_id); + let node = self.tcx.hir().get(ty_alias_hir_id); + match node { + hir::Node::Item(hir::Item { + ident, kind, span: ty_alias_span, .. + }) => match kind { + hir::ItemKind::TyAlias(_, _) => { + self.ty_alias_span = Some(*ty_alias_span); + self.ty_alias_ident = Some(*ident); + self.field_ty_span = Some(span); + return; + } + _ => bug!("expected an item of kind TyAlias"), + }, + _ => { + self.field_ty_span = Some(span); + return; + } + } + } + } + } + intravisit::walk_ty(self, t); + } + } + + fn find_ty_alias_information( + tcx: TyCtxt<'tcx>, + field_def: &ty::FieldDef, + ) -> (Option, Option, Option, Option) { + let field_def_def_id = field_def.did; + if let Some(field_def_local_id) = field_def_def_id.as_local() { + let field_def_hir_id = tcx.hir().local_def_id_to_hir_id(field_def_local_id); + if let hir::Node::Field(hir::FieldDef { + span: field_def_span, ty: field_def_ty, .. + }) = tcx.hir().get(field_def_hir_id) + { + let mut type_alias_finder = TyAliasFinder::new(tcx); + type_alias_finder.visit_ty(field_def_ty); + + let (field_ty_span, ty_alias_ident, ty_alias_span) = + type_alias_finder.get_collected_information(); + return (Some(*field_def_span), field_ty_span, ty_alias_ident, ty_alias_span); + } + } + (None, None, None, None) + } + + if tcx.features().type_alias_impl_trait { + return; + } + + debug!("check_fields_of_opaque_types(adt_def: {:?}, span: {:?})", adt_def, span); + + let item_type = tcx.type_of(def_id); + let substs = match item_type.kind() { + ty::Adt(_, substs) => substs, + _ => bug!("check_fields_for_opaque_types should only be called on Adts"), + }; + adt_def.all_fields().for_each(|field_def| { + debug!("field_def: {:?}", field_def); + + let field_ty = field_def.ty(tcx, substs); + if field_ty.has_opaque_types() { + use ty::AdtKind::*; + let adt_kind = match adt_def.adt_kind() { + Struct => "struct", + Enum => "enum", + Union => "union", + }; + + let mut diag; + match find_ty_alias_information(tcx, field_def) { + ( + Some(field_def_span), + Some(field_ty_span), + Some(ty_alias_ident), + Some(ty_alias_span), + ) => { + diag = tcx.sess.struct_span_err( + span, + &format!( + "type aliases of `impl Trait` are not allowed as field types in {}s", + adt_kind + ), + ); + let field_def_span_msg = format!( + "this field contains a type alias `{}` of an `impl Trait`", + ty_alias_ident + ); + + let field_ty_span_msg = + "this type is a type alias of an `impl Trait`".to_string(); + + diag.span_label(field_def_span, field_def_span_msg); + diag.span_label(field_ty_span, field_ty_span_msg); + diag.span_label(ty_alias_span, "type alias defined here"); + } + (Some(field_def_span), Some(field_ty_span), None, None) => { + diag = tcx.sess.struct_span_err( + span, + &format!( + "type aliases of `impl Trait` are not allowed as field types in {}s", + adt_kind + ), + ); + + diag.span_label( + field_def_span, + "this field contains a type alias of an `impl trait`", + ); + diag.span_label(field_ty_span, "this type is a type alias of an `impl trait`"); + } + _ => { + diag = tcx.sess.struct_span_err( + span, + &format!( + "type alias impl traits are not allowed as field types in {}s", + adt_kind + ), + ); + } + } + + diag.emit(); + } + }); +} + fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { let def = tcx.adt_def(def_id); + check_fields_for_opaque_types(tcx, def, def_id, span); def.destructor(tcx); // force the destructor to be evaluated check_representable(tcx, span, def_id); check_transparent(tcx, span, def); @@ -1408,6 +1579,7 @@ fn check_enum<'tcx>( def_id: LocalDefId, ) { let def = tcx.adt_def(def_id); + check_fields_for_opaque_types(tcx, def, def_id, sp); def.destructor(tcx); // force the destructor to be evaluated if vs.is_empty() { diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index dfd82a25f4c8..52a4ef14c5ce 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -6,6 +6,7 @@ type Foo = impl Debug; //~^ ERROR could not find defining uses struct Bar(Foo); +//~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs fn define() -> Bar { Bar(42) //~ ERROR mismatched types } diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr index 43fd76ef0ed9..21c7447df587 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-type_alias_impl_trait.rs:10:9 + --> $DIR/feature-gate-type_alias_impl_trait.rs:11:9 | LL | type Foo = impl Debug; | ---------- the expected opaque type @@ -11,7 +11,7 @@ LL | Bar(42) found type `{integer}` error[E0658]: type alias impl trait is not permitted here - --> $DIR/feature-gate-type_alias_impl_trait.rs:16:19 + --> $DIR/feature-gate-type_alias_impl_trait.rs:17:19 | LL | let x = || -> Foo2 { 42 }; | ^^^^ @@ -20,7 +20,7 @@ LL | let x = || -> Foo2 { 42 }; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0308]: mismatched types - --> $DIR/feature-gate-type_alias_impl_trait.rs:23:18 + --> $DIR/feature-gate-type_alias_impl_trait.rs:24:18 | LL | type Foo3 = impl Debug; | ---------- the found opaque type @@ -34,7 +34,7 @@ LL | let y: i32 = x; found opaque type `impl Debug` error[E0308]: mismatched types - --> $DIR/feature-gate-type_alias_impl_trait.rs:26:13 + --> $DIR/feature-gate-type_alias_impl_trait.rs:27:13 | LL | type Foo3 = impl Debug; | ---------- the expected opaque type @@ -46,7 +46,7 @@ LL | define3(42) found type `{integer}` error[E0658]: type alias impl trait is not permitted here - --> $DIR/feature-gate-type_alias_impl_trait.rs:33:12 + --> $DIR/feature-gate-type_alias_impl_trait.rs:34:12 | LL | let y: Foo4 = 42; | ^^^^ @@ -60,19 +60,31 @@ error: could not find defining uses LL | type Foo = impl Debug; | ^^^^^^^^^^ +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/feature-gate-type_alias_impl_trait.rs:8:1 + | +LL | type Foo = impl Debug; + | ---------------------- type alias defined here +... +LL | struct Bar(Foo); + | ^^^^^^^^^^^---^^ + | | + | this field contains a type alias `Foo` of an `impl Trait` + | this type is a type alias of an `impl Trait` + error: could not find defining uses - --> $DIR/feature-gate-type_alias_impl_trait.rs:19:13 + --> $DIR/feature-gate-type_alias_impl_trait.rs:20:13 | LL | type Foo3 = impl Debug; | ^^^^^^^^^^ error: could not find defining uses - --> $DIR/feature-gate-type_alias_impl_trait.rs:29:13 + --> $DIR/feature-gate-type_alias_impl_trait.rs:30:13 | LL | type Foo4 = impl Debug; | ^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/reject-opaque_types-in-fields.rs b/src/test/ui/impl-trait/reject-opaque_types-in-fields.rs new file mode 100644 index 000000000000..9debcc50f59a --- /dev/null +++ b/src/test/ui/impl-trait/reject-opaque_types-in-fields.rs @@ -0,0 +1,45 @@ +#![feature(min_type_alias_impl_trait)] + +type ImplCopy = impl Copy; +//~^ ERROR could not find defining uses + +enum Wrapper { +//~^ ERROR type aliases of `impl Trait` are not allowed as field types in enums + First(ImplCopy), + Second +} + +type X = impl Iterator + Unpin; +//~^ ERROR could not find defining uses + +struct Foo(X); +//~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs + +impl Foo { + fn new(z: Vec) -> Self { + Foo(z.into_iter()) + //~^ ERROR mismatched types + } +} + +struct FooNested(Vec); +//~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs + +struct Bar {a : X} +//~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs + +impl Bar { + fn new(z: Vec) -> Self { + Bar {a: z.into_iter() } + //~^ ERROR mismatched types + } +} + +union MyUnion { + //~^ ERROR type aliases of `impl Trait` are not allowed as field types in unions + a: X, + //~^ ERROR unions may not contain fields that need dropping +} + + +fn main() {} diff --git a/src/test/ui/impl-trait/reject-opaque_types-in-fields.stderr b/src/test/ui/impl-trait/reject-opaque_types-in-fields.stderr new file mode 100644 index 000000000000..61a5b400e24c --- /dev/null +++ b/src/test/ui/impl-trait/reject-opaque_types-in-fields.stderr @@ -0,0 +1,122 @@ +error[E0308]: mismatched types + --> $DIR/reject-opaque_types-in-fields.rs:20:13 + | +LL | type X = impl Iterator + Unpin; + | --------------------------------- the expected opaque type +... +LL | Foo(z.into_iter()) + | ^^^^^^^^^^^^^ expected opaque type, found struct `std::vec::IntoIter` + | + = note: expected opaque type `impl Iterator+Unpin` + found struct `std::vec::IntoIter` + +error[E0308]: mismatched types + --> $DIR/reject-opaque_types-in-fields.rs:33:13 + | +LL | type X = impl Iterator + Unpin; + | --------------------------------- the expected opaque type +... +LL | Bar {a: z.into_iter() } + | ^^^^^^^^^^^^^ expected opaque type, found struct `std::vec::IntoIter` + | + = note: expected opaque type `impl Iterator+Unpin` + found struct `std::vec::IntoIter` + +error: could not find defining uses + --> $DIR/reject-opaque_types-in-fields.rs:3:17 + | +LL | type ImplCopy = impl Copy; + | ^^^^^^^^^ + +error: type aliases of `impl Trait` are not allowed as field types in enums + --> $DIR/reject-opaque_types-in-fields.rs:6:1 + | +LL | type ImplCopy = impl Copy; + | -------------------------- type alias defined here +... +LL | / enum Wrapper { +LL | | +LL | | First(ImplCopy), + | | -------- + | | | + | | this field contains a type alias `ImplCopy` of an `impl Trait` + | | this type is a type alias of an `impl Trait` +LL | | Second +LL | | } + | |_^ + +error: could not find defining uses + --> $DIR/reject-opaque_types-in-fields.rs:12:10 + | +LL | type X = impl Iterator + Unpin; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/reject-opaque_types-in-fields.rs:15:1 + | +LL | type X = impl Iterator + Unpin; + | ------------------------------------------- type alias defined here +... +LL | struct Foo(X); + | ^^^^^^^^^^^-^^ + | | + | this field contains a type alias `X` of an `impl Trait` + | this type is a type alias of an `impl Trait` + +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/reject-opaque_types-in-fields.rs:25:1 + | +LL | type X = impl Iterator + Unpin; + | ------------------------------------------- type alias defined here +... +LL | struct FooNested(Vec); + | ^^^^^^^^^^^^^^^^^------^^ + | | | + | | this type is a type alias of an `impl Trait` + | this field contains a type alias `X` of an `impl Trait` + +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/reject-opaque_types-in-fields.rs:28:1 + | +LL | type X = impl Iterator + Unpin; + | ------------------------------------------- type alias defined here +... +LL | struct Bar {a : X} + | ^^^^^^^^^^^^-----^ + | | | + | | this type is a type alias of an `impl Trait` + | this field contains a type alias `X` of an `impl Trait` + +error: type aliases of `impl Trait` are not allowed as field types in unions + --> $DIR/reject-opaque_types-in-fields.rs:38:1 + | +LL | type X = impl Iterator + Unpin; + | ------------------------------------------- type alias defined here +... +LL | / union MyUnion { +LL | | +LL | | a: X, + | | ---- + | | | | + | | | this type is a type alias of an `impl Trait` + | | this field contains a type alias `X` of an `impl Trait` +LL | | +LL | | } + | |_^ + +error[E0740]: unions may not contain fields that need dropping + --> $DIR/reject-opaque_types-in-fields.rs:40:3 + | +LL | a: X, + | ^^^^ + | +note: `std::mem::ManuallyDrop` can be used to wrap the type + --> $DIR/reject-opaque_types-in-fields.rs:40:3 + | +LL | a: X, + | ^^^^ + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0308, E0740. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/lint/lint-ctypes-73249-3.full_tait.stderr b/src/test/ui/lint/lint-ctypes-73249-3.full_tait.stderr index af0f26a9f43e..0689397a5636 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.full_tait.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-3.full_tait.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: `extern` block uses type `impl Baz`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-3.rs:21:25 + --> $DIR/lint-ctypes-73249-3.rs:22:25 | LL | pub fn lint_me() -> A; | ^ not FFI-safe diff --git a/src/test/ui/lint/lint-ctypes-73249-3.min_tait.stderr b/src/test/ui/lint/lint-ctypes-73249-3.min_tait.stderr index 880581ff05d2..7ab692384b5d 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.min_tait.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-3.min_tait.stderr @@ -1,15 +1,18 @@ -error: `extern` block uses type `impl Baz`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-3.rs:21:25 +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/lint-ctypes-73249-3.rs:16:1 | -LL | pub fn lint_me() -> A; - | ^ not FFI-safe - | -note: the lint level is defined here - --> $DIR/lint-ctypes-73249-3.rs:5:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent +LL | type Qux = impl Baz; + | -------------------- type alias defined here +... +LL | / pub struct A { +LL | | +LL | | x: Qux, + | | ------ + | | | | + | | | this type is a type alias of an `impl Trait` + | | this field contains a type alias `Qux` of an `impl Trait` +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73249-3.rs b/src/test/ui/lint/lint-ctypes-73249-3.rs index 966c7d5ce3cb..1f563d2497d7 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.rs +++ b/src/test/ui/lint/lint-ctypes-73249-3.rs @@ -14,11 +14,13 @@ fn assign() -> Qux { 3 } #[repr(C)] pub struct A { + //[min_tait]~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs x: Qux, } extern "C" { - pub fn lint_me() -> A; //~ ERROR: uses type `impl Baz` + pub fn lint_me() -> A; + //[full_tait]~^ ERROR `extern` block uses type `impl Baz`, which is not FFI-safe } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73249-5.full_tait.stderr b/src/test/ui/lint/lint-ctypes-73249-5.full_tait.stderr index b80084fce068..5125a5e6caf5 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.full_tait.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-5.full_tait.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: `extern` block uses type `impl Baz`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-5.rs:21:25 + --> $DIR/lint-ctypes-73249-5.rs:22:25 | LL | pub fn lint_me() -> A; | ^ not FFI-safe diff --git a/src/test/ui/lint/lint-ctypes-73249-5.min_tait.stderr b/src/test/ui/lint/lint-ctypes-73249-5.min_tait.stderr index f42549d90965..d60a733be126 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.min_tait.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-5.min_tait.stderr @@ -1,15 +1,18 @@ -error: `extern` block uses type `impl Baz`, which is not FFI-safe - --> $DIR/lint-ctypes-73249-5.rs:21:25 +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/lint-ctypes-73249-5.rs:16:1 | -LL | pub fn lint_me() -> A; - | ^ not FFI-safe - | -note: the lint level is defined here - --> $DIR/lint-ctypes-73249-5.rs:5:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent +LL | type Qux = impl Baz; + | -------------------- type alias defined here +... +LL | / pub struct A { +LL | | +LL | | x: Qux, + | | ------ + | | | | + | | | this type is a type alias of an `impl Trait` + | | this field contains a type alias `Qux` of an `impl Trait` +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73249-5.rs b/src/test/ui/lint/lint-ctypes-73249-5.rs index 81979a9b6e69..27bb910d10b9 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.rs +++ b/src/test/ui/lint/lint-ctypes-73249-5.rs @@ -14,11 +14,13 @@ fn assign() -> Qux { 3 } #[repr(transparent)] pub struct A { + //[min_tait]~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs x: Qux, } extern "C" { - pub fn lint_me() -> A; //~ ERROR: uses type `impl Baz` + pub fn lint_me() -> A; + //[full_tait]~^ ERROR `extern` block uses type `impl Baz`, which is not FFI-safe } fn main() {} diff --git a/src/test/ui/mir/issue-75053.full_tait.stderr b/src/test/ui/mir/issue-75053.full_tait.stderr index aff19094b7af..3e0217202845 100644 --- a/src/test/ui/mir/issue-75053.full_tait.stderr +++ b/src/test/ui/mir/issue-75053.full_tait.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error[E0658]: type alias impl trait is not permitted here - --> $DIR/issue-75053.rs:52:15 + --> $DIR/issue-75053.rs:53:15 | LL | let _pos: Phantom1> = Scope::new().my_index(); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/mir/issue-75053.in_bindings.stderr b/src/test/ui/mir/issue-75053.in_bindings.stderr index a43fabc8f5d9..b4984e2c953b 100644 --- a/src/test/ui/mir/issue-75053.in_bindings.stderr +++ b/src/test/ui/mir/issue-75053.in_bindings.stderr @@ -8,7 +8,7 @@ LL | #![cfg_attr(in_bindings, feature(impl_trait_in_bindings))] = note: see issue #63065 for more information error[E0282]: type annotations needed - --> $DIR/issue-75053.rs:52:38 + --> $DIR/issue-75053.rs:53:38 | LL | type O; | ------- `>::O` defined here @@ -19,6 +19,18 @@ LL | let _pos: Phantom1> = Scope::new().my_index(); | this method call resolves to `>::O` | cannot infer type for type parameter `T` -error: aborting due to previous error; 1 warning emitted +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/issue-75053.rs:28:1 + | +LL | type DummyT = impl F; + | ------------------------ type alias defined here +... +LL | struct Scope(Phantom2>); + | ^^^^^^^^^^^^^^^^-------------------^^ + | | | + | | this type is a type alias of an `impl Trait` + | this field contains a type alias `DummyT` of an `impl Trait` + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/mir/issue-75053.min_tait.stderr b/src/test/ui/mir/issue-75053.min_tait.stderr index 7ce91e851a75..158c9f9bfa0b 100644 --- a/src/test/ui/mir/issue-75053.min_tait.stderr +++ b/src/test/ui/mir/issue-75053.min_tait.stderr @@ -1,5 +1,5 @@ error[E0658]: type alias impl trait is not permitted here - --> $DIR/issue-75053.rs:52:15 + --> $DIR/issue-75053.rs:53:15 | LL | let _pos: Phantom1> = Scope::new().my_index(); | ^^^^^^^^^^^^^^^^^^^^ @@ -7,6 +7,18 @@ LL | let _pos: Phantom1> = Scope::new().my_index(); = note: see issue #63065 for more information = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable -error: aborting due to previous error +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/issue-75053.rs:28:1 + | +LL | type DummyT = impl F; + | ------------------------ type alias defined here +... +LL | struct Scope(Phantom2>); + | ^^^^^^^^^^^^^^^^-------------------^^ + | | | + | | this type is a type alias of an `impl Trait` + | this field contains a type alias `DummyT` of an `impl Trait` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/mir/issue-75053.rs b/src/test/ui/mir/issue-75053.rs index 89ae3ca3006b..b45e915723f2 100644 --- a/src/test/ui/mir/issue-75053.rs +++ b/src/test/ui/mir/issue-75053.rs @@ -26,6 +26,7 @@ fn _dummy_t() -> DummyT {} struct Phantom1(PhantomData); struct Phantom2(PhantomData); struct Scope(Phantom2>); +//[min_tait,in_bindings]~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs impl Scope { fn new() -> Self { diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs index c30608176aad..c8c7429b2fc0 100644 --- a/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs @@ -1,9 +1,9 @@ // aux-build:cross_crate_ice.rs -// build-pass (FIXME(62277): could be check-pass?) extern crate cross_crate_ice; struct Bar(cross_crate_ice::Foo); +//~^ type alias impl traits are not allowed as field types in structs impl Bar { fn zero(&self) -> &cross_crate_ice::Foo { diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice.stderr b/src/test/ui/type-alias-impl-trait/cross_crate_ice.stderr new file mode 100644 index 000000000000..13fb6273974d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice.stderr @@ -0,0 +1,8 @@ +error: type alias impl traits are not allowed as field types in structs + --> $DIR/cross_crate_ice.rs:5:1 + | +LL | struct Bar(cross_crate_ice::Foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.full_tait.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.full_tait.stderr index 1a351867bff2..6d5587c29b1e 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/type-alias-impl-trait-tuple.rs:5:32 + --> $DIR/type-alias-impl-trait-tuple.rs:4:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.min_tait.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.min_tait.stderr new file mode 100644 index 000000000000..96d2783f2a1d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.min_tait.stderr @@ -0,0 +1,19 @@ +error: type aliases of `impl Trait` are not allowed as field types in structs + --> $DIR/type-alias-impl-trait-tuple.rs:12:1 + | +LL | / struct Blah { +LL | | +LL | | my_foo: Foo, + | | ----------- + | | | | + | | | this type is a type alias of an `impl Trait` + | | this field contains a type alias `Foo` of an `impl Trait` +LL | | my_u8: u8 +LL | | } + | |_^ +... +LL | type Foo = impl MyTrait; + | ------------------------ type alias defined here + +error: aborting due to previous error + diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs index ad2c11d4f994..09944542d584 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -1,6 +1,5 @@ -// check-pass - // revisions: min_tait full_tait +//[full_tait] check-pass #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] //[full_tait]~^ WARN incomplete @@ -11,6 +10,7 @@ pub trait MyTrait {} impl MyTrait for bool {} struct Blah { + //[min_tait]~^ ERROR type aliases of `impl Trait` are not allowed as field types in structs my_foo: Foo, my_u8: u8 }