mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-08 04:56:58 +00:00
Auto merge of #91269 - matthiaskrgr:rollup-jh8i8eh, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #90611 (Fix another ICE in rustdoc scrape_examples) - #91197 (rustdoc: Rename `Type::ResolvedPath` to `Type::Path` and don't re-export it) - #91223 (Fix headings indent) - #91240 (Saner formatting for UTF8_CHAR_WIDTH table) - #91248 (Bump compiler-builtins to 0.1.53) - #91252 (Fix bug where submodules wouldn't be updated when running x.py from a subdirectory) - #91259 (Remove `--display-doctest-warnings`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
bbad745a68
@ -678,9 +678,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.52"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6591c2442ee984e2b264638a8b5e7ae44fd47b32d28e3a08e2e9c3cdb0c2fb0"
|
||||
checksum = "2467ff455350a4df7d02f1ed1449d0279605a763de5d586dcf6aa7d732508bcb"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc-std-workspace-core",
|
||||
|
@ -244,22 +244,23 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
|
||||
|
||||
// https://tools.ietf.org/html/rfc3629
|
||||
const UTF8_CHAR_WIDTH: &[u8; 256] = &[
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, // 0x1F
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, // 0x3F
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, // 0x5F
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, // 0x7F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, // 0x9F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, // 0xBF
|
||||
0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, // 0xDF
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF
|
||||
4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF
|
||||
// 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
|
||||
0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E
|
||||
4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F
|
||||
];
|
||||
|
||||
/// Given a first byte, determines how many bytes are in this UTF-8 character.
|
||||
|
@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
|
||||
panic_abort = { path = "../panic_abort" }
|
||||
core = { path = "../core" }
|
||||
libc = { version = "0.2.106", default-features = false, features = ['rustc-dep-of-std'] }
|
||||
compiler_builtins = { version = "0.1.52" }
|
||||
compiler_builtins = { version = "0.1.53" }
|
||||
profiler_builtins = { path = "../profiler_builtins", optional = true }
|
||||
unwind = { path = "../unwind" }
|
||||
hashbrown = { version = "0.11", default-features = false, features = ['rustc-dep-of-std'] }
|
||||
|
@ -493,7 +493,7 @@ impl Build {
|
||||
|
||||
// NOTE: The check for the empty directory is here because when running x.py the first time,
|
||||
// the submodule won't be checked out. Check it out now so we can build it.
|
||||
if !channel::GitInfo::new(false, relative_path).is_git() && !dir_is_empty(&absolute_path) {
|
||||
if !channel::GitInfo::new(false, &absolute_path).is_git() && !dir_is_empty(&absolute_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,6 +261,16 @@ conversion, so type inference fails because the type is not unique. Please note
|
||||
that you must write the `(())` in one sequence without intermediate whitespace
|
||||
so that `rustdoc` understands you want an implicit `Result`-returning function.
|
||||
|
||||
## Showing warnings in doctests
|
||||
|
||||
You can show warnings in doctests by running `rustdoc --test --test-args=--show-output`
|
||||
(or, if you're using cargo, `cargo test --doc -- --show-output`).
|
||||
By default, this will still hide `unused` warnings, since so many examples use private functions;
|
||||
you can add `#![warn(unused)]` to the top of your example if you want to see unused variables or dead code warnings.
|
||||
You can also use [`#![doc(test(attr(warn(unused))))]`][test-attr] in the crate root to enable warnings globally.
|
||||
|
||||
[test-attr]: ./the-doc-attribute.md#testattr
|
||||
|
||||
## Documenting macros
|
||||
|
||||
Here’s an example of documenting a macro:
|
||||
|
@ -257,22 +257,6 @@ all these files are linked from every page, changing where they are can be cumbe
|
||||
specially cache them. This flag will rename all these files in the output to include the suffix in
|
||||
the filename. For example, `light.css` would become `light-suf.css` with the above command.
|
||||
|
||||
### `--display-doctest-warnings`: display warnings when documenting or running documentation tests
|
||||
|
||||
Using this flag looks like this:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --display-doctest-warnings
|
||||
$ rustdoc --test src/lib.rs -Z unstable-options --display-doctest-warnings
|
||||
```
|
||||
|
||||
The intent behind this flag is to allow the user to see warnings that occur within their library or
|
||||
their documentation tests, which are usually suppressed. However, [due to a
|
||||
bug][issue-display-warnings], this flag doesn't 100% work as intended. See the linked issue for
|
||||
details.
|
||||
|
||||
[issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574
|
||||
|
||||
### `--extern-html-root-url`: control how rustdoc links to non-local crates
|
||||
|
||||
Using this flag looks like this:
|
||||
|
@ -41,14 +41,8 @@ use crate::visit_ast::Module as DocModule;
|
||||
|
||||
use utils::*;
|
||||
|
||||
crate use utils::{get_auto_trait_and_blanket_impls, krate, register_res};
|
||||
|
||||
crate use self::types::FnRetTy::*;
|
||||
crate use self::types::ItemKind::*;
|
||||
crate use self::types::SelfTy::*;
|
||||
crate use self::types::Type::*;
|
||||
crate use self::types::Visibility::{Inherited, Public};
|
||||
crate use self::types::*;
|
||||
crate use self::utils::{get_auto_trait_and_blanket_impls, krate, register_res};
|
||||
|
||||
crate trait Clean<T> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> T;
|
||||
@ -1411,12 +1405,12 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
};
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
let path = external_path(cx, did, false, vec![], substs);
|
||||
ResolvedPath { path }
|
||||
Type::Path { path }
|
||||
}
|
||||
ty::Foreign(did) => {
|
||||
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
|
||||
let path = external_path(cx, did, false, vec![], InternalSubsts::empty());
|
||||
ResolvedPath { path }
|
||||
Type::Path { path }
|
||||
}
|
||||
ty::Dynamic(obj, ref reg) => {
|
||||
// HACK: pick the first `did` as the `did` of the trait object. Someone
|
||||
|
@ -34,7 +34,6 @@ use rustc_target::spec::abi::Abi;
|
||||
use crate::clean::cfg::Cfg;
|
||||
use crate::clean::external_path;
|
||||
use crate::clean::inline::{self, print_inlined_const};
|
||||
use crate::clean::types::Type::{QPath, ResolvedPath};
|
||||
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
|
||||
use crate::clean::Clean;
|
||||
use crate::core::DocContext;
|
||||
@ -43,10 +42,14 @@ use crate::formats::item_type::ItemType;
|
||||
use crate::html::render::cache::ExternalLocation;
|
||||
use crate::html::render::Context;
|
||||
|
||||
use self::FnRetTy::*;
|
||||
use self::ItemKind::*;
|
||||
use self::SelfTy::*;
|
||||
use self::Type::*;
|
||||
crate use self::FnRetTy::*;
|
||||
crate use self::ItemKind::*;
|
||||
crate use self::SelfTy::*;
|
||||
crate use self::Type::{
|
||||
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
|
||||
RawPointer, Slice, Tuple,
|
||||
};
|
||||
crate use self::Visibility::{Inherited, Public};
|
||||
|
||||
crate type ItemIdSet = FxHashSet<ItemId>;
|
||||
|
||||
@ -1418,8 +1421,9 @@ crate struct PolyTrait {
|
||||
crate enum Type {
|
||||
/// A named type, which could be a trait.
|
||||
///
|
||||
/// This is mostly Rustdoc's version of [`hir::Path`]. It has to be different because Rustdoc's [`PathSegment`] can contain cleaned generics.
|
||||
ResolvedPath { path: Path },
|
||||
/// This is mostly Rustdoc's version of [`hir::Path`].
|
||||
/// It has to be different because Rustdoc's [`PathSegment`] can contain cleaned generics.
|
||||
Path { path: Path },
|
||||
/// A `dyn Trait` object: `dyn for<'a> Trait<'a> + Send + 'static`
|
||||
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
|
||||
/// A type parameter.
|
||||
@ -1485,7 +1489,7 @@ impl Type {
|
||||
/// Checks if this is a `T::Name` path for an associated type.
|
||||
crate fn is_assoc_ty(&self) -> bool {
|
||||
match self {
|
||||
ResolvedPath { path, .. } => path.is_assoc_ty(),
|
||||
Type::Path { path, .. } => path.is_assoc_ty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -1499,7 +1503,7 @@ impl Type {
|
||||
|
||||
crate fn generics(&self) -> Option<Vec<&Type>> {
|
||||
match self {
|
||||
ResolvedPath { path, .. } => path.generics(),
|
||||
Type::Path { path, .. } => path.generics(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -1522,7 +1526,7 @@ impl Type {
|
||||
|
||||
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
|
||||
let t: PrimitiveType = match *self {
|
||||
ResolvedPath { ref path } => return Some(path.def_id()),
|
||||
Type::Path { ref path } => return Some(path.def_id()),
|
||||
DynTrait(ref bounds, _) => return Some(bounds[0].trait_.def_id()),
|
||||
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
|
||||
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
|
||||
|
@ -2,8 +2,7 @@ use crate::clean::auto_trait::AutoTraitFinder;
|
||||
use crate::clean::blanket_impl::BlanketImplFinder;
|
||||
use crate::clean::{
|
||||
inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item,
|
||||
ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Type,
|
||||
TypeBinding, Visibility,
|
||||
ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility,
|
||||
};
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::item_type::ItemType;
|
||||
@ -187,7 +186,7 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret:
|
||||
for &did in prim.impls(tcx).iter().filter(|did| !did.is_local()) {
|
||||
inline::build_impl(cx, None, did, None, ret);
|
||||
}
|
||||
} else if let ResolvedPath { path } = target {
|
||||
} else if let Type::Path { path } = target {
|
||||
let did = path.def_id();
|
||||
if !did.is_local() {
|
||||
inline::build_impls(cx, None, did, None, ret);
|
||||
@ -362,7 +361,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
|
||||
_ => {
|
||||
let _ = register_res(cx, path.res);
|
||||
ResolvedPath { path }
|
||||
Type::Path { path }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,9 +136,6 @@ crate struct Options {
|
||||
///
|
||||
/// Be aware: This option can come both from the CLI and from crate attributes!
|
||||
crate manual_passes: Vec<String>,
|
||||
/// Whether to display warnings during doc generation or while gathering doctests. By default,
|
||||
/// all non-rustdoc-specific lints are allowed when generating docs.
|
||||
crate display_doctest_warnings: bool,
|
||||
/// Whether to run the `calculate-doc-coverage` pass, which counts the number of public items
|
||||
/// with and without documentation.
|
||||
crate show_coverage: bool,
|
||||
@ -197,7 +194,6 @@ impl fmt::Debug for Options {
|
||||
.field("persist_doctests", &self.persist_doctests)
|
||||
.field("default_passes", &self.default_passes)
|
||||
.field("manual_passes", &self.manual_passes)
|
||||
.field("display_doctest_warnings", &self.display_doctest_warnings)
|
||||
.field("show_coverage", &self.show_coverage)
|
||||
.field("crate_version", &self.crate_version)
|
||||
.field("render_options", &self.render_options)
|
||||
@ -639,7 +635,6 @@ impl Options {
|
||||
let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
|
||||
let playground_url = matches.opt_str("playground-url");
|
||||
let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
|
||||
let display_doctest_warnings = matches.opt_present("display-doctest-warnings");
|
||||
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
|
||||
let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
|
||||
let enable_minification = !matches.opt_present("disable-minification");
|
||||
@ -707,7 +702,6 @@ impl Options {
|
||||
test_args,
|
||||
default_passes,
|
||||
manual_passes,
|
||||
display_doctest_warnings,
|
||||
show_coverage,
|
||||
crate_version,
|
||||
test_run_directory,
|
||||
|
@ -38,9 +38,6 @@ use crate::passes::span_of_attrs;
|
||||
crate struct TestOptions {
|
||||
/// Whether to disable the default `extern crate my_crate;` when creating doctests.
|
||||
crate no_crate_inject: bool,
|
||||
/// Whether to emit compilation warnings when compiling doctests. Setting this will suppress
|
||||
/// the default `#![allow(unused)]`.
|
||||
crate display_doctest_warnings: bool,
|
||||
/// Additional crate-level attributes to add to doctests.
|
||||
crate attrs: Vec<String>,
|
||||
}
|
||||
@ -65,6 +62,8 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
}
|
||||
});
|
||||
|
||||
debug!(?lint_opts);
|
||||
|
||||
let crate_types =
|
||||
if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
|
||||
|
||||
@ -72,7 +71,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
maybe_sysroot: options.maybe_sysroot.clone(),
|
||||
search_paths: options.libs.clone(),
|
||||
crate_types,
|
||||
lint_opts: if !options.display_doctest_warnings { lint_opts } else { vec![] },
|
||||
lint_opts,
|
||||
lint_cap: Some(options.lint_cap.unwrap_or(lint::Forbid)),
|
||||
cg: options.codegen_options.clone(),
|
||||
externs: options.externs.clone(),
|
||||
@ -106,7 +105,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
};
|
||||
|
||||
let test_args = options.test_args.clone();
|
||||
let display_doctest_warnings = options.display_doctest_warnings;
|
||||
let nocapture = options.nocapture;
|
||||
let externs = options.externs.clone();
|
||||
let json_unused_externs = options.json_unused_externs;
|
||||
@ -118,8 +116,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
let collector = global_ctxt.enter(|tcx| {
|
||||
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
|
||||
|
||||
let mut opts = scrape_test_config(crate_attrs);
|
||||
opts.display_doctest_warnings |= options.display_doctest_warnings;
|
||||
let opts = scrape_test_config(crate_attrs);
|
||||
let enable_per_target_ignores = options.enable_per_target_ignores;
|
||||
let mut collector = Collector::new(
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
@ -165,7 +162,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
Err(ErrorReported) => return Err(ErrorReported),
|
||||
};
|
||||
|
||||
run_tests(test_args, nocapture, display_doctest_warnings, tests);
|
||||
run_tests(test_args, nocapture, tests);
|
||||
|
||||
// Collect and warn about unused externs, but only if we've gotten
|
||||
// reports for each doctest
|
||||
@ -208,29 +205,19 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
crate fn run_tests(
|
||||
mut test_args: Vec<String>,
|
||||
nocapture: bool,
|
||||
display_doctest_warnings: bool,
|
||||
tests: Vec<test::TestDescAndFn>,
|
||||
) {
|
||||
crate fn run_tests(mut test_args: Vec<String>, nocapture: bool, tests: Vec<test::TestDescAndFn>) {
|
||||
test_args.insert(0, "rustdoctest".to_string());
|
||||
if nocapture {
|
||||
test_args.push("--nocapture".to_string());
|
||||
}
|
||||
test::test_main(
|
||||
&test_args,
|
||||
tests,
|
||||
Some(test::Options::new().display_output(display_doctest_warnings)),
|
||||
);
|
||||
test::test_main(&test_args, tests, None);
|
||||
}
|
||||
|
||||
// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
|
||||
fn scrape_test_config(attrs: &[ast::Attribute]) -> TestOptions {
|
||||
use rustc_ast_pretty::pprust;
|
||||
|
||||
let mut opts =
|
||||
TestOptions { no_crate_inject: false, display_doctest_warnings: false, attrs: Vec::new() };
|
||||
let mut opts = TestOptions { no_crate_inject: false, attrs: Vec::new() };
|
||||
|
||||
let test_attrs: Vec<_> = attrs
|
||||
.iter()
|
||||
@ -510,7 +497,7 @@ crate fn make_test(
|
||||
let mut prog = String::new();
|
||||
let mut supports_color = false;
|
||||
|
||||
if opts.attrs.is_empty() && !opts.display_doctest_warnings {
|
||||
if opts.attrs.is_empty() {
|
||||
// If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some
|
||||
// lints that are commonly triggered in doctests. The crate-level test attributes are
|
||||
// commonly used to make tests fail in case they trigger warnings, so having this there in
|
||||
|
@ -52,8 +52,7 @@ assert_eq!(2+2, 4);
|
||||
fn make_test_no_crate_inject() {
|
||||
// Even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
|
||||
// adding it anyway.
|
||||
let opts =
|
||||
TestOptions { no_crate_inject: true, display_doctest_warnings: false, attrs: vec![] };
|
||||
let opts = TestOptions { no_crate_inject: true, attrs: vec![] };
|
||||
let input = "use asdf::qwop;
|
||||
assert_eq!(2+2, 4);";
|
||||
let expected = "#![allow(unused)]
|
||||
@ -215,20 +214,6 @@ assert_eq!(2+2, 4);"
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_test_display_doctest_warnings() {
|
||||
// If the user is asking to display doctest warnings, suppress the default `allow(unused)`.
|
||||
let mut opts = TestOptions::default();
|
||||
opts.display_doctest_warnings = true;
|
||||
let input = "assert_eq!(2+2, 4);";
|
||||
let expected = "fn main() {
|
||||
assert_eq!(2+2, 4);
|
||||
}"
|
||||
.to_string();
|
||||
let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
|
||||
assert_eq!((output, len), (expected, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_test_issues_21299_33731() {
|
||||
let opts = TestOptions::default();
|
||||
|
@ -27,7 +27,7 @@ use crate::html::render::IndexItem;
|
||||
#[derive(Default)]
|
||||
crate struct Cache {
|
||||
/// Maps a type ID to all known implementations for that type. This is only
|
||||
/// recognized for intra-crate `ResolvedPath` types, and is used to print
|
||||
/// recognized for intra-crate [`clean::Type::Path`]s, and is used to print
|
||||
/// out extra documentation on the page of an enum/struct.
|
||||
///
|
||||
/// The values of the map are a list of implementations and documentation
|
||||
@ -401,7 +401,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
||||
clean::ImplItem(ref i) => {
|
||||
self.cache.parent_is_trait_impl = i.trait_.is_some();
|
||||
match i.for_ {
|
||||
clean::ResolvedPath { ref path } => {
|
||||
clean::Type::Path { ref path } => {
|
||||
self.cache.parent_stack.push(path.def_id());
|
||||
true
|
||||
}
|
||||
@ -436,8 +436,8 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
||||
// Note: matching twice to restrict the lifetime of the `i` borrow.
|
||||
let mut dids = FxHashSet::default();
|
||||
match i.for_ {
|
||||
clean::ResolvedPath { ref path }
|
||||
| clean::BorrowedRef { type_: box clean::ResolvedPath { ref path }, .. } => {
|
||||
clean::Type::Path { ref path }
|
||||
| clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => {
|
||||
dids.insert(path.def_id());
|
||||
}
|
||||
clean::DynTrait(ref bounds, _)
|
||||
|
@ -607,8 +607,7 @@ crate fn href_relative_parts<'a>(fqp: &'a [String], relative_to_fqp: &'a [String
|
||||
}
|
||||
}
|
||||
|
||||
/// Used when rendering a `ResolvedPath` structure. This invokes the `path`
|
||||
/// rendering function with the necessary arguments for linking to a local path.
|
||||
/// Used to render a [`clean::Path`].
|
||||
fn resolved_path<'cx>(
|
||||
w: &mut fmt::Formatter<'_>,
|
||||
did: DefId,
|
||||
@ -762,7 +761,7 @@ fn fmt_type<'cx>(
|
||||
|
||||
match *t {
|
||||
clean::Generic(name) => write!(f, "{}", name),
|
||||
clean::ResolvedPath { ref path } => {
|
||||
clean::Type::Path { ref path } => {
|
||||
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
|
||||
let did = path.def_id();
|
||||
resolved_path(f, did, path, path.is_assoc_ty(), use_absolute, cx)
|
||||
|
@ -218,7 +218,7 @@ fn get_index_type(clean_type: &clean::Type, generics: Vec<TypeWithKind>) -> Rend
|
||||
|
||||
fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<Symbol> {
|
||||
match *clean_type {
|
||||
clean::ResolvedPath { ref path, .. } => {
|
||||
clean::Type::Path { ref path, .. } => {
|
||||
let path_segment = path.segments.last().unwrap();
|
||||
Some(path_segment.name)
|
||||
}
|
||||
@ -371,7 +371,7 @@ crate fn get_real_types<'tcx>(
|
||||
let mut ty_generics = Vec::new();
|
||||
for bound in bound.get_bounds().unwrap_or(&[]) {
|
||||
if let Some(path) = bound.get_trait_path() {
|
||||
let ty = Type::ResolvedPath { path };
|
||||
let ty = Type::Path { path };
|
||||
get_real_types(generics, &ty, tcx, recurse + 1, &mut ty_generics, cache);
|
||||
}
|
||||
}
|
||||
|
@ -1227,7 +1227,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
|
||||
| SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => {
|
||||
(mutability == Mutability::Mut, false, false)
|
||||
}
|
||||
SelfTy::SelfExplicit(clean::ResolvedPath { path }) => {
|
||||
SelfTy::SelfExplicit(clean::Type::Path { path }) => {
|
||||
(false, Some(path.def_id()) == tcx.lang_items().owned_box(), false)
|
||||
}
|
||||
SelfTy::SelfValue => (false, false, true),
|
||||
@ -2520,7 +2520,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
|
||||
}
|
||||
|
||||
match ty {
|
||||
clean::Type::ResolvedPath { path } => process_path(path.def_id()),
|
||||
clean::Type::Path { path } => process_path(path.def_id()),
|
||||
clean::Type::Tuple(tys) => {
|
||||
work.extend(tys.into_iter());
|
||||
}
|
||||
|
@ -727,8 +727,8 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
|
||||
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
|
||||
for implementor in implementors {
|
||||
match implementor.inner_impl().for_ {
|
||||
clean::ResolvedPath { ref path }
|
||||
| clean::BorrowedRef { type_: box clean::ResolvedPath { ref path }, .. }
|
||||
clean::Type::Path { ref path }
|
||||
| clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. }
|
||||
if !path.is_assoc_ty() =>
|
||||
{
|
||||
let did = path.def_id();
|
||||
@ -1453,8 +1453,8 @@ fn render_implementor(
|
||||
// If there's already another implementor that has the same abridged name, use the
|
||||
// full path, for example in `std::iter::ExactSizeIterator`
|
||||
let use_absolute = match implementor.inner_impl().for_ {
|
||||
clean::ResolvedPath { ref path, .. }
|
||||
| clean::BorrowedRef { type_: box clean::ResolvedPath { ref path, .. }, .. }
|
||||
clean::Type::Path { ref path, .. }
|
||||
| clean::BorrowedRef { type_: box clean::Type::Path { ref path, .. }, .. }
|
||||
if !path.is_assoc_ty() =>
|
||||
{
|
||||
implementor_dups[&path.last()].1
|
||||
|
@ -1129,13 +1129,15 @@ h3.variant {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.docblock > .section-header:first-child {
|
||||
.top-doc .docblock > .section-header:first-child {
|
||||
margin-left: 15px;
|
||||
margin-top: 0;
|
||||
}
|
||||
.top-doc .docblock > .section-header:first-child:hover > a:before {
|
||||
left: -10px;
|
||||
}
|
||||
|
||||
.docblock > .section-header:first-child:hover > a:before {
|
||||
left: -10px;
|
||||
.docblock > .section-header:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
:target > code, :target > .code-header {
|
||||
|
@ -365,7 +365,7 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
|
||||
match bound {
|
||||
TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
|
||||
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
|
||||
let trait_ = clean::ResolvedPath { path: trait_ }.into_tcx(tcx);
|
||||
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
|
||||
GenericBound::TraitBound {
|
||||
trait_,
|
||||
generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
|
||||
@ -388,9 +388,13 @@ crate fn from_trait_bound_modifier(modifier: rustc_hir::TraitBoundModifier) -> T
|
||||
|
||||
impl FromWithTcx<clean::Type> for Type {
|
||||
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
|
||||
use clean::Type::*;
|
||||
use clean::Type::{
|
||||
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive,
|
||||
QPath, RawPointer, Slice, Tuple,
|
||||
};
|
||||
|
||||
match ty {
|
||||
ResolvedPath { path } => Type::ResolvedPath {
|
||||
clean::Type::Path { path } => Type::ResolvedPath {
|
||||
name: path.whole_name(),
|
||||
id: from_item_id(path.def_id().into()),
|
||||
args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))),
|
||||
@ -435,7 +439,7 @@ impl FromWithTcx<clean::Type> for Type {
|
||||
},
|
||||
QPath { name, self_type, trait_, .. } => {
|
||||
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
|
||||
let trait_ = ResolvedPath { path: trait_ }.into_tcx(tcx);
|
||||
let trait_ = clean::Type::Path { path: trait_ }.into_tcx(tcx);
|
||||
Type::QualifiedPath {
|
||||
name: name.to_string(),
|
||||
self_type: Box::new((*self_type).into_tcx(tcx)),
|
||||
@ -501,7 +505,7 @@ impl FromWithTcx<clean::Impl> for Impl {
|
||||
let provided_trait_methods = impl_.provided_trait_methods(tcx);
|
||||
let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_;
|
||||
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
|
||||
let trait_ = trait_.map(|path| clean::ResolvedPath { path }.into_tcx(tcx));
|
||||
let trait_ = trait_.map(|path| clean::Type::Path { path }.into_tcx(tcx));
|
||||
// FIXME: use something like ImplKind in JSON?
|
||||
let (synthetic, blanket_impl) = match kind {
|
||||
clean::ImplKind::Normal => (false, None),
|
||||
|
@ -131,7 +131,6 @@ crate fn test(options: Options) -> Result<(), String> {
|
||||
.map_err(|err| format!("{}: {}", options.input.display(), err))?;
|
||||
let mut opts = TestOptions::default();
|
||||
opts.no_crate_inject = true;
|
||||
opts.display_doctest_warnings = options.display_doctest_warnings;
|
||||
let mut collector = Collector::new(
|
||||
Symbol::intern(&options.input.display().to_string()),
|
||||
options.clone(),
|
||||
@ -146,11 +145,6 @@ crate fn test(options: Options) -> Result<(), String> {
|
||||
|
||||
find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
|
||||
|
||||
crate::doctest::run_tests(
|
||||
options.test_args,
|
||||
options.nocapture,
|
||||
options.display_doctest_warnings,
|
||||
collector.tests,
|
||||
);
|
||||
crate::doctest::run_tests(options.test_args, options.nocapture, collector.tests);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -142,16 +142,21 @@ where
|
||||
hir::ExprKind::Call(f, _) => {
|
||||
let types = tcx.typeck(ex.hir_id.owner);
|
||||
|
||||
match types.node_type_opt(f.hir_id) {
|
||||
Some(ty) => (ty, ex.span),
|
||||
None => {
|
||||
return;
|
||||
}
|
||||
if let Some(ty) = types.node_type_opt(f.hir_id) {
|
||||
(ty, ex.span)
|
||||
} else {
|
||||
trace!("node_type_opt({}) = None", f.hir_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
hir::ExprKind::MethodCall(_, _, _, span) => {
|
||||
let types = tcx.typeck(ex.hir_id.owner);
|
||||
let def_id = types.type_dependent_def_id(ex.hir_id).unwrap();
|
||||
let def_id = if let Some(def_id) = types.type_dependent_def_id(ex.hir_id) {
|
||||
def_id
|
||||
} else {
|
||||
trace!("type_dependent_def_id({}) = None", ex.hir_id);
|
||||
return;
|
||||
};
|
||||
(tcx.type_of(def_id), span)
|
||||
}
|
||||
_ => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// This test is to ensure that the anchors (`§`) have the expected color.
|
||||
// This test is to ensure that the anchors (`§`) have the expected color and position.
|
||||
goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html
|
||||
show-text: true
|
||||
|
||||
@ -28,3 +28,47 @@ assert-css: ("h2#implementations a.anchor", {"color": "rgb(0, 0, 0)"})
|
||||
// Same thing with the impl block title.
|
||||
move-cursor-to: "#impl"
|
||||
assert-css: ("#impl a.anchor", {"color": "rgb(0, 0, 0)"})
|
||||
|
||||
// Now we check the positions: only the first heading of the top doc comment should
|
||||
// have a different position.
|
||||
move-cursor-to: ".top-doc .docblock .section-header:first-child"
|
||||
assert-css: (
|
||||
".top-doc .docblock .section-header:first-child > a::before",
|
||||
{"left": "-10px", "padding-right": "10px"}
|
||||
)
|
||||
// We also check that the heading itself has a different indent.
|
||||
assert-css: (".top-doc .docblock .section-header:first-child", {"margin-left": "15px"})
|
||||
|
||||
move-cursor-to: ".top-doc .docblock .section-header:not(:first-child)"
|
||||
assert-css: (
|
||||
".top-doc .docblock .section-header:not(:first-child) > a::before",
|
||||
{"left": "-25px", "padding-right": "10px"}
|
||||
)
|
||||
assert-css: (".top-doc .docblock .section-header:not(:first-child)", {"margin-left": "0px"})
|
||||
|
||||
// Now let's check some other docblock headings...
|
||||
// First the impl block docs.
|
||||
move-cursor-to: "#title-for-struct-impl-doc"
|
||||
assert-css: (
|
||||
"#title-for-struct-impl-doc > a::before",
|
||||
{"left": "-25px", "padding-right": "10px"}
|
||||
)
|
||||
assert-css: ("#title-for-struct-impl-doc", {"margin-left": "0px"})
|
||||
// Now a method docs.
|
||||
move-cursor-to: "#title-for-struct-impl-item-doc"
|
||||
assert-css: (
|
||||
"#title-for-struct-impl-item-doc > a::before",
|
||||
{"left": "-25px", "padding-right": "10px"}
|
||||
)
|
||||
assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})
|
||||
|
||||
// Finally, we want to ensure that if the first element of the doc block isn't a heading,
|
||||
// if there is a heading afterwards, it won't have the indent.
|
||||
goto: file://|DOC_PATH|/test_docs/enum.WhoLetTheDogOut.html
|
||||
|
||||
move-cursor-to: ".top-doc .docblock .section-header"
|
||||
assert-css: (
|
||||
".top-doc .docblock .section-header > a::before",
|
||||
{"left": "-25px", "padding-right": "10px"}
|
||||
)
|
||||
assert-css: (".top-doc .docblock .section-header", {"margin-left": "0px"})
|
||||
|
@ -47,6 +47,8 @@ impl AsRef<str> for Foo {
|
||||
}
|
||||
|
||||
/// Just a normal enum.
|
||||
///
|
||||
/// # title!
|
||||
#[doc(alias = "ThisIsAnAlias")]
|
||||
pub enum WhoLetTheDogOut {
|
||||
/// Woof!
|
||||
|
@ -1,9 +1,15 @@
|
||||
// Test that `--show-output` has an effect and `allow(unused)` can be overriden.
|
||||
|
||||
// check-pass
|
||||
// compile-flags:-Zunstable-options --display-doctest-warnings --test
|
||||
// edition:2018
|
||||
// compile-flags:--test --test-args=--show-output
|
||||
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
|
||||
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
|
||||
/// ```
|
||||
/// #![warn(unused)]
|
||||
/// let x = 12;
|
||||
///
|
||||
/// fn foo(x: &std::fmt::Display) {}
|
||||
/// ```
|
||||
pub fn foo() {}
|
||||
|
@ -1,24 +1,58 @@
|
||||
|
||||
running 1 test
|
||||
test $DIR/display-output.rs - foo (line 6) ... ok
|
||||
test $DIR/display-output.rs - foo (line 9) ... ok
|
||||
|
||||
successes:
|
||||
|
||||
---- $DIR/display-output.rs - foo (line 6) stdout ----
|
||||
---- $DIR/display-output.rs - foo (line 9) stdout ----
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/display-output.rs:13:12
|
||||
|
|
||||
LL | fn foo(x: &std::fmt::Display) {}
|
||||
| ^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn std::fmt::Display`
|
||||
|
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
|
||||
warning: unused variable: `x`
|
||||
--> $DIR/display-output.rs:7:5
|
||||
--> $DIR/display-output.rs:11:5
|
||||
|
|
||||
LL | let x = 12;
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
|
||||
= note: `#[warn(unused_variables)]` on by default
|
||||
note: the lint level is defined here
|
||||
--> $DIR/display-output.rs:9:9
|
||||
|
|
||||
LL | #![warn(unused)]
|
||||
| ^^^^^^
|
||||
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
|
||||
|
||||
warning: 1 warning emitted
|
||||
warning: unused variable: `x`
|
||||
--> $DIR/display-output.rs:13:8
|
||||
|
|
||||
LL | fn foo(x: &std::fmt::Display) {}
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
||||
warning: function is never used: `foo`
|
||||
--> $DIR/display-output.rs:13:4
|
||||
|
|
||||
LL | fn foo(x: &std::fmt::Display) {}
|
||||
| ^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/display-output.rs:9:9
|
||||
|
|
||||
LL | #![warn(unused)]
|
||||
| ^^^^^^
|
||||
= note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
|
||||
|
||||
warning: 4 warnings emitted
|
||||
|
||||
|
||||
|
||||
successes:
|
||||
$DIR/display-output.rs - foo (line 6)
|
||||
$DIR/display-output.rs - foo (line 9)
|
||||
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
||||
|
4
src/test/rustdoc-ui/scrape-examples-ice.rs
Normal file
4
src/test/rustdoc-ui/scrape-examples-ice.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// compile-flags: -Z unstable-options --scrape-examples-output-path t.calls --scrape-examples-target-crate foobar
|
||||
// check-pass
|
||||
#![no_std]
|
||||
use core as _;
|
Loading…
Reference in New Issue
Block a user