about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-18 12:04:21 +0100
committerGitHub <noreply@github.com>2023-03-18 12:04:21 +0100
commit9599f3cc5430039b615bc5171be41a6733083dc0 (patch)
tree47d18861bffc4761a2c33160c07fcdd02a2d93d0 /compiler
parentdf61fcaec1fdd3b949a7721abfaf37a8ca6e144c (diff)
parent75563cd7253bb72876c5c97ff2f7813dd1485bc5 (diff)
downloadrust-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.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0794.md64
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs2
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 {