Skip to content

Commit 0e5d7b8

Browse files
committed
Restrict TAITs to argument and return types only and add an additional feature gate for the other cases
1 parent 73cfef3 commit 0e5d7b8

12 files changed

+87
-32
lines changed

compiler/rustc_feature/src/active.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ declare_features! (
524524
(active, try_blocks, "1.29.0", Some(31436), None),
525525
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
526526
(active, type_alias_impl_trait, "1.38.0", Some(63063), None),
527+
/// Allows functions with TAITs in their where bounds to register hidden types.
528+
(active, type_alias_impl_trait_in_where_bounds, "CURRENT_RUSTC_VERSION", Some(63063), None),
527529
/// Allows the use of type ascription in expressions.
528530
(active, type_ascription, "1.6.0", Some(23416), None),
529531
/// Allows creation of instances of a struct by moving fields that have

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ use rustc_middle::ty::{
1616
self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder,
1717
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
1818
};
19+
use rustc_session::parse::feature_err;
1920
use rustc_span::symbol::Ident;
20-
use rustc_span::{Span, DUMMY_SP};
21+
use rustc_span::{sym, Span, DUMMY_SP};
2122

2223
use super::ItemCtxt;
2324
use super::{bad_placeholder, is_suggestable_infer_ty};
@@ -639,7 +640,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
639640
let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types;
640641
debug!(?concrete_opaque_types);
641642
if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) {
642-
if !may_define_opaque_type(self.tcx, item_def_id, self.def_id) {
643+
if !may_define_opaque_type(self.tcx, item_def_id, self.def_id, concrete_type.span) {
643644
self.tcx.sess.emit_err(OpaqueTypeConstrainedButNotInSig {
644645
span: concrete_type.span,
645646
item_span: self.tcx.def_span(item_def_id),
@@ -758,6 +759,7 @@ fn may_define_opaque_type<'tcx>(
758759
tcx: TyCtxt<'tcx>,
759760
def_id: LocalDefId,
760761
opaque_def_id: LocalDefId,
762+
span: Span,
761763
) -> bool {
762764
if tcx.is_descendant_of(opaque_def_id.to_def_id(), def_id.to_def_id()) {
763765
// If the opaque type is defined in the body of a function, that function
@@ -766,7 +768,7 @@ fn may_define_opaque_type<'tcx>(
766768
}
767769

768770
if tcx.is_closure(def_id.to_def_id()) {
769-
return may_define_opaque_type(tcx, tcx.local_parent(def_id), opaque_def_id);
771+
return may_define_opaque_type(tcx, tcx.local_parent(def_id), opaque_def_id, span);
770772
}
771773

772774
let param_env = tcx.param_env(def_id);
@@ -860,8 +862,25 @@ fn may_define_opaque_type<'tcx>(
860862
_ => false,
861863
};
862864
trace!(?tait_in_fn_sig);
863-
tait_in_fn_sig
864-
|| has_tait(tcx.predicates_of(def_id.to_def_id()).predicates, opaque_def_id, tcx, param_env)
865+
if tait_in_fn_sig {
866+
return true;
867+
}
868+
let tait_in_where_bounds =
869+
has_tait(tcx.predicates_of(def_id.to_def_id()).predicates, opaque_def_id, tcx, param_env);
870+
if tcx.features().type_alias_impl_trait_in_where_bounds {
871+
tait_in_where_bounds
872+
} else {
873+
if tait_in_where_bounds {
874+
feature_err(
875+
&tcx.sess.parse_sess,
876+
sym::type_alias_impl_trait_in_where_bounds,
877+
span,
878+
"type alias impl trait is only usable in argument or return types",
879+
)
880+
.emit();
881+
}
882+
false
883+
}
865884
}
866885

867886
fn find_opaque_ty_constraints_for_rpit(
@@ -1072,8 +1091,6 @@ fn infer_placeholder_type<'a>(
10721091

10731092
fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
10741093
if !tcx.features().inherent_associated_types {
1075-
use rustc_session::parse::feature_err;
1076-
use rustc_span::symbol::sym;
10771094
feature_err(
10781095
&tcx.sess.parse_sess,
10791096
sym::inherent_associated_types,

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,7 @@ symbols! {
15091509
ty,
15101510
type_alias_enum_variants,
15111511
type_alias_impl_trait,
1512+
type_alias_impl_trait_in_where_bounds,
15121513
type_ascribe,
15131514
type_ascription,
15141515
type_changing_struct_update,

tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
#![allow(dead_code)]
88
#![allow(incomplete_features)]
99
#![allow(unused_must_use)]
10-
#![feature(adt_const_params, extern_types, inline_const, type_alias_impl_trait)]
10+
#![feature(
11+
adt_const_params,
12+
extern_types,
13+
inline_const,
14+
type_alias_impl_trait,
15+
type_alias_impl_trait_in_where_bounds
16+
)]
1117

1218
extern crate core;
1319
use core::ffi::c_void;

tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@ fn define() -> Bar {
1010
Bar(42)
1111
}
1212

13-
type Foo2 = impl Debug;
14-
15-
fn define2()
16-
where
17-
Foo2: Debug,
18-
{
13+
fn define2() {
14+
type Foo2 = impl Debug;
1915
let x = || -> Foo2 { 42 };
2016
}
2117

@@ -24,19 +20,9 @@ type Foo3 = impl Debug;
2420
fn define3(x: Foo3) {
2521
let y: i32 = x;
2622
}
27-
fn define3_1()
28-
where
29-
Foo3: Debug,
30-
{
31-
define3(42)
32-
}
33-
34-
type Foo4 = impl Debug;
3523

36-
fn define4()
37-
where
38-
Foo4: Debug,
39-
{
24+
fn define4() {
25+
type Foo4 = impl Debug;
4026
let y: Foo4 = 42;
4127
}
4228

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// ignore-compare-mode-chalk
2+
// check-pass
3+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
4+
use std::fmt::Debug;
5+
6+
type Foo = impl Debug;
7+
8+
struct Bar(Foo);
9+
fn define() -> Bar {
10+
Bar(42)
11+
}
12+
13+
type Foo2 = impl Debug;
14+
15+
fn define2()
16+
where
17+
Foo2: Debug,
18+
{
19+
let x = || -> Foo2 { 42 };
20+
}
21+
22+
type Foo3 = impl Debug;
23+
24+
fn define3(x: Foo3) {
25+
let y: i32 = x;
26+
}
27+
fn define3_1()
28+
where
29+
Foo3: Debug,
30+
{
31+
define3(42)
32+
}
33+
34+
type Foo4 = impl Debug;
35+
36+
fn define4()
37+
where
38+
Foo4: Debug,
39+
{
40+
let y: Foo4 = 42;
41+
}
42+
43+
fn main() {}

tests/ui/impl-trait/deduce-signature-from-supertrait.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// check-pass
22

3-
#![feature(type_alias_impl_trait)]
3+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
44

55
trait SuperExpectation: Fn(i32) {}
66

tests/ui/type-alias-impl-trait/closure_args.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// regression test for https://github.com/rust-lang/rust/issues/100800
44

5-
#![feature(type_alias_impl_trait)]
5+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
66

77
trait Anything {}
88
impl<T> Anything for T {}

tests/ui/type-alias-impl-trait/closure_args2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-pass
22

3-
#![feature(type_alias_impl_trait)]
3+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
44

55
trait Foo {
66
// This was reachable in https://github.com/rust-lang/rust/issues/100800

tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(type_alias_impl_trait)]
1+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
22

33
fn foo()
44
where

tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// check-pass
22

3-
#![feature(type_alias_impl_trait, rustc_attrs)]
3+
#![feature(type_alias_impl_trait, rustc_attrs, type_alias_impl_trait_in_where_bounds)]
44

55
type T = impl Sized;
66
// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed

tests/ui/type-alias-impl-trait/type_of_a_let.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(type_alias_impl_trait)]
1+
#![feature(type_alias_impl_trait, type_alias_impl_trait_in_where_bounds)]
22
#![allow(dead_code)]
33

44
use std::fmt::Debug;

0 commit comments

Comments
 (0)