Skip to content

Commit

Permalink
Auto merge of #117450 - oli-obk:rustdoc_verify, r=estebank
Browse files Browse the repository at this point in the history
Accept less invalid Rust in rustdoc

pulled out of #117213 where this change was already approved

This only affects rustdoc, and has up to [20% perf regressions in rustdoc](#117213 (comment)). These are unavoidable, as we are simply doing more checks now, but it's part of the longer term plan of making rustdoc more resistant to ICEs by only accepting valid Rust code.
  • Loading branch information
bors committed Oct 31, 2023
2 parents d7d9f15 + 4512f21 commit 50be229
Show file tree
Hide file tree
Showing 35 changed files with 428 additions and 127 deletions.
20 changes: 0 additions & 20 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,26 +1077,6 @@ mod prim_tuple {}
#[doc(hidden)]
impl<T> (T,) {}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Clone> Clone for (T,) {
fn clone(&self) -> Self {
loop {}
}
}

// Fake impl that's only really used for docs.
#[cfg(doc)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(fake_variadic)]
/// This trait is implemented on arbitrary-length tuples.
impl<T: Copy> Copy for (T,) {
// empty
}

#[rustc_doc_primitive = "f32"]
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
///
Expand Down
6 changes: 5 additions & 1 deletion src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,14 @@ pub(crate) fn run_global_ctxt(
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.
// NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes.
let _ = tcx.sess.time("wf_checking", || {
tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
});
tcx.sess.time("item_types_checking", || {
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
});

tcx.sess.abort_if_errors();
tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx));
tcx.sess.time("check_mod_attrs", || {
Expand Down
9 changes: 7 additions & 2 deletions tests/rustdoc-gui/src/lib2/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ pub struct LongItemInfo2;
#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
impl SimpleTrait for LongItemInfo2 {}

pub struct WhereWhitespace<T>;
pub struct WhereWhitespace<T>(T);

impl<T> WhereWhitespace<T> {
pub fn new<F>(f: F) -> Self
where
F: FnMut() -> i32,
{}
{todo!()}
}

impl<K, T> Whitespace<&K> for WhereWhitespace<T>
Expand Down Expand Up @@ -187,6 +187,11 @@ impl ItemInfoAlignmentTest {
pub mod scroll_traits {
use std::iter::*;

struct Intersperse<T>(T);
struct IntersperseWith<T, U>(T, U);
struct Flatten<T>(T);
struct Peekable<T>(T);

/// Shamelessly (partially) copied from `std::iter::Iterator`.
/// It allows us to check that the scroll is working as expected on "hidden" items.
pub trait Iterator {
Expand Down
5 changes: 4 additions & 1 deletion tests/rustdoc-json/enums/field_hidden.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Regression test for <https://github.com/rust-lang/rust/issues/100529>.

#![no_core]
#![feature(no_core)]
#![feature(no_core, lang_items)]

#[lang = "sized"]
trait Sized {}

// @has "$.index[*][?(@.name=='ParseError')]"
// @has "$.index[*][?(@.name=='UnexpectedEndTag')]"
Expand Down
5 changes: 4 additions & 1 deletion tests/rustdoc-json/enums/kind.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// ignore-tidy-linelength

#![feature(no_core)]
#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
trait Sized {}

pub enum Foo {
// @set Unit = "$.index[*][?(@.name=='Unit')].id"
// @is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"'
Expand Down
5 changes: 4 additions & 1 deletion tests/rustdoc-json/enums/tuple_fields_hidden.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![feature(no_core)]
#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
trait Sized {}

// @set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id"
// @set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id"
// @set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id"
Expand Down
5 changes: 4 additions & 1 deletion tests/rustdoc-json/generic-associated-types/gats.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// ignore-tidy-linelength

#![no_core]
#![feature(lang_items, no_core)]
#![feature(lang_items, no_core, arbitrary_self_types)]

#[lang = "sized"]
pub trait Sized {}

#[lang = "receiver"]
pub trait Receiver {}

pub trait Display {}

pub trait LendingIterator {
Expand Down
9 changes: 6 additions & 3 deletions tests/rustdoc-json/impls/auto.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#![feature(no_core, auto_traits, lang_items)]
#![feature(no_core, auto_traits, lang_items, arbitrary_self_types)]
#![no_core]

#[lang = "sized"]
trait Sized {}

#[lang = "receiver"]
pub trait Receiver {}

pub auto trait Bar {}

/// has span
Expand All @@ -12,8 +15,8 @@ impl Foo {
}

// Testing spans, so all tests below code
// @is "$.index[*][?(@.docs=='has span')].span.begin" "[10, 0]"
// @is "$.index[*][?(@.docs=='has span')].span.end" "[12, 1]"
// @is "$.index[*][?(@.docs=='has span')].span.begin" "[13, 0]"
// @is "$.index[*][?(@.docs=='has span')].span.end" "[15, 1]"
// FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91
// is "$.index[*][?(@.inner.impl.synthetic==true)].span" null
pub struct Foo;
2 changes: 1 addition & 1 deletion tests/rustdoc-json/type/inherent_associated_type_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ pub struct Carrier<'a>(&'a ());
pub fn user(_: for<'b> fn(Carrier<'b>::Focus<i32>)) {}

impl<'a> Carrier<'a> {
pub type Focus<T> = &'a mut T;
pub type Focus<T> = &'a mut T where T: 'a;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// check-pass

pub fn f() -> impl Sized {
pub enum E {
//~^ ERROR: recursive type
V(E),
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0072]: recursive type `f::E` has infinite size
--> $DIR/infinite-recursive-type-2.rs:2:5
|
LL | pub enum E {
| ^^^^^^^^^^
LL |
LL | V(E),
| - recursive without indirection
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
LL | V(Box<E>),
| ++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0072`.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// check-pass

fn f() -> impl Sized {
enum E {
//~^ ERROR: recursive type
V(E),
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0072]: recursive type `f::E` has infinite size
--> $DIR/infinite-recursive-type.rs:2:5
|
LL | enum E {
| ^^^^^^
LL |
LL | V(E),
| - recursive without indirection
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
LL | V(Box<E>),
| ++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0072`.
5 changes: 5 additions & 0 deletions tests/rustdoc-ui/invalid_const_in_lifetime_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ trait X {
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
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments
//~| ERROR associated type takes 0 generic arguments but 1 generic argument
//~| ERROR trait `X` cannot be made into an object
84 changes: 82 additions & 2 deletions tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,86 @@ note: associated type defined here, with 0 generic parameters
LL | type Y<'a>;
| ^

error: aborting due to 2 previous errors
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>;
| ^ --
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
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>;
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

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>;
| ^ --
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
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>;
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0038]: the trait `X` cannot be made into an object
--> $DIR/invalid_const_in_lifetime_position.rs:4:20
|
LL | fn f<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/invalid_const_in_lifetime_position.rs:2:10
|
LL | trait X {
| - this trait cannot be made into an object...
LL | type Y<'a>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0107`.
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.
8 changes: 8 additions & 0 deletions tests/rustdoc-ui/issues/issue-105742.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub trait SVec: Index<
//~| 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`
//~| missing generics for associated type `SVec::Item`
Output = <Index<<Self as SVec>::Item,
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
Expand All @@ -30,6 +32,8 @@ pub trait SVec: Index<
//~| 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`
//~| missing generics for associated type `SVec::Item`
Output = <Self as SVec>::Item> as SVec>::Item,
//~^ expected 1 lifetime argument
//~| expected 1 generic argument
Expand All @@ -47,6 +51,10 @@ pub trait SVec: Index<
//~| 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`
//~| 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>;

Expand Down
Loading

0 comments on commit 50be229

Please sign in to comment.