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

rust-2021-incompatible-closure-captures trait evaluation overflow error #88103

Closed
ehuss opened this issue Aug 17, 2021 · 2 comments · Fixed by #88320
Closed

rust-2021-incompatible-closure-captures trait evaluation overflow error #88103

ehuss opened this issue Aug 17, 2021 · 2 comments · Fixed by #88320
Labels
A-closures Area: Closures (`|…| { … }`) A-edition-2021 Area: The 2021 edition C-bug Category: This is a bug.

Comments

@ehuss
Copy link
Contributor

ehuss commented Aug 17, 2021

While trying to migrate sv-parser 0.11.1 to the 2021 edition, the compiler fails with this error:

error[E0275]: overflow evaluating the requirement `Box<sv_parser::ValueRangeBinary>: Sync`

It is hard to create a small reproduction, but here is the command to run in that package to reproduce the error:

cargo rustc --profile=check --example module_list -v -- --force-warn rust-2021-incompatible-closure-captures -Zunstable-options

I'm not sure if it is feasible to avoid this. I'm guessing that the lint is doing some kind of trait evaluation that happens to add some additional recursion that is not normally there. Adding #![recursion_limit="256"] fixes the problem. Opening this issue to track whether or not there is anything to do here.

Note that the lint doesn't actually fire, so this is just during the analysis (presumably somewhere in compute_2229_migrations).

Full error:

