diff options
| author | bors <bors@rust-lang.org> | 2022-07-30 09:35:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-30 09:35:22 +0000 |
| commit | 110777b60c0c02a9bb62c6ffc081dc276de81210 (patch) | |
| tree | 4b11b80567388b669a66d93b157bc2781abd198b | |
| parent | 760d8a2cb169974971cb54302c857bfed0070f6e (diff) | |
| parent | 16f49800db7be11e7255036f05ca811c1bf98926 (diff) | |
| download | rust-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.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/outlives/obligations.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/compare_method.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/coherence/builtin.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs | 3 | ||||
| -rw-r--r-- | src/test/ui/coercion/issue-53475.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/coercion/issue-53475.stderr | 14 |
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`. |
