Rollup merge of #138174 - compiler-errors:elaborate-unsize-self-pred, r=BoxyUwU
Elaborate trait assumption in `receiver_is_dispatchable` Fixes #138172. See comment on the linked test. Probably not a fix for the general problem, bc I think this may still be incomplete for other weird `where` clauses on the receiver. But 🤷, supertraits seems like an obvious one to fix.
This commit is contained in:
commit
143eb4f03e
5 changed files with 105 additions and 12 deletions
|
@ -24,7 +24,9 @@ use super::elaborate;
|
||||||
use crate::infer::TyCtxtInferExt;
|
use crate::infer::TyCtxtInferExt;
|
||||||
pub use crate::traits::DynCompatibilityViolation;
|
pub use crate::traits::DynCompatibilityViolation;
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use crate::traits::{MethodViolationCode, Obligation, ObligationCause, util};
|
use crate::traits::{
|
||||||
|
MethodViolationCode, Obligation, ObligationCause, normalize_param_env_or_error, util,
|
||||||
|
};
|
||||||
|
|
||||||
/// Returns the dyn-compatibility violations that affect HIR ty lowering.
|
/// Returns the dyn-compatibility violations that affect HIR ty lowering.
|
||||||
///
|
///
|
||||||
|
@ -579,8 +581,8 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
let unsized_receiver_ty =
|
let unsized_receiver_ty =
|
||||||
receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id);
|
receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id);
|
||||||
|
|
||||||
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
|
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
|
||||||
// `U: ?Sized` is already implied here
|
// its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
|
||||||
let param_env = {
|
let param_env = {
|
||||||
let param_env = tcx.param_env(method.def_id);
|
let param_env = tcx.param_env(method.def_id);
|
||||||
|
|
||||||
|
@ -598,10 +600,13 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
|
ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
|
||||||
};
|
};
|
||||||
|
|
||||||
let caller_bounds =
|
normalize_param_env_or_error(
|
||||||
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
tcx,
|
||||||
|
ty::ParamEnv::new(tcx.mk_clauses_from_iter(
|
||||||
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds))
|
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]),
|
||||||
|
)),
|
||||||
|
ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||||
|
|
|
@ -15,6 +15,7 @@ pub trait ThriftService<Bug: NotFoo>:
|
||||||
{
|
{
|
||||||
fn get_service(
|
fn get_service(
|
||||||
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
|
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
|
||||||
|
//~| ERROR the trait bound `Bug: Foo` is not satisfied
|
||||||
&self,
|
&self,
|
||||||
) -> Self::AssocType;
|
) -> Self::AssocType;
|
||||||
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
|
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
|
||||||
|
|
|
@ -32,6 +32,7 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
||||||
|
|
|
|
||||||
LL | / fn get_service(
|
LL | / fn get_service(
|
||||||
LL | |
|
LL | |
|
||||||
|
LL | |
|
||||||
LL | | &self,
|
LL | | &self,
|
||||||
LL | | ) -> Self::AssocType;
|
LL | | ) -> Self::AssocType;
|
||||||
| |_________________________^ the trait `Foo` is not implemented for `Bug`
|
| |_________________________^ the trait `Foo` is not implemented for `Bug`
|
||||||
|
@ -41,8 +42,18 @@ help: consider further restricting type parameter `Bug` with trait `Foo`
|
||||||
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
|
LL | pub trait ThriftService<Bug: NotFoo + Foo>:
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
||||||
|
--> $DIR/issue-59324.rs:16:5
|
||||||
|
|
|
||||||
|
LL | / fn get_service(
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | &self,
|
||||||
|
LL | | ) -> Self::AssocType;
|
||||||
|
| |_________________________^ the trait `Foo` is not implemented for `Bug`
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): Foo` is not satisfied
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
--> $DIR/issue-59324.rs:23:29
|
--> $DIR/issue-59324.rs:24:29
|
||||||
|
|
|
|
||||||
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
@ -54,7 +65,7 @@ LL | pub trait Foo: NotFoo {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
||||||
--> $DIR/issue-59324.rs:19:10
|
--> $DIR/issue-59324.rs:20:10
|
||||||
|
|
|
|
||||||
LL | ) -> Self::AssocType;
|
LL | ) -> Self::AssocType;
|
||||||
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
||||||
|
@ -65,7 +76,7 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): Foo` is not satisfied
|
error[E0277]: the trait bound `(): Foo` is not satisfied
|
||||||
--> $DIR/issue-59324.rs:23:29
|
--> $DIR/issue-59324.rs:24:29
|
||||||
|
|
|
|
||||||
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
|
||||||
|
@ -78,7 +89,7 @@ LL | pub trait Foo: NotFoo {
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/issue-59324.rs:23:29
|
--> $DIR/issue-59324.rs:24:29
|
||||||
|
|
|
|
||||||
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -95,6 +106,6 @@ help: function arguments must have a statically known size, borrowed types alway
|
||||||
LL | fn with_factory<H>(factory: &dyn ThriftService<()>) {}
|
LL | fn with_factory<H>(factory: &dyn ThriftService<()>) {}
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
38
tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs
Normal file
38
tests/ui/self/dyn-dispatch-requires-supertrait-norm.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(derive_coerce_pointee)]
|
||||||
|
#![feature(arbitrary_self_types)]
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::marker::CoercePointee;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
trait MyTrait<T> {}
|
||||||
|
|
||||||
|
#[derive(CoercePointee)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct MyArc<T: ?Sized + MyTrait<u8>>(Arc<T>);
|
||||||
|
|
||||||
|
impl<T: ?Sized + MyTrait<u8>> Deref for MyArc<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Mirror {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
impl<T> Mirror for T {
|
||||||
|
type Assoc = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is variant on "tests/ui/self/dyn-dispatch-requires-supertrait.rs" but with
|
||||||
|
// a supertrait that requires normalization to match the pred in the old solver.
|
||||||
|
trait MyOtherTrait: MyTrait<<u8 as Mirror>::Assoc> {
|
||||||
|
fn foo(self: MyArc<Self>);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(_: MyArc<dyn MyOtherTrait>) {}
|
||||||
|
|
||||||
|
fn main() {}
|
38
tests/ui/self/dyn-dispatch-requires-supertrait.rs
Normal file
38
tests/ui/self/dyn-dispatch-requires-supertrait.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(derive_coerce_pointee)]
|
||||||
|
#![feature(arbitrary_self_types)]
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::marker::CoercePointee;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
trait MyTrait {}
|
||||||
|
|
||||||
|
#[derive(CoercePointee)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct MyArc<T>
|
||||||
|
where
|
||||||
|
T: MyTrait + ?Sized,
|
||||||
|
{
|
||||||
|
inner: Arc<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: MyTrait + ?Sized> Deref for MyArc<T> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proving that `MyArc<Self>` is dyn-dispatchable requires proving `MyArc<T>` implements
|
||||||
|
// `DispatchFromDyn<MyArc<U>>`. The `DispatchFromDyn` impl that is generated from the
|
||||||
|
// `CoercePointee` implementation requires the pointee impls `MyTrait`, but previously we
|
||||||
|
// were only assuming the pointee impl'd `MyOtherTrait`. Elaboration comes to the rescue here.
|
||||||
|
trait MyOtherTrait: MyTrait {
|
||||||
|
fn foo(self: MyArc<Self>);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(_: MyArc<dyn MyOtherTrait>) {}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue