about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs142
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs12
3 files changed, 86 insertions, 70 deletions
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index b19fb6da6de..e426b937542 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let inferred_sig = self.normalize(
                     span,
                     self.deduce_sig_from_projection(
-                    Some(span),
+                        Some(span),
                         bound_predicate.rebind(proj_predicate),
                     ),
                 );
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index f50aeaf4511..5be67a4b14e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         else {
             return false;
         };
-        let hir = self.tcx.hir();
-        let hir::Node::Expr(expr) = hir.get(hir_id) else {
-            return false;
-        };
 
         let Some(unsubstituted_pred) = self
             .tcx
@@ -69,15 +65,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Account for enum variant constructors, where the type param corresponds to the enum
         // itself.
-        let enum_def_id = if let hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _) =
-            self.tcx.def_kind(def_id)
-        {
-            // `def_id` corresponds to a constructor, and its parent is the variant, and we want
-            // the enum.
-            Some(self.tcx.parent(self.tcx.parent(def_id)))
-        } else {
-            None
-        };
+        let enum_def_id =
+            if let DefKind::Ctor(hir::def::CtorOf::Variant, _) = self.tcx.def_kind(def_id) {
+                // `def_id` corresponds to a constructor, and its parent is the variant, and we want
+                // the enum.
+                Some(self.tcx.parent(self.tcx.parent(def_id)))
+            } else {
+                None
+            };
         let variant_param_to_point_at = find_param_matching(&|param_term| {
             // FIXME: It would be nice to make this not use string manipulation,
             // but it's pretty hard to do this, since `ty::ParamTy` is missing
@@ -90,11 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             // Account for enum variant constructors, where the type param corresponds to the enum
             // itself.
-            let def_id = if let Some(def_id) = enum_def_id {
-                def_id
-            } else {
-                def_id
-            };
+            let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id };
             self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id
                 && include
         });
@@ -127,68 +118,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
         }
 
-        if self.closure_span_overlaps_error(error, expr.span) {
-            return false;
-        }
-
-        match &expr.kind {
-            hir::ExprKind::Path(qpath) => {
-                let def_id = if let Some(def_id) = enum_def_id {
-                    def_id
-                } else {
-                    def_id
-                };
-                if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind {
-                    for segment in path.segments {
-                        if let Some(param) = variant_param_to_point_at
-                            && self.point_at_generic_if_possible(error, def_id, param, segment)
-                        {
-                            return true;
-                        }
-                    }
+        let hir = self.tcx.hir();
+        let (expr, qpath) = match hir.get(hir_id) {
+            hir::Node::Expr(expr) => {
+                if self.closure_span_overlaps_error(error, expr.span) {
+                    return false;
                 }
-                if let hir::Node::Expr(hir::Expr {
-                    kind: hir::ExprKind::Call(callee, args),
-                    hir_id: call_hir_id,
-                    span: call_span,
-                    ..
-                }) = hir.get_parent(expr.hir_id)
-                    && callee.hir_id == expr.hir_id
-                {
-                    if self.closure_span_overlaps_error(error, *call_span) {
-                        return false;
-                    }
+                let qpath =
+                    if let hir::ExprKind::Path(qpath) = expr.kind { Some(qpath) } else { None };
 
-                    for param in
-                        [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
-                        .into_iter()
-                        .flatten()
+                (Some(*expr), qpath)
+            }
+            hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => (None, Some(*qpath)),
+            _ => return false,
+        };
+
+        if let Some(qpath) = qpath {
+            let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id };
+            if let hir::QPath::Resolved(None, path) = qpath {
+                for segment in path.segments {
+                    if let Some(param) = variant_param_to_point_at
+                        && self.point_at_generic_if_possible(error, def_id, param, segment)
                     {
-                        if self.blame_specific_arg_if_possible(
-                                error,
-                                def_id,
-                                param,
-                                *call_hir_id,
-                                callee.span,
-                                None,
-                                args,
-                            )
-                        {
-                            return true;
-                        }
+                        return true;
                     }
                 }
+            }
+            if let hir::QPath::TypeRelative(_ty, segment) = qpath {
+                if let Some(param) = variant_param_to_point_at
+                    && self.point_at_generic_if_possible(error, def_id, param, segment)
+                {
+                    return true;
+                }
+            }
+            if let hir::Node::Expr(hir::Expr {
+                kind: hir::ExprKind::Call(callee, args),
+                hir_id: call_hir_id,
+                span: call_span,
+                ..
+            }) = hir.get_parent(hir_id)
+                && callee.hir_id == hir_id
+            {
+                if self.closure_span_overlaps_error(error, *call_span) {
+                    return false;
+                }
 
-                for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                for param in
+                    [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
                     .into_iter()
                     .flatten()
                 {
-                    if self.point_at_path_if_possible(error, def_id, param, qpath) {
+                    if self.blame_specific_arg_if_possible(
+                            error,
+                            def_id,
+                            param,
+                            *call_hir_id,
+                            callee.span,
+                            None,
+                            args,
+                        )
+                    {
                         return true;
                     }
                 }
             }
-            hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
+
+            for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
+                .into_iter()
+                .flatten()
+            {
+                if self.point_at_path_if_possible(error, def_id, param, &qpath) {
+                    return true;
+                }
+            }
+        }
+
+        match expr.map(|e| e.kind) {
+            Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => {
                 for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
                     .into_iter()
                     .flatten()
@@ -220,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     return true;
                 }
             }
-            hir::ExprKind::Struct(qpath, fields, ..) => {
+            Some(hir::ExprKind::Struct(qpath, fields, ..)) => {
                 if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
                     self.typeck_results.borrow().qpath_res(qpath, hir_id)
                 {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 6a82b00211e..45bf43efa83 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -317,7 +317,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
 
     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
         // FIXME: normalization and escaping regions
-        let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
+        let ty = if !ty.has_escaping_bound_vars() {
+            if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) =
+                ty.kind()
+            {
+                self.add_required_obligations_for_hir(span, *def_id, args, hir_id);
+                self.select_obligations_where_possible(|_| {});
+            }
+            self.normalize(span, ty)
+        } else {
+            ty
+        };
         self.write_ty(hir_id, ty)
     }