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_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 @@ pub(crate) fn report_illegal_mutation_of_borrowed( 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_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 @@ fn later_use_kind( } 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_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 @@ pub(super) fn borrowed_content_source( 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 @@ pub(super) fn move_spans( 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 @@ pub(super) fn move_spans( 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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 @@ fn visit_terminator_before_primary_effect( 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 @@ fn check_terminator( } // 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 @@ fn check_terminator( .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 @@ fn check_call_inputs( 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 @@ fn check_call_inputs( 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 @@ fn codegen_terminator( 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 @@ pub(super) fn eval_terminator( 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); @@ -823,7 +823,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); return; @@ -866,7 +866,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location callee, substs, span: *fn_span, - from_hir_call: *from_hir_call, + call_source: *call_source, feature: None, }); return; @@ -926,7 +926,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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::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, } @@ -110,7 +110,7 @@ fn build_error( 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 @@ fn build_error( } }; - 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 @@ macro_rules! error { err } CallKind::Operator { trait_id, self_ty, .. } => { - let mut sugg = None; + 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 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, - }); + 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 @@ fn promote_temp(&mut self, temp: Local) -> Local { }; 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 @@ fn promote_temp(&mut self, temp: Local) -> Local { 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, /// 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 @@ fn super_terminator(&mut self, 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 @@ fn parse_call( 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 @@ pub(crate) fn as_rvalue( 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 @@ pub(crate) fn expr_into_dest( .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 @@ pub(super) fn perform_test( 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 @@ fn non_scalar_compare( 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 @@ fn destructor_call_block(&mut self, (succ, unwind): (BasicBlock, Unwind)) -> Bas 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 @@ fn join_state_into_successors_of<'tcx, A>( 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 @@ fn gather_terminator(&mut self, term: &Terminator<'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 @@ fn call(&mut self, some_from_block: Option) -> BasicBlock { 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location 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_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 @@ fn make_clone_call( 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 @@ fn stable(&self) -> Self::T { 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`.