about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-10 19:33:25 +0000
committerbors <bors@rust-lang.org>2020-08-10 19:33:25 +0000
commitd495ef527c6ab41c837ff13ed74f648bacee921f (patch)
treeb1beb16bc99570e25929d5d0d4badf3078b188b9 /src
parent1275cc15d6aa0597f0b3bbf8aa0750239f9da7b2 (diff)
parenta306e12874e3d9da225e41a904d27dd53629ca54 (diff)
downloadrust-d495ef527c6ab41c837ff13ed74f648bacee921f.tar.gz
rust-d495ef527c6ab41c837ff13ed74f648bacee921f.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/librustc_privacy/lib.rs17
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustdoc/core.rs12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/async.rs7
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/async.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/closure.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/closure.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/generic-argument.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs28
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.stderr12
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs2
-rw-r--r--src/test/rustdoc-ui/error-in-impl-trait/trait-alias.stderr12
-rw-r--r--src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs15
-rw-r--r--src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr17
-rw-r--r--src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs7
-rw-r--r--src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr17
23 files changed, 126 insertions, 105 deletions
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 2aa7780aaaf..3ba5acd00a0 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -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(..)
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3d58fb30d91..63e9e9a8215 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -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);
-
-            let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
-            check_opaque(tcx, def_id, substs, it.span, &origin);
+            // 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);
+            }
         }
         hir::ItemKind::TyAlias(..) => {
             let def_id = tcx.hir().local_def_id(it.hir_id);
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index a8247e2f494..056090baa22 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -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));
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index cbd0ca0de64..b13acaae1bf 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -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);
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/async.rs b/src/test/rustdoc-ui/error-in-impl-trait/async.rs
index 112a2c494a5..cda53bff07a 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/async.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/async.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/async.stderr b/src/test/rustdoc-ui/error-in-impl-trait/async.stderr
deleted file mode 100644
index 086db1be722..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/async.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/closure.rs
index df40c121d57..f1fd85bb23c 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/closure.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/closure.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/closure.stderr b/src/test/rustdoc-ui/error-in-impl-trait/closure.stderr
deleted file mode 100644
index 4ee9c4d1f43..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/closure.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs b/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs
index 0ccf2e3866f..dcec379d47e 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.rs
@@ -1,7 +1,7 @@
+// check-pass
 trait ValidTrait {}
 
 /// This has docs
 pub fn f() -> impl ValidTrait {
     Vec::<DoesNotExist>::new()
-    //~^ ERROR failed to resolve
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.stderr b/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.stderr
deleted file mode 100644
index 72716c258dc..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/generic-argument.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs
index 399fb827517..b935b0832f0 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.stderr b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.stderr
deleted file mode 100644
index 55f9b609a11..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword-closure.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs
index 24b5734dbd0..701126f87a1 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.stderr b/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.stderr
deleted file mode 100644
index 3257079f942..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/impl-keyword.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs b/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs
new file mode 100644
index 00000000000..248575d3528
--- /dev/null
+++ b/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs
@@ -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()
+}
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs
index 1498fa4f890..31dd786cbbf 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.stderr b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.stderr
deleted file mode 100644
index 84b28139dbc..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias-closure.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs
index cf9bc48c7f8..c18a024af4b 100644
--- a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs
+++ b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.rs
@@ -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
 }
diff --git a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.stderr b/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.stderr
deleted file mode 100644
index 9be6a3d8d6b..00000000000
--- a/src/test/rustdoc-ui/error-in-impl-trait/trait-alias.stderr
+++ /dev/null
@@ -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`.
diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs
new file mode 100644
index 00000000000..acce0f77a25
--- /dev/null
+++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs
@@ -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() {}
diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr
new file mode 100644
index 00000000000..991dc6eec1d
--- /dev/null
+++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr
@@ -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`.
diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs
new file mode 100644
index 00000000000..b3a7ee56313
--- /dev/null
+++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.rs
@@ -0,0 +1,7 @@
+fn f() -> impl Sized {
+    enum E {
+    //~^ ERROR recursive type `f::E` has infinite size
+        V(E),
+    }
+    unimplemented!()
+}
diff --git a/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr
new file mode 100644
index 00000000000..ec1bb786fe5
--- /dev/null
+++ b/src/test/rustdoc-ui/infinite-recursive-type-impl-trait.stderr
@@ -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`.