diff options
Diffstat (limited to 'compiler/rustc_error_codes/src/error_codes/E0794.md')
-rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0794.md | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0794.md b/compiler/rustc_error_codes/src/error_codes/E0794.md new file mode 100644 index 000000000..c8f73de95 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0794.md @@ -0,0 +1,64 @@ +A lifetime parameter of a function definition is called *late-bound* if it both: + +1. appears in an argument type +2. does not appear in a generic type constraint + +You cannot specify lifetime arguments for late-bound lifetime parameters. + +Erroneous code example: + +```compile_fail,E0794 +fn foo<'a>(x: &'a str) -> &'a str { x } +let _ = foo::<'static>; +``` + +The type of a concrete instance of a generic function is universally quantified +over late-bound lifetime parameters. This is because we want the function to +work for any lifetime substituted for the late-bound lifetime parameter, no +matter where the function is called. Consequently, it doesn't make sense to +specify arguments for late-bound lifetime parameters, since they are not +resolved until the function's call site(s). + +To fix the issue, remove the specified lifetime: + +``` +fn foo<'a>(x: &'a str) -> &'a str { x } +let _ = foo; +``` + +### Additional information + +Lifetime parameters that are not late-bound are called *early-bound*. +Confusion may arise from the fact that late-bound and early-bound +lifetime parameters are declared the same way in function definitions. +When referring to a function pointer type, universal quantification over +late-bound lifetime parameters can be made explicit: + +``` +trait BarTrait<'a> {} + +struct Bar<'a> { + s: &'a str +} + +impl<'a> BarTrait<'a> for Bar<'a> {} + +fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str +where T: BarTrait<'b> +{ + x +} + +let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK +let bar_fn2 = bar::<'static, Bar>; // Not allowed +let bar_fn3 = bar::<Bar>; // OK +``` + +In the definition of `bar`, the lifetime parameter `'a` is late-bound, while +`'b` is early-bound. This is reflected in the type annotation for `bar_fn`, +where `'a` is universally quantified and `'b` is substituted by a specific +lifetime. It is not allowed to explicitly specify early-bound lifetime +arguments when late-bound lifetime parameters are present (as for `bar_fn2`, +see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although +the types that are constrained by early-bound parameters can be specified (as +for `bar_fn3`). |