Skip to content

stabilize member constraints #84701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -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
3 changes: 0 additions & 3 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -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),

66 changes: 0 additions & 66 deletions compiler/rustc_trait_selection/src/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -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
29 changes: 0 additions & 29 deletions src/doc/unstable-book/src/language-features/member-constraints.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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 { }
20 changes: 0 additions & 20 deletions src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/ret-impl-trait-one.rs:12:80
--> $DIR/ret-impl-trait-one.rs:10:80
|
LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
| ________________________________--__--__________________________________________^
Original file line number Diff line number Diff line change
@@ -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 { }

Original file line number Diff line number Diff line change
@@ -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> {
| ------ ^^^^^^^^^^^^^^
10 changes: 0 additions & 10 deletions src/test/ui/feature-gates/feature-gate-member-constraints.rs

This file was deleted.

18 changes: 0 additions & 18 deletions src/test/ui/feature-gates/feature-gate-member-constraints.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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))]
2 changes: 0 additions & 2 deletions src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
Original file line number Diff line number Diff line change
@@ -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 {}

Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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 {}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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>
| ^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// edition:2018

#![feature(member_constraints)]

trait Trait<'a, 'b> {}
impl<T> Trait<'_, '_> for T {}

Original file line number Diff line number Diff line change
@@ -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>
| ^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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>
| ^^^^^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -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:
//
Original file line number Diff line number Diff line change
@@ -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>
| ^^^^^^^^^^^^^^^^^^
2 changes: 0 additions & 2 deletions src/test/ui/impl-trait/needs_least_region_or_bound.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// check-pass

#![feature(member_constraints)]

trait MultiRegionTrait<'a, 'b> {}
impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {}

Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr
Original file line number Diff line number Diff line change
@@ -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 change: 0 additions & 1 deletion src/test/ui/type-alias-impl-trait/issue-74761.rs
Original file line number Diff line number Diff line change
@@ -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))]