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

Add tests for normalize-docs overflow errors #91430

Merged
merged 1 commit into from
Dec 1, 2021

Conversation

jyn514
Copy link
Member

@jyn514 jyn514 commented Dec 1, 2021

@b-naber do you understand why using try_normalize_erasing_regions doesn't silence these cycle errors? Rustdoc isn't emitting them, rustc is aborting before returning an error, even though the function has try_ in the name.

cc #82692, #91255

@jyn514 jyn514 added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. A-trait-system Area: Trait system labels Dec 1, 2021
@rust-highfive
Copy link
Collaborator

r? @GuillaumeGomez

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 1, 2021
@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

r? @jackh726

@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

For context, when -Znormalize-docs is enabled by default, I get the following errors from the new tests:

running 2 tests
FF
failures:

---- [ui] rustdoc-ui/normalize-cycle.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit status: 1
command: "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/home/joshua/rustc/src/test/rustdoc-ui/normalize-cycle.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-o" "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/normalize-cycle" "-Cdebuginfo=0" "-Lnative=/home/joshua/rustc/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/normalize-cycle/auxiliary"
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
error[E0275]: overflow evaluating the requirement `<Source as SelectDsl<Selection>>::Output == _`

error: aborting due to previous error

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

------------------------------------------


---- [ui] rustdoc-ui/normalize-overflow.rs stdout ----

