Use resolutions(()).effective_visiblities
to avoid cycle errors
This commit is contained in:
parent
6bc08a725f
commit
6a2bd5acd6
3 changed files with 110 additions and 1 deletions
|
@ -132,7 +132,10 @@ pub fn report_object_safety_error<'tcx>(
|
||||||
};
|
};
|
||||||
let externally_visible = if !impls.is_empty()
|
let externally_visible = if !impls.is_empty()
|
||||||
&& let Some(def_id) = trait_def_id.as_local()
|
&& let Some(def_id) = trait_def_id.as_local()
|
||||||
&& tcx.effective_visibilities(()).is_exported(def_id)
|
// We may be executing this during typeck, which would result in cycle
|
||||||
|
// if we used effective_visibilities query, which looks into opaque types
|
||||||
|
// (and therefore calls typeck).
|
||||||
|
&& tcx.resolutions(()).effective_visibilities.is_exported(def_id)
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
trait Marker {}
|
||||||
|
impl Marker for u32 {}
|
||||||
|
|
||||||
|
trait MyTrait {
|
||||||
|
fn foo(&self) -> impl Marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Outer;
|
||||||
|
|
||||||
|
impl MyTrait for Outer {
|
||||||
|
fn foo(&self) -> impl Marker {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl dyn MyTrait {
|
||||||
|
//~^ ERROR the trait `MyTrait` cannot be made into an object
|
||||||
|
fn other(&self) -> impl Marker {
|
||||||
|
//~^ ERROR the trait `MyTrait` cannot be made into an object
|
||||||
|
MyTrait::foo(&self)
|
||||||
|
//~^ ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
|
//~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
|
//~| ERROR the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
|
//~| ERROR the trait `MyTrait` cannot be made into an object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,78 @@
|
||||||
|
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
|
--> $DIR/cycle-effective-visibilities-during-object-safety.rs:20:22
|
||||||
|
|
|
||||||
|
LL | MyTrait::foo(&self)
|
||||||
|
| ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `MyTrait` is implemented for `Outer`
|
||||||
|
|
||||||
|
error[E0038]: the trait `MyTrait` cannot be made into an object
|
||||||
|
--> $DIR/cycle-effective-visibilities-during-object-safety.rs:20:9
|
||||||
|
|
|
||||||
|
LL | MyTrait::foo(&self)
|
||||||
|
| ^^^^^^^^^^^^ `MyTrait` 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/cycle-effective-visibilities-during-object-safety.rs:5:22
|
||||||
|
|
|
||||||
|
LL | trait MyTrait {
|
||||||
|
| ------- this trait cannot be made into an object...
|
||||||
|
LL | fn foo(&self) -> impl Marker;
|
||||||
|
| ^^^^^^^^^^^ ...because method `foo` references an `impl Trait` type in its return type
|
||||||
|
= help: consider moving `foo` to another trait
|
||||||
|
= help: only type `Outer` implements the trait, consider using it directly instead
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||||
|
--> $DIR/cycle-effective-visibilities-during-object-safety.rs:20: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/cycle-effective-visibilities-during-object-safety.rs:20:9
|
||||||
|
|
|
||||||
|
LL | MyTrait::foo(&self)
|
||||||
|
| ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||||
|
|
|
||||||
|
= help: the trait `MyTrait` is implemented for `Outer`
|
||||||
|
|
||||||
|
error[E0038]: the trait `MyTrait` cannot be made into an object
|
||||||
|
--> $DIR/cycle-effective-visibilities-during-object-safety.rs:16:6
|
||||||
|
|
|
||||||
|
LL | impl dyn MyTrait {
|
||||||
|
| ^^^^^^^^^^^ `MyTrait` 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/cycle-effective-visibilities-during-object-safety.rs:5:22
|
||||||
|
|
|
||||||
|
LL | trait MyTrait {
|
||||||
|
| ------- this trait cannot be made into an object...
|
||||||
|
LL | fn foo(&self) -> impl Marker;
|
||||||
|
| ^^^^^^^^^^^ ...because method `foo` references an `impl Trait` type in its return type
|
||||||
|
= help: consider moving `foo` to another trait
|
||||||
|
= help: only type `Outer` implements the trait, consider using it directly instead
|
||||||
|
|
||||||
|
error[E0038]: the trait `MyTrait` cannot be made into an object
|
||||||
|
--> $DIR/cycle-effective-visibilities-during-object-safety.rs:18:15
|
||||||
|
|
|
||||||
|
LL | fn other(&self) -> impl Marker {
|
||||||
|
| ^^^^ `MyTrait` 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/cycle-effective-visibilities-during-object-safety.rs:5:22
|
||||||
|
|
|
||||||
|
LL | trait MyTrait {
|
||||||
|
| ------- this trait cannot be made into an object...
|
||||||
|
LL | fn foo(&self) -> impl Marker;
|
||||||
|
| ^^^^^^^^^^^ ...because method `foo` references an `impl Trait` type in its return type
|
||||||
|
= help: consider moving `foo` to another trait
|
||||||
|
= help: only type `Outer` implements the trait, consider using it directly instead
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0038, E0277.
|
||||||
|
For more information about an error, try `rustc --explain E0038`.
|
Loading…
Add table
Add a link
Reference in a new issue