stabilize member constraints
This commit is contained in:
parent
1969c2e312
commit
128d385e56
@ -285,6 +285,8 @@ declare_features! (
|
||||
(accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
|
||||
/// Allows unsizing coercions in `const fn`.
|
||||
(accepted, const_fn_unsize, "1.54.0", Some(64992), None),
|
||||
/// Allows `impl Trait` with multiple unrelated lifetimes.
|
||||
(accepted, member_constraints, "1.54.0", Some(61997), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: accepted features
|
||||
|
@ -472,9 +472,6 @@ declare_features! (
|
||||
/// Allows explicit discriminants on non-unit enum variants.
|
||||
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
|
||||
|
||||
/// Allows `impl Trait` with multiple unrelated lifetimes.
|
||||
(active, member_constraints, "1.37.0", Some(61997), None),
|
||||
|
||||
/// Allows `async || body` closures.
|
||||
(active, async_closure, "1.37.0", Some(62290), None),
|
||||
|
||||
|
@ -140,15 +140,6 @@ pub trait InferCtxtExt<'tcx> {
|
||||
first_own_region_index: usize,
|
||||
);
|
||||
|
||||
/*private*/
|
||||
fn member_constraint_feature_gate(
|
||||
&self,
|
||||
opaque_defn: &OpaqueTypeDecl<'tcx>,
|
||||
opaque_type_def_id: DefId,
|
||||
conflict1: ty::Region<'tcx>,
|
||||
conflict2: ty::Region<'tcx>,
|
||||
) -> bool;
|
||||
|
||||
fn infer_opaque_definition_from_instantiation(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
@ -490,9 +481,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
// ['a, 'b, 'c]`, where `'a..'c` are the
|
||||
// regions that appear in the impl trait.
|
||||
|
||||
// For now, enforce a feature gate outside of async functions.
|
||||
self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_region);
|
||||
|
||||
return self.generate_member_constraint(
|
||||
concrete_ty,
|
||||
opaque_defn,
|
||||
@ -559,60 +547,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
/// Member constraints are presently feature-gated except for
|
||||
/// async-await. We expect to lift this once we've had a bit more
|
||||
/// time.
|
||||
fn member_constraint_feature_gate(
|
||||
&self,
|
||||
opaque_defn: &OpaqueTypeDecl<'tcx>,
|
||||
opaque_type_def_id: DefId,
|
||||
conflict1: ty::Region<'tcx>,
|
||||
conflict2: ty::Region<'tcx>,
|
||||
) -> bool {
|
||||
// If we have `#![feature(member_constraints)]`, no problems.
|
||||
if self.tcx.features().member_constraints {
|
||||
return false;
|
||||
}
|
||||
|
||||
let span = self.tcx.def_span(opaque_type_def_id);
|
||||
|
||||
// Without a feature-gate, we only generate member-constraints for async-await.
|
||||
let context_name = match opaque_defn.origin {
|
||||
// No feature-gate required for `async fn`.
|
||||
hir::OpaqueTyOrigin::AsyncFn => return false,
|
||||
|
||||
// Otherwise, generate the label we'll use in the error message.
|
||||
hir::OpaqueTyOrigin::Binding
|
||||
| hir::OpaqueTyOrigin::FnReturn
|
||||
| hir::OpaqueTyOrigin::TyAlias
|
||||
| hir::OpaqueTyOrigin::Misc => "impl Trait",
|
||||
};
|
||||
let msg = format!("ambiguous lifetime bound in `{}`", context_name);
|
||||
let mut err = self.tcx.sess.struct_span_err(span, &msg);
|
||||
|
||||
let conflict1_name = conflict1.to_string();
|
||||
let conflict2_name = conflict2.to_string();
|
||||
let label_owned;
|
||||
let label = match (&*conflict1_name, &*conflict2_name) {
|
||||
("'_", "'_") => "the elided lifetimes here do not outlive one another",
|
||||
_ => {
|
||||
label_owned = format!(
|
||||
"neither `{}` nor `{}` outlives the other",
|
||||
conflict1_name, conflict2_name,
|
||||
);
|
||||
&label_owned
|
||||
}
|
||||
};
|
||||
err.span_label(span, label);
|
||||
|
||||
if self.tcx.sess.is_nightly_build() {
|
||||
err.help("add #![feature(member_constraints)] to the crate attributes to enable");
|
||||
}
|
||||
|
||||
err.emit();
|
||||
true
|
||||
}
|
||||
|
||||
/// Given the fully resolved, instantiated type for an opaque
|
||||
/// type, i.e., the value of an inference variable like C1 or C2
|
||||
/// (*), computes the "definition type" for an opaque type
|
||||
|
@ -1,29 +0,0 @@
|
||||
# `member_constraints`
|
||||
|
||||
The tracking issue for this feature is: [#61997]
|
||||
|
||||
[#61997]: https://github.com/rust-lang/rust/issues/61997
|
||||
|
||||
------------------------
|
||||
|
||||
The `member_constraints` feature gate lets you use `impl Trait` syntax with
|
||||
multiple unrelated lifetime parameters.
|
||||
|
||||
A simple example is:
|
||||
|
||||
```rust
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
|
||||
(x, y)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
```
|
||||
|
||||
Without the `member_constraints` feature gate, the above example is an
|
||||
error because both `'a` and `'b` appear in the impl Trait bounds, but
|
||||
neither outlives the other.
|
@ -1,10 +1,9 @@
|
||||
// edition:2018
|
||||
// run-pass
|
||||
|
||||
// Test that a feature gate is needed to use `impl Trait` as the
|
||||
// return type of an async.
|
||||
|
||||
#![feature(member_constraints)]
|
||||
// Test member constraints that appear in the `impl Trait`
|
||||
// return type of an async function.
|
||||
// (This used to require a feature gate.)
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
|
@ -1,20 +0,0 @@
|
||||
// edition:2018
|
||||
|
||||
// Test that a feature gate is needed to use `impl Trait` as the
|
||||
// return type of an async.
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
|
||||
async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
//~^ ERROR ambiguous lifetime bound
|
||||
//~| ERROR ambiguous lifetime bound
|
||||
//~| ERROR ambiguous lifetime bound
|
||||
//~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
//~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
(a, b)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = async_ret_impl_trait(&22, &44);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
error: ambiguous lifetime bound in `impl Trait`
|
||||
--> $DIR/ret-impl-trait-no-fg.rs:9:64
|
||||
|
|
||||
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
|
||||
|
|
||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||
|
||||
error: ambiguous lifetime bound in `impl Trait`
|
||||
--> $DIR/ret-impl-trait-no-fg.rs:9:64
|
||||
|
|
||||
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
|
||||
|
|
||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||
|
||||
error: ambiguous lifetime bound in `impl Trait`
|
||||
--> $DIR/ret-impl-trait-no-fg.rs:9:64
|
||||
|
|
||||
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another
|
||||
|
|
||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/ret-impl-trait-no-fg.rs:9:1
|
||||
|
|
||||
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: hidden type `(&u8, &u8)` captures lifetime '_#5r
|
||||
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/ret-impl-trait-no-fg.rs:9:1
|
||||
|
|
||||
LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: hidden type `(&u8, &u8)` captures lifetime '_#6r
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
@ -3,8 +3,6 @@
|
||||
// Test that a feature gate is needed to use `impl Trait` as the
|
||||
// return type of an async.
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a> { }
|
||||
impl<T> Trait<'_> for T { }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ret-impl-trait-one.rs:12:65
|
||||
--> $DIR/ret-impl-trait-one.rs:10:65
|
||||
|
|
||||
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
|
||||
| ------ ^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +0,0 @@
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
|
||||
//~^ ERROR ambiguous lifetime bound
|
||||
//~| ERROR ambiguous lifetime bound
|
||||
(x, y)
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,18 +0,0 @@
|
||||
error: ambiguous lifetime bound in `impl Trait`
|
||||
--> $DIR/feature-gate-member-constraints.rs:4:43
|
||||
|
|
||||
LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
|
||||
|
|
||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||
|
||||
error: ambiguous lifetime bound in `impl Trait`
|
||||
--> $DIR/feature-gate-member-constraints.rs:4:43
|
||||
|
|
||||
LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
|
||||
| ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another
|
||||
|
|
||||
= help: add #![feature(member_constraints)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/error-handling.rs:6:32
|
||||
--> $DIR/error-handling.rs:5:32
|
||||
|
|
||||
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/error-handling.rs:26:16
|
||||
--> $DIR/error-handling.rs:25:16
|
||||
|
|
||||
LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||
| -- -- lifetime `'b` defined here
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/error-handling.rs:26:16
|
||||
--> $DIR/error-handling.rs:25:16
|
||||
|
|
||||
LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||
| -- -- lifetime `'b` defined here
|
||||
|
@ -1,6 +1,5 @@
|
||||
// compile-flags:-Zborrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
// revisions: min_tait full_tait
|
||||
#![feature(min_type_alias_impl_trait)]
|
||||
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
|
@ -3,8 +3,6 @@
|
||||
// revisions: migrate mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
|
@ -3,10 +3,8 @@
|
||||
// revisions: migrate mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
// Test case where we have elision in the impl trait and we have to
|
||||
// pick the right region.
|
||||
@ -26,4 +24,4 @@ fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> {
|
||||
(a, a)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
@ -3,10 +3,9 @@
|
||||
// revisions: migrate mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
#![feature(min_type_alias_impl_trait)]
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
// Here we wind up selecting `'a` and `'b` in the hidden type because
|
||||
// those are the types that appear in the original values.
|
||||
@ -28,4 +27,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> {
|
||||
(a, b)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
@ -3,10 +3,8 @@
|
||||
// revisions: migrate mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> { }
|
||||
impl<T> Trait<'_, '_> for T { }
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
// Here we wind up selecting `'a` and `'b` in the hidden type because
|
||||
// those are the types that appear in the original values.
|
||||
@ -26,4 +24,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
|
||||
(a, b)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
@ -3,8 +3,6 @@
|
||||
// revisions: migrate mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/ordinary-bounds-unrelated.rs:18:74
|
||||
--> $DIR/ordinary-bounds-unrelated.rs:16:74
|
||||
|
|
||||
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
|
||||
--> $DIR/ordinary-bounds-unrelated.rs:18:74
|
||||
--> $DIR/ordinary-bounds-unrelated.rs:16:74
|
||||
|
|
||||
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait Trait<'a, 'b> {}
|
||||
impl<T> Trait<'_, '_> for T {}
|
||||
|
||||
@ -18,7 +16,7 @@ struct Ordinary<'a>(&'a u8);
|
||||
// consider the loans for both `'a` and `'b` alive.
|
||||
|
||||
fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
{
|
||||
// We return a value:
|
||||
//
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
|
||||
--> $DIR/ordinary-bounds-unsuited.rs:20:62
|
||||
--> $DIR/ordinary-bounds-unsuited.rs:18:62
|
||||
|
|
||||
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body
|
||||
--> $DIR/ordinary-bounds-unsuited.rs:20:62
|
||||
--> $DIR/ordinary-bounds-unsuited.rs:18:62
|
||||
|
|
||||
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,7 +1,5 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(member_constraints)]
|
||||
|
||||
trait MultiRegionTrait<'a, 'b> {}
|
||||
impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-74761.rs:4:32
|
||||
--> $DIR/issue-74761.rs:3:32
|
||||
|
|
||||
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
|
||||
|
||||
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761.rs:11:6
|
||||
--> $DIR/issue-74761.rs:10:6
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
||||
error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761.rs:11:10
|
||||
--> $DIR/issue-74761.rs:10:10
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761.rs:11:6
|
||||
--> $DIR/issue-74761.rs:10:6
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
||||
error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/issue-74761.rs:11:10
|
||||
--> $DIR/issue-74761.rs:10:10
|
||||
|
|
||||
LL | impl<'a, 'b> A for () {
|
||||
| ^^ unconstrained lifetime parameter
|
||||
|
@ -1,4 +1,3 @@
|
||||
#![feature(member_constraints)]
|
||||
// revisions: min_tait full_tait
|
||||
#![feature(min_type_alias_impl_trait)]
|
||||
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
|
||||
|
Loading…
x
Reference in New Issue
Block a user