about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-09 08:40:08 +0000
committerbors <bors@rust-lang.org>2023-01-09 08:40:08 +0000
commitc54c8cbac882e149e04a9e1f2d146fd548ae30ae (patch)
tree150c71f8e82da696d81c791a7e4e732b660a79bd /compiler/rustc_hir_analysis
parent2e677c0645862d17a12c6d04b3019203c8e23fcc (diff)
parente77e8eb9455264b70eb4344a404243b7c012db08 (diff)
downloadrust-c54c8cbac882e149e04a9e1f2d146fd548ae30ae.tar.gz
rust-c54c8cbac882e149e04a9e1f2d146fd548ae30ae.zip
Auto merge of #106582 - compiler-errors:better-spans-on-bad-tys, r=lcnr
Improve spans of non-WF implied bound types

Fixes #60980
Diffstat (limited to 'compiler/rustc_hir_analysis')
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs65
1 files changed, 25 insertions, 40 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 1afe6242403..969f7de51ce 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -97,21 +97,22 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
     let infcx = &tcx.infer_ctxt().build();
     let ocx = ObligationCtxt::new(infcx);
 
-    let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id);
-
     let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env };
 
     if !tcx.features().trivial_bounds {
         wfcx.check_false_global_bounds()
     }
     f(&mut wfcx);
+
+    let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id);
+    let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
+
     let errors = wfcx.select_all_or_error();
     if !errors.is_empty() {
         infcx.err_ctxt().report_fulfillment_errors(&errors, None);
         return;
     }
 
-    let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types);
     let outlives_environment =
         OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
 
@@ -1489,54 +1490,38 @@ fn check_fn_or_method<'tcx>(
     def_id: LocalDefId,
 ) {
     let tcx = wfcx.tcx();
-    let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
+    let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig);
 
     // Normalize the input and output types one at a time, using a different
     // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
     // on the entire `FnSig`, since this would use the same `WellFormedLoc`
     // for each type, preventing the HIR wf check from generating
     // a nice error message.
-    let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
-    inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
-        wfcx.normalize(
-            span,
-            Some(WellFormedLoc::Param {
-                function: def_id,
-                // Note that the `param_idx` of the output type is
-                // one greater than the index of the last input type.
-                param_idx: i.try_into().unwrap(),
-            }),
-            ty,
-        )
-    }));
-    // Manually call `normalize_associated_types_in` on the other types
-    // in `FnSig`. This ensures that if the types of these fields
-    // ever change to include projections, we will start normalizing
-    // them automatically.
-    let sig = ty::FnSig {
-        inputs_and_output,
-        c_variadic: wfcx.normalize(span, None, c_variadic),
-        unsafety: wfcx.normalize(span, None, unsafety),
-        abi: wfcx.normalize(span, None, abi),
-    };
+    let arg_span =
+        |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span);
+
+    sig.inputs_and_output =
+        tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
+            wfcx.normalize(
+                arg_span(idx),
+                Some(WellFormedLoc::Param {
+                    function: def_id,
+                    // Note that the `param_idx` of the output type is
+                    // one greater than the index of the last input type.
+                    param_idx: idx.try_into().unwrap(),
+                }),
+                ty,
+            )
+        }));
 
-    for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
+    for (idx, ty) in sig.inputs_and_output.iter().enumerate() {
         wfcx.register_wf_obligation(
-            ty.span,
-            Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }),
-            input_ty.into(),
+            arg_span(idx),
+            Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }),
+            ty.into(),
         );
     }
 
-    wfcx.register_wf_obligation(
-        hir_decl.output.span(),
-        Some(WellFormedLoc::Param {
-            function: def_id,
-            param_idx: sig.inputs().len().try_into().unwrap(),
-        }),
-        sig.output().into(),
-    );
-
     check_where_clauses(wfcx, span, def_id);
 
     check_return_position_impl_trait_in_trait_bounds(