error: test compilation failed although it shouldn't!
status: exit status: 1
command: "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/home/joshua/rustc/src/test/rustdoc-ui/normalize-overflow.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zemit-future-incompat-report" "-o" "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/normalize-overflow" "-Cdebuginfo=0" "-Lnative=/home/joshua/rustc/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/normalize-overflow/auxiliary" "--extern" "overflow=/home/joshua/rustc/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/normalize-overflow/auxiliary/liboverflow.so"
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
error[E0275]: overflow evaluating the requirement `overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<U, B>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>: std::marker::Sized`
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_overflow`)
   = note: required because of the requirements on the impl of `std::ops::Shl<overflow::UInt<_, _>>` for `overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<overflow::UInt<U, B>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>, overflow::B0>`

error: aborting due to previous error

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

------------------------------------------



failures:
    [ui] rustdoc-ui/normalize-cycle.rs
    [ui] rustdoc-ui/normalize-overflow.rs

and if it helps, this is the backtrace for the cycle error:

   4: <rustc_errors::diagnostic_builder::DiagnosticBuilder>::emit
   5: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtExt>::report_overflow_error::<rustc_middle::ty::Predicate>
   6: <rustc_infer::infer::InferCtxt as rustc_trait_selection::traits::error_reporting::InferCtxtExt>::report_overflow_error_cycle
   7: <rustc_trait_selection::traits::fulfill::FulfillProcessor as rustc_data_structures::obligation_forest::ObligationProcessor>::process_backedge::<core::iter::adapters::map::Map<core::slice::iter::Iter<usize>, <rustc_data_structures::obligation_forest::ObligationForest<rustc_trait_selection::traits::fulfill::PendingPredicateObligation>>::find_cycles_from_node<rustc_trait_selection::traits::fulfill::FulfillProcessor>::{closure#1}>>
   8: <rustc_data_structures::obligation_forest::ObligationForest<rustc_trait_selection::traits::fulfill::PendingPredicateObligation>>::find_cycles_from_node::<rustc_trait_selection::traits::fulfill::FulfillProcessor>
   9: <rustc_data_structures::obligation_forest::ObligationForest<rustc_trait_selection::traits::fulfill::PendingPredicateObligation>>::find_cycles_from_node::<rustc_trait_selection::traits::fulfill::FulfillProcessor>
  10: <rustc_data_structures::obligation_forest::ObligationForest<rustc_trait_selection::traits::fulfill::PendingPredicateObligation>>::process_obligations::<rustc_trait_selection::traits::fulfill::FulfillProcessor, rustc_data_structures::obligation_forest::Outcome<rustc_trait_selection::traits::fulfill::PendingPredicateObligation, rustc_infer::traits::FulfillmentErrorCode>>
  11: <rustc_trait_selection::traits::fulfill::FulfillmentContext as rustc_infer::traits::engine::TraitEngine>::select_where_possible
  12: <rustc_infer::infer::InferCtxtBuilder as rustc_trait_selection::infer::InferCtxtBuilderExt>::enter_canonical_trait_query::<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::sty::ProjectionTy>, rustc_middle::traits::query::NormalizationResult, rustc_traits::normalize_projection_ty::normalize_projection_ty::{closure#0}>
  13: rustc_traits::normalize_projection_ty::normalize_projection_ty
  14: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_middle::infer::canonical::Canonical<rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::sty::ProjectionTy>>, core::result::Result<&rustc_middle::infer::canonical::Canonical<rustc_middle::infer::canonical::QueryResponse<rustc_middle::traits::query::NormalizationResult>>, rustc_middle::traits::query::NoSolution>>>
  15: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::normalize_projection_ty, rustc_query_impl::plumbing::QueryCtxt>
  16: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::normalize_projection_ty
  17: <rustc_trait_selection::traits::query::normalize::QueryNormalizer as rustc_middle::ty::fold::TypeFolder>::fold_ty
  18: <rustc_infer::infer::at::At as rustc_trait_selection::traits::query::normalize::AtExt>::normalize::<rustc_middle::ty::subst::GenericArg>
  19: <rustc_infer::infer::InferCtxtBuilder>::enter::<core::result::Result<rustc_middle::ty::subst::GenericArg, rustc_middle::traits::query::NoSolution>, rustc_traits::normalize_erasing_regions::try_normalize_after_erasing_regions<rustc_middle::ty::subst::GenericArg>::{closure#0}>
  20: <rustc_traits::normalize_erasing_regions::provide::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, rustc_middle::ty::ParamEnvAnd<rustc_middle::ty::subst::GenericArg>)>>::call_once
  21: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::try_normalize_generic_arg_after_erasing_regions, rustc_query_impl::plumbing::QueryCtxt>
  22: <rustc_middle::ty::normalize_erasing_regions::TryNormalizeAfterErasingRegionsFolder>::try_normalize_generic_arg_after_erasing_regions
  23: <rustc_middle::ty::normalize_erasing_regions::TryNormalizeAfterErasingRegionsFolder as rustc_middle::ty::fold::TypeFolder>::fold_ty
  24: <&rustc_middle::ty::TyS as rustc_middle::ty::fold::TypeFoldable>::fold_with::<rustc_middle::ty::normalize_erasing_regions::TryNormalizeAfterErasingRegionsFolder>
             at /rustc/f04a2f4b8e89eac1119061ea2055d33c97e618b4/compiler/rustc_middle/src/ty/structural_impls.rs:913:9
  25: <rustc_middle::ty::context::TyCtxt>::try_normalize_erasing_regions::<&rustc_middle::ty::TyS>
             at /rustc/f04a2f4b8e89eac1119061ea2055d33c97e618b4/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:93:13
  26: rustdoc::clean::normalize

@jyn514 jyn514 force-pushed the normalize-fallible branch 2 times, most recently from 362d15a to 9646f3f Compare December 1, 2021 19:10
@rust-log-analyzer

This comment has been minimized.

This unfortunately is still giving an unsilenceable overflow error :(
@jackh726
Copy link
Member

jackh726 commented Dec 1, 2021

Overflow errors are treated differently than how other errors. This has been brought up before.

It might be beneficial to change this behavior, but it is what it is for now.

@bors r+

@bors
Copy link
Contributor

bors commented Dec 1, 2021

📌 Commit 18ddf8d has been approved by jackh726

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 1, 2021
@jyn514
Copy link
Member Author

jyn514 commented Dec 1, 2021

Overflow errors are treated differently than how other errors. This has been brought up before.

and I had trouble getting straight answers then, too :/ https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Make.20.60TypeFolder.3A.3Afold_*.60.20return.20.60Result.60.20compiler-team.23432/near/239300519

@jackh726
Copy link
Member

jackh726 commented Dec 1, 2021

Ah haha. I completely didn't register you had brought it up 🤐 I haven't put a lot of thought into why we need to emit overflow errors regardless of "speculation" or not.

Off the top of my head, we definitely should be careful about treating overflow errors the same as "not implemented for some reason" errors. Otherwise, you could end up with behavior that is different depending on recursion depth. But, that might be context-dependent.

bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 1, 2021
…askrgr

Rollup of 5 pull requests

Successful merges:

 - rust-lang#88502 (Add slice take methods)
 - rust-lang#91313 (expand: Turn `ast::Crate` into a first class expansion target)
 - rust-lang#91424 (Update LLVM with patches for better llvm-cov diagnostics)
 - rust-lang#91425 (Include lint errors in error count for `-Ztreat-err-as-bug`)
 - rust-lang#91430 (Add tests for `normalize-docs` overflow errors)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 4ae75cf into rust-lang:master Dec 1, 2021
@rustbot rustbot added this to the 1.59.0 milestone Dec 1, 2021
@jyn514 jyn514 deleted the normalize-fallible branch December 7, 2021 21:24
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 20, 2022
Make cycle errors recoverable

In particular, this allows rustdoc to recover from cycle errors when normalizing associated types for documentation.

In the past, `@jackh726` has said we need to be careful about overflow errors: rust-lang#91430 (comment)

> Off the top of my head, we definitely should be careful about treating overflow errors the same as
"not implemented for some reason" errors. Otherwise, you could end up with behavior that is
different depending on recursion depth. But, that might be context-dependent.

But cycle errors should be safe to unconditionally report; they don't depend on the recursion depth, they will always be an error whenever they're encountered.

Helps with rust-lang#81091.

r? `@lcnr` cc `@matthewjasper`
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 22, 2022
Make cycle errors recoverable

In particular, this allows rustdoc to recover from cycle errors when normalizing associated types for documentation.

In the past, ``@jackh726`` has said we need to be careful about overflow errors: rust-lang#91430 (comment)

> Off the top of my head, we definitely should be careful about treating overflow errors the same as
"not implemented for some reason" errors. Otherwise, you could end up with behavior that is
different depending on recursion depth. But, that might be context-dependent.

But cycle errors should be safe to unconditionally report; they don't depend on the recursion depth, they will always be an error whenever they're encountered.

Helps with rust-lang#81091.

r? ``@lcnr`` cc ``@matthewjasper``
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Sep 22, 2022
Make cycle errors recoverable

In particular, this allows rustdoc to recover from cycle errors when normalizing associated types for documentation.

In the past, ```@jackh726``` has said we need to be careful about overflow errors: rust-lang#91430 (comment)

> Off the top of my head, we definitely should be careful about treating overflow errors the same as
"not implemented for some reason" errors. Otherwise, you could end up with behavior that is
different depending on recursion depth. But, that might be context-dependent.

But cycle errors should be safe to unconditionally report; they don't depend on the recursion depth, they will always be an error whenever they're encountered.

Helps with rust-lang#81091.

r? ```@lcnr``` cc ```@matthewjasper```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants