about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-31 06:58:27 +0100
committerGitHub <noreply@github.com>2022-01-31 06:58:27 +0100
commit55d55136629ddafa712480a6937a2d3654ce3c55 (patch)
tree07d22db07cc8acc54258624e5ae8884065371172
parent6749f32c3389185ab655b0781ea495d46040092b (diff)
parentd671948779fc14c195833f48b64e2c6e1a54a0bb (diff)
downloadrust-55d55136629ddafa712480a6937a2d3654ce3c55.tar.gz
rust-55d55136629ddafa712480a6937a2d3654ce3c55.zip
Rollup merge of #92918 - compiler-errors:gat-expr-lifetime-elision, r=jackh726
Allow eliding GATs in expression position

Thoughts on whether this is worthwhile?

Fixes #92836

r? ``@jackh726``
-rw-r--r--compiler/rustc_typeck/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs15
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.rs38
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.stderr35
4 files changed, 88 insertions, 2 deletions
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 956696546da..05ff7f818c7 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -445,7 +445,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let named_type_param_count =
             param_counts.types - has_self as usize - synth_type_param_count;
         let infer_lifetimes =
-            gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params();
+            (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
 
         if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() {
             Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span);
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 4cf8ddcb8f0..16fc9a01a27 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -482,7 +482,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             ) -> subst::GenericArg<'tcx> {
                 let tcx = self.astconv.tcx();
                 match param.kind {
-                    GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
+                    GenericParamDefKind::Lifetime => self
+                        .astconv
+                        .re_infer(Some(param), self.span)
+                        .unwrap_or_else(|| {
+                            debug!(?param, "unelided lifetime in signature");
+
+                            // This indicates an illegal lifetime in a non-assoc-trait position
+                            tcx.sess.delay_span_bug(self.span, "unelided lifetime in signature");
+
+                            // Supply some dummy value. We don't have an
+                            // `re_error`, annoyingly, so use `'static`.
+                            tcx.lifetimes.re_static
+                        })
+                        .into(),
                     GenericParamDefKind::Type { has_default, .. } => {
                         if !infer_args && has_default {
                             // No type parameter provided, but a default exists.
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.rs b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
new file mode 100644
index 00000000000..482d0d5c00a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
@@ -0,0 +1,38 @@
+#![feature(generic_associated_types)]
+#![allow(unused)]
+
+pub trait Trait  {
+    type Assoc<'a> where Self: 'a;
+
+    fn f(&self) -> Self::Assoc<'_>;
+
+    // Disallow elision in return position, for now
+    fn g(&self) -> Self::Assoc;
+    //~^ ERROR missing generics for associated type `Trait::Assoc`
+}
+
+pub struct Struct {
+    item: f32
+}
+
+pub struct GenericStruct<'a> {
+    ref_item: &'a f32
+}
+
+impl Trait for Struct {
+    type Assoc<'a> = GenericStruct<'a>;
+
+    fn f(&self) -> Self::Assoc<'_> {
+        Self::Assoc {
+            ref_item: &self.item
+        }
+    }
+
+    // Disallow elision in return position, for now
+    fn g(&self) -> Self::Assoc {
+    //~^ ERROR missing generics for associated type `Trait::Assoc`
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
new file mode 100644
index 00000000000..9263f3d67e3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
@@ -0,0 +1,35 @@
+error[E0107]: missing generics for associated type `Trait::Assoc`
+  --> $DIR/elided-in-expr-position.rs:10:26
+   |
+LL |     fn g(&self) -> Self::Assoc;
+   |                          ^^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/elided-in-expr-position.rs:5:10
+   |
+LL |     type Assoc<'a> where Self: 'a;
+   |          ^^^^^ --
+help: add missing lifetime argument
+   |
+LL |     fn g(&self) -> Self::Assoc<'_>;
+   |                          ~~~~~~~~~
+
+error[E0107]: missing generics for associated type `Trait::Assoc`
+  --> $DIR/elided-in-expr-position.rs:32:26
+   |
+LL |     fn g(&self) -> Self::Assoc {
+   |                          ^^^^^ expected 1 lifetime argument
+   |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+  --> $DIR/elided-in-expr-position.rs:5:10
+   |
+LL |     type Assoc<'a> where Self: 'a;
+   |          ^^^^^ --
+help: add missing lifetime argument
+   |
+LL |     fn g(&self) -> Self::Assoc<'_> {
+   |                          ~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.