mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
Auto merge of #75127 - jyn514:impl-trait, r=pnkfelix
Fix async-std by special-casing rustdoc in typeck https://github.com/rust-lang/rust/issues/75100
This commit is contained in:
commit
d495ef527c
@ -784,11 +784,18 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||
// The interface is empty.
|
||||
hir::ItemKind::GlobalAsm(..) => {}
|
||||
hir::ItemKind::OpaqueTy(..) => {
|
||||
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
||||
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
|
||||
// reachable if they are returned via `impl Trait`, even from private functions.
|
||||
let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
|
||||
self.reach(item.hir_id, exist_level).generics().predicates().ty();
|
||||
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
|
||||
// Since rustdoc never need to do codegen and doesn't care about link-time reachability,
|
||||
// mark this as unreachable.
|
||||
// See https://github.com/rust-lang/rust/issues/75100
|
||||
if !self.tcx.sess.opts.actually_rustdoc {
|
||||
// FIXME: This is some serious pessimization intended to workaround deficiencies
|
||||
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
|
||||
// reachable if they are returned via `impl Trait`, even from private functions.
|
||||
let exist_level =
|
||||
cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
|
||||
self.reach(item.hir_id, exist_level).generics().predicates().ty();
|
||||
}
|
||||
}
|
||||
// Visit everything.
|
||||
hir::ItemKind::Const(..)
|
||||
|
@ -1967,10 +1967,16 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
|
||||
check_union(tcx, it.hir_id, it.span);
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
||||
let def_id = tcx.hir().local_def_id(it.hir_id);
|
||||
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
|
||||
// `async-std` (and `pub async fn` in general).
|
||||
// Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
|
||||
// See https://github.com/rust-lang/rust/issues/75100
|
||||
if !tcx.sess.opts.actually_rustdoc {
|
||||
let def_id = tcx.hir().local_def_id(it.hir_id);
|
||||
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
check_opaque(tcx, def_id, substs, it.span, &origin);
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
check_opaque(tcx, def_id, substs, it.span, &origin);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::TyAlias(..) => {
|
||||
let def_id = tcx.hir().local_def_id(it.hir_id);
|
||||
|
@ -390,6 +390,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
|
||||
tcx.sess.time("wf_checking", || check::check_wf_new(tcx));
|
||||
})?;
|
||||
|
||||
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
|
||||
tcx.sess.time("item_types_checking", || {
|
||||
for &module in tcx.hir().krate().modules.keys() {
|
||||
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
|
||||
|
@ -452,10 +452,20 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
||||
// Certain queries assume that some checks were run elsewhere
|
||||
// (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425),
|
||||
// so type-check everything other than function bodies in this crate before running lints.
|
||||
|
||||
// NOTE: this does not call `tcx.analysis()` so that we won't
|
||||
// typeck function bodies or run the default rustc lints.
|
||||
// (see `override_queries` in the `config`)
|
||||
let _ = rustc_typeck::check_crate(tcx);
|
||||
|
||||
// HACK(jynelson) this calls an _extremely_ limited subset of `typeck`
|
||||
// and might break if queries change their assumptions in the future.
|
||||
|
||||
// NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
|
||||
tcx.sess.time("item_types_checking", || {
|
||||
for &module in tcx.hir().krate().modules.keys() {
|
||||
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
|
||||
}
|
||||
});
|
||||
tcx.sess.abort_if_errors();
|
||||
sess.time("missing_docs", || {
|
||||
rustc_lint::check_crate(tcx, rustc_lint::builtin::MissingDoc::new);
|
||||
|
@ -1,10 +1,7 @@
|
||||
// edition:2018
|
||||
// check-pass
|
||||
|
||||
/// This used to work with ResolveBodyWithLoop.
|
||||
/// However now that we ignore type checking instead of modifying the function body,
|
||||
/// the return type is seen as `impl Future<Output = u32>`, not a `u32`.
|
||||
/// So it no longer allows errors in the function body.
|
||||
/// Should compile fine
|
||||
pub async fn a() -> u32 {
|
||||
error::_in::async_fn()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `error::_in::async_fn`
|
||||
--> $DIR/async.rs:8:5
|
||||
|
|
||||
LL | error::_in::async_fn()
|
||||
| ^^^^^^^^^^^^^^^^^^^^ could not resolve path `error::_in::async_fn`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,5 +1,5 @@
|
||||
// check-pass
|
||||
// manually desugared version of an `async fn` (but with a closure instead of a generator)
|
||||
pub fn a() -> impl Fn() -> u32 {
|
||||
|| content::doesnt::matter()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `content::doesnt::matter`
|
||||
--> $DIR/closure.rs:3:8
|
||||
|
|
||||
LL | || content::doesnt::matter()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `content::doesnt::matter`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,7 +1,7 @@
|
||||
// check-pass
|
||||
trait ValidTrait {}
|
||||
|
||||
/// This has docs
|
||||
pub fn f() -> impl ValidTrait {
|
||||
Vec::<DoesNotExist>::new()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `DoesNotExist`
|
||||
--> $DIR/generic-argument.rs:5:11
|
||||
|
|
||||
LL | Vec::<DoesNotExist>::new()
|
||||
| ^^^^^^^^^^^^ could not resolve path `DoesNotExist`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,6 +1,6 @@
|
||||
// check-pass
|
||||
pub trait ValidTrait {}
|
||||
/// This returns impl trait
|
||||
pub fn g() -> impl ValidTrait {
|
||||
(|| error::_in::impl_trait::alias::nested::closure())()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `error::_in::impl_trait::alias::nested::closure`
|
||||
--> $DIR/impl-keyword-closure.rs:4:9
|
||||
|
|
||||
LL | (|| error::_in::impl_trait::alias::nested::closure())()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `error::_in::impl_trait::alias::nested::closure`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,6 +1,6 @@
|
||||
// check-pass
|
||||
pub trait ValidTrait {}
|
||||
/// This returns impl trait
|
||||
pub fn g() -> impl ValidTrait {
|
||||
error::_in::impl_trait()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `error::_in::impl_trait`
|
||||
--> $DIR/impl-keyword.rs:4:5
|
||||
|
|
||||
LL | error::_in::impl_trait()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `error::_in::impl_trait`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
28
src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs
Normal file
28
src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// edition:2018
|
||||
// check-pass
|
||||
|
||||
mod windows {
|
||||
pub trait WinFoo {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
impl WinFoo for () {}
|
||||
}
|
||||
|
||||
#[cfg(any(windows, doc))]
|
||||
use windows::*;
|
||||
|
||||
mod unix {
|
||||
pub trait UnixFoo {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
impl UnixFoo for () {}
|
||||
}
|
||||
|
||||
#[cfg(any(unix, doc))]
|
||||
use unix::*;
|
||||
|
||||
async fn bar() {
|
||||
().foo()
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
// check-pass
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait ValidTrait {}
|
||||
@ -6,5 +7,4 @@ type ImplTrait = impl ValidTrait;
|
||||
/// This returns impl trait, but using a type alias
|
||||
pub fn h() -> ImplTrait {
|
||||
(|| error::_in::impl_trait::alias::nested::closure())()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `error::_in::impl_trait::alias::nested::closure`
|
||||
--> $DIR/trait-alias-closure.rs:8:9
|
||||
|
|
||||
LL | (|| error::_in::impl_trait::alias::nested::closure())()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `error::_in::impl_trait::alias::nested::closure`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -1,3 +1,4 @@
|
||||
// check-pass
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub trait ValidTrait {}
|
||||
@ -6,5 +7,4 @@ type ImplTrait = impl ValidTrait;
|
||||
/// This returns impl trait, but using a type alias
|
||||
pub fn h() -> ImplTrait {
|
||||
error::_in::impl_trait::alias()
|
||||
//~^ ERROR failed to resolve
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0433]: failed to resolve: could not resolve path `error::_in::impl_trait::alias`
|
||||
--> $DIR/trait-alias.rs:8:5
|
||||
|
|
||||
LL | error::_in::impl_trait::alias()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not resolve path `error::_in::impl_trait::alias`
|
||||
|
|
||||
= note: this error was originally ignored because you are running `rustdoc`
|
||||
= note: try running again with `rustc` or `cargo check` and you may get a more detailed error
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -0,0 +1,15 @@
|
||||
// normalize-stderr-test: "`.*`" -> "`DEF_ID`"
|
||||
// normalize-stdout-test: "`.*`" -> "`DEF_ID`"
|
||||
// edition:2018
|
||||
|
||||
pub async fn f() -> impl std::fmt::Debug {
|
||||
#[derive(Debug)]
|
||||
enum E {
|
||||
//~^ ERROR recursive type `f::{{closure}}#0::E` has infinite size
|
||||
This(E),
|
||||
Unit,
|
||||
}
|
||||
E::Unit
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,17 @@
|
||||
error[E0072]: recursive type `DEF_ID` has infinite size
|
||||
--> $DIR/infinite-recursive-type-impl-trait-return.rs:7:5
|
||||
|
|
||||
LL | enum E {
|
||||
| ^^^^^^ recursive type has infinite size
|
||||
LL |
|
||||
LL | This(E),
|
||||
| - recursive without indirection
|
||||
|
|
||||
help: insert some indirection (e.g., a `DEF_ID` representable
|
||||
|
|
||||
LL | This(Box<E>),
|
||||
| ^^^^ ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `DEF_ID`.
|
@ -0,0 +1,7 @@
|
||||
fn f() -> impl Sized {
|
||||
enum E {
|
||||
//~^ ERROR recursive type `f::E` has infinite size
|
||||
V(E),
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
error[E0072]: recursive type `f::E` has infinite size
|
||||
--> $DIR/infinite-recursive-type-impl-trait.rs:2:5
|
||||
|
|
||||
LL | enum E {
|
||||
| ^^^^^^ recursive type has infinite size
|
||||
LL |
|
||||
LL | V(E),
|
||||
| - recursive without indirection
|
||||
|
|
||||
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `f::E` representable
|
||||
|
|
||||
LL | V(Box<E>),
|
||||
| ^^^^ ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0072`.
|
Loading…
Reference in New Issue
Block a user