diff options
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/check_consts/qualifs.rs | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 9fd7219499b..d5d3f7767b1 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -100,7 +100,33 @@ impl Qualif for HasMutInterior { } fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool { - !ty.is_freeze(cx.tcx, cx.param_env) + // Avoid selecting for simple cases, such as builtin types. + if ty.is_trivially_freeze() { + return false; + } + + // We do not use `ty.is_freeze` here, because that requires revealing opaque types, which + // requires borrowck, which in turn will invoke mir_const_qualifs again, causing a cycle error. + // Instead we invoke an obligation context manually, and provide the opaque type inference settings + // that allow the trait solver to just error out instead of cycling. + let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span)); + + let obligation = Obligation::new( + cx.tcx, + ObligationCause::dummy_with_span(cx.body.span), + cx.param_env, + ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]), + ); + + let infcx = cx + .tcx + .infer_ctxt() + .with_opaque_type_inference(cx.body.source.def_id().expect_local()) + .build(); + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligation(obligation); + let errors = ocx.select_all_or_error(); + !errors.is_empty() } fn in_adt_inherently<'tcx>( |
