Skip to content

Commit 9a36840

Browse files
committed
Only allow tait defining uses in function and method return position
1 parent bc9019f commit 9a36840

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+384
-113
lines changed

Diff for: compiler/rustc_typeck/src/check/check.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,26 @@ pub(super) fn check_fn<'a, 'tcx>(
8787

8888
let declared_ret_ty = fn_sig.output();
8989

90-
let revealed_ret_ty =
91-
fcx.instantiate_opaque_types_from_value(fn_id, declared_ret_ty, decl.output.span());
90+
let feature = match tcx.hir().get(fn_id) {
91+
Node::Item(hir::Item { kind: ItemKind::Fn(..), .. }) |
92+
Node::ImplItem(hir::ImplItem {
93+
kind: hir::ImplItemKind::Fn(..), ..
94+
}) => None,
95+
// I don't know if TAIT uses in trait declarations make sense at all
96+
Node::TraitItem(hir::TraitItem {
97+
kind: hir::TraitItemKind::Fn(..),
98+
..
99+
}) |
100+
// Forbid TAIT in closure return position for now.
101+
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => Some(sym::type_alias_impl_trait),
102+
node => bug!("Item being checked wasn't a function/closure: {:?}", node),
103+
};
104+
let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
105+
fn_id,
106+
declared_ret_ty,
107+
decl.output.span(),
108+
feature,
109+
);
92110
debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
93111
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
94112
fcx.ret_type_span = Some(decl.output.span());

