Skip to content

Commit 02a24c8

Browse files
committed
Don't ICE on infinitely recursive types
`evaluate_obligation` can only be run on types that are already valid. So rustdoc still has to run typeck even though it doesn't care about the result.
1 parent 2d0e8e2 commit 02a24c8

File tree

6 files changed

+40
-0
lines changed

6 files changed

+40
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4027,6 +4027,7 @@ name = "rustdoc"
40274027
version = "0.0.0"
40284028
dependencies = [
40294029
"itertools 0.8.0",
4030+
"lazy_static",
40304031
"minifier",
40314032
"pulldown-cmark",
40324033
"rustc-rayon",

src/librustdoc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ serde = { version = "1.0", features = ["derive"] }
1616
serde_json = "1.0"
1717
tempfile = "3"
1818
itertools = "0.8"
19+
lazy_static = "1"

src/librustdoc/core.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
364364
..Options::default()
365365
};
366366

367+
lazy_static! {
368+
static ref EMPTY_MAP: FxHashSet<LocalDefId> = FxHashSet::default();
369+
}
367370
let config = interface::Config {
368371
opts: sessopts,
369372
crate_cfg: interface::parse_cfgspecs(cfgs),
@@ -378,8 +381,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
378381
lint_caps,
379382
register_lints: None,
380383
override_queries: Some(|_sess, local_providers, external_providers| {
384+
// Most lints will require typechecking, so just don't run them.
381385
local_providers.lint_mod = |_, _| {};
382386
external_providers.lint_mod = |_, _| {};
387+
local_providers.typeck_item_bodies = |_, _| {};
388+
// hack so that `used_trait_imports` won't try to call typeck_tables_of
389+
local_providers.used_trait_imports = |_, _| &EMPTY_MAP;
390+
// In case typeck does end up being called, don't ICE in case there were name resolution errors
383391
local_providers.typeck_tables_of = move |tcx, def_id| {
384392
// Closures' tables come from their outermost function,
385393
// as they are part of the same "inference environment".
@@ -439,6 +447,13 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
439447
let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take();
440448

441449
global_ctxt.enter(|tcx| {
450+
// Some queries require that they only run on valid types:
451+
// https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425
452+
// Therefore typecheck this crate before running lints.
453+
// NOTE: this does not typeck item bodies or run the default rustc lints
454+
// (see `override_queries` in the `config`)
455+
let _ = rustc_typeck::check_crate(tcx);
456+
tcx.sess.abort_if_errors();
442457
sess.time("missing_docs", || {
443458
rustc_lint::check_crate(tcx, rustc_lint::builtin::MissingDoc::new);
444459
});

src/librustdoc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#![recursion_limit = "256"]
1616

1717
extern crate env_logger;
18+
#[macro_use]
19+
extern crate lazy_static;
1820
extern crate rustc_ast;
1921
extern crate rustc_ast_pretty;
2022
extern crate rustc_attr;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum E {
2+
//~^ ERROR recursive type `E` has infinite size
3+
V(E),
4+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0072]: recursive type `E` has infinite size
2+
--> $DIR/infinite-recursive-type.rs:1:1
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 `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)