Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Only allow tait defining uses in function and method return position
  • Loading branch information
oli-obk committed Mar 15, 2021
commit 4a6dc8e20328ecb627a519c6704afadcf378a72b
22 changes: 20 additions & 2 deletions compiler/rustc_typeck/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,26 @@ pub(super) fn check_fn<'a, 'tcx>(

let declared_ret_ty = fn_sig.output();

let revealed_ret_ty =
fcx.instantiate_opaque_types_from_value(fn_id, declared_ret_ty, decl.output.span());
let feature = match tcx.hir().get(fn_id) {
Node::Item(hir::Item { kind: ItemKind::Fn(..), .. }) |
Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(..), ..
}) => None,
// I don't know if TAIT uses in trait declarations make sense at all
Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Fn(..),
..
}) |
// Forbid TAIT in closure return position for now.
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => Some(sym::type_alias_impl_trait),
node => bug!("Item being checked wasn't a function/closure: {:?}", node),
};
let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(
fn_id,
declared_ret_ty,
decl.output.span(),
feature,
);
debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
fcx.ret_type_span = Some(decl.output.span());
Expand Down
19 changes: 17 additions & 2 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ use rustc_middle::ty::{
self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
Ty, UserType,
};
use rustc_session::lint;
use rustc_span::hygiene::DesugaringKind;
use rustc_session::{lint, parse::feature_err};
use rustc_span::source_map::{original_sp, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{self, BytePos, MultiSpan, Span};
use rustc_span::{hygiene::DesugaringKind, Symbol};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::opaque_types::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
Expand Down Expand Up @@ -362,6 +362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
parent_id: hir::HirId,
value: T,
value_span: Span,
feature: Option<Symbol>,
) -> T {
let parent_def_id = self.tcx.hir().local_def_id(parent_id);
debug!(
Expand All @@ -380,7 +381,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let mut opaque_types = self.opaque_types.borrow_mut();
let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();

for (ty, decl) in opaque_type_map {
if let Some(feature) = feature {
if let hir::OpaqueTyOrigin::TyAlias = decl.origin {
if !self.tcx.features().enabled(feature) {
feature_err(
&self.tcx.sess.parse_sess,
feature,
value_span,
"type alias impl trait is not permitted here",
)
.emit();
}
}
}
let _ = opaque_types.insert(ty, decl);
let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
}
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_typeck/src/check/gather_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::PatKind;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::Ty;
use rustc_span::Span;
use rustc_span::{sym, Span};
use rustc_trait_selection::traits;
use std::mem;

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

let revealed_ty = if self.fcx.tcx.features().impl_trait_in_bindings {
self.fcx.instantiate_opaque_types_from_value(self.parent_id, o_ty, ty.span)
} else {
o_ty
};
let revealed_ty = self.fcx.instantiate_opaque_types_from_value(
self.parent_id,
o_ty,
ty.span,
Some(sym::impl_trait_in_bindings),
);

let c_ty =
self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(revealed_ty));
Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ use rustc_middle::ty::{self, RegionKind, Ty, TyCtxt, UserType};
use rustc_session::config;
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, BytePos, MultiSpan, Span};
use rustc_span::{source_map::DUMMY_SP, sym};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
Expand Down Expand Up @@ -547,11 +547,12 @@ fn typeck_with_fallback<'tcx>(
let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);

let revealed_ty = if tcx.features().impl_trait_in_bindings {
fcx.instantiate_opaque_types_from_value(id, expected_type, body.value.span)
} else {
expected_type
};
let revealed_ty = fcx.instantiate_opaque_types_from_value(
id,
expected_type,
body.value.span,
Some(sym::impl_trait_in_bindings),
);

