Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2d45cdb
Test RUSTC_FORCE_RUSTC_VERSION
oli-obk Apr 25, 2024
b961660
Make RUSTC_FORCE_RUSTC_VERSION overwrite the rendered version output,…
oli-obk Apr 25, 2024
90cbd0b
impl FusedIterator and a size hint for the error sources iter
Sky9x Jun 28, 2024
321eba5
Update f16/f128 FIXMEs that needed (NEG_)INFINITY
tgross35 Jul 8, 2024
ec662e7
`#[doc(alias)]`'s doc: say that ASCII spaces are allowed
ShE3py Jul 8, 2024
96a7916
Update a f16/f128 FIXME to be more accurate
tgross35 Jul 8, 2024
7097dbc
exhaustively destructure external constraints
lcnr Jul 9, 2024
e38109d
use `update_parent_goal` for lazy updates
lcnr Jul 9, 2024
fd9a925
Automatically taint when reporting errors from ItemCtxt
oli-obk Jul 5, 2024
aece064
Remove HirTyLowerer::set_tainted_by_errors, since it is now redundant
oli-obk Jul 5, 2024
dd175fe
cycle_participants to nested_goals
lcnr Jul 9, 2024
7af825f
Split out overflow handling into its own module
compiler-errors Jul 8, 2024
cd68a28
Move some stuff into the ambiguity and suggestion modules
compiler-errors Jul 8, 2024
bbbff80
Split out fulfillment error reporting a bit more
compiler-errors Jul 8, 2024
4700b5b
Remove spastorino from SMIR
spastorino Jul 9, 2024
25637e2
Adds expr_2024 migration lit
vincenzopalazzo May 25, 2024
568e78f
tests: adds cargo fix tests
vincenzopalazzo May 25, 2024
dfac6fa
cmake version is from LLVM, link to LLVM docs
simonLeary42 Jul 9, 2024
4d44291
Rollup merge of #124339 - oli-obk:supports_feature, r=wesleywiser
matthiaskrgr Jul 9, 2024
9fc9f13
Rollup merge of #125627 - vincenzopalazzo:macros/cargo-fix-expr2024, …
matthiaskrgr Jul 9, 2024
82bd4a8
Rollup merge of #127091 - Sky9x:fused-error-sources-iter, r=dtolnay
matthiaskrgr Jul 9, 2024
503268e
Rollup merge of #127358 - oli-obk:taint_itemctxt, r=fmease
matthiaskrgr Jul 9, 2024
615f5a3
Rollup merge of #127484 - ShE3py:rustdoc-doc-alias-whitespace-doc, r=…
matthiaskrgr Jul 9, 2024
9dcac1c
Rollup merge of #127495 - compiler-errors:more-trait-error-reworking,…
matthiaskrgr Jul 9, 2024
056bac8
Rollup merge of #127496 - tgross35:f16-f128-pattern-fixme, r=Nadrieril
matthiaskrgr Jul 9, 2024
7320313
Rollup merge of #127508 - lcnr:search-graph-prep, r=compiler-errors
matthiaskrgr Jul 9, 2024
998f4f4
Rollup merge of #127521 - spastorino:remove-myself-from-smir-pings, r…
matthiaskrgr Jul 9, 2024
53aae31
Rollup merge of #127532 - simonLeary42:patch-1, r=Nilstrieb
matthiaskrgr Jul 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Split out overflow handling into its own module
  • Loading branch information
compiler-errors committed Jul 9, 2024
commit 7af825fea4fea17d0b58fcd8c1f2b6fa11638cfb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod ambiguity;
mod infer_ctxt_ext;
pub mod on_unimplemented;
mod overflow;
pub mod suggestions;
mod type_err_ctxt_ext;

Expand All @@ -17,6 +18,7 @@ use rustc_span::Span;
use std::ops::ControlFlow;

pub use self::infer_ctxt_ext::*;
pub use self::overflow::*;
pub use self::type_err_ctxt_ext::*;

// When outputting impl candidates, prefer showing those that are more similar.
Expand Down
197 changes: 197 additions & 0 deletions compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use std::fmt;

use rustc_errors::{
struct_span_code_err, Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, E0275,
};
use rustc_hir::def::Namespace;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::traits::{Obligation, PredicateObligation};
use rustc_macros::extension;
use rustc_middle::ty::print::{FmtPrinter, Print};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Limit;
use rustc_span::Span;
use rustc_type_ir::Upcast;

use super::InferCtxtPrivExt;
use crate::error_reporting::traits::suggestions::TypeErrCtxtExt;

