Consolidate WF for aliases
This commit is contained in:
parent
c2fbe404d2
commit
04524c8f6a
6 changed files with 68 additions and 26 deletions
|
@ -164,7 +164,7 @@ pub fn clause_obligations<'tcx>(
|
||||||
wf.compute(ty.into());
|
wf.compute(ty.into());
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Projection(t) => {
|
ty::ClauseKind::Projection(t) => {
|
||||||
wf.compute_projection(t.projection_ty);
|
wf.compute_alias(t.projection_ty);
|
||||||
wf.compute(match t.term.unpack() {
|
wf.compute(match t.term.unpack() {
|
||||||
ty::TermKind::Ty(ty) => ty.into(),
|
ty::TermKind::Ty(ty) => ty.into(),
|
||||||
ty::TermKind::Const(c) => c.into(),
|
ty::TermKind::Const(c) => c.into(),
|
||||||
|
@ -436,9 +436,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes the obligations required for `trait_ref::Item` to be WF
|
/// Pushes the obligations required for an alias (except inherent) to be WF
|
||||||
/// into `self.out`.
|
/// into `self.out`.
|
||||||
fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) {
|
fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) {
|
||||||
// A projection is well-formed if
|
// A projection is well-formed if
|
||||||
//
|
//
|
||||||
// (a) its predicates hold (*)
|
// (a) its predicates hold (*)
|
||||||
|
@ -466,6 +466,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
self.compute_projection_args(data.args);
|
self.compute_projection_args(data.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pushes the obligations required for an inherent alias to be WF
|
||||||
|
/// into `self.out`.
|
||||||
|
// FIXME(inherent_associated_types): Merge this function with `fn compute_alias`.
|
||||||
fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
|
fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
|
||||||
// An inherent projection is well-formed if
|
// An inherent projection is well-formed if
|
||||||
//
|
//
|
||||||
|
@ -688,8 +691,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||||
// Simple cases that are WF if their type args are WF.
|
// Simple cases that are WF if their type args are WF.
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Alias(ty::Projection, data) => {
|
ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => {
|
||||||
self.compute_projection(data);
|
self.compute_alias(data);
|
||||||
return; // Subtree handled by compute_projection.
|
return; // Subtree handled by compute_projection.
|
||||||
}
|
}
|
||||||
ty::Alias(ty::Inherent, data) => {
|
ty::Alias(ty::Inherent, data) => {
|
||||||
|
@ -791,21 +794,6 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||||
// types appearing in the fn signature.
|
// types appearing in the fn signature.
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
|
||||||
// All of the requirements on type parameters
|
|
||||||
// have already been checked for `impl Trait` in
|
|
||||||
// return position. We do need to check type-alias-impl-trait though.
|
|
||||||
if self.tcx().is_type_alias_impl_trait(def_id) {
|
|
||||||
let obligations = self.nominal_obligations(def_id, args);
|
|
||||||
self.out.extend(obligations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Alias(ty::Weak, ty::AliasTy { def_id, args, .. }) => {
|
|
||||||
let obligations = self.nominal_obligations(def_id, args);
|
|
||||||
self.out.extend(obligations);
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Dynamic(data, r, _) => {
|
ty::Dynamic(data, r, _) => {
|
||||||
// WfObject
|
// WfObject
|
||||||
//
|
//
|
||||||
|
|
|
@ -9,6 +9,7 @@ impl Foo<char> for Bar {
|
||||||
//~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
|
//~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
|
||||||
//~| ERROR: the trait bound `Bar: Foo<u8>` is not satisfied [E0277]
|
//~| ERROR: the trait bound `Bar: Foo<u8>` is not satisfied [E0277]
|
||||||
//~| ERROR: impl has stricter requirements than trait
|
//~| ERROR: impl has stricter requirements than trait
|
||||||
|
//~| ERROR: the trait bound `F2: Foo<u8>` is not satisfied
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,22 @@ note: required by a bound in `Foo::{synthetic#0}`
|
||||||
LL | fn foo<F2>(self) -> impl Foo<T>;
|
LL | fn foo<F2>(self) -> impl Foo<T>;
|
||||||
| ^^^^^^ required by this bound in `Foo::{synthetic#0}`
|
| ^^^^^^ required by this bound in `Foo::{synthetic#0}`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `F2: Foo<u8>` is not satisfied
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:8:34
|
||||||
|
|
|
||||||
|
LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
| ^^^^^^^^^^^^ the trait `Foo<u8>` is not implemented for `F2`
|
||||||
|
|
|
||||||
|
note: required by a bound in `<Bar as Foo<char>>::foo`
|
||||||
|
--> $DIR/return-dont-satisfy-bounds.rs:8:16
|
||||||
|
|
|
||||||
|
LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
| ^^^^^^^ required by this bound in `<Bar as Foo<char>>::foo`
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
LL | fn foo<F2: Foo<u8> + Foo<u8>>(self) -> impl Foo<u8> {
|
||||||
|
| +++++++++
|
||||||
|
|
||||||
error[E0276]: impl has stricter requirements than trait
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/return-dont-satisfy-bounds.rs:8:16
|
--> $DIR/return-dont-satisfy-bounds.rs:8:16
|
||||||
|
|
|
|
||||||
|
@ -32,7 +48,7 @@ LL | self
|
||||||
= help: the trait `Foo<char>` is implemented for `Bar`
|
= help: the trait `Foo<char>` is implemented for `Bar`
|
||||||
= help: for that trait implementation, expected `char`, found `u8`
|
= help: for that trait implementation, expected `char`, found `u8`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0276, E0277.
|
Some errors have detailed explanations: E0276, E0277.
|
||||||
For more information about an error, try `rustc --explain E0276`.
|
For more information about an error, try `rustc --explain E0276`.
|
||||||
|
|
|
@ -7,6 +7,7 @@ async fn wrapper<F>(f: F)
|
||||||
//~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
//~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
|
//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
where
|
where
|
||||||
F:,
|
F:,
|
||||||
for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | / async fn wrapper<F>(f: F)
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | | where
|
... |
|
||||||
LL | | F:,
|
LL | | F:,
|
||||||
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
||||||
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
|
@ -27,7 +27,7 @@ LL | / async fn wrapper<F>(f: F)
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | | where
|
... |
|
||||||
LL | | F:,
|
LL | | F:,
|
||||||
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
||||||
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
|
@ -35,7 +35,22 @@ LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a
|
||||||
= help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
|
= help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
|
||||||
|
|
||||||
error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
--> $DIR/issue-76168-hr-outlives-3.rs:13:1
|
--> $DIR/issue-76168-hr-outlives-3.rs:6:1
|
||||||
|
|
|
||||||
|
LL | / async fn wrapper<F>(f: F)
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
... |
|
||||||
|
LL | | F:,
|
||||||
|
LL | | for<'a> <i32 as FnOnce<(&'a mut i32,)>>::Output: Future<Output = ()> + 'a,
|
||||||
|
| |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
|
|
|
||||||
|
= help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32`
|
||||||
|
--> $DIR/issue-76168-hr-outlives-3.rs:14:1
|
||||||
|
|
|
|
||||||
LL | / {
|
LL | / {
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -46,6 +61,6 @@ LL | | }
|
||||||
|
|
|
|
||||||
= help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
|
= help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -7,6 +7,27 @@ LL | #![feature(non_lifetime_binders)]
|
||||||
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0309]: the placeholder type `!1_"F"` may not live long enough
|
||||||
|
--> $DIR/type-match-with-late-bound.rs:8:1
|
||||||
|
|
|
||||||
|
LL | async fn walk2<'a, T: 'a>(_: T)
|
||||||
|
| ^ -- the placeholder type `!1_"F"` must be valid for the lifetime `'a` as defined here...
|
||||||
|
| _|
|
||||||
|
| |
|
||||||
|
LL | | where
|
||||||
|
LL | | for<F> F: 'a,
|
||||||
|
| |_________________^ ...so that the type `F` will meet its required lifetime bounds...
|
||||||
|
|
|
||||||
|
note: ...that is required by this bound
|
||||||
|
--> $DIR/type-match-with-late-bound.rs:10:15
|
||||||
|
|
|
||||||
|
LL | for<F> F: 'a,
|
||||||
|
| ^^
|
||||||
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
||||||
|
LL | for<F> F: 'a, !1_"F": 'a
|
||||||
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0309]: the placeholder type `!1_"F"` may not live long enough
|
error[E0309]: the placeholder type `!1_"F"` may not live long enough
|
||||||
--> $DIR/type-match-with-late-bound.rs:11:1
|
--> $DIR/type-match-with-late-bound.rs:11:1
|
||||||
|
|
|
|
||||||
|
@ -35,6 +56,6 @@ help: consider adding an explicit lifetime bound
|
||||||
LL | for<F> F: 'a, !2_"F": 'a
|
LL | for<F> F: 'a, !2_"F": 'a
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
error: aborting due to 3 previous errors; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0309`.
|
For more information about this error, try `rustc --explain E0309`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue