Skip to content
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

WIP PoC for impl Trait in impl Fn return in fn parameters #1

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion src/librustc_ast_lowering/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
attributes to enable",
);
}
// Explodes here
Copy link
Owner Author

@alsuren alsuren Jun 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Explodes here

No longer explodes here. Now explodes in self.find_entry(id).unwrap_or_else(|| panic!("Can't find Entry for HirId {:?}", id)), below.

err.emit();
hir::TyKind::Err
}
Expand Down Expand Up @@ -1660,7 +1661,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Lowers a function declaration.
//
// `decl`: the unlowered (AST) function declaration.
// `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
// `in_band_ty_params`: if `Some`, impl Trait arguments are lowered into generic parameters on the
// given DefId, otherwise impl Trait is disallowed. Must be `Some` if
// `make_ret_async` is also `Some`.
// `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
Expand Down
12 changes: 11 additions & 1 deletion src/librustc_ast_lowering/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let inputs = this.arena.alloc_from_iter(
inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
);

// FIXME: if output_ty is `impl Trait`, this will get populated with
// GenericParam { bounds: [Trait(...)], ...}
// We should probably do something with this.
let mut generic_params = Vec::new();
let output_ty = match output {
FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
FnRetTy::Ty(ty) => {
this.lower_ty(&ty, ImplTraitContext::Universal(&mut generic_params))
}
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
};
if generic_params.len() != 0 {
println!("FIXME: Generic params from impl Trait: {:?}", generic_params);
}
let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))];
let binding = this.output_ty_binding(output_ty.span, output_ty);
(
Expand Down
8 changes: 6 additions & 2 deletions src/librustc_middle/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ impl<'hir> Map<'hir> {
}

fn get_entry(&self, id: HirId) -> Entry<'hir> {
self.find_entry(id).unwrap()
self.find_entry(id).unwrap_or_else(|| panic!("Can't find Entry for HirId {:?}", id))
}

pub fn item(&self, id: HirId) -> &'hir Item<'hir> {
Expand Down Expand Up @@ -503,7 +503,11 @@ impl<'hir> Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
self.find_entry(hir_id).and_then(|entry| {
if let Node::Crate(..) = entry.node { None } else { Some(entry.node) }
if let Node::Crate(..) = entry.node {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing to see here. Just my rust-analyser not being set up correctly.

None
} else {
Some(entry.node)
}
})
}

Expand Down
222 changes: 0 additions & 222 deletions src/test/ui/impl-trait/where-allowed.rs
Original file line number Diff line number Diff line change
@@ -1,224 +1,2 @@
//! A simple test for testing many permutations of allowedness of
//! impl Trait
use std::fmt::Debug;

// Allowed
fn in_parameters(_: impl Debug) { panic!() }

// Allowed
fn in_return() -> impl Debug { panic!() }

// Allowed
fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }

// Disallowed
fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
//~^^ ERROR nested `impl Trait` is not allowed

// Disallowed
fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
//~| ERROR nested `impl Trait` is not allowed

// Disallowed
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types


// Allowed
fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!() }

// Allowed
fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
vec![vec![0; 10], vec![12; 7], vec![8; 3]]
}

// Disallowed
struct InBraceStructField { x: impl Debug }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
struct InAdtInBraceStructField { x: Vec<impl Debug> }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
struct InTupleStructField(impl Debug);
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

// Disallowed
enum InEnum {
InBraceVariant { x: impl Debug },
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
InTupleVariant(impl Debug),
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Allowed
trait InTraitDefnParameters {
fn in_parameters(_: impl Debug);
}

// Disallowed
trait InTraitDefnReturn {
fn in_return() -> impl Debug;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Allowed and disallowed in trait impls
trait DummyTrait {
type Out;
fn in_trait_impl_parameter(_: impl Debug);
fn in_trait_impl_return() -> Self::Out;
}
impl DummyTrait for () {
type Out = impl Debug;
//~^ ERROR `impl Trait` in type aliases is unstable
//~^^ ERROR could not find defining uses

fn in_trait_impl_parameter(_: impl Debug) { }
// Allowed

fn in_trait_impl_return() -> impl Debug { () }
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Allowed
struct DummyType;
impl DummyType {
fn in_inherent_impl_parameters(_: impl Debug) { }
fn in_inherent_impl_return() -> impl Debug { () }
}

// Disallowed
extern "C" {
fn in_foreign_parameters(_: impl Debug);
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types

fn in_foreign_return() -> impl Debug;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Allowed
extern "C" fn in_extern_fn_parameters(_: impl Debug) {
}

// Allowed
extern "C" fn in_extern_fn_return() -> impl Debug {
22
}

type InTypeAlias<R> = impl Debug;
//~^ ERROR `impl Trait` in type aliases is unstable
//~^^ ERROR could not find defining uses

type InReturnInTypeAlias<R> = fn() -> impl Debug;
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
//~| ERROR `impl Trait` in type aliases is unstable

// Disallowed in impl headers
impl PartialEq<impl Debug> for () {
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Disallowed in impl headers
impl PartialEq<()> for impl Debug {
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Disallowed in inherent impls
impl impl Debug {
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Disallowed in inherent impls
struct InInherentImplAdt<T> { t: T }
impl InInherentImplAdt<impl Debug> {
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}

// Disallowed in where clauses
fn in_fn_where_clause()
where impl Debug: Debug
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
}

// Disallowed in where clauses
fn in_adt_in_fn_where_clause()
where Vec<impl Debug>: Debug
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
}

// Disallowed
fn in_trait_parameter_in_fn_where_clause<T>()
where T: PartialEq<impl Debug>
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
}

// Disallowed
fn in_Fn_parameter_in_fn_where_clause<T>()
where T: Fn(impl Debug)
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
}

// Disallowed
fn in_Fn_return_in_fn_where_clause<T>()
where T: Fn() -> impl Debug
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
{
}

fn main() {
let _in_local_variable: impl Fn() = || {};
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
let _in_return_in_local_variable = || -> impl Fn() { || {} };
//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
}
Loading