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,

`