// Gather locals in statics (because of block expressions).
GatherLocalsVisitor::new(&fcx, id).visit_body(body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn define() -> Bar {
type Foo2 = impl Debug;

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

type Foo3 = impl Debug;
Expand All @@ -31,7 +31,7 @@ type Foo4 = impl Debug;

fn define4() {
let y: Foo4 = 42;
//~^ ERROR mismatched types
//~^ ERROR not permitted here
}

fn main() {}
29 changes: 17 additions & 12 deletions src/test/ui/feature-gates/feature-gate-type_alias_impl_trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ LL | Bar(42)
= note: expected opaque type `impl Debug`
found type `{integer}`

error[E0658]: type alias impl trait is not permitted here
--> $DIR/feature-gate-type_alias_impl_trait.rs:16:19
|
LL | let x = || -> Foo2 { 42 };
| ^^^^
|
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable

error[E0308]: mismatched types
--> $DIR/feature-gate-type_alias_impl_trait.rs:23:18
|
Expand All @@ -36,19 +45,14 @@ LL | define3(42)
= note: expected opaque type `impl Debug`
found type `{integer}`

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

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

error: aborting due to 7 previous errors
error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0308, E0658.
For more information about an error, try `rustc --explain E0308`.
35 changes: 33 additions & 2 deletions src/test/ui/generator/layout-error.min_tait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,37 @@ error[E0425]: cannot find value `Foo` in this scope
LL | let a = Foo;
| ^^^ not found in this scope

error: aborting due to previous error
error[E0658]: type alias impl trait is not permitted here
--> $DIR/layout-error.rs:31:27
|
LL | Task::spawn(&POOL, || cb());
| ^
|
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable

error[E0658]: type alias impl trait is not permitted here
--> $DIR/layout-error.rs:30:28
|
LL | static POOL: Task<F> = Task::new();
| ^^^^^^^^^^^
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable

error: concrete type differs from previous defining opaque type use
--> $DIR/layout-error.rs:31:24
|
LL | Task::spawn(&POOL, || cb());
| ^^^^^^^ expected `[type error]`, got `impl Future`
|
note: previous use here
--> $DIR/layout-error.rs:30:5
|
LL | static POOL: Task<F> = Task::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0425`.
Some errors have detailed explanations: E0425, E0658.
For more information about an error, try `rustc --explain E0425`.
7 changes: 4 additions & 3 deletions src/test/ui/generator/layout-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::future::Future;

pub struct Task<F: Future>(F);
impl<F: Future> Task<F> {
fn new() -> Self {
const fn new() -> Self {
todo!()
}
fn spawn(&self, _: impl FnOnce() -> F) {
Expand All @@ -27,6 +27,7 @@ fn main() {

type F = impl Future;
// Check that statics are inhabited computes they layout.
static POOL: Task<F> = Task::new();
Task::spawn(&POOL, || cb());
static POOL: Task<F> = Task::new(); //[min_tait]~ ERROR not permitted here
Task::spawn(&POOL, || cb()); //[min_tait]~ ERROR type alias impl trait is not permitted here
//[min_tait]~^ ERROR concrete type differs from previous
}
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/metadata-sufficient-for-layout.rs:11:32
--> $DIR/metadata-sufficient-for-layout.rs:10:32
|
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
| ^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -8,12 +8,18 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_binding
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information

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

warning: 2 warnings emitted
error: fatal error triggered by #[rustc_error]
--> $DIR/metadata-sufficient-for-layout.rs:29:1
|
LL | fn main() {}
| ^^^^^^^^^

error: aborting due to previous error; 2 warnings emitted

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0658]: type alias impl trait is not permitted here
--> $DIR/metadata-sufficient-for-layout.rs:22:23
|
LL | static A: Option<F> = None;
| ^^^^
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable

error: concrete type differs from previous defining opaque type use
--> $DIR/metadata-sufficient-for-layout.rs:25:1
|
LL | fn f() -> F { metadata_sufficient_for_layout::g() }
| ^^^^^^^^^^^ expected `[type error]`, got `impl Generator`
|
note: previous use here
--> $DIR/metadata-sufficient-for-layout.rs:22:1
|
LL | static A: Option<F> = None;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
8 changes: 5 additions & 3 deletions src/test/ui/generator/metadata-sufficient-for-layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
// Regression test for #80998.
//
// aux-build:metadata-sufficient-for-layout.rs
// check-pass

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

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

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

fn main() {}
#[rustc_error]
fn main() {} //[full_tait]~ ERROR
12 changes: 8 additions & 4 deletions src/test/ui/mir/issue-75053.full_tait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information

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

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0658`.
2 changes: 1 addition & 1 deletion src/test/ui/mir/issue-75053.in_bindings.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | #![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information

error[E0282]: type annotations needed
--> $DIR/issue-75053.rs:53:38
--> $DIR/issue-75053.rs:52:38
|
LL | type O;
| ------- `<Self as MyIndex<T>>::O` defined here
Expand Down
12 changes: 8 additions & 4 deletions src/test/ui/mir/issue-75053.min_tait.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: fatal error triggered by #[rustc_error]
--> $DIR/issue-75053.rs:51:1
error[E0658]: type alias impl trait is not permitted here
--> $DIR/issue-75053.rs:52:15
|
LL | fn main() {
| ^^^^^^^^^
LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
= help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
3 changes: 1 addition & 2 deletions src/test/ui/mir/issue-75053.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {

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