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

Overflow evaluating the requirement [stable/nightly] #89275

Closed
ZippyMagician opened this issue Sep 26, 2021 · 8 comments · Fixed by #89576
Closed

Overflow evaluating the requirement [stable/nightly] #89275

ZippyMagician opened this issue Sep 26, 2021 · 8 comments · Fixed by #89576
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference A-trait-system Area: Trait system D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ZippyMagician
Copy link

Given the following code snippet:

use num_rational as _;

struct Foo;

impl Foo {
    fn downcast<W>(&self) -> &W {
        todo!()
    }
}

struct Other;

fn main() {
    let other: &mut Other = Foo.downcast();
}

One would expect the code to error, explaining that the types differ in mutability (we will come back to this in a moment).

However, it instead leaves a long and confusing error:

error[E0275]: overflow evaluating the requirement `&Ratio<_>: num_traits::pow::Pow<u32>`
  --> src/main.rs:14:29
   |
14 |     let other: &mut Other = Foo.downcast();
   |                             ^^^^^^^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`bug`)
   = note: required because of the requirements on the impl of `num_traits::pow::Pow<u32>` for `&Ratio<Ratio<_>>`
   = note: 127 redundant requirements hidden
   = note: required because of the requirements on the impl of `num_traits::pow::Pow<&i32>` for `&Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<Ratio<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.
error: could not compile `bug`

To learn more, run the command again with --verbose.

If you follow the suggestion of increasing the recursion limit each time, it will eventually segfault once you have #![recursion_limit="2048"]

error: could not compile `bug`

Caused by:
  process didn't exit successfully: `rustc --crate-name bug --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=f6406766fb3e32c0 -C extra-filename=-f6406766fb3e32c0 --out-dir /home/zippy/bug/target/debug/deps -C incremental=/home/zippy/bug/target/debug/incremental -L dependency=/home/zippy/bug/target/debug/deps --extern num_rational=/home/zippy/bug/target/debug/deps/libnum_rational-13f69084195ac9b5.rlib` (signal: 11, SIGSEGV: invalid memory reference)

Furthermore, removing the import of num-rational leads to the program erroring as expected

error[E0308]: mismatched types
  --> src/main.rs:12:29
   |
12 |     let other: &mut Other = Foo.downcast();
   |                ----------   ^^^^^^^^^^^^^^ types differ in mutability
   |                |
   |                expected due to this
   |
   = note: expected mutable reference `&mut Other`
                      found reference `&_`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `bug` due to previous error

Meta

rustc --version --verbose:

rustc 1.57.0-nightly (addb4da68 2021-09-25)
binary: rustc
commit-hash: addb4da686a97da46159f0123cb6cdc2ce3d7fdb
commit-date: 2021-09-25
host: x86_64-unknown-linux-gnu
release: 1.57.0-nightly
LLVM version: 13.0.0

This error exists on stable, too.

Backtrace

The code doesn't compile, and as such there's no backtrace

@ZippyMagician ZippyMagician added the C-bug Category: This is a bug. label Sep 26, 2021
@ZippyMagician ZippyMagician changed the title Overflow evaluating the requirement [stable/nightly] (buggy trait collisions?) Overflow evaluating the requirement [stable/nightly] Sep 26, 2021
@lordnoriyuki
Copy link

This issue and #77291 and #75397 potentially look like the same problem.

@lordnoriyuki
Copy link

It's worth noting that if you use the turbofish syntax the compiler gives the correct error message:

let other: &mut Other = Foo.downcast::<Other>();

@edward-shen
Copy link
Contributor

For a little more context, this issue was filed from a discussion on reddit.

@KamilaBorowska
Copy link
Contributor

KamilaBorowska commented Sep 26, 2021

It's possible to trigger this issue with num_traits by providing a minimal implementation of Pow trait.

use num_traits as _;

struct Ratio<T>(T);

pub trait Pow {
    fn pow(self);
}

impl<'a, T> Pow for &'a Ratio<T>
where
    &'a T: Pow,
{
    fn pow(self) {
        unimplemented!()
    }
}

struct Foo;

impl Foo {
    fn downcast<W>(&self) -> &W {
        todo!()
    }
}

struct Other;

fn main() {
    let other: &mut Other = Foo.downcast();
}

@obsgolem
Copy link
Contributor

obsgolem commented Sep 26, 2021

I am having a similar issue with ndarray arrays throwing an error like overflow evaluating the requirement &ArrayBase<_, _>: Not whenever I make some kind of error. This appears to be hiding the actual real error. I don't currently have a MRE though, will update if I find one.

@tom7980
Copy link
Contributor

tom7980 commented Sep 28, 2021

For info here is a backtrace of the compiler during compilation of this Minimal reproduction (with recursion limit set to 8 for more brevity)

Backtrace
   0: rust_begin_unwind
             at /rustc/98c8619502093f34ca82f8f26ccf32e753924440/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/98c8619502093f34ca82f8f26ccf32e753924440/library/core/src/panicking.rs:100:14
   2: rustc_errors::HandlerInner::emit_diagnostic
   3: rustc_errors::diagnostic_builder::DiagnosticBuilder::emit
   4: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtExt>::report_overflow_error
   5: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
   6: rustc_infer::infer::InferCtxt::probe
   7: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
   8: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
   9: rustc_trait_selection::traits::select::SelectionContext::select
  10: rustc_trait_selection::traits::project::opt_normalize_projection_type
  11: rustc_trait_selection::traits::project::poly_project_and_unify_type
  12: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  13: rustc_infer::infer::InferCtxt::probe
  14: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  15: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  16: rustc_trait_selection::traits::select::SelectionContext::select
  17: rustc_trait_selection::traits::project::opt_normalize_projection_type
  18: rustc_trait_selection::traits::project::poly_project_and_unify_type
  19: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  20: rustc_infer::infer::InferCtxt::probe
  21: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  22: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  23: rustc_trait_selection::traits::select::SelectionContext::select
  24: rustc_trait_selection::traits::project::opt_normalize_projection_type
  25: rustc_trait_selection::traits::project::poly_project_and_unify_type
  26: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  27: rustc_infer::infer::InferCtxt::probe
  28: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  29: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  30: rustc_trait_selection::traits::select::SelectionContext::select
  31: rustc_trait_selection::traits::project::opt_normalize_projection_type
  32: rustc_trait_selection::traits::project::poly_project_and_unify_type
  33: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  34: rustc_infer::infer::InferCtxt::probe
  35: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  36: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  37: rustc_trait_selection::traits::select::SelectionContext::select
  38: rustc_trait_selection::traits::project::opt_normalize_projection_type
  39: rustc_trait_selection::traits::project::poly_project_and_unify_type
  40: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  41: rustc_infer::infer::InferCtxt::probe
  42: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  43: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  44: rustc_trait_selection::traits::select::SelectionContext::select
  45: rustc_trait_selection::traits::project::opt_normalize_projection_type
  46: rustc_trait_selection::traits::project::poly_project_and_unify_type
  47: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  48: rustc_infer::infer::InferCtxt::probe
  49: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  50: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  51: rustc_trait_selection::traits::select::SelectionContext::select
  52: rustc_trait_selection::traits::project::opt_normalize_projection_type
  53: rustc_trait_selection::traits::project::poly_project_and_unify_type
  54: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  55: rustc_infer::infer::InferCtxt::probe
  56: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  57: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  58: rustc_trait_selection::traits::select::SelectionContext::select
  59: rustc_trait_selection::traits::project::opt_normalize_projection_type
  60: rustc_trait_selection::traits::project::poly_project_and_unify_type
  61: rustc_trait_selection::traits::select::SelectionContext::evaluate_predicates_recursively
  62: rustc_infer::infer::InferCtxt::probe
  63: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  64: rustc_trait_selection::traits::select::candidate_assembly::<impl rustc_trait_selection::traits::select::SelectionContext>::candidate_from_obligation_no_cache
  65: rustc_query_system::dep_graph::graph::DepGraph<K>::with_anon_task
  66: rustc_trait_selection::traits::select::SelectionContext::evaluate_stack
  67: rustc_trait_selection::traits::select::SelectionContext::evaluate_trait_predicate_recursively
  68: rustc_trait_selection::traits::select::SelectionContext::evaluate_root_obligation
  69: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt>::predicate_may_hold
  70: rustc_infer::infer::InferCtxt::probe
  71: rustc_typeck::check::method::probe::ProbeContext::pick_method
  72: rustc_typeck::check::method::probe::ProbeContext::pick_core
  73: rustc_typeck::check::method::probe::ProbeContext::pick
  74: rustc_infer::infer::InferCtxt::probe
  75: rustc_typeck::check::method::probe::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::probe_op
  76: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
  77: <core::iter::adapters::flatten::FlatMap<I,U,F> as core::iter::traits::iterator::Iterator>::next
  78: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
  79: rustc_typeck::check::method::probe::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::probe_for_return_type
  80: rustc_typeck::check::demand::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::get_conversion_methods
  81: rustc_typeck::check::fn_ctxt::suggestions::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::suggest_deref_ref_or_into
  82: rustc_typeck::check::demand::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::emit_coerce_suggestions
  83: rustc_typeck::check::demand::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::demand_coerce
  84: rustc_typeck::check::fn_ctxt::checks::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_decl_local
  85: rustc_typeck::check::fn_ctxt::checks::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_stmt
  86: rustc_typeck::check::fn_ctxt::checks::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_block_with_expected
  87: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation
  88: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_return_expr
  89: rustc_typeck::check::check::check_fn
  90: rustc_infer::infer::InferCtxtBuilder::enter
  91: rustc_typeck::check::typeck

I believe we start to go awry at around line 68 - it looks like it's perhaps inferring the wrong return type for the method downcast() (line 71) and recursing from there but I'm fairly new to debugging the compiler and I could be extremely off on my guesswork.

I will try running a backtrace on some of the other reproductions of this and see if they're similar

@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference A-trait-system Area: Trait system D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed C-bug Category: This is a bug. labels Sep 29, 2021
@matthewjasper
Copy link
Contributor

Version with no dependencies:

#![recursion_limit = "5"] // To reduce noise

struct Ratio<T>(T);

pub trait Pow {
    fn pow(self) -> Self;
}

impl<'a, T> Pow for &'a Ratio<T>
where
    &'a T: Pow,
{
    fn pow(self) -> Self {
        self
    }
}

fn downcast<'a, W: ?Sized>() -> &'a W {
    todo!()
}

struct Other;

fn main() {
    let other: &mut Other = downcast();
}

@tom7980
Copy link
Contributor

tom7980 commented Oct 3, 2021

From chatting to some people on the rust Zulip this is happening because the error reporting system is trying to find a valid conversion method to put as a suggestion in the mutability error. It's iterating over every trait implementation in scope to check for a conversion method on &_ so either we need a way to tell the error reporting system not to report new errors if it encounters one or fix which span the error is reported on

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference A-trait-system Area: Trait system D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
8 participants