Skip to content

Commit ffeec17

Browse files
committed
update error reporting in trait selection for deduplication
1 parent 9728930 commit ffeec17

File tree

1 file changed

+92
-1
lines changed
  • compiler/rustc_trait_selection/src/traits/error_reporting

1 file changed

+92
-1
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ use rustc_hir::intravisit::Visitor;
1919
use rustc_hir::GenericParam;
2020
use rustc_hir::Item;
2121
use rustc_hir::Node;
22+
use rustc_middle::mir::interpret::{
23+
ConstDedupResult, ConstErrorEmitted, ErrorHandled, SilentError,
24+
};
2225
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
2326
use rustc_middle::ty::error::ExpectedFound;
2427
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
@@ -238,6 +241,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
238241
error: &SelectionError<'tcx>,
239242
fallback_has_occurred: bool,
240243
) {
244+
debug!("report_selection_error(error: {:?})", error);
241245
let tcx = self.tcx;
242246
let mut span = obligation.cause.span;
243247

@@ -799,7 +803,94 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
799803
bug!(
800804
"MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"
801805
)
802-
ConstEvalFailure(ErrorHandled::Silent) => {
806+
}
807+
SelectionError::NotConstEvaluatable(NotConstEvaluatable::Silent(id)) => {
808+
// try to report a ConstEvalErr which gives better diagnostics by providing
809+
// information about why the constant couldn't be evaluated.
810+
let const_dedup_map = tcx.dedup_const_map.lock();
811+
debug!("const_dedup_map: {:#?}", &const_dedup_map);
812+
debug!(?id);
813+
814+
// FIXME This only reports errors stored as `ConstDedupResult::Selection`
815+
// but we should also report cached errors with other Reveal variants
816+
// here. See e.g. test `ui/const-generics/generic_const_exprs/issue-62504.rs`
817+
// which fails to report the `TooGeneric` error because it was stored
818+
// with `Reveal::All`.
819+
if !const_dedup_map.error_reported_map.borrow().contains_key(&id) {
820+
if let Some(ConstDedupResult::Selection((
821+
Err(SilentError::ConstErr(err)),
822+
sp,
823+
))) = const_dedup_map.alloc_map.borrow().get(&id)
824+
{
825+
let def = id.instance.def.with_opt_param();
826+
let is_static = tcx.is_static(def.did);
827+
828+
let err_emitted = tcx.report_const_alloc_error(
829+
&const_dedup_map,
830+
id,
831+
obligation.param_env,
832+
err,
833+
is_static,
834+
def,
835+
*sp,
836+
);
837+
838+
match err_emitted {
839+
ConstErrorEmitted::NotEmitted(err) => {
840+
if let ErrorHandled::TooGeneric = err {
841+
let selection_err = SelectionError::NotConstEvaluatable(
842+
NotConstEvaluatable::MentionsParam,
843+
);
844+
845+
self.report_selection_error(
846+
obligation.clone(),
847+
root_obligation,
848+
&selection_err,
849+
fallback_has_occurred,
850+
);
851+
}
852+
}
853+
_ => {}
854+
}
855+
} else {
856+
if let Some(ConstDedupResult::Selection((
857+
Err(SilentError::ConstErr(err)),
858+
sp,
859+
))) = const_dedup_map.const_val_map.borrow().get(&id)
860+
{
861+
let def = id.instance.def.with_opt_param();
862+
let is_static = tcx.is_static(def.did);
863+
864+
let err_emitted = tcx.report_const_alloc_error(
865+
&const_dedup_map,
866+
id,
867+
obligation.param_env,
868+
err,
869+
is_static,
870+
def,
871+
*sp,
872+
);
873+
874+
match err_emitted {
875+
ConstErrorEmitted::NotEmitted(err) => {
876+
if let ErrorHandled::TooGeneric = err {
877+
let selection_err = SelectionError::NotConstEvaluatable(
878+
NotConstEvaluatable::MentionsParam,
879+
);
880+
881+
self.report_selection_error(
882+
obligation.clone(),
883+
root_obligation,
884+
&selection_err,
885+
fallback_has_occurred,
886+
);
887+
}
888+
}
889+
_ => {}
890+
}
891+
}
892+
}
893+
}
803894
tcx.sess.struct_span_err(span, "failed to evaluate the given constant")
804895
}
805896
SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {

0 commit comments

Comments
 (0)