diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 790b583134c..1c5ad820bd6 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -117,13 +117,13 @@ ast_passes_fn_without_body = free function without a body .suggestion = provide a definition for the function +ast_passes_forbidden_bound = + bounds cannot be used in this context + ast_passes_forbidden_default = `default` is only allowed on items in trait impls .label = `default` because of this -ast_passes_forbidden_lifetime_bound = - lifetime bounds cannot be used in this context - ast_passes_forbidden_non_lifetime_param = only lifetime parameters can be used in this context diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 4283fc7c07d..304c5c1bde9 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -52,8 +52,8 @@ pub struct TraitFnConst { } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_lifetime_bound)] -pub struct ForbiddenLifetimeBound { +#[diag(ast_passes_forbidden_bound)] +pub struct ForbiddenBound { #[primary_span] pub spans: Vec, } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 142cdd15e64..1cc9309c45c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -152,8 +152,8 @@ fn visit_ty(&mut self, ty: &ast::Ty) { } fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) { - // Check only lifetime parameters are present and that the lifetime - // parameters that are present have no bounds. + // Check only lifetime parameters are present and that the + // generic parameters that are present have no bounds. let non_lt_param_spans = params.iter().filter_map(|param| match param.kind { ast::GenericParamKind::Lifetime { .. } => None, _ => Some(param.ident.span), @@ -164,10 +164,11 @@ fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) { non_lt_param_spans, crate::fluent_generated::ast_passes_forbidden_non_lifetime_param ); + for param in params { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - self.sess.emit_err(errors::ForbiddenLifetimeBound { spans }); + self.sess.emit_err(errors::ForbiddenBound { spans }); } } } diff --git a/tests/rustdoc-ui/bounded-hr-lifetime.rs b/tests/rustdoc-ui/bounded-hr-lifetime.rs index b2e000b9757..d6c90f552a2 100644 --- a/tests/rustdoc-ui/bounded-hr-lifetime.rs +++ b/tests/rustdoc-ui/bounded-hr-lifetime.rs @@ -4,6 +4,6 @@ pub fn hrlt<'b, 'c>() where for<'a: 'b + 'c> &'a (): std::fmt::Debug, - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context { } diff --git a/tests/rustdoc-ui/bounded-hr-lifetime.stderr b/tests/rustdoc-ui/bounded-hr-lifetime.stderr index d7c4e8c380c..c936e4022ef 100644 --- a/tests/rustdoc-ui/bounded-hr-lifetime.stderr +++ b/tests/rustdoc-ui/bounded-hr-lifetime.stderr @@ -1,4 +1,4 @@ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/bounded-hr-lifetime.rs:6:13 | LL | for<'a: 'b + 'c> &'a (): std::fmt::Debug, diff --git a/tests/ui/bounds-lifetime.rs b/tests/ui/bounds-lifetime.rs index e3e635a4e84..f26976066ac 100644 --- a/tests/ui/bounds-lifetime.rs +++ b/tests/ui/bounds-lifetime.rs @@ -1,6 +1,6 @@ -type A = for<'b, 'a: 'b> fn(); //~ ERROR lifetime bounds cannot be used in this context -type B = for<'b, 'a: 'b,> fn(); //~ ERROR lifetime bounds cannot be used in this context -type C = for<'b, 'a: 'b +> fn(); //~ ERROR lifetime bounds cannot be used in this context +type A = for<'b, 'a: 'b> fn(); //~ ERROR bounds cannot be used in this context +type B = for<'b, 'a: 'b,> fn(); //~ ERROR bounds cannot be used in this context +type C = for<'b, 'a: 'b +> fn(); //~ ERROR bounds cannot be used in this context type D = for<'a, T> fn(); //~ ERROR only lifetime parameters can be used in this context type E = dyn for Fn(); //~ ERROR only lifetime parameters can be used in this context diff --git a/tests/ui/bounds-lifetime.stderr b/tests/ui/bounds-lifetime.stderr index bbae835d875..de9b9e01242 100644 --- a/tests/ui/bounds-lifetime.stderr +++ b/tests/ui/bounds-lifetime.stderr @@ -1,16 +1,16 @@ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/bounds-lifetime.rs:1:22 | LL | type A = for<'b, 'a: 'b> fn(); | ^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/bounds-lifetime.rs:2:22 | LL | type B = for<'b, 'a: 'b,> fn(); | ^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/bounds-lifetime.rs:3:22 | LL | type C = for<'b, 'a: 'b +> fn(); diff --git a/tests/ui/closures/binder/bounds-on-closure-type-binders.rs b/tests/ui/closures/binder/bounds-on-closure-type-binders.rs new file mode 100644 index 00000000000..099047251ca --- /dev/null +++ b/tests/ui/closures/binder/bounds-on-closure-type-binders.rs @@ -0,0 +1,14 @@ +// check-fail + +#![allow(incomplete_features)] +#![feature(non_lifetime_binders)] +#![feature(closure_lifetime_binder)] + +trait Trait {} + +fn main() { + // Regression test for issue #119067 + let _ = for || -> () {}; + //~^ ERROR bounds cannot be used in this context + //~| ERROR late-bound type parameter not allowed on closures +} diff --git a/tests/ui/closures/binder/bounds-on-closure-type-binders.stderr b/tests/ui/closures/binder/bounds-on-closure-type-binders.stderr new file mode 100644 index 00000000000..9cb921f6631 --- /dev/null +++ b/tests/ui/closures/binder/bounds-on-closure-type-binders.stderr @@ -0,0 +1,14 @@ +error: bounds cannot be used in this context + --> $DIR/bounds-on-closure-type-binders.rs:11:20 + | +LL | let _ = for || -> () {}; + | ^^^^^ + +error: late-bound type parameter not allowed on closures + --> $DIR/bounds-on-closure-type-binders.rs:11:17 + | +LL | let _ = for || -> () {}; + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/higher-lifetime-bounds.rs b/tests/ui/higher-ranked/higher-lifetime-bounds.rs index f3393347d90..f1de1d1cf53 100644 --- a/tests/ui/higher-ranked/higher-lifetime-bounds.rs +++ b/tests/ui/higher-ranked/higher-lifetime-bounds.rs @@ -6,7 +6,7 @@ fn bar1<'a, 'b>( x: &'a i32, y: &'b i32, f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context { // If the bound in f's type would matter, the call below would (have to) // be rejected. @@ -14,7 +14,7 @@ fn bar1<'a, 'b>( } fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context x: &'a i32, y: &'b i32, f: F) @@ -29,7 +29,7 @@ fn bar3<'a, 'b, F>( y: &'b i32, f: F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context { // If the bound in f's type would matter, the call below would (have to) // be rejected. @@ -41,7 +41,7 @@ fn bar4<'a, 'b, F>( y: &'b i32, f: F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context { // If the bound in f's type would matter, the call below would (have to) // be rejected. @@ -49,21 +49,21 @@ fn bar4<'a, 'b, F>( } struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); -//~^ ERROR lifetime bounds cannot be used in this context +//~^ ERROR bounds cannot be used in this context struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; -//~^ ERROR lifetime bounds cannot be used in this context +//~^ ERROR bounds cannot be used in this context struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; -//~^ ERROR lifetime bounds cannot be used in this context +//~^ ERROR bounds cannot be used in this context struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); -//~^ ERROR lifetime bounds cannot be used in this context +//~^ ERROR bounds cannot be used in this context type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; -//~^ ERROR lifetime bounds cannot be used in this context +//~^ ERROR bounds cannot be used in this context fn main() { let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; - //~^ ERROR lifetime bounds cannot be used in this context + //~^ ERROR bounds cannot be used in this context } diff --git a/tests/ui/higher-ranked/higher-lifetime-bounds.stderr b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr index bc6d2288cdf..de83d8bccdb 100644 --- a/tests/ui/higher-ranked/higher-lifetime-bounds.stderr +++ b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr @@ -1,64 +1,64 @@ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:8:22 | LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) | ^^^ ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:16:34 | LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:31:28 | LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:43:25 | LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:51:28 | LL | struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:53:40 | LL | struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:55:37 | LL | struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:58:29 | LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:61:33 | LL | type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:65:34 | LL | let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; | ^^^ -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/higher-lifetime-bounds.rs:67:42 | LL | let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs index 31de418be5f..76c56a715d2 100644 --- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs @@ -21,7 +21,7 @@ fn main() { let _: extern fn<'a: 'static>(); //~^ ERROR function pointer types may not have generic parameters - //~| ERROR lifetime bounds cannot be used in this context + //~| ERROR bounds cannot be used in this context let _: for<'any> extern "C" fn<'u>(); //~^ ERROR function pointer types may not have generic parameters diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr index 069fcffe9a0..6b6cb2d6bdd 100644 --- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr @@ -100,7 +100,7 @@ error[E0412]: cannot find type `T` in this scope LL | type Identity = fn(T) -> T; | ^ not found in this scope -error: lifetime bounds cannot be used in this context +error: bounds cannot be used in this context --> $DIR/recover-fn-ptr-with-generics.rs:22:26 | LL | let _: extern fn<'a: 'static>(); diff --git a/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.rs b/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.rs new file mode 100644 index 00000000000..2535eb99c59 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.rs @@ -0,0 +1,14 @@ +// check-fail + +#![allow(incomplete_features)] +#![feature(non_lifetime_binders)] + +trait Trait {} + +trait Trait2 +where + for ():, +{ //~^ ERROR bounds cannot be used in this context +} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.stderr b/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.stderr new file mode 100644 index 00000000000..0a2f4cea614 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/bounds-on-type-binders.stderr @@ -0,0 +1,8 @@ +error: bounds cannot be used in this context + --> $DIR/bounds-on-type-binders.rs:10:12 + | +LL | for ():, + | ^^^^^ + +error: aborting due to 1 previous error +