Diff for: compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ use rustc_middle::ty::{
2626
self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
2727
Ty, UserType,
2828
};
29-
use rustc_session::lint;
30-
use rustc_span::hygiene::DesugaringKind;
29+
use rustc_session::{lint, parse::feature_err};
3130
use rustc_span::source_map::{original_sp, DUMMY_SP};
3231
use rustc_span::symbol::{kw, sym, Ident};
3332
use rustc_span::{self, BytePos, MultiSpan, Span};
33+
use rustc_span::{hygiene::DesugaringKind, Symbol};
3434
use rustc_trait_selection::infer::InferCtxtExt as _;
3535
use rustc_trait_selection::opaque_types::InferCtxtExt as _;
3636
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
@@ -362,6 +362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362362
parent_id: hir::HirId,
363363
value: T,
364364
value_span: Span,
365+
feature: Option<Symbol>,
365366
) -> T {
366367
let parent_def_id = self.tcx.hir().local_def_id(parent_id);
367368
debug!(
@@ -380,7 +381,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
380381

381382
let mut opaque_types = self.opaque_types.borrow_mut();
382383
let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
384+
383385
for (ty, decl) in opaque_type_map {
386+
if let Some(feature) = feature {
387+
if let hir::OpaqueTyOrigin::TyAlias = decl.origin {
388+
if !self.tcx.features().enabled(feature) {
389+
feature_err(
390+
&self.tcx.sess.parse_sess,
391+
feature,
392+
value_span,
393+
"type alias impl trait is not permitted here",
394+
)
395+
.emit();
396+
}
397+
}
398+
}
384399
let _ = opaque_types.insert(ty, decl);
385400
let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
386401
}

Diff for: compiler/rustc_typeck/src/check/gather_locals.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
44
use rustc_hir::PatKind;
55
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
66
use rustc_middle::ty::Ty;
7-
use rustc_span::Span;
7+
use rustc_span::{sym, Span};
88
use rustc_trait_selection::traits;
99
use std::mem;
1010

@@ -58,11 +58,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
5858
Some(ref ty) => {
5959
let o_ty = self.fcx.to_ty(&ty);
6060

61-
let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
62-
self.fcx.instantiate_opaque_types_from_value(self.parent_id, o_ty, ty.span)
63-
} else {
64-
o_ty
65-
};
61+
let revealed_ty = self.fcx.instantiate_opaque_types_from_value(
62+
self.parent_id,
63+
o_ty,
64+
ty.span,
65+
Some(sym::impl_trait_in_bindings),
66+
);
6667

6768
let c_ty =
6869
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(revealed_ty));

Diff for: compiler/rustc_typeck/src/check/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ use rustc_middle::ty::{self, RegionKind, Ty, TyCtxt, UserType};
121121
use rustc_session::config;
122122
use rustc_session::parse::feature_err;
123123
use rustc_session::Session;
124-
use rustc_span::source_map::DUMMY_SP;
125124
use rustc_span::symbol::{kw, Ident};
126125
use rustc_span::{self, BytePos, MultiSpan, Span};
126+
use rustc_span::{source_map::DUMMY_SP, sym};
127127
use rustc_target::abi::VariantIdx;
128128
use rustc_target::spec::abi::Abi;
129129
use rustc_trait_selection::traits;
@@ -547,11 +547,12 @@ fn typeck_with_fallback<'tcx>(
547547
let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
548548
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
549549

550-
let revealed_ty = if tcx.features().impl_trait_in_bindings {
551-
fcx.instantiate_opaque_types_from_value(id, expected_type, body.value.span)
552-
} else {
553-
expected_type
554-
};
550+
let revealed_ty = fcx.instantiate_opaque_types_from_value(
551+
id,
552+
expected_type,
553+
body.value.span,
554+
Some(sym::impl_trait_in_bindings),
555+
);
555556

556557
// Gather locals in statics (because of block expressions).
557558
GatherLocalsVisitor::new(&fcx, id).visit_body(body);

Diff for: src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn define() -> Bar {
1313
type Foo2 = impl Debug;
1414

1515
fn define2() {
16-
let x = || -> Foo2 { 42 };
16+
let x = || -> Foo2 { 42 }; //~ ERROR not permitted here
1717
}
1818

1919
type Foo3 = impl Debug;
@@ -31,7 +31,7 @@ type Foo4 = impl Debug;
3131

3232
fn define4() {
3333
let y: Foo4 = 42;
34-
//~^ ERROR mismatched types
34+
//~^ ERROR not permitted here
3535
}
3636

3737
fn main() {}

Diff for: src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr

+17-12
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ LL | Bar(42)
1010
= note: expected opaque type `impl Debug`
1111
found type `{integer}`
1212

13+
error[E0658]: type alias impl trait is not permitted here
14+
--> $DIR/feature-gate-type_alias_impl_trait.rs:16:19
15+
|
16+
LL | let x = || -> Foo2 { 42 };
17+
| ^^^^
18+
|
19+
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
20+
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
21+
1322
error[E0308]: mismatched types
1423
--> $DIR/feature-gate-type_alias_impl_trait.rs:23:18
1524
|
@@ -36,19 +45,14 @@ LL | define3(42)
3645
= note: expected opaque type `impl Debug`
3746
found type `{integer}`
3847

39-
error[E0308]: mismatched types
40-
--> $DIR/feature-gate-type_alias_impl_trait.rs:33:19
48+
error[E0658]: type alias impl trait is not permitted here
49+
--> $DIR/feature-gate-type_alias_impl_trait.rs:33:12
4150
|
42-
LL | type Foo4 = impl Debug;
43-
| ---------- the expected opaque type
44-
...
4551
LL | let y: Foo4 = 42;
46-
| ---- ^^ expected opaque type, found integer
47-
| |
48-
| expected due to this
52+
| ^^^^
4953
|
50-
= note: expected opaque type `impl Debug`
51-
found type `{integer}`
54+
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
55+
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
5256

5357
error: could not find defining uses
5458
--> $DIR/feature-gate-type_alias_impl_trait.rs:5:12
@@ -68,6 +72,7 @@ error: could not find defining uses
6872
LL | type Foo4 = impl Debug;
6973
| ^^^^^^^^^^
7074

71-
error: aborting due to 7 previous errors
75+
error: aborting due to 8 previous errors
7276

73-
For more information about this error, try `rustc --explain E0308`.
77+
Some errors have detailed explanations: E0308, E0658.
78+
For more information about an error, try `rustc --explain E0308`.

Diff for: src/test/ui/generator/layout-error.min_tait.stderr

+33-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@ error[E0425]: cannot find value `Foo` in this scope
44
LL | let a = Foo;
55
| ^^^ not found in this scope
66

7-
error: aborting due to previous error
7+
error[E0658]: type alias impl trait is not permitted here
8+
--> $DIR/layout-error.rs:31:27
9+
|
10+
LL | Task::spawn(&POOL, || cb());
11+
| ^
12+
|
13+
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
14+
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
15+
16+
error[E0658]: type alias impl trait is not permitted here
17+
--> $DIR/layout-error.rs:30:28
18+
|
19+
LL | static POOL: Task<F> = Task::new();
20+
| ^^^^^^^^^^^
21+
|
22+
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
23+
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
24+
25+
error: concrete type differs from previous defining opaque type use
26+
--> $DIR/layout-error.rs:31:24
27+
|
28+
LL | Task::spawn(&POOL, || cb());
29+
| ^^^^^^^ expected `[type error]`, got `impl Future`
30+
|
31+
note: previous use here
32+
--> $DIR/layout-error.rs:30:5
33+
|
34+
LL | static POOL: Task<F> = Task::new();
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
37+
error: aborting due to 4 previous errors
838

9-
For more information about this error, try `rustc --explain E0425`.
39+
Some errors have detailed explanations: E0425, E0658.
40+
For more information about an error, try `rustc --explain E0425`.

Diff for: src/test/ui/generator/layout-error.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::future::Future;
1212

1313
pub struct Task<F: Future>(F);
1414
impl<F: Future> Task<F> {
15-
fn new() -> Self {
15+
const fn new() -> Self {
1616
todo!()
1717
}
1818
fn spawn(&self, _: impl FnOnce() -> F) {
@@ -27,6 +27,7 @@ fn main() {
2727

2828
type F = impl Future;
2929
// Check that statics are inhabited computes they layout.
30-
static POOL: Task<F> = Task::new();
31-
Task::spawn(&POOL, || cb());
30+
static POOL: Task<F> = Task::new(); //[min_tait]~ ERROR not permitted here
31+
Task::spawn(&POOL, || cb()); //[min_tait]~ ERROR type alias impl trait is not permitted here
32+
//[min_tait]~^ ERROR concrete type differs from previous
3233
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/metadata-sufficient-for-layout.rs:11:32
2+
--> $DIR/metadata-sufficient-for-layout.rs:10:32
33
|
44
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
55
| ^^^^^^^^^^^^^^^^^^^^^
@@ -8,12 +8,18 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_binding
88
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
99

1010
warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
11-
--> $DIR/metadata-sufficient-for-layout.rs:11:55
11+
--> $DIR/metadata-sufficient-for-layout.rs:10:55
1212
|
1313
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
1414
| ^^^^^^^^^^^^^^^^^^^^^^
1515
|
1616
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
1717

18-
warning: 2 warnings emitted
18+
error: fatal error triggered by #[rustc_error]
19+
--> $DIR/metadata-sufficient-for-layout.rs:29:1
20+
|
21+
LL | fn main() {}
22+
| ^^^^^^^^^
23+
24+
error: aborting due to previous error; 2 warnings emitted
1925

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0658]: type alias impl trait is not permitted here
2+
--> $DIR/metadata-sufficient-for-layout.rs:22:23
3+
|
4+
LL | static A: Option<F> = None;
5+
| ^^^^
6+
|
7+
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
8+
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
9+
10+
error: concrete type differs from previous defining opaque type use
11+
--> $DIR/metadata-sufficient-for-layout.rs:25:1
12+
|
13+
LL | fn f() -> F { metadata_sufficient_for_layout::g() }
14+
| ^^^^^^^^^^^ expected `[type error]`, got `impl Generator`
15+
|
16+
note: previous use here
17+
--> $DIR/metadata-sufficient-for-layout.rs:22:1
18+
|
19+
LL | static A: Option<F> = None;
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0658`.

Diff for: src/test/ui/generator/metadata-sufficient-for-layout.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
// Regression test for #80998.
55
//
66
// aux-build:metadata-sufficient-for-layout.rs
7-
// check-pass
87

98
// revisions: min_tait full_tait
10-
#![feature(min_type_alias_impl_trait)]
9+
#![feature(min_type_alias_impl_trait, rustc_attrs)]
1110
#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
1211
//[full_tait]~^ WARN incomplete
1312
//[full_tait]~| WARN incomplete
@@ -21,7 +20,10 @@ type F = impl Generator<(), Yield = (), Return = ()>;
2120

2221
// Static queries the layout of the generator.
2322
static A: Option<F> = None;
23+
//[min_tait]~^ ERROR not permitted here
2424

2525
fn f() -> F { metadata_sufficient_for_layout::g() }
26+
//[min_tait]~^ ERROR concrete type differs
2627

27-
fn main() {}
28+
#[rustc_error]
29+
fn main() {} //[full_tait]~ ERROR

Diff for: src/test/ui/mir/issue-75053.full_tait.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
77
= note: `#[warn(incomplete_features)]` on by default
88
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
99

10-
error: fatal error triggered by #[rustc_error]
11-
--> $DIR/issue-75053.rs:51:1
10+
error[E0658]: type alias impl trait is not permitted here
11+
--> $DIR/issue-75053.rs:52:15
1212
|
13-
LL | fn main() {
14-
| ^^^^^^^^^
13+
LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
14+
| ^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
17+
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
1518

1619
error: aborting due to previous error; 1 warning emitted
1720

21+
For more information about this error, try `rustc --explain E0658`.

Diff for: src/test/ui/mir/issue-75053.in_bindings.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | #![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
88
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
99

1010
error[E0282]: type annotations needed
11-
--> $DIR/issue-75053.rs:53:38
11+
--> $DIR/issue-75053.rs:52:38
1212
|
1313
LL | type O;
1414
| ------- `<Self as MyIndex<T>>::O` defined here

Diff for: src/test/ui/mir/issue-75053.min_tait.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
error: fatal error triggered by #[rustc_error]
2-
--> $DIR/issue-75053.rs:51:1
1+
error[E0658]: type alias impl trait is not permitted here
2+
--> $DIR/issue-75053.rs:52:15
33
|
4-
LL | fn main() {
5-
| ^^^^^^^^^
4+
LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
8+
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
69

710
error: aborting due to previous error
811

12+
For more information about this error, try `rustc --explain E0658`.

Diff for: src/test/ui/mir/issue-75053.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {
4949

5050
#[rustc_error]
5151
fn main() {
52-
//[min_tait,full_tait]~^ ERROR rustc_error
53-
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
52+
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index(); //[min_tait,full_tait]~ ERROR not permitted here
5453
//[in_bindings]~^ ERROR type annotations needed
5554
}

0 commit comments

Comments
 (0)