Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove sub_relations from the InferCtxt #119989

Merged
merged 5 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
overflow errors: change source to a concrete enum
  • Loading branch information
lcnr committed Feb 22, 2024
commit f7cdff825c9a8087406ce56792e07d19f2d04e17
10 changes: 7 additions & 3 deletions compiler/rustc_trait_selection/src/solve/normalize.rs
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
use crate::traits::error_reporting::TypeErrCtxtExt;
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
use rustc_data_structures::stack::ensure_sufficient_stack;
Expand Down Expand Up @@ -60,8 60,12 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
let tcx = infcx.tcx;
let recursion_limit = tcx.recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let ty::Alias(_, data) = *alias_ty.kind() else {
unreachable!();
};

self.at.infcx.err_ctxt().report_overflow_error(
&alias_ty,
OverflowCause::DeeplyNormalize(data),
self.at.cause.span,
true,
|_| {},
Expand Down Expand Up @@ -109,7 113,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
let recursion_limit = tcx.recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
self.at.infcx.err_ctxt().report_overflow_error(
&ty::Const::new_unevaluated(tcx, uv, ty),
OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)),
self.at.cause.span,
true,
|_| {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 57,11 @@ use super::{

pub use rustc_infer::traits::error_reporting::*;

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

#[extension(pub trait TypeErrCtxtExt<'tcx>)]
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn report_fulfillment_errors(
Expand Down Expand Up @@ -184,49 189,65 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// 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<T>(
fn report_overflow_error(
&self,
predicate: &T,
cause: OverflowCause<'tcx>,
span: Span,
suggest_increasing_limit: bool,
mutate: impl FnOnce(&mut DiagnosticBuilder<'_>),
) -> !
where
T: fmt::Display TypeFoldable<TyCtxt<'tcx>> Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
{
let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit);
) -> ! {
let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
mutate(&mut err);
err.emit();
FatalError.raise();
}

fn build_overflow_error<T>(
fn build_overflow_error(
&self,
predicate: &T,
cause: OverflowCause<'tcx>,
span: Span,
suggest_increasing_limit: bool,
) -> DiagnosticBuilder<'tcx>
where
T: fmt::Display TypeFoldable<TyCtxt<'tcx>> Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
{
let predicate = self.resolve_vars_if_possible(predicate.clone());
let mut pred_str = predicate.to_string();

if pred_str.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(self.tcx, Namespace::TypeNS, rustc_session::Limit(6));
predicate.print(&mut cx).unwrap();
pred_str = cx.into_buffer();
) -> DiagnosticBuilder<'tcx> {
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 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider && !sess.opts.verbose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is existing, please fix this in a separate PR if you think it's worth changing 🤔

// 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 = struct_span_code_err!(
self.dcx(),
span,
E0275,
"overflow evaluating the requirement `{}`",
pred_str,
);

let mut err = match cause {
OverflowCause::DeeplyNormalize(alias_ty) => {
let alias_ty = self.resolve_vars_if_possible(alias_ty);
let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr());
let alias_str = with_short_path(self.tcx, alias_ty);
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);
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 {
self.suggest_new_overflow_limit(&mut err);
Expand All @@ -252,7 273,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
let predicate = self.resolve_vars_if_possible(predicate);
self.report_overflow_error(
&predicate,
OverflowCause::TraitSolver(predicate),
obligation.cause.span,
suggest_increasing_limit,
|err| {
Expand Down Expand Up @@ -303,7 324,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {

fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
let obligation = self.resolve_vars_if_possible(obligation);
let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true);
let mut err = self.build_overflow_error(
OverflowCause::TraitSolver(obligation.predicate),
obligation.cause.span,
true,
);
self.note_obligation_cause(&mut err, &obligation);
self.point_at_returns_when_relevant(&mut err, &obligation);
err.emit()
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 450,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
.recursion_limit()
.value_within_limit(obligation.recursion_depth) =>
{
self.selcx.infcx.err_ctxt().report_overflow_error(
&obligation.predicate,
obligation.cause.span,
false,
|_| {},
);
self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
}

ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_trait_selection/src/traits/normalize.rs
Original file line number Diff line number Diff line change
@@ -1,4 1,8 @@
//! Deeply normalize types using the old trait solver.
use super::error_reporting::OverflowCause;
use super::error_reporting::TypeErrCtxtExt;
use super::SelectionContext;
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::infer::at::At;
use rustc_infer::infer::InferOk;
Expand All @@ -8,10 12,6 @@ use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder};
use rustc_middle::ty::{TypeFoldable, TypeSuperFoldable, TypeVisitable, TypeVisitableExt};

use super::error_reporting::TypeErrCtxtExt;
use super::SelectionContext;
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};

#[extension(pub trait NormalizeExt<'tcx>)]
impl<'tcx> At<'_, 'tcx> {
/// Normalize a value using the `AssocTypeNormalizer`.
Expand Down Expand Up @@ -173,7 173,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
}

let (kind, data) = match *ty.kind() {
ty::Alias(kind, alias_ty) => (kind, alias_ty),
ty::Alias(kind, data) => (kind, data),
_ => return ty.super_fold_with(self),
};

Expand Down Expand Up @@ -210,7 210,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
let recursion_limit = self.interner().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
self.selcx.infcx.err_ctxt().report_overflow_error(
&ty,
OverflowCause::DeeplyNormalize(data),
self.cause.span,
true,
|_| {},
Expand Down Expand Up @@ -306,7 306,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
let recursion_limit = self.interner().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
self.selcx.infcx.err_ctxt().report_overflow_error(
&ty,
OverflowCause::DeeplyNormalize(data),
self.cause.span,
false,
|diag| {
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 5,7 @@
use crate::infer::at::At;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::OverflowCause;
use crate::traits::error_reporting::TypeErrCtxtExt;
use crate::traits::normalize::needs_normalization;
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
Expand Down Expand Up @@ -228,7 229,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
let guar = self
.infcx
.err_ctxt()
.build_overflow_error(&ty, self.cause.span, true)
.build_overflow_error(
OverflowCause::DeeplyNormalize(data),
self.cause.span,
true,
)
.delay_as_bug();
return Ok(Ty::new_error(self.interner(), guar));
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 105,17 @@ pub enum AliasKind {
Weak,
}

impl AliasKind {
pub fn descr(self) -> &'static str {
match self {
AliasKind::Projection => "associated type",
AliasKind::Inherent => "inherent associated type",
AliasKind::Opaque => "opaque type",
AliasKind::Weak => "type alias",
}
}
}

/// Defines the kinds of types used by the type system.
///
/// Types written by the user start out as `hir::TyKind` and get
Expand Down
1 change: 0 additions & 1 deletion tests/ui/impl-trait/issues/issue-62742.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 4,6 @@ fn _alias_check() {
WrongImpl::foo(0i32);
//~^ ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
WrongImpl::<()>::foo(0i32);
//~^ ERROR the trait bound `RawImpl<()>: Raw<()>` is not satisfied
//~| ERROR trait bounds were not satisfied
Expand Down
26 changes: 9 additions & 17 deletions tests/ui/impl-trait/issues/issue-62742.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 2,11 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
--> $DIR/issue-62742.rs:4:5
|
LL | WrongImpl::foo(0i32);
| ^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
| ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
|
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
note: required by a bound in `SafeImpl::<T, A>::foo`
--> $DIR/issue-62742.rs:30:20
--> $DIR/issue-62742.rs:29:20
|
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
| ^^^^^^ required by this bound in `SafeImpl::<T, A>::foo`
Expand All @@ -21,21 21,13 @@ LL | WrongImpl::foo(0i32);
|
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
note: required by a bound in `SafeImpl`
--> $DIR/issue-62742.rs:28:35
--> $DIR/issue-62742.rs:27:35
|
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
| ^^^^^^ required by this bound in `SafeImpl`

error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
--> $DIR/issue-62742.rs:4:5
|
LL | WrongImpl::foo(0i32);
| ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
|
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`

error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied
--> $DIR/issue-62742.rs:8:22
--> $DIR/issue-62742.rs:7:22
|
LL | WrongImpl::<()>::foo(0i32);
| ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds
Expand All @@ -47,33 39,33 @@ LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
| ----------------------------------------- function or associated item `foo` not found for this struct
|
note: trait bound `RawImpl<()>: Raw<()>` was not satisfied
--> $DIR/issue-62742.rs:30:20
--> $DIR/issue-62742.rs:29:20
|
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
| ^^^^^^ --------------
| |
| unsatisfied trait bound introduced here
note: the trait `Raw` must be implemented
--> $DIR/issue-62742.rs:14:1
--> $DIR/issue-62742.rs:13:1
|
LL | pub trait Raw<T: ?Sized> {
| ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied
--> $DIR/issue-62742.rs:8:5
--> $DIR/issue-62742.rs:7:5
|
LL | WrongImpl::<()>::foo(0i32);
| ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>`
|
= help: the trait `Raw<[()]>` is implemented for `RawImpl<()>`
= help: for that trait implementation, expected `[()]`, found `()`
note: required by a bound in `SafeImpl`
--> $DIR/issue-62742.rs:28:35
--> $DIR/issue-62742.rs:27:35
|
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
| ^^^^^^ required by this bound in `SafeImpl`

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -1,20 1,20 @@
error[E0275]: overflow evaluating the requirement `X2`
error[E0275]: overflow normalizing the type alias `X2`
--> $DIR/infinite-type-alias-mutual-recursion.rs:6:11
|
LL | type X1 = X2;
| ^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow evaluating the requirement `X3`
error[E0275]: overflow normalizing the type alias `X3`
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
|
LL | type X2 = X3;
| ^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead

error[E0275]: overflow evaluating the requirement `X1`
error[E0275]: overflow normalizing the type alias `X1`
--> $DIR/infinite-type-alias-mutual-recursion.rs:11:11
|
LL | type X3 = X1;
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/infinite/infinite-type-alias-mutual-recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 5,10 @@

type X1 = X2;
//[gated]~^ ERROR cycle detected when expanding type alias `X1`
//[feature]~^^ ERROR: overflow evaluating the requirement `X2`
//[feature]~^^ ERROR: overflow normalizing the type alias `X2`
type X2 = X3;
//[feature]~^ ERROR: overflow evaluating the requirement `X3`
//[feature]~^ ERROR: overflow normalizing the type alias `X3`
type X3 = X1;
//[feature]~^ ERROR: overflow evaluating the requirement `X1`
//[feature]~^ ERROR: overflow normalizing the type alias `X1`

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
error[E0275]: overflow evaluating the requirement `X`
error[E0275]: overflow normalizing the type alias `X`
--> $DIR/infinite-vec-type-recursion.rs:6:10
|
LL | type X = Vec<X>;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/infinite/infinite-vec-type-recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 5,7 @@

type X = Vec<X>;
//[gated]~^ ERROR cycle detected
//[feature]~^^ ERROR: overflow evaluating the requirement `X`
//[feature]~^^ ERROR: overflow normalizing the type alias `X`

#[rustfmt::skip]
fn main() { let b: X = Vec::new(); }
Loading