diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2023-03-24 09:17:51 +0000 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2023-03-28 08:39:55 +0000 |
| commit | b17e6680d668d136e643976c4079c7b1cac1b6b4 (patch) | |
| tree | c08029cdf9c2042474cac25244ffd654f143273b /compiler/rustc_const_eval | |
| parent | cbc064b341be231403d181402a786cce7f1c73f1 (diff) | |
Move const trait bounds checks to MIR constck
Fixes #109543. When checking paths in HIR typeck, we don't want to check for const predicates since all we want might just be a function pointer. Therefore we move this to MIR constck and check that bounds are met during MIR constck.
Diffstat (limited to 'compiler/rustc_const_eval')
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0d9cd78fe12..d6110a050f2 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -722,6 +722,32 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } }; + // Check that all trait bounds that are marked as `~const` can be satisfied. + // + // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish + // which path expressions are getting called on and which path expressions are only used + // as function pointers. This is required for correctness. + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + + let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); + let cause = ObligationCause::new( + terminator.source_info.span, + self.body.source.def_id().expect_local(), + ObligationCauseCode::ItemObligation(callee), + ); + let normalized_predicates = ocx.normalize(&cause, param_env, predicates); + ocx.register_obligations(traits::predicates_for_generics( + |_, _| cause.clone(), + self.param_env, + normalized_predicates, + )); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(&errors); + } + // Attempting to call a trait method? if let Some(trait_id) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); @@ -749,31 +775,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { selcx.select(&obligation) }; - // do a well-formedness check on the trait method being called. This is because typeck only does a - // "non-const" check. This is required for correctness here. - { - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); - - let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); - let cause = ObligationCause::new( - terminator.source_info.span, - self.body.source.def_id().expect_local(), - ObligationCauseCode::ItemObligation(callee), - ); - let normalized_predicates = ocx.normalize(&cause, param_env, predicates); - ocx.register_obligations(traits::predicates_for_generics( - |_, _| cause.clone(), - self.param_env, - normalized_predicates, - )); - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors); - } - } - match implsrc { Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { debug!( |
