Skip to content

Commit

Permalink
Rollup merge of rust-lang#108909 - spastorino:new-rpitit-7, r=compile…
Browse files Browse the repository at this point in the history
…r-errors

Fix object safety checks for new RPITITs

This one goes on top of rust-lang#108869

r? `@compiler-errors`
  • Loading branch information
matthiaskrgr authored Mar 14, 2023
2 parents 5037836 + 8b9344a commit 48934c4
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 15 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,6 +1440,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.associated_items(pred.def_id())
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
.map(|item| item.def_id),
);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -157,6 +156,7 @@ fn object_safety_violations_for_trait(
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
.filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
.map(|item| {
let ident = item.ident(tcx);
ObjectSafetyViolation::GAT(ident.name, ident.span)
Expand Down Expand Up @@ -854,7 +854,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
}
}
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(())
Expand Down Expand Up @@ -921,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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/object-safety.rs:3:12
--> $DIR/object-safety.rs:5:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
Expand All @@ -8,13 +8,13 @@ LL | #![feature(async_fn_in_trait)]
= note: `#[warn(incomplete_features)]` on by default

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:11:12
--> $DIR/object-safety.rs:13:12
|
LL | let x: &dyn Foo = todo!();
| ^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:14
--> $DIR/object-safety.rs:9:14
|
LL | trait Foo {
| --- this trait cannot be made into an object...
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/async-await/in-trait/object-safety.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/object-safety.rs:5:12
|
LL | #![feature(async_fn_in_trait)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:13:12
|
LL | let x: &dyn Foo = todo!();
| ^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:9:14
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | async fn foo(&self);
| ^^^ ...because method `foo` is `async`
= help: consider moving `foo` to another trait

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0038`.
2 changes: 2 additions & 0 deletions tests/ui/async-await/in-trait/object-safety.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// edition:2021
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
// revisions: current next

#![feature(async_fn_in_trait)]
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:23:22
--> $DIR/issue-102140.rs:26:22
|
LL | MyTrait::foo(&self)
| ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
Expand All @@ -13,15 +13,15 @@ LL + MyTrait::foo(self)
|

error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:23:9
--> $DIR/issue-102140.rs:26:9
|
LL | MyTrait::foo(&self)
| ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
= help: the trait `MyTrait` is implemented for `Outer`

error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:23:9
--> $DIR/issue-102140.rs:26:9
|
LL | MyTrait::foo(&self)
| ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/impl-trait/in-trait/issue-102140.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:26:22
|
LL | MyTrait::foo(&self)
| ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
| |
| required by a bound introduced by this call
|
help: consider removing the leading `&`-reference
|
LL - MyTrait::foo(&self)
LL + MyTrait::foo(self)
|

error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:26:9
|
LL | MyTrait::foo(&self)
| ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
= help: the trait `MyTrait` is implemented for `Outer`

error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:26:9
|
LL | MyTrait::foo(&self)
| ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
= help: the trait `MyTrait` is implemented for `Outer`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
3 changes: 3 additions & 0 deletions tests/ui/impl-trait/in-trait/issue-102140.rs
Original file line number Diff line number Diff line change
@@ -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)]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
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<dyn Foo>;
| ^^^^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:22
--> $DIR/object-safety.rs:10:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
Expand All @@ -14,13 +14,13 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:20:13
--> $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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:22
--> $DIR/object-safety.rs:10:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
Expand All @@ -29,13 +29,13 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait

error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:17:13
--> $DIR/object-safety.rs:20:13
|
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety.rs:7:22
--> $DIR/object-safety.rs:10:22
|
LL | trait Foo {
| --- this trait cannot be made into an object...
Expand Down
50 changes: 50 additions & 0 deletions tests/ui/impl-trait/in-trait/object-safety.next.stderr
Original file line number Diff line number Diff line change
@@ -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<dyn Foo>;
| ^^^^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $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<dyn Foo>;
| ^^^^^^^^^^^^^^^^ `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 <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $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<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
= note: required by cast to type `Box<dyn Foo>`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0038`.
3 changes: 3 additions & 0 deletions tests/ui/impl-trait/in-trait/object-safety.rs
Original file line number Diff line number Diff line change
@@ -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)]

Expand Down

0 comments on commit 48934c4

Please sign in to comment.