diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-03-18 12:04:21 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-18 12:04:21 +0100 |
| commit | 9599f3cc5430039b615bc5171be41a6733083dc0 (patch) | |
| tree | 47d18861bffc4761a2c33160c07fcdd02a2d93d0 /compiler | |
| parent | df61fcaec1fdd3b949a7721abfaf37a8ca6e144c (diff) | |
| parent | 75563cd7253bb72876c5c97ff2f7813dd1485bc5 (diff) | |
| download | rust-9599f3cc5430039b615bc5171be41a6733083dc0.tar.gz rust-9599f3cc5430039b615bc5171be41a6733083dc0.zip | |
Rollup merge of #107416 - czzrr:issue-80618, r=GuillaumeGomez
Error code E0794 for late-bound lifetime parameter error. This PR addresses [#80618](https://github.com/rust-lang/rust/issues/80618).
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0794.md | 64 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/generics.rs | 2 |
3 files changed, 66 insertions, 1 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index df857be85ad..d104ff0891d 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -513,6 +513,7 @@ E0790: include_str!("./error_codes/E0790.md"), E0791: include_str!("./error_codes/E0791.md"), E0792: include_str!("./error_codes/E0792.md"), E0793: include_str!("./error_codes/E0793.md"), +E0794: include_str!("./error_codes/E0794.md"), } // Undocumented removed error codes. Note that many removed error codes are documented. 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 00000000000..a33802885c0 --- /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`). diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 2f4963f6bc3..3b5c67de239 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -612,7 +612,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( if position == GenericArgPosition::Value && args.num_lifetime_params() != param_counts.lifetimes { - let mut err = tcx.sess.struct_span_err(span, msg); + let mut err = struct_span_err!(tcx.sess, span, E0794, "{}", msg); err.span_note(span_late, note); err.emit(); } else { |
