From 8b9344acc3cc7f63ce2294c1482d7e386e812b6e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 8 Mar 2023 13:07:20 -0300 Subject: [PATCH] Fix object safety checks for new RPITITs --- .../src/traits/object_safety.rs | 5 +- ...ty.stderr => object-safety.current.stderr} | 36 ++++++------- .../in-trait/object-safety.next.stderr | 50 +++++++++++++++++++ tests/ui/impl-trait/in-trait/object-safety.rs | 3 ++ 4 files changed, 73 insertions(+), 21 deletions(-) rename tests/ui/impl-trait/in-trait/{object-safety.stderr => object-safety.current.stderr} (93%) create mode 100644 tests/ui/impl-trait/in-trait/object-safety.next.stderr diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4b06304f402..a5def4151bf 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,6 @@ use super::{elaborate_predicates, elaborate_trait_ref}; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use hir::def::DefKind; use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -855,7 +854,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable>>( } } ty::Alias(ty::Projection, ref data) - if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder => + if self.tcx.is_impl_trait_in_trait(data.def_id) => { // We'll deny these later in their own pass ControlFlow::Continue(()) @@ -922,7 +921,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>( ty.skip_binder().walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Alias(ty::Projection, proj) = ty.kind() - && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder + && tcx.is_impl_trait_in_trait(proj.def_id) { Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id))) } else { diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr similarity index 93% rename from tests/ui/impl-trait/in-trait/object-safety.stderr rename to tests/ui/impl-trait/in-trait/object-safety.current.stderr index ca0e760ff6d..b7f2b019a77 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr @@ -1,11 +1,26 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:33 + --> $DIR/object-safety.rs:20:33 | LL | let i = Box::new(42_u32) as Box; | ^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:23:13 + | +LL | let s = i.baz(); + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 | LL | trait Foo { | --- this trait cannot be made into an object... @@ -16,26 +31,11 @@ LL | fn baz(&self) -> impl Debug; error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety.rs:20:13 | -LL | let s = i.baz(); - | ^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:17:13 - | LL | let i = Box::new(42_u32) as Box; | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:7:22 + --> $DIR/object-safety.rs:10:22 | LL | trait Foo { | --- this trait cannot be made into an object... diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr new file mode 100644 index 00000000000..b7f2b019a77 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr @@ -0,0 +1,50 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:33 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:23:13 + | +LL | let s = i.baz(); + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:13 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:10:22 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + = note: required for `Box` to implement `CoerceUnsized>` + = note: required by cast to type `Box` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs index dd35b9a2d8a..016a0aaae4b 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.rs +++ b/tests/ui/impl-trait/in-trait/object-safety.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)]