pub enum OverflowCause<'tcx> {
DeeplyNormalize(ty::AliasTerm<'tcx>),
TraitSolver(ty::Predicate<'tcx>),
}

pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>(
tcx: TyCtxt<'tcx>,
err: &mut Diag<'_, G>,
) {
let suggested_limit = match tcx.recursion_limit() {
Limit(0) => Limit(2),
limit => limit * 2,
};
err.help(format!(
"consider increasing the recursion limit by adding a \
`#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
suggested_limit,
tcx.crate_name(LOCAL_CRATE),
));
}

#[extension(pub trait TypeErrCtxtOverflowExt<'a, 'tcx>)]
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
/// Reports that an overflow has occurred and halts compilation. We
/// halt compilation unconditionally because it is important that
/// overflows never be masked -- they basically represent computations
/// whose result could not be truly determined and thus we can't say
/// if the program type checks or not -- and they are unusual
/// occurrences in any case.
fn report_overflow_error(
&self,
cause: OverflowCause<'tcx>,
span: Span,
suggest_increasing_limit: bool,
mutate: impl FnOnce(&mut Diag<'_>),
) -> ! {
let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
mutate(&mut err);
err.emit();
FatalError.raise();
}

fn build_overflow_error(
&self,
cause: OverflowCause<'tcx>,
span: Span,
suggest_increasing_limit: bool,
) -> Diag<'a> {
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
where
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
{
let s = value.to_string();
if s.len() > 50 {
// We don't need to save the type to a file, we will be talking about this type already
// in a separate note when we explain the obligation, so it will be available that way.
let mut cx: FmtPrinter<'_, '_> =
FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6));
value.print(&mut cx).unwrap();
cx.into_buffer()
} else {
s
}
}

let mut err = match cause {
OverflowCause::DeeplyNormalize(alias_term) => {
let alias_term = self.resolve_vars_if_possible(alias_term);
let kind = alias_term.kind(self.tcx).descr();
let alias_str = with_short_path(self.tcx, alias_term);
struct_span_code_err!(
self.dcx(),
span,
E0275,
"overflow normalizing the {kind} `{alias_str}`",
)
}
OverflowCause::TraitSolver(predicate) => {
let predicate = self.resolve_vars_if_possible(predicate);
match predicate.kind().skip_binder() {
ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ })
| ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => {
struct_span_code_err!(
self.dcx(),
span,
E0275,
"overflow assigning `{a}` to `{b}`",
)
}
_ => {
let pred_str = with_short_path(self.tcx, predicate);
struct_span_code_err!(
self.dcx(),
span,
E0275,
"overflow evaluating the requirement `{pred_str}`",
)
}
}
}
};

if suggest_increasing_limit {
suggest_new_overflow_limit(self.tcx, &mut err);
}

err
}

/// Reports that an overflow has occurred and halts compilation. We
/// halt compilation unconditionally because it is important that
/// overflows never be masked -- they basically represent computations
/// whose result could not be truly determined and thus we can't say
/// if the program type checks or not -- and they are unusual
/// occurrences in any case.
fn report_overflow_obligation<T>(
&self,
obligation: &Obligation<'tcx, T>,
suggest_increasing_limit: bool,
) -> !
where
T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>> + Clone,
{
let predicate = obligation.predicate.clone().upcast(self.tcx);
let predicate = self.resolve_vars_if_possible(predicate);
self.report_overflow_error(
OverflowCause::TraitSolver(predicate),
obligation.cause.span,
suggest_increasing_limit,
|err| {
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
);
},
);
}

/// Reports that a cycle was detected which led to overflow and halts
/// compilation. This is equivalent to `report_overflow_obligation` except
/// that we can give a more helpful error message (and, in particular,
/// we do not suggest increasing the overflow limit, which is not
/// going to help).
fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
let cycle = self.resolve_vars_if_possible(cycle.to_owned());
assert!(!cycle.is_empty());

debug!(?cycle, "report_overflow_error_cycle");

// The 'deepest' obligation is most likely to have a useful
// cause 'backtrace'
self.report_overflow_obligation(
cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(),
false,
);
}

fn report_overflow_no_abort(
&self,
obligation: PredicateObligation<'tcx>,
suggest_increasing_limit: bool,
) -> ErrorGuaranteed {
let obligation = self.resolve_vars_if_possible(obligation);
let mut err = self.build_overflow_error(
OverflowCause::TraitSolver(obligation.predicate),
obligation.cause.span,
suggest_increasing_limit,
);
self.note_obligation_cause(&mut err, &obligation);
self.point_at_returns_when_relevant(&mut err, &obligation);
err.emit()
}
}
Loading