Skip to content

Commit d495ef5

Browse files
committed
Auto merge of #75127 - jyn514:impl-trait, r=pnkfelix
Fix async-std by special-casing rustdoc in typeck #75100
2 parents 1275cc1 + a306e12 commit d495ef5

23 files changed

+126
-105
lines changed

src/librustc_privacy/lib.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,18 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
784784
// The interface is empty.
785785
hir::ItemKind::GlobalAsm(..) => {}
786786
hir::ItemKind::OpaqueTy(..) => {
787-
// FIXME: This is some serious pessimization intended to workaround deficiencies
788-
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
789-
// reachable if they are returned via `impl Trait`, even from private functions.
790-
let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
791-
self.reach(item.hir_id, exist_level).generics().predicates().ty();
787+
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
788+
// Since rustdoc never need to do codegen and doesn't care about link-time reachability,
789+
// mark this as unreachable.
790+
// See https://github.com/rust-lang/rust/issues/75100
791+
if !self.tcx.sess.opts.actually_rustdoc {
792+
// FIXME: This is some serious pessimization intended to workaround deficiencies
793+
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
794+
// reachable if they are returned via `impl Trait`, even from private functions.
795+
let exist_level =
796+
cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
797+
self.reach(item.hir_id, exist_level).generics().predicates().ty();
798+
}
792799
}
793800
// Visit everything.
794801
hir::ItemKind::Const(..)

src/librustc_typeck/check/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1967,10 +1967,16 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
19671967
check_union(tcx, it.hir_id, it.span);
19681968
}
19691969
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
1970-
let def_id = tcx.hir().local_def_id(it.hir_id);
1971-
1972-
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1973-
check_opaque(tcx, def_id, substs, it.span, &origin);
1970+
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
1971+
// `async-std` (and `pub async fn` in general).
1972+
// Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
1973+
// See https://github.com/rust-lang/rust/issues/75100
1974+
if !tcx.sess.opts.actually_rustdoc {
1975+
let def_id = tcx.hir().local_def_id(it.hir_id);
1976+
1977+
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
1978+
check_opaque(tcx, def_id, substs, it.span, &origin);
1979+
}
19741980
}
19751981
hir::ItemKind::TyAlias(..) => {
19761982
let def_id = tcx.hir().local_def_id(it.hir_id);

src/librustc_typeck/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
390390
tcx.sess.time("wf_checking", || check::check_wf_new(tcx));
391391
})?;
392392

