about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-07-01 06:05:52 +0200
committerGitHub <noreply@github.com>2022-07-01 06:05:52 +0200
commit0d5636ce8879381f151d7c03d691b35fe4a8ea56 (patch)
treec9d64315df2897c91ceace5c7609d3a7f3b90252
parentacdcdfb61b7b472bfacbb8bb889bdf3204827f2e (diff)
parente043821e93588addaa0f11ad3a1bd6c9a913b098 (diff)
downloadrust-0d5636ce8879381f151d7c03d691b35fe4a8ea56.tar.gz
rust-0d5636ce8879381f151d7c03d691b35fe4a8ea56.zip
Rollup merge of #98610 - lcnr:emit_inference_failure_err-ice, r=estebank
fix `emit_inference_failure_err` ICE

fixes #98598

this fix doesn't make me too happy, but :shrug:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs23
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs3
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.rs21
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr14
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs21
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr9
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative.rs21
-rw-r--r--src/test/ui/inference/need_type_info/expr-struct-type-relative.stderr14
8 files changed, 119 insertions, 7 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 20b9ed9cd73..d290752614c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -334,7 +334,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let mut local_visitor = FindInferSourceVisitor::new(&self, typeck_results, arg);
         if let Some(body_id) = body_id {
             let expr = self.tcx.hir().expect_expr(body_id.hir_id);
-            debug!(?expr);
             local_visitor.visit_expr(expr);
         }
 
@@ -550,6 +549,7 @@ impl<'tcx> InferSourceKind<'tcx> {
     }
 }
 
+#[derive(Debug)]
 struct InsertableGenericArgs<'tcx> {
     insert_span: Span,
     substs: SubstsRef<'tcx>,
@@ -735,10 +735,20 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                     return self.path_inferred_subst_iter(expr.hir_id, substs, path);
                 }
             }
-            hir::ExprKind::Struct(path, _, _) => {
+            // FIXME(#98711): Ideally we would also deal with type relative
+            // paths here, even if that is quite rare.
+            //
+            // See the `need_type_info/expr-struct-type-relative-gat.rs` test
+            // for an example where that would be needed.
+            //
+            // However, the `type_dependent_def_id` for `Self::Output` in an
+            // impl is currently the `DefId` of `Output` in the trait definition
+            // which makes this somewhat difficult and prevents us from just
+            // using `self.path_inferred_subst_iter` here.
+            hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _) => {
                 if let Some(ty) = self.opt_node_type(expr.hir_id) {
                     if let ty::Adt(_, substs) = ty.kind() {
-                        return self.path_inferred_subst_iter(expr.hir_id, substs, path);
+                        return Box::new(self.resolved_path_inferred_subst_iter(path, substs));
                     }
                 }
             }
@@ -945,6 +955,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
         intravisit::walk_body(self, body);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         let tcx = self.infcx.tcx;
         match expr.kind {
@@ -959,9 +970,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             _ => intravisit::walk_expr(self, expr),
         }
 
-        for InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } in
-            self.expr_inferred_subst_iter(expr)
-        {
+        for args in self.expr_inferred_subst_iter(expr) {
+            debug!(?args);
+            let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args;
             let generics = tcx.generics_of(generics_def_id);
             if let Some(argument_index) =
                 generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index d5075537ced..5ad5692e762 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -156,6 +156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
     }
 
+    #[instrument(level = "debug", skip(self))]
     pub(in super::super) fn write_resolution(
         &self,
         hir_id: hir::HirId,
@@ -164,8 +165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
     }
 
+    #[instrument(level = "debug", skip(self))]
     pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
-        debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
         self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
         self.write_substs(hir_id, method.substs);
 
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.rs b/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.rs
new file mode 100644
index 00000000000..42af9fa8d11
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    type Output;
+
+    fn baz() -> Self::Output;
+}
+
+fn needs_infer<T>() {}
+
+enum Bar {
+    Variant {}
+}
+
+impl Foo for u8 {
+    type Output = Bar;
+    fn baz() -> Self::Output {
+        needs_infer(); //~ ERROR type annotations needed
+        Self::Output::Variant {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr b/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr
new file mode 100644
index 00000000000..68ecb381348
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-enum.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+  --> $DIR/expr-struct-type-relative-enum.rs:16:9
+   |
+LL |         needs_infer();
+   |         ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `needs_infer`
+   |
+help: consider specifying the generic argument
+   |
+LL |         needs_infer::<T>();
+   |                    +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
new file mode 100644
index 00000000000..bcd29bb4e34
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.rs
@@ -0,0 +1,21 @@
+#![feature(generic_associated_types)]
+
+trait Foo {
+    type Output<T>;
+
+    fn baz();
+}
+
+enum Bar<T> {
+    Simple {},
+    Generic(T),
+}
+
+impl Foo for u8 {
+    type Output<T> = Bar<T>;
+    fn baz() {
+        Self::Output::Simple {}; //~ ERROR type annotations needed
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
new file mode 100644
index 00000000000..65a75b68c1f
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative-gat.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/expr-struct-type-relative-gat.rs:17:9
+   |
+LL |         Self::Output::Simple {};
+   |         ^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated type `Output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative.rs b/src/test/ui/inference/need_type_info/expr-struct-type-relative.rs
new file mode 100644
index 00000000000..c3ece2b16cf
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative.rs
@@ -0,0 +1,21 @@
+// regression test for #98598
+
+trait Foo {
+    type Output;
+
+    fn baz() -> Self::Output;
+}
+
+fn needs_infer<T>() {}
+
+struct Bar {}
+
+impl Foo for u8 {
+    type Output = Bar;
+    fn baz() -> Self::Output {
+        needs_infer(); //~ ERROR type annotations needed
+        Self::Output {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/expr-struct-type-relative.stderr b/src/test/ui/inference/need_type_info/expr-struct-type-relative.stderr
new file mode 100644
index 00000000000..397d8e7be04
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/expr-struct-type-relative.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+  --> $DIR/expr-struct-type-relative.rs:16:9
+   |
+LL |         needs_infer();
+   |         ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `needs_infer`
+   |
+help: consider specifying the generic argument
+   |
+LL |         needs_infer::<T>();
+   |                    +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.