Skip to content

Commit

Permalink
Auto merge of #99796 - compiler-errors:issue-53475, r=oli-obk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jul 30, 2022
2 parents 760d8a2 + 16f4980 commit 110777b
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 13 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
});
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
_ => {
Expand Down Expand Up @@ -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 }
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/coercion/issue-53475.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 14 additions & 0 deletions src/test/ui/coercion/issue-53475.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 110777b

Please sign in to comment.