about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs16
-rw-r--r--compiler/rustc_borrowck/src/invalidation.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs2
-rw-r--r--compiler/rustc_const_eval/messages.ftl3
-rw-r--r--compiler/rustc_const_eval/src/errors.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs12
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs94
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs6
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs32
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs10
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs2
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs2
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs6
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs4
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr26
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr13
35 files changed, 213 insertions, 102 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 15d73ed732f..fd5c21cfdf6 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -14,7 +14,7 @@ use rustc_infer::traits::ObligationCause;
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
-    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
+    self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
     FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
     ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
 };
@@ -2579,7 +2579,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diagnostic) {
         let tcx = self.infcx.tcx;
         if let (
-            Some(Terminator { kind: TerminatorKind::Call { from_hir_call: false, .. }, .. }),
+            Some(Terminator {
+                kind: TerminatorKind::Call { call_source: CallSource::OverloadedOperator, .. },
+                ..
+            }),
             Some((method_did, method_substs)),
         ) = (
             &self.body[loan.reserve_location.block].terminator,
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 1d430a93a87..6c01fd63b1e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor;
 use rustc_index::IndexSlice;
 use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::mir::{
-    Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place,
-    Rvalue, Statement, StatementKind, TerminatorKind,
+    Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
+    Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
 };
 use rustc_middle::ty::adjustment::PointerCast;
 use rustc_middle::ty::{self, RegionVid, TyCtxt};
@@ -494,7 +494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 } else if self.was_captured_by_trait_object(borrow) {
                     LaterUseKind::TraitCapture
                 } else if location.statement_index == block.statements.len() {
-                    if let TerminatorKind::Call { func, from_hir_call: true, .. } =
+                    if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
                         &block.terminator().kind
                     {
                         // Just point to the function, to reduce the chance of overlapping spans.
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 20370e4c6ac..1d3cc851888 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -13,8 +13,9 @@ use rustc_index::IndexSlice;
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::{
-    AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place,
-    PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
+    AggregateKind, CallSource, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location,
+    Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
+    TerminatorKind,
 };
 use rustc_middle::ty::print::Print;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
@@ -414,7 +415,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     if !is_terminator {
                         continue;
                     } else if let Some(Terminator {
-                        kind: TerminatorKind::Call { func, from_hir_call: false, .. },
+                        kind:
+                            TerminatorKind::Call {
+                                func,
+                                call_source: CallSource::OverloadedOperator,
+                                ..
+                            },
                         ..
                     }) = &bbd.terminator
                     {
@@ -839,7 +845,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         debug!("move_spans: target_temp = {:?}", target_temp);
 
         if let Some(Terminator {
-            kind: TerminatorKind::Call { fn_span, from_hir_call, .. }, ..
+            kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
         }) = &self.body[location.block].terminator
         {
             let Some((method_did, method_substs)) =
@@ -859,7 +865,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 method_did,
                 method_substs,
                 *fn_span,
-                *from_hir_call,
+                call_source.from_hir_call(),
                 Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
             );
 
diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs
index b2ff25ecb96..e4fbe6ea4f4 100644
--- a/compiler/rustc_borrowck/src/invalidation.rs
+++ b/compiler/rustc_borrowck/src/invalidation.rs
@@ -128,7 +128,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 destination,
                 target: _,
                 unwind: _,
-                from_hir_call: _,
+                call_source: _,
                 fn_span: _,
             } => {
                 self.consume_operand(location, func);
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 99a988f2c62..4fcdda311bf 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -710,7 +710,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
                 destination,
                 target: _,
                 unwind: _,
-                from_hir_call: _,
+                call_source: _,
                 fn_span: _,
             } => {
                 self.consume_operand(loc, (func, span), flow_state);
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6697e1aff7d..dba1993a8c3 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1370,7 +1370,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
                 // FIXME: check the values
             }
-            TerminatorKind::Call { func, args, destination, from_hir_call, target, .. } => {
+            TerminatorKind::Call { func, args, destination, call_source, target, .. } => {
                 self.check_operand(func, term_location);
                 for arg in args {
                     self.check_operand(arg, term_location);
@@ -1444,7 +1444,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         .add_element(region_vid, term_location);
                 }
 
-                self.check_call_inputs(body, term, &sig, args, term_location, *from_hir_call);
+                self.check_call_inputs(body, term, &sig, args, term_location, *call_source);
             }
             TerminatorKind::Assert { cond, msg, .. } => {
                 self.check_operand(cond, term_location);
@@ -1571,7 +1571,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         sig: &ty::FnSig<'tcx>,
         args: &[Operand<'tcx>],
         term_location: Location,
-        from_hir_call: bool,
+        call_source: CallSource,
     ) {
         debug!("check_call_inputs({:?}, {:?})", sig, args);
         if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
@@ -1589,7 +1589,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             let op_arg_ty = op_arg.ty(body, self.tcx());
 
             let op_arg_ty = self.normalize(op_arg_ty, term_location);
-            let category = if from_hir_call {
+            let category = if call_source.from_hir_call() {
                 ConstraintCategory::CallArgument(self.infcx.tcx.erase_regions(func_ty))
             } else {
                 ConstraintCategory::Boring
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 5abb4644e1b..ce10780f9de 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -421,7 +421,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 target,
                 fn_span,
                 unwind: _,
-                from_hir_call: _,
+                call_source: _,
             } => {
                 fx.tcx.prof.generic_activity("codegen call").run(|| {
                     crate::abi::codegen_terminator_call(
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a4a8aad8726..0cec560ba45 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1280,7 +1280,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 destination,
                 target,
                 unwind,
-                from_hir_call: _,
+                call_source: _,
                 fn_span,
             } => self.codegen_call_terminator(
                 helper,
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index bf660c59cab..e99005316b3 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -210,6 +210,9 @@ const_eval_long_running =
     .label = the const evaluator is currently interpreting this expression
     .help = the constant being evaluated
 
+const_eval_match_eq_non_const = cannot match on `{$ty}` in {const_eval_const_context}s
+    .note = `{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es
+
 const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
 
 const_eval_memory_access_test = memory access failed
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index eed3091d481..ca38cce710e 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -271,6 +271,18 @@ pub struct RawBytesNote {
     pub bytes: String,
 }
 
+// FIXME(fee1-dead) do not use stringly typed `ConstContext`
+
+#[derive(Diagnostic)]
+#[diag(const_eval_match_eq_non_const, code = "E0015")]
+#[note]
+pub struct NonConstMatchEq<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub ty: Ty<'tcx>,
+    pub kind: ConstContext,
+}
+
 #[derive(Diagnostic)]
 #[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")]
 pub struct NonConstForLoopIntoIter<'tcx> {
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 7269ff8d53c..719d8a14b41 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -62,7 +62,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 destination,
                 target,
                 unwind,
-                from_hir_call: _,
+                call_source: _,
                 fn_span: _,
             } => {
                 let old_stack = self.frame_idx();
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 106cf111474..2aaf1340eb4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -702,7 +702,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
         self.super_terminator(terminator, location);
 
         match &terminator.kind {
-            TerminatorKind::Call { func, args, fn_span, from_hir_call, .. } => {
+            TerminatorKind::Call { func, args, fn_span, call_source, .. } => {
                 let ConstCx { tcx, body, param_env, .. } = *self.ccx;
                 let caller = self.def_id();
 
@@ -755,7 +755,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             callee,
                             substs,
                             span: *fn_span,
-                            from_hir_call: *from_hir_call,
+                            call_source: *call_source,
                             feature: Some(sym::const_trait_impl),
                         });
                         return;
@@ -797,7 +797,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                                     callee,
                                     substs,
                                     span: *fn_span,
-                                    from_hir_call: *from_hir_call,
+                                    call_source: *call_source,
                                     feature: None,
                                 });
 
@@ -823,7 +823,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                                     callee,
                                     substs,
                                     span: *fn_span,
-                                    from_hir_call: *from_hir_call,
+                                    call_source: *call_source,
                                     feature: None,
                                 });
                                 return;
@@ -866,7 +866,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                                     callee,
                                     substs,
                                     span: *fn_span,
-                                    from_hir_call: *from_hir_call,
+                                    call_source: *call_source,
                                     feature: None,
                                 });
                                 return;
@@ -926,7 +926,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             callee,
                             substs,
                             span: *fn_span,
-                            from_hir_call: *from_hir_call,
+                            call_source: *call_source,
                             feature: None,
                         });
                         return;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 236e43bdfcc..32bd9cda6f2 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
-use rustc_middle::mir;
+use rustc_middle::mir::{self, CallSource};
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
 use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty};
@@ -100,7 +100,7 @@ pub struct FnCallNonConst<'tcx> {
     pub callee: DefId,
     pub substs: SubstsRef<'tcx>,
     pub span: Span,
-    pub from_hir_call: bool,
+    pub call_source: CallSource,
     pub feature: Option<Symbol>,
 }
 
@@ -110,7 +110,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
         ccx: &ConstCx<'_, 'tcx>,
         _: Span,
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let FnCallNonConst { caller, callee, substs, span, from_hir_call, feature } = *self;
+        let FnCallNonConst { caller, callee, substs, span, call_source, feature } = *self;
         let ConstCx { tcx, param_env, .. } = *ccx;
 
         let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
@@ -157,7 +157,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
             }
         };
 
-        let call_kind = call_kind(tcx, ccx.param_env, callee, substs, span, from_hir_call, None);
+        let call_kind =
+            call_kind(tcx, ccx.param_env, callee, substs, span, call_source.from_hir_call(), None);
 
         debug!(?call_kind);
 
@@ -219,48 +220,59 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                 err
             }
             CallKind::Operator { trait_id, self_ty, .. } => {
-                let mut sugg = None;
-
-                if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
-                    match (substs[0].unpack(), substs[1].unpack()) {
-                        (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
-                            if self_ty == rhs_ty
-                                && self_ty.is_ref()
-                                && self_ty.peel_refs().is_primitive() =>
-                        {
-                            let mut num_refs = 0;
-                            let mut tmp_ty = self_ty;
-                            while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
-                                num_refs += 1;
-                                tmp_ty = *inner_ty;
-                            }
-                            let deref = "*".repeat(num_refs);
-
-                            if let Ok(call_str) = ccx.tcx.sess.source_map().span_to_snippet(span) {
-                                if let Some(eq_idx) = call_str.find("==") {
-                                    if let Some(rhs_idx) =
-                                        call_str[(eq_idx + 2)..].find(|c: char| !c.is_whitespace())
-                                    {
-                                        let rhs_pos =
-                                            span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx);
-                                        let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
-                                        sugg = Some(errors::ConsiderDereferencing {
-                                            deref,
-                                            span: span.shrink_to_lo(),
-                                            rhs_span,
-                                        });
+                let mut err = if let CallSource::MatchCmp = call_source {
+                    tcx.sess.create_err(errors::NonConstMatchEq {
+                        span,
+                        kind: ccx.const_kind(),
+                        ty: self_ty,
+                    })
+                } else {
+                    let mut sugg = None;
+
+                    if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
+                        match (substs[0].unpack(), substs[1].unpack()) {
+                            (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
+                                if self_ty == rhs_ty
+                                    && self_ty.is_ref()
+                                    && self_ty.peel_refs().is_primitive() =>
+                            {
+                                let mut num_refs = 0;
+                                let mut tmp_ty = self_ty;
+                                while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
+                                    num_refs += 1;
+                                    tmp_ty = *inner_ty;
+                                }
+                                let deref = "*".repeat(num_refs);
+
+                                if let Ok(call_str) =
+                                    ccx.tcx.sess.source_map().span_to_snippet(span)
+                                {
+                                    if let Some(eq_idx) = call_str.find("==") {
+                                        if let Some(rhs_idx) = call_str[(eq_idx + 2)..]
+                                            .find(|c: char| !c.is_whitespace())
+                                        {
+                                            let rhs_pos = span.lo()
+                                                + BytePos::from_usize(eq_idx + 2 + rhs_idx);
+                                            let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
+                                            sugg = Some(errors::ConsiderDereferencing {
+                                                deref,
+                                                span: span.shrink_to_lo(),
+                                                rhs_span,
+                                            });
+                                        }
                                     }
                                 }
                             }
+                            _ => {}
                         }
-                        _ => {}
                     }
-                }
-                let mut err = tcx.sess.create_err(errors::NonConstOperator {
-                    span,
-                    kind: ccx.const_kind(),
-                    sugg,
-                });
+                    tcx.sess.create_err(errors::NonConstOperator {
+                        span,
+                        kind: ccx.const_kind(),
+                        sugg,
+                    })
+                };
+
                 diag_trait(&mut err, self_ty, trait_id);
                 err
             }
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 0e2d9ee8fb2..809cf62d814 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -795,7 +795,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
             };
 
             match terminator.kind {
-                TerminatorKind::Call { mut func, mut args, from_hir_call, fn_span, .. } => {
+                TerminatorKind::Call {
+                    mut func, mut args, call_source: desugar, fn_span, ..
+                } => {
                     self.visit_operand(&mut func, loc);
                     for arg in &mut args {
                         self.visit_operand(arg, loc);
@@ -811,7 +813,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                             unwind: UnwindAction::Continue,
                             destination: Place::from(new_temp),
                             target: Some(new_target),
-                            from_hir_call,
+                            call_source: desugar,
                             fn_span,
                         },
                         source_info: SourceInfo::outermost(terminator.source_info.span),
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 1a65f74f4fe..fb3841f8776 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -512,6 +512,31 @@ pub struct CopyNonOverlapping<'tcx> {
     pub count: Operand<'tcx>,
 }
 
+/// Represents how a `TerminatorKind::Call` was constructed, used for diagnostics
+#[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, PartialEq, Hash, HashStable)]
+#[derive(TypeFoldable, TypeVisitable)]
+pub enum CallSource {
+    /// This came from something such as `a > b` or `a + b`. In THIR, if `from_hir_call`
+    /// is false then this is the desugaring.
+    OverloadedOperator,
+    /// This was from comparison generated by a match, used by const-eval for better errors
+    /// when the comparison cannot be done in compile time.
+    ///
+    /// See https://github.com/rust-lang/rust/issues/90237.
+    MatchCmp,
+    /// Other types of desugaring that did not come from the HIR, but we don't care about
+    /// for diagnostics (yet).
+    Misc,
+    /// Normal function call, no special source
+    Normal,
+}
+
+impl CallSource {
+    pub fn from_hir_call(self) -> bool {
+        matches!(self, CallSource::Normal)
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Terminators
 
@@ -638,11 +663,10 @@ pub enum TerminatorKind<'tcx> {
         target: Option<BasicBlock>,
         /// Action to be taken if the call unwinds.
         unwind: UnwindAction,
-        /// `true` if this is from a call in HIR rather than from an overloaded
-        /// operator. True for overloaded function call.
-        from_hir_call: bool,
+        /// Where this call came from in HIR/THIR.
+        call_source: CallSource,
         /// This `Span` is the span of the function, without the dot and receiver
-        /// (e.g. `foo(a, b)` in `x.foo(a, b)`
+        /// e.g. `foo(a, b)` in `x.foo(a, b)`
         fn_span: Span,
     },
 
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 8d44e929afd..ce55b770cbc 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -519,7 +519,7 @@ macro_rules! make_mir_visitor {
                         destination,
                         target: _,
                         unwind: _,
-                        from_hir_call: _,
+                        call_source: _,
                         fn_span: _
                     } => {
                         self.visit_operand(func, location);
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index ebf830cb9c1..4cb9d7babe1 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -128,7 +128,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
                     destination,
                     target: Some(target),
                     unwind: UnwindAction::Continue,
-                    from_hir_call: *from_hir_call,
+                    call_source: if *from_hir_call { CallSource::Normal } else {
+                        CallSource::OverloadedOperator
+                    },
                     fn_span: *fn_span,
                 })
             },
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 3742d640e3b..fd08b32807c 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -173,7 +173,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         destination: storage,
                         target: Some(success),
                         unwind: UnwindAction::Continue,
-                        from_hir_call: false,
+                        call_source: CallSource::Misc,
                         fn_span: expr_span,
                     },
                 );
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 29ff916d2cc..731f3996244 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -277,7 +277,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             .ty
                             .is_inhabited_from(this.tcx, this.parent_module, this.param_env)
                             .then_some(success),
-                        from_hir_call,
+                        call_source: if from_hir_call {
+                            CallSource::Normal
+                        } else {
+                            CallSource::OverloadedOperator
+                        },
                         fn_span,
                     },
                 );
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index dbdb5b4a9a1..f431023f2b6 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -264,7 +264,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             destination: ref_str,
                             target: Some(eq_block),
                             unwind: UnwindAction::Continue,
-                            from_hir_call: false,
+                            call_source: CallSource::Misc,
                             fn_span: source_info.span
                         }
                     );
@@ -496,7 +496,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 destination: eq_result,
                 target: Some(eq_block),
                 unwind: UnwindAction::Continue,
-                from_hir_call: false,
+                call_source: CallSource::MatchCmp,
                 fn_span: source_info.span,
             },
         );
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 4fc45eaf522..27232b70d96 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -654,7 +654,7 @@ where
                     destination: unit_temp,
                     target: Some(succ),
                     unwind: unwind.into_action(),
-                    from_hir_call: true,
+                    call_source: CallSource::Misc,
                     fn_span: self.source_info.span,
                 },
                 source_info: self.source_info,
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 0c379288a09..804b44a6bf0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -502,15 +502,7 @@ impl Direction for Forward {
                 propagate(target, exit_state);
             }
 
-            Call {
-                unwind,
-                destination,
-                target,
-                func: _,
-                args: _,
-                from_hir_call: _,
-                fn_span: _,
-            } => {
+            Call { unwind, destination, target, func: _, args: _, call_source: _, fn_span: _ } => {
                 if let UnwindAction::Cleanup(unwind) = unwind {
                     propagate(unwind, exit_state);
                 }
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 45c2fe55aca..cb0ec144ef0 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -40,7 +40,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
             destination: dummy_place.clone(),
             target: Some(mir::START_BLOCK),
             unwind: mir::UnwindAction::Continue,
-            from_hir_call: false,
+            call_source: mir::CallSource::Misc,
             fn_span: DUMMY_SP,
         },
     );
@@ -54,7 +54,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
             destination: dummy_place.clone(),
             target: Some(mir::START_BLOCK),
             unwind: mir::UnwindAction::Continue,
-            from_hir_call: false,
+            call_source: mir::CallSource::Misc,
             fn_span: DUMMY_SP,
         },
     );
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 096bc0acfcc..fe9631653ea 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -399,7 +399,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 destination,
                 target,
                 unwind: _,
-                from_hir_call: _,
+                call_source: _,
                 fn_span: _,
             } => {
                 self.gather_operand(func);
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 90b58933df7..25891d3ca0f 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -140,7 +140,7 @@ impl<'tcx> MockBlocks<'tcx> {
                 destination: self.dummy_place.clone(),
                 target: Some(TEMP_BLOCK),
                 unwind: UnwindAction::Continue,
-                from_hir_call: false,
+                call_source: CallSource::Misc,
                 fn_span: DUMMY_SP,
             },
         )
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index b1c9c4acc40..7f631cccddf 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -34,7 +34,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
             destination: _,
             target: _,
             unwind: _,
-            from_hir_call: _,
+            call_source: _,
             fn_span: _,
         } = &terminator.kind
         {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index fe3f8ed047a..04134eb2fb1 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1692,7 +1692,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
                 destination,
                 target: Some(_),
                 unwind: _,
-                from_hir_call: _,
+                call_source: _,
                 fn_span: _,
             } => {
                 self.check_assigned_place(*destination, |this| {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 9c8c0ea0be0..fa8257cf984 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -30,8 +30,8 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_index::IndexVec;
 use rustc_middle::mir::visit::Visitor as _;
 use rustc_middle::mir::{
-    traversal, AnalysisPhase, Body, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, MirPass,
-    MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
+    traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstQualifs, Constant, LocalDecl,
+    MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
     Statement, StatementKind, TerminatorKind, START_BLOCK,
 };
 use rustc_middle::query::Providers;
@@ -189,7 +189,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
                     };
                     method(place)
                 }).collect();
-                terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, from_hir_call: false, fn_span };
+                terminator.kind = TerminatorKind::Call { func, args: arguments, destination, target, unwind, call_source: CallSource::Misc, fn_span };
             }
             _ => {}
         }
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index 6e40dfa0d13..b7cc0db9559 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -54,7 +54,7 @@ fn lower_slice_len_call<'tcx>(
             args,
             destination,
             target: Some(bb),
-            from_hir_call: true,
+            call_source: CallSource::Normal,
             ..
         } => {
             // some heuristics for fast rejection
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index 5f12f1937c0..9d6ef9db4ea 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -500,7 +500,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
                 destination: dest,
                 target: Some(next),
                 unwind: UnwindAction::Cleanup(cleanup),
-                from_hir_call: true,
+                call_source: CallSource::Normal,
                 fn_span: self.span,
             },
             false,
@@ -789,7 +789,7 @@ fn build_call_shim<'tcx>(
             } else {
                 UnwindAction::Continue
             },
-            from_hir_call: true,
+            call_source: CallSource::Misc,
             fn_span: span,
         },
         false,
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 6bd030b13d1..5327f8a3cc3 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -346,7 +346,7 @@ impl<'tcx> Stable for mir::Terminator<'tcx> {
                 target: target.as_usize(),
                 unwind: unwind.stable(),
             },
-            Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => {
+            Call { func, args, destination, target, unwind, call_source: _, fn_span: _ } => {
                 Terminator::Call {
                     func: func.stable(),
                     args: args.iter().map(|arg| arg.stable()).collect(),
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index c0d2c835d63..566eecf36a7 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -317,7 +317,7 @@ fn check_terminator<'tcx>(
         TerminatorKind::Call {
             func,
             args,
-            from_hir_call: _,
+            call_source: _,
             destination: _,
             target: _,
             unwind: _,
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr
new file mode 100644
index 00000000000..bd0dd126c5e
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr
@@ -0,0 +1,26 @@
+error[E0277]: can't compare `str` with `str` in const contexts
+  --> $DIR/match-non-const-eq.rs:6:9
+   |
+LL |         "a" => (),
+   |         ^^^ no implementation for `str == str`
+   |
+   = help: the trait `~const PartialEq` is not implemented for `str`
+note: the trait `PartialEq` is implemented for `str`, but that implementation is not `const`
+  --> $DIR/match-non-const-eq.rs:6:9
+   |
+LL |         "a" => (),
+   |         ^^^
+
+error[E0015]: cannot match on `str` in constant functions
+  --> $DIR/match-non-const-eq.rs:6:9
+   |
+LL |         "a" => (),
+   |         ^^^
+   |
+   = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0015, E0277.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs
new file mode 100644
index 00000000000..0d04101a383
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.rs
@@ -0,0 +1,12 @@
+// revisions: stock gated
+#![cfg_attr(gated, feature(const_trait_impl))]
+
+const fn foo(input: &'static str) {
+    match input {
+        "a" => (), //[gated]~ ERROR can't compare `str` with `str` in const contexts
+        //~^ ERROR cannot match on `str` in constant functions
+        _ => (),
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr
new file mode 100644
index 00000000000..dcb9b49ea04
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.stock.stderr
@@ -0,0 +1,13 @@
+error[E0015]: cannot match on `str` in constant functions
+  --> $DIR/match-non-const-eq.rs:6:9
+   |
+LL |         "a" => (),
+   |         ^^^
+   |
+   = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.