393+
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
393394
tcx.sess.time("item_types_checking", || {
394395
for &module in tcx.hir().krate().modules.keys() {
395396
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));

src/librustdoc/core.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,20 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
452452
// Certain queries assume that some checks were run elsewhere
453453
// (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425),
454454
// so type-check everything other than function bodies in this crate before running lints.
455+
455456
// NOTE: this does not call `tcx.analysis()` so that we won't
456457
// typeck function bodies or run the default rustc lints.
457458
// (see `override_queries` in the `config`)
458-
let _ = rustc_typeck::check_crate(tcx);
459+
460+
// HACK(jynelson) this calls an _extremely_ limited subset of `typeck`
461+
// and might break if queries change their assumptions in the future.
462+
463+
// NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
464+
tcx.sess.time("item_types_checking", || {
465+
for &module in tcx.hir().krate().modules.keys() {
466+
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
467+
}
468+
});
459469
tcx.sess.abort_if_errors();
460470
sess.time("missing_docs", || {
461471
rustc_lint::check_crate(tcx, rustc_lint::builtin::MissingDoc::new);
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// edition:2018
2+
// check-pass
23

3-
/// This used to work with ResolveBodyWithLoop.
4-
/// However now that we ignore type checking instead of modifying the function body,
5-
/// the return type is seen as `impl Future<Output = u32>`, not a `u32`.
6-
/// So it no longer allows errors in the function body.
4+
/// Should compile fine
75
pub async fn a() -> u32 {
86
error::_in::async_fn()
9-
//~^ ERROR failed to resolve
107
}

src/test/rustdoc-ui/error-in-impl-trait/async.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
// check-pass
12
// manually desugared version of an `async fn` (but with a closure instead of a generator)
23
pub fn a() -> impl Fn() -> u32 {
34
|| content::doesnt::matter()
4-
//~^ ERROR failed to resolve
55
}

src/test/rustdoc-ui/error-in-impl-trait/closure.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
// check-pass
12
trait ValidTrait {}
23

34
/// This has docs
45
pub fn f() -> impl ValidTrait {
56
Vec::<DoesNotExist>::new()
6-
//~^ ERROR failed to resolve
77
}

src/test/rustdoc-ui/error-in-impl-trait/generic-argument.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
// check-pass
12
pub trait ValidTrait {}
23
/// This returns impl trait
34
pub fn g() -> impl ValidTrait {
45
(|| error::_in::impl_trait::alias::nested::closure())()
5-
//~^ ERROR failed to resolve
66
}

src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
// check-pass
12
pub trait ValidTrait {}
23
/// This returns impl trait
34
pub fn g() -> impl ValidTrait {
45
error::_in::impl_trait()
5-
//~^ ERROR failed to resolve
66
}

src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// edition:2018
2+
// check-pass
3+
4+
mod windows {
5+
pub trait WinFoo {
6+
fn foo(&self) {}
7+
}
8+
9+
impl WinFoo for () {}
10+
}
11+
12+
#[cfg(any(windows, doc))]
13+
use windows::*;
14+
15+
mod unix {
16+
pub trait UnixFoo {
17+
fn foo(&self) {}
18+
}
19+
20+
impl UnixFoo for () {}
21+
}
22+
23+
#[cfg(any(unix, doc))]
24+
use unix::*;
25+
26+
async fn bar() {
27+
().foo()
28+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// check-pass
12
#![feature(type_alias_impl_trait)]
23

34
pub trait ValidTrait {}
@@ -6,5 +7,4 @@ type ImplTrait = impl ValidTrait;
67
/// This returns impl trait, but using a type alias
78
pub fn h() -> ImplTrait {
89
(|| error::_in::impl_trait::alias::nested::closure())()
9-
//~^ ERROR failed to resolve
1010
}

src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// check-pass
12
#![feature(type_alias_impl_trait)]
23

34
pub trait ValidTrait {}
@@ -6,5 +7,4 @@ type ImplTrait = impl ValidTrait;
67
/// This returns impl trait, but using a type alias
78
pub fn h() -> ImplTrait {
89
error::_in::impl_trait::alias()
9-
//~^ ERROR failed to resolve
1010
}

src/test/rustdoc-ui/error-in-impl-trait/trait-alias.stderr

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// normalize-stderr-test: "`.*`" -> "`DEF_ID`"
2+
// normalize-stdout-test: "`.*`" -> "`DEF_ID`"
3+
// edition:2018
4+
5+
pub async fn f() -> impl std::fmt::Debug {
6+
#[derive(Debug)]
7+
enum E {
8+
//~^ ERROR recursive type `f::{{closure}}#0::E` has infinite size
9+
This(E),
10+
Unit,
11+
}
12+
E::Unit
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0072]: recursive type `DEF_ID` has infinite size
2+
--> $DIR/infinite-recursive-type-impl-trait-return.rs:7:5
3+
|
4+
LL | enum E {
5+
| ^^^^^^ recursive type has infinite size
6+
LL |
7+
LL | This(E),
8+
| - recursive without indirection
9+
|
10+
help: insert some indirection (e.g., a `DEF_ID` representable
11+
|
12+
LL | This(Box<E>),
13+
| ^^^^ ^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `DEF_ID`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn f() -> impl Sized {
2+
enum E {
3+
//~^ ERROR recursive type `f::E` has infinite size
4+
V(E),
5+
}
6+
unimplemented!()
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0072]: recursive type `f::E` has infinite size
2+
--> $DIR/infinite-recursive-type-impl-trait.rs:2:5
3+
|
4+
LL | enum E {
5+
| ^^^^^^ recursive type has infinite size
6+
LL |
7+
LL | V(E),
8+
| - recursive without indirection
9+
|
10+
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `f::E` representable
11+
|
12+
LL | V(Box<E>),
13+
| ^^^^ ^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0072`.

0 commit comments

Comments
 (0)