error[E0275]: overflow evaluating the requirement `Box<sv_parser::ValueRangeBinary>: Sync`
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`module_list`)
  = note: required because it appears within the type `sv_parser::ValueRange`
  = note: required because it appears within the type `(sv_parser::ValueRange, std::option::Option<sv_parser::DistWeight>)`
  = note: required because it appears within the type `sv_parser::DistItem`
  = note: required because it appears within the type `(sv_parser::DistItem, Vec<(sv_parser::Symbol, sv_parser::DistItem)>)`
  = note: required because it appears within the type `sv_parser::List<sv_parser::Symbol, sv_parser::DistItem>`
  = note: required because it appears within the type `(sv_parser::List<sv_parser::Symbol, sv_parser::DistItem>,)`
  = note: required because it appears within the type `sv_parser::DistList`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::DistList, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::Brace<sv_parser::DistList>`
  = note: required because it appears within the type `(sv_parser::Keyword, sv_parser::Brace<sv_parser::DistList>)`
  = note: required because it appears within the type `std::option::Option<(sv_parser::Keyword, sv_parser::Brace<sv_parser::DistList>)>`
  = note: required because it appears within the type `(sv_parser::Expression, std::option::Option<(sv_parser::Keyword, sv_parser::Brace<sv_parser::DistList>)>)`
  = note: required because it appears within the type `sv_parser::ExpressionOrDist`
  = note: required because it appears within the type `(sv_parser::ExpressionOrDist, std::option::Option<sv_parser::BooleanAbbrev>)`
  = note: required because it appears within the type `sv_parser::SequenceExprExpression`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::SequenceExprExpression>`
  = note: required because it appears within the type `Box<sv_parser::SequenceExprExpression>`
  = note: required because it appears within the type `sv_parser::SequenceExpr`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::SequenceExpr>`
  = note: required because it appears within the type `Box<sv_parser::SequenceExpr>`
  = note: required because it appears within the type `sv_parser::SequenceActualArg`
  = note: required because it appears within the type `std::option::Option<sv_parser::SequenceActualArg>`
  = note: required because it appears within the type `(std::option::Option<sv_parser::SequenceActualArg>, Vec<(sv_parser::Symbol, std::option::Option<sv_parser::SequenceActualArg>)>)`
  = note: required because it appears within the type `sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::SequenceActualArg>>`
  = note: required because it appears within the type `(sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::SequenceActualArg>>, Vec<(sv_parser::Symbol, sv_parser::Symbol, sv_parser::Identifier, sv_parser::Paren<std::option::Option<sv_parser::SequenceActualArg>>)>)`
  = note: required because it appears within the type `sv_parser::SequenceListOfArgumentsOrdered`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::SequenceListOfArgumentsOrdered>`
  = note: required because it appears within the type `Box<sv_parser::SequenceListOfArgumentsOrdered>`
  = note: required because it appears within the type `sv_parser::SequenceListOfArguments`
  = note: required because it appears within the type `std::option::Option<sv_parser::SequenceListOfArguments>`
  = note: required because it appears within the type `(sv_parser::Symbol, std::option::Option<sv_parser::SequenceListOfArguments>, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::Paren<std::option::Option<sv_parser::SequenceListOfArguments>>`
  = note: required because it appears within the type `std::option::Option<sv_parser::Paren<std::option::Option<sv_parser::SequenceListOfArguments>>>`
  = note: required because it appears within the type `(sv_parser::PsOrHierarchicalSequenceIdentifier, std::option::Option<sv_parser::Paren<std::option::Option<sv_parser::SequenceListOfArguments>>>)`
  = note: required because it appears within the type `sv_parser::SequenceInstance`
  = note: required because it appears within the type `(sv_parser::SequenceInstance, std::option::Option<(sv_parser::Keyword, sv_parser::Expression)>)`
  = note: required because it appears within the type `sv_parser::EventExpressionSequence`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::EventExpressionSequence>`
  = note: required because it appears within the type `Box<sv_parser::EventExpressionSequence>`
  = note: required because it appears within the type `sv_parser::EventExpression`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::EventExpression, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::Paren<sv_parser::EventExpression>`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::Paren<sv_parser::EventExpression>)`
  = note: required because it appears within the type `sv_parser::ClockingEventExpression`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::ClockingEventExpression>`
  = note: required because it appears within the type `Box<sv_parser::ClockingEventExpression>`
  = note: required because it appears within the type `sv_parser::ClockingEvent`
  = note: required because it appears within the type `std::option::Option<sv_parser::ClockingEvent>`
  = note: required because it appears within the type `(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)`
  = note: required because it appears within the type `std::option::Option<(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)>`
  = note: required because it appears within the type `(sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::Expression>>, std::option::Option<(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)>)`
  = note: required because it appears within the type `(sv_parser::Symbol, (sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::Expression>>, std::option::Option<(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)>), sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::Paren<(sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::Expression>>, std::option::Option<(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)>)>`
  = note: required because it appears within the type `(sv_parser::SystemTfIdentifier, sv_parser::Paren<(sv_parser::List<sv_parser::Symbol, std::option::Option<sv_parser::Expression>>, std::option::Option<(sv_parser::Symbol, std::option::Option<sv_parser::ClockingEvent>)>)>)`
  = note: required because it appears within the type `sv_parser::SystemTfCallArgExpression`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::SystemTfCallArgExpression>`
  = note: required because it appears within the type `Box<sv_parser::SystemTfCallArgExpression>`
  = note: required because it appears within the type `sv_parser::SystemTfCall`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::SystemTfCall>`
  = note: required because it appears within the type `Box<sv_parser::SystemTfCall>`
  = note: required because it appears within the type `sv_parser::SubroutineCall`
  = note: required because it appears within the type `(sv_parser::SubroutineCall,)`
  = note: required because it appears within the type `sv_parser::FunctionSubroutineCall`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::FunctionSubroutineCall>`
  = note: required because it appears within the type `Box<sv_parser::FunctionSubroutineCall>`
  = note: required because it appears within the type `sv_parser::Primary`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::Primary>`
  = note: required because it appears within the type `Box<sv_parser::Primary>`
  = note: required because it appears within the type `sv_parser::Expression`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::Expression>`
  = note: required because it appears within the type `Box<sv_parser::Expression>`
  = note: required because it appears within the type `sv_parser::MintypmaxExpression`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::MintypmaxExpression>`
  = note: required because it appears within the type `Box<sv_parser::MintypmaxExpression>`
  = note: required because it appears within the type `sv_parser::ParamExpression`
  = note: required because it appears within the type `(sv_parser::ParamExpression,)`
  = note: required because it appears within the type `sv_parser::OrderedParameterAssignment`
  = note: required because it appears within the type `(sv_parser::OrderedParameterAssignment, Vec<(sv_parser::Symbol, sv_parser::OrderedParameterAssignment)>)`
  = note: required because it appears within the type `sv_parser::List<sv_parser::Symbol, sv_parser::OrderedParameterAssignment>`
  = note: required because it appears within the type `(sv_parser::List<sv_parser::Symbol, sv_parser::OrderedParameterAssignment>,)`
  = note: required because it appears within the type `sv_parser::ListOfParameterAssignmentsOrdered`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::ListOfParameterAssignmentsOrdered>`
  = note: required because it appears within the type `Box<sv_parser::ListOfParameterAssignmentsOrdered>`
  = note: required because it appears within the type `sv_parser::ListOfParameterAssignments`
  = note: required because it appears within the type `std::option::Option<sv_parser::ListOfParameterAssignments>`
  = note: required because it appears within the type `(sv_parser::Symbol, std::option::Option<sv_parser::ListOfParameterAssignments>, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::Paren<std::option::Option<sv_parser::ListOfParameterAssignments>>`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::Paren<std::option::Option<sv_parser::ListOfParameterAssignments>>)`
  = note: required because it appears within the type `sv_parser::ParameterValueAssignment`
  = note: required because it appears within the type `std::option::Option<sv_parser::ParameterValueAssignment>`
  = note: required because it appears within the type `(sv_parser::PsClassIdentifier, std::option::Option<sv_parser::ParameterValueAssignment>, Vec<(sv_parser::Symbol, sv_parser::ClassIdentifier, std::option::Option<sv_parser::ParameterValueAssignment>)>)`
  = note: required because it appears within the type `sv_parser::ClassType`
  = note: required because it appears within the type `(sv_parser::ClassType, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::ClassScope`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::ClassScope>`
  = note: required because it appears within the type `Box<sv_parser::ClassScope>`
  = note: required because it appears within the type `sv_parser::PackageScopeOrClassScope`
  = note: required because it appears within the type `std::option::Option<sv_parser::PackageScopeOrClassScope>`
  = note: required because it appears within the type `(std::option::Option<sv_parser::PackageScopeOrClassScope>, sv_parser::ParameterIdentifier)`
  = note: required because it appears within the type `sv_parser::PsParameterIdentifierScope`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::PsParameterIdentifierScope>`
  = note: required because it appears within the type `Box<sv_parser::PsParameterIdentifierScope>`
  = note: required because it appears within the type `sv_parser::PsParameterIdentifier`
  = note: required because it appears within the type `(sv_parser::PsParameterIdentifier, sv_parser::ConstantSelect)`
  = note: required because it appears within the type `sv_parser::ConstantPrimaryPsParameter`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::ConstantPrimaryPsParameter>`
  = note: required because it appears within the type `Box<sv_parser::ConstantPrimaryPsParameter>`
  = note: required because it appears within the type `sv_parser::ConstantPrimary`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::ConstantPrimary>`
  = note: required because it appears within the type `Box<sv_parser::ConstantPrimary>`
  = note: required because it appears within the type `sv_parser::ConstantExpression`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::ConstantExpression)`
  = note: required because it appears within the type `std::option::Option<(sv_parser::Symbol, sv_parser::ConstantExpression)>`
  = note: required because it appears within the type `(sv_parser::Identifier, std::option::Option<(sv_parser::Symbol, sv_parser::ConstantExpression)>)`
  = note: required because it appears within the type `sv_parser::AttrSpec`
  = note: required because it appears within the type `(sv_parser::AttrSpec, Vec<(sv_parser::Symbol, sv_parser::AttrSpec)>)`
  = note: required because it appears within the type `sv_parser::List<sv_parser::Symbol, sv_parser::AttrSpec>`
  = note: required because it appears within the type `(sv_parser::Symbol, sv_parser::List<sv_parser::Symbol, sv_parser::AttrSpec>, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::AttributeInstance`
  = note: required because of the requirements on the impl of `Sync` for `std::ptr::Unique<sv_parser::AttributeInstance>`
  = note: required because it appears within the type `alloc::raw_vec::RawVec<sv_parser::AttributeInstance>`
  = note: required because it appears within the type `Vec<sv_parser::AttributeInstance>`
  = note: required because it appears within the type `(Vec<sv_parser::AttributeInstance>, sv_parser::ModuleKeyword, std::option::Option<sv_parser::Lifetime>, sv_parser::ModuleIdentifier, Vec<sv_parser::PackageImportDeclaration>, std::option::Option<sv_parser::ParameterPortList>, sv_parser::ListOfPorts, sv_parser::Symbol)`
  = note: required because it appears within the type `sv_parser::ModuleNonansiHeader`
  = note: required because it appears within the type `(sv_parser::ModuleNonansiHeader, std::option::Option<sv_parser::TimeunitsDeclaration>, Vec<sv_parser::ModuleItem>, sv_parser::Keyword, std::option::Option<(sv_parser::Symbol, sv_parser::ModuleIdentifier)>)`
  = note: required because it appears within the type `sv_parser::ModuleDeclarationNonansi`
  = note: required because it appears within the type `&sv_parser::ModuleDeclarationNonansi`
  = note: required because it appears within the type `&&sv_parser::ModuleDeclarationNonansi`

For more information about this error, try `rustc --explain E0275`.

Meta

rustc --version --verbose:

rustc 1.56.0-nightly (8007b506a 2021-08-14)
binary: rustc
commit-hash: 8007b506ac5da629f223b755f5a5391edd5f6d01
commit-date: 2021-08-14
host: x86_64-apple-darwin
release: 1.56.0-nightly
LLVM version: 12.0.1

cc @rust-lang/wg-rfc-2229

@ehuss ehuss added A-closures Area: Closures (`|…| { … }`) C-bug Category: This is a bug. A-edition-2021 Area: The 2021 edition labels Aug 17, 2021
@roxelo
Copy link
Member

roxelo commented Aug 19, 2021

@arora-aman don't think I have much context on this one either

@nikomatsakis
Copy link
Contributor

I think the problem here is that we are using type_implements_trait:

self.infcx
.type_implements_trait(
check_trait,
ty,
self.tcx.mk_substs_trait(ty, &[]),
self.param_env,
)
.must_apply_modulo_regions()

But that uses evaluate_obligation_no_overflow:

self.evaluate_obligation_no_overflow(&obligation)

which is the variant that aborts on overflow

// Helper function that canonicalizes and runs the query. If an
// overflow results, we re-run it in the local context so we can
// report a nice error.
/*crate*/
fn evaluate_obligation_no_overflow(
&self,
obligation: &PredicateObligation<'tcx>,
) -> EvaluationResult;

we could write into fn type_implements_trait() -> Result<bool, OverflowError> and or something like that. I have to look at the places that call type_implements_trait -- in this case, if we see overflow, we could just treat it as false.

Scanning where type_implements_trait is used:

  • conflict_errors.rs: diagnostics, would be better to squelch overflow here too
  • suggestions.rs: as above
  • cast.rs: as above
  • upvar.rs: seems to be for lints, as above (side note that the is-drop-implemented-for-ty is not needed, right?)
  • prelude_2021: another 2021 lint, would prefer not to abort
  • clippy: also a lint, probably also true there

So, my proposed fix is that we change fn type_implements_trait to return false on overflow. i.e., if it overflows, we don't know that the type implements the trait (we don't, in fact, know anything at all). The function is already approximating in the case of generics -- i.e., a false result doesn't mean that the type does NOT implement the trait, just that we don't know that it does.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Aug 26, 2021
…akis

type_implements_trait consider obligation failure on overflow

Fixes: rust-lang#88103
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue Aug 26, 2021
…akis

type_implements_trait consider obligation failure on overflow

Fixes: rust-lang#88103
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Aug 26, 2021
…akis

type_implements_trait consider obligation failure on overflow

Fixes: rust-lang#88103
@bors bors closed this as completed in c418a48 Aug 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-edition-2021 Area: The 2021 edition C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants