diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 79262235cd9f2..c32440d293e5a 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -222,7 +222,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), + ParenthesizedGenericArgs::Ok => { + self.lower_parenthesized_parameter_data(data, itctx) + } ParenthesizedGenericArgs::Err => { let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); err.span_label(data.span, "only `Fn` traits may use parentheses"); @@ -384,6 +386,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_parenthesized_parameter_data( &mut self, data: &ParenthesizedArgs, + itctx: ImplTraitContext<'_, 'hir>, ) -> (GenericArgsCtor<'hir>, bool) { // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref`, where `Ref` has @@ -396,7 +399,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())), ); let output_ty = match output { - FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()), + FnRetTy::Ty(ty) => this.lower_ty(&ty, itctx), FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])), }; let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))]; diff --git a/src/test/ui/impl-trait/impl_fn_associativity.rs b/src/test/ui/impl-trait/impl_fn_associativity.rs new file mode 100644 index 0000000000000..f5f1909cf58b0 --- /dev/null +++ b/src/test/ui/impl-trait/impl_fn_associativity.rs @@ -0,0 +1,16 @@ +// run-pass +use std::fmt::Debug; + +fn f_debug() -> impl Fn() -> impl Debug { + || () +} + +fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug { + || f_debug() +} + +fn main() { + // Check that `ff_debug` is `() -> (() -> Debug)` and not `(() -> ()) -> Debug` + let debug = ff_debug()()(); + assert_eq!(format!("{:?}", debug), "()"); +} diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs index be2c21a7743ce..fab8764ccab98 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.rs +++ b/src/test/ui/impl-trait/nested_impl_trait.rs @@ -23,8 +23,7 @@ fn allowed_in_assoc_type() -> impl Iterator { } fn allowed_in_ret_type() -> impl Fn() -> impl Into { -//~^ `impl Trait` not allowed - || 5 + || 5u8 } fn main() {} diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr index 59c7e4d5f4e92..bc8ae267951c8 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.stderr +++ b/src/test/ui/impl-trait/nested_impl_trait.stderr @@ -40,13 +40,7 @@ error[E0562]: `impl Trait` not allowed outside of function and method return typ LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ^^^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/nested_impl_trait.rs:25:42 - | -LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into { - | ^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0562, E0666. For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs index 35fb42d621322..f15c4b2cfdc7b 100644 --- a/src/test/ui/impl-trait/where-allowed.rs +++ b/src/test/ui/impl-trait/where-allowed.rs @@ -31,44 +31,38 @@ fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and method return types -// Disallowed +// Allowed fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } -//~^ ERROR `impl Trait` not allowed outside of function and 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 method return types -// Disallowed +// Allowed fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } -//~^ ERROR `impl Trait` not allowed outside of function and 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 method return types //~^^ ERROR nested `impl Trait` is not allowed -// Disallowed +// Allowed fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } -//~^ ERROR `impl Trait` not allowed outside of function and 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 method return types //~| ERROR nested `impl Trait` is not allowed -// Disallowed +// Allowed fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } -//~^ ERROR `impl Trait` not allowed outside of function and method return types // Disallowed fn in_Fn_parameter_in_generics (_: F) { panic!() } //~^ ERROR `impl Trait` not allowed outside of function and method return types -// Disallowed +// Allowed fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } -//~^ ERROR `impl Trait` not allowed outside of function and method return types - // Allowed fn in_impl_Trait_in_parameters(_: impl Iterator) { panic!() } diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 236cf449e85fa..9036605245d2c 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -1,5 +1,5 @@ error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:47:51 + --> $DIR/where-allowed.rs:45:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | --------^^^^^^^^^^- @@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/where-allowed.rs:56:57 + --> $DIR/where-allowed.rs:53:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | --------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic | outer `impl Trait` error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:119:16 + --> $DIR/where-allowed.rs:113:16 | LL | type Out = impl Debug; | ^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Out = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:154:23 + --> $DIR/where-allowed.rs:148:23 | LL | type InTypeAlias = impl Debug; | ^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type InTypeAlias = impl Debug; = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: `impl Trait` in type aliases is unstable - --> $DIR/where-allowed.rs:157:39 + --> $DIR/where-allowed.rs:151:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ @@ -74,223 +74,193 @@ LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:35:51 - | -LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:39:55 + --> $DIR/where-allowed.rs:38:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:43:57 - | -LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:47:51 + --> $DIR/where-allowed.rs:45:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:52:53 - | -LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:56:57 + --> $DIR/where-allowed.rs:53:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:61:59 - | -LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:65:38 + --> $DIR/where-allowed.rs:61:38 | LL | fn in_Fn_parameter_in_generics (_: F) { panic!() } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:69:40 - | -LL | fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } - | ^^^^^^^^^^ - -error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:82:32 + --> $DIR/where-allowed.rs:76:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:86:41 + --> $DIR/where-allowed.rs:80:41 | LL | struct InAdtInBraceStructField { x: Vec } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:90:27 + --> $DIR/where-allowed.rs:84:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:95:25 + --> $DIR/where-allowed.rs:89:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:97:20 + --> $DIR/where-allowed.rs:91:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:108:23 + --> $DIR/where-allowed.rs:102:23 | LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:125:34 + --> $DIR/where-allowed.rs:119:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:138:33 + --> $DIR/where-allowed.rs:132:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:141:31 + --> $DIR/where-allowed.rs:135:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:157:39 + --> $DIR/where-allowed.rs:151:39 | LL | type InReturnInTypeAlias = fn() -> impl Debug; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:162:16 + --> $DIR/where-allowed.rs:156:16 | LL | impl PartialEq for () { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:167:24 + --> $DIR/where-allowed.rs:161:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:172:6 + --> $DIR/where-allowed.rs:166:6 | LL | impl impl Debug { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:178:24 + --> $DIR/where-allowed.rs:172:24 | LL | impl InInherentImplAdt { | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:184:11 + --> $DIR/where-allowed.rs:178:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:191:15 + --> $DIR/where-allowed.rs:185:15 | LL | where Vec: Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:198:24 + --> $DIR/where-allowed.rs:192:24 | LL | where T: PartialEq | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:205:17 + --> $DIR/where-allowed.rs:199:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:212:22 + --> $DIR/where-allowed.rs:206:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:218:40 + --> $DIR/where-allowed.rs:212:40 | LL | struct InStructGenericParamDefault(T); | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:222:36 + --> $DIR/where-allowed.rs:216:36 | LL | enum InEnumGenericParamDefault { Variant(T) } | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:226:38 + --> $DIR/where-allowed.rs:220:38 | LL | trait InTraitGenericParamDefault {} | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:230:41 + --> $DIR/where-allowed.rs:224:41 | LL | type InTypeAliasGenericParamDefault = T; | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:234:11 + --> $DIR/where-allowed.rs:228:11 | LL | impl T {} | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:241:40 + --> $DIR/where-allowed.rs:235:40 | LL | fn in_method_generic_param_default(_: T) {} | ^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:247:29 + --> $DIR/where-allowed.rs:241:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and method return types - --> $DIR/where-allowed.rs:249:46 + --> $DIR/where-allowed.rs:243:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; | ^^^^^^^^^ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:234:7 + --> $DIR/where-allowed.rs:228:7 | LL | impl T {} | ^ @@ -300,7 +270,7 @@ LL | impl T {} = note: for more information, see issue #36887 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/where-allowed.rs:241:36 + --> $DIR/where-allowed.rs:235:36 | LL | fn in_method_generic_param_default(_: T) {} | ^ @@ -309,14 +279,14 @@ LL | fn in_method_generic_param_default(_: T) {} = note: for more information, see issue #36887 error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:234:23 + --> $DIR/where-allowed.rs:228:23 | LL | impl T {} | ^ impl requires a nominal type | = note: either implement a trait on it or create a newtype to wrap it instead -error: aborting due to 49 previous errors +error: aborting due to 44 previous errors Some errors have detailed explanations: E0118, E0562, E0658, E0666. For more information about an error, try `rustc --explain E0118`.