Skip to content

Commit

Permalink
Auto merge of rust-lang#108576 - megakorre:rustdock_additional_typech…
Browse files Browse the repository at this point in the history
…eck_before_clean, r=GuillaumeGomez

rustdoc: run more HIR validation to mirror rustc

# Explanation

While investigating these issues: rust-lang#107093, rust-lang#106079
I thought it maybe would be useful to test running `rustdoc` on all rust files under `tests/ui` grepping for files that causes any ICEs.
And these are the files I found would cause ICEs.
```
// These are handled by this fix.
tests/ui/late-bound-lifetimes/mismatched_arg_count.rs
tests/ui/associated-consts/issue-102335-const.rs
tests/ui/const-generics/generic_const_exprs/issue-102768.rs
tests/ui/const-generics/const-arg-type-arg-misordered.rs
tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
tests/ui/typeck/issue-88643.rs
tests/ui/typeck/issue-75889.rs
tests/ui/typeck/issue-83621-placeholder-static-in-extern.rs
// These are not they will still produce a ICE after this change
tests/ui/limits/issue-56762.rs
tests/ui/union/projection-as-union-type-error-2.rs
tests/ui/union/projection-as-union-type-error.rs
```

I reduces the issues handled by this PR down to the tests added in the PR. That includes the linked issues.
But the 3 files that are not handled I will leave for a future PR.

This PR adds the `type_collecting` step from `hir_analysis::check_crate` to the rustdoc typechecks.
It had the following comment on it.
```
// this ensures that later parts of type checking can assume that items
// have valid types and not error
```
Adding the check report the same errors as rustc does for these input.
And not ICE when the lint checker walks the HIR or when in the `rustdoc::clean` pass.

This PR updates the expected errors of some existing rustdoc-ui tests (some now report less errors).
These new reported errors does mirror the errors reported by rustc.

# Performance
It does more checking so it will probably regress. We should run ``@bors` try `@rust-timer` queue` and see.

# Discussion

Maybe instead of calling a subset of the checks in `hir_analysis::check_crate` and having comments that say they should be kept in sync. We could instead call `check_crate` directly and pass in some flag. Maybe `check_toplevel_signatures_only` or something like that. That flag would have to skip most of the checks in that function tough.
  • Loading branch information
bors committed Mar 30, 2023
2 parents 516a6d3 + 1f9e2d0 commit 789ee5e
Show file tree
Hide file tree
Showing 18 changed files with 483 additions and 29 deletions.
3 changes: 3 additions & 0 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ pub(crate) fn run_global_ctxt(

// HACK(jynelson) this calls an _extremely_ limited subset of `typeck`
// and might break if queries change their assumptions in the future.
tcx.sess.time("type_collecting", || {
tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module))
});

// NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
tcx.sess.time("item_types_checking", || {
Expand Down
6 changes: 6 additions & 0 deletions tests/rustdoc-ui/const_arg_in_type_position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type Array<T, const N: usize> = [T; N];

fn foo<const N: usize>() -> Array<N, ()> {
//~^ ERROR constant provided when a type was expected
unimplemented!()
}
9 changes: 9 additions & 0 deletions tests/rustdoc-ui/const_arg_in_type_position.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0747]: constant provided when a type was expected
--> $DIR/const_arg_in_type_position.rs:3:35
|
LL | fn foo<const N: usize>() -> Array<N, ()> {
| ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0747`.
10 changes: 10 additions & 0 deletions tests/rustdoc-ui/invalid_associated_const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(associated_const_equality)]

trait T {
type A: S<C<X = 0i32> = 34>;
//~^ ERROR associated type bindings are not allowed here
}

trait S {
const C: i32;
}
9 changes: 9 additions & 0 deletions tests/rustdoc-ui/invalid_associated_const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0229]: associated type bindings are not allowed here
--> $DIR/invalid_associated_const.rs:4:17
|
LL | type A: S<C<X = 0i32> = 34>;
| ^^^^^^^^ associated type not allowed here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0229`.
6 changes: 6 additions & 0 deletions tests/rustdoc-ui/invalid_const_in_lifetime_position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
trait X {
type Y<'a>;
}
fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
//~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
33 changes: 33 additions & 0 deletions tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
--> $DIR/invalid_const_in_lifetime_position.rs:4:26
|
LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| ^ expected 1 lifetime argument
|
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/invalid_const_in_lifetime_position.rs:2:10
|
LL | type Y<'a>;
| ^ --
help: add missing lifetime argument
|
LL | fn f<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++

error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/invalid_const_in_lifetime_position.rs:4:26
|
LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| ^--- help: remove these generics
| |
| expected 0 generic arguments
|
note: associated type defined here, with 0 generic parameters
--> $DIR/invalid_const_in_lifetime_position.rs:2:10
|
LL | type Y<'a>;
| ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0107`.
2 changes: 2 additions & 0 deletions tests/rustdoc-ui/invalid_infered_static_and_const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const FOO: dyn Fn() -> _ = ""; //~ ERROR E0121
static BOO: dyn Fn() -> _ = ""; //~ ERROR E0121
15 changes: 15 additions & 0 deletions tests/rustdoc-ui/invalid_infered_static_and_const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items
--> $DIR/invalid_infered_static_and_const.rs:1:24
|
LL | const FOO: dyn Fn() -> _ = "";
| ^ not allowed in type signatures

error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items
--> $DIR/invalid_infered_static_and_const.rs:2:25
|
LL | static BOO: dyn Fn() -> _ = "";
| ^ not allowed in type signatures

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0121`.
37 changes: 34 additions & 3 deletions tests/rustdoc-ui/issue-105742.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
// compile-flags: -Znormalize-docs

use std::ops::Index;

pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
//~| the trait `SVec` cannot be made into an object
//~| `SVec` cannot be made into an object
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
let _ = s;
}

pub trait SVec: Index<
<Self as SVec>::Item,
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
Output = <Index<<Self as SVec>::Item,
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
Output = <Self as SVec>::Item> as SVec>::Item,
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
//~| expected 1 lifetime argument
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| expected 1 generic argument
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
//~| missing generics for associated type `SVec::Item`
> {
type Item<'a, T>;

fn len(&self) -> <Self as SVec>::Item;
//~^ ERROR
//~^^ ERROR
//~^ expected 1 lifetime argument
//~| missing generics for associated type `SVec::Item`
//~| expected 1 generic argument
//~| missing generics for associated type `SVec::Item`
}
Loading

0 comments on commit 789ee5e

Please sign in to comment.