about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-30 09:35:22 +0000
committerbors <bors@rust-lang.org>2022-07-30 09:35:22 +0000
commit110777b60c0c02a9bb62c6ffc081dc276de81210 (patch)
tree4b11b80567388b669a66d93b157bc2781abd198b
parent760d8a2cb169974971cb54302c857bfed0070f6e (diff)
parent16f49800db7be11e7255036f05ca811c1bf98926 (diff)
downloadrust-110777b60c0c02a9bb62c6ffc081dc276de81210.tar.gz
rust-110777b60c0c02a9bb62c6ffc081dc276de81210.zip
Auto merge of #99796 - compiler-errors:issue-53475, r=oli-obk
use `check_region_obligations_and_report_errors` to avoid ICEs

If we don't call `process_registered_region_obligations` before `resolve_regions_and_report_errors` then we'll ICE if we have any region obligations, and `check_region_obligations_and_report_errors` just does both of these for us in a nice convenient function.

Fixes #53475

r? types
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs8
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs6
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs4
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs3
-rw-r--r--src/test/ui/coercion/issue-53475.rs13
-rw-r--r--src/test/ui/coercion/issue-53475.stderr14
8 files changed, 45 insertions, 13 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 21045a0585c..6d5f4993d8d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1325,6 +1325,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// result. After this, no more unification operations should be
     /// done -- or the compiler will panic -- but it is legal to use
     /// `resolve_vars_if_possible` as well as `fully_resolve`.
+    ///
+    /// Make sure to call [`InferCtxt::process_registered_region_obligations`]
+    /// first, or preferrably use [`InferCtxt::check_region_obligations_and_report_errors`]
+    /// to do both of these operations together.
     pub fn resolve_regions_and_report_errors(
         &self,
         generic_param_scope: LocalDefId,
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index a57971bfb69..ad052f58ca8 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -111,6 +111,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         std::mem::take(&mut self.inner.borrow_mut().region_obligations)
     }
 
+    /// NOTE: Prefer using [`InferCtxt::check_region_obligations_and_report_errors`]
+    /// instead of calling this directly.
+    ///
     /// Process the region obligations that must be proven (during
     /// `regionck`) for the given `body_id`, given information about
     /// the region bounds in scope and so forth. This function must be
@@ -162,6 +165,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
         }
     }
 
+    /// Processes registered region obliations and resolves regions, reporting
+    /// any errors if any were raised. Prefer using this function over manually
+    /// calling `resolve_regions_and_report_errors`.
     pub fn check_region_obligations_and_report_errors(
         &self,
         generic_param_scope: LocalDefId,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index fa94aa19abd..f62ccb99df5 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -398,13 +398,7 @@ fn resolve_negative_obligation<'cx, 'tcx>(
     let outlives_env = OutlivesEnvironment::new(param_env);
     infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env);
 
-    let errors = infcx.resolve_regions(&outlives_env);
-
-    if !errors.is_empty() {
-        return false;
-    }
-
-    true
+    infcx.resolve_regions(&outlives_env).is_empty()
 }
 
 pub fn trait_ref_is_knowable<'tcx>(
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index af77efc3c2d..e3ac23686b6 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1154,8 +1154,10 @@ pub(crate) fn compare_const_impl<'tcx>(
         }
 
         let outlives_environment = OutlivesEnvironment::new(param_env);
-        infcx
-            .resolve_regions_and_report_errors(impl_c.def_id.expect_local(), &outlives_environment);
+        infcx.check_region_obligations_and_report_errors(
+            impl_c.def_id.expect_local(),
+            &outlives_environment,
+        );
     });
 }
 
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index d8e42729ff3..1e404fda035 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -349,7 +349,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
 
                     // Finally, resolve all regions.
                     let outlives_env = OutlivesEnvironment::new(param_env);
-                    infcx.resolve_regions_and_report_errors(impl_did, &outlives_env);
+                    infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
                 }
             }
             _ => {
@@ -606,7 +606,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
 
         // Finally, resolve all regions.
         let outlives_env = OutlivesEnvironment::new(param_env);
-        infcx.resolve_regions_and_report_errors(impl_did, &outlives_env);
+        infcx.check_region_obligations_and_report_errors(impl_did, &outlives_env);
 
         CoerceUnsizedInfo { custom_kind: kind }
     })
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
index f16888345e9..74abb71a18e 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
@@ -158,8 +158,7 @@ fn get_impl_substs<'tcx>(
         implied_bounds,
         tcx.hir().local_def_id_to_hir_id(impl1_def_id),
     );
-    infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env);
-    infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
+    infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
     let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
         let span = tcx.def_span(impl1_def_id);
         tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
diff --git a/src/test/ui/coercion/issue-53475.rs b/src/test/ui/coercion/issue-53475.rs
new file mode 100644
index 00000000000..3770c024fb9
--- /dev/null
+++ b/src/test/ui/coercion/issue-53475.rs
@@ -0,0 +1,13 @@
+#![feature(coerce_unsized)]
+
+use std::any::Any;
+use std::ops::CoerceUnsized;
+
+struct Foo<T> {
+    data: Box<T>,
+}
+
+impl<T> CoerceUnsized<Foo<dyn Any>> for Foo<T> {}
+//~^ ERROR the parameter type `T` may not live long enough
+
+fn main() {}
diff --git a/src/test/ui/coercion/issue-53475.stderr b/src/test/ui/coercion/issue-53475.stderr
new file mode 100644
index 00000000000..522c50dca95
--- /dev/null
+++ b/src/test/ui/coercion/issue-53475.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/issue-53475.rs:10:1
+   |
+LL | impl<T> CoerceUnsized<Foo<dyn Any>> for Foo<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL | impl<T: 'static> CoerceUnsized<Foo<dyn Any>> for Foo<T> {}
+   |       +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.