Do not consider traits that have unsatisfied const conditions to be c… · rust-lang/rust@2669f2a (original) (raw)
`@@ -35,6 +35,12 @@ use crate::errors;
`
35
35
`type QualifResults<'mir, 'tcx, Q> =
`
36
36
` rustc_mir_dataflow::ResultsCursor<'mir, 'tcx, FlowSensitiveAnalysis<'mir, 'mir, 'tcx, Q>>;
`
37
37
``
``
38
`+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
`
``
39
`+
enum ConstConditionsHold {
`
``
40
`+
Yes,
`
``
41
`+
No,
`
``
42
`+
}
`
``
43
+
38
44
`#[derive(Default)]
`
39
45
`pub(crate) struct Qualifs<'mir, 'tcx> {
`
40
46
`has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
`
`@@ -376,15 +382,15 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
`
376
382
`callee: DefId,
`
377
383
`callee_args: ty::GenericArgsRef<'tcx>,
`
378
384
`call_span: Span,
`
379
``
`-
) -> bool {
`
``
385
`+
) -> Option {
`
380
386
`let tcx = self.tcx;
`
381
387
`if !tcx.is_conditionally_const(callee) {
`
382
``
`-
return false;
`
``
388
`+
return None;
`
383
389
`}
`
384
390
``
385
391
`let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
`
386
392
`if const_conditions.is_empty() {
`
387
``
`-
return false;
`
``
393
`+
return None;
`
388
394
`}
`
389
395
``
390
396
`let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
`
`@@ -413,12 +419,13 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
`
413
419
`}));
`
414
420
``
415
421
`let errors = ocx.select_all_or_error();
`
416
``
`-
if !errors.is_empty() {
`
``
422
`+
if errors.is_empty() {
`
``
423
`+
Some(ConstConditionsHold::Yes)
`
``
424
`+
} else {
`
417
425
` tcx.dcx()
`
418
426
`.span_delayed_bug(call_span, "this should have reported a ~const error in HIR");
`
``
427
`+
Some(ConstConditionsHold::No)
`
419
428
`}
`
420
``
-
421
``
`-
true
`
422
429
`}
`
423
430
``
424
431
`pub fn check_drop_terminator(
`
`@@ -706,7 +713,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
`
706
713
`trace!("attempting to call a trait method");
`
707
714
`let trait_is_const = tcx.is_const_trait(trait_did);
`
708
715
``
709
``
`-
if trait_is_const {
`
``
716
`+
// Only consider a trait to be const if the const conditions hold.
`
``
717
`+
// Otherwise, it's really misleading to call something "conditionally"
`
``
718
`+
// const when it's very obviously not conditionally const.
`
``
719
`+
if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) {
`
710
720
`// Trait calls are always conditionally-const.
`
711
721
`self.check_op(ops::ConditionallyConstCall {
`
712
722
` callee,
`
`@@ -730,7 +740,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
`
730
740
`}
`
731
741
``
732
742
`// Even if we know the callee, ensure we can use conditionally-const calls.
`
733
``
`-
if has_const_conditions {
`
``
743
`+
if has_const_conditions.is_some() {
`
734
744
`self.check_op(ops::ConditionallyConstCall {
`
735
745
` callee,
`
736
746
`args: fn_args,
`