Auto merge of #91019 - JohnTitor:rollup-q95ra7r, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #90386 (Add `-Zassert-incr-state` to assert state of incremental cache) - #90438 (Clean up mess for --show-coverage documentation) - #90480 (Mention `Vec::remove` in `Vec::swap_remove`'s docs) - #90607 (Make slice->str conversion and related functions `const`) - #90750 (rustdoc: Replace where-bounded Clean impl with simple function) - #90895 (require full validity when determining the discriminant of a value) - #90989 (Avoid suggesting literal formatting that turns into member access) - #91002 (rustc: Remove `#[rustc_synthetic]`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
cc946fcd32
36 changed files with 310 additions and 251 deletions
|
|
@ -348,6 +348,18 @@ Using this flag looks like this:
|
|||
$ rustdoc src/lib.rs -Z unstable-options --show-coverage
|
||||
```
|
||||
|
||||
It generates something like this:
|
||||
|
||||
```bash
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| File | Documented | Percentage | Examples | Percentage |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| lib.rs | 4 | 100.0% | 1 | 25.0% |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| Total | 4 | 100.0% | 1 | 25.0% |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
```
|
||||
|
||||
If you want to determine how many items in your crate are documented, pass this flag to rustdoc.
|
||||
When it receives this flag, it will count the public items in your crate that have documentation,
|
||||
and print out the counts and a percentage instead of generating docs.
|
||||
|
|
@ -367,17 +379,25 @@ Some methodology notes about what rustdoc counts in this metric:
|
|||
Public items that are not documented can be seen with the built-in `missing_docs` lint. Private
|
||||
items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint.
|
||||
|
||||
### `-w`/`--output-format`: output format
|
||||
Calculating code examples follows these rules:
|
||||
|
||||
When using
|
||||
[`--show-coverage`](https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#--show-coverage-get-statistics-about-code-documentation-coverage),
|
||||
passing `--output-format json` will display the coverage information in JSON format. For example,
|
||||
here is the JSON for a file with one documented item and one undocumented item:
|
||||
1. These items aren't accounted by default:
|
||||
* struct/union field
|
||||
* enum variant
|
||||
* constant
|
||||
* static
|
||||
* typedef
|
||||
2. If one of the previously listed items has a code example, then it'll be counted.
|
||||
|
||||
#### JSON output
|
||||
|
||||
When using `--output-format json` with this option, it will display the coverage information in
|
||||
JSON format. For example, here is the JSON for a file with one documented item and one
|
||||
undocumented item:
|
||||
|
||||
```rust
|
||||
/// This item has documentation
|
||||
pub fn foo() {}
|
||||
|
||||
pub fn no_documentation() {}
|
||||
```
|
||||
|
||||
|
|
@ -387,10 +407,16 @@ pub fn no_documentation() {}
|
|||
|
||||
Note that the third item is the crate root, which in this case is undocumented.
|
||||
|
||||
When not using `--show-coverage`, `--output-format json` emits documentation in the experimental
|
||||
### `-w`/`--output-format`: output format
|
||||
|
||||
`--output-format json` emits documentation in the experimental
|
||||
[JSON format](https://github.com/rust-lang/rfcs/pull/2963). `--output-format html` has no effect,
|
||||
and is also accepted on stable toolchains.
|
||||
|
||||
It can also be used with `--show-coverage`. Take a look at its
|
||||
[documentation](#--show-coverage-get-statistics-about-code-documentation-coverage) for more
|
||||
information.
|
||||
|
||||
### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests
|
||||
|
||||
Using this flag looks like this:
|
||||
|
|
@ -441,39 +467,6 @@ $ rustdoc src/lib.rs -Z unstable-options --runtool valgrind
|
|||
|
||||
Another use case would be to run a test inside an emulator, or through a Virtual Machine.
|
||||
|
||||
### `--show-coverage`: get statistics about code documentation coverage
|
||||
|
||||
This option allows you to get a nice overview over your code documentation coverage, including both
|
||||
doc-comments and code examples in the doc-comments. Example:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --show-coverage
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| File | Documented | Percentage | Examples | Percentage |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| lib.rs | 4 | 100.0% | 1 | 25.0% |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
| Total | 4 | 100.0% | 1 | 25.0% |
|
||||
+-------------------------------------+------------+------------+------------+------------+
|
||||
```
|
||||
|
||||
You can also use this option with the `--output-format` one:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --show-coverage --output-format json
|
||||
{"lib.rs":{"total":4,"with_docs":4,"total_examples":4,"with_examples":1}}
|
||||
```
|
||||
|
||||
Calculating code examples follows these rules:
|
||||
|
||||
1. These items aren't accounted by default:
|
||||
* struct/union field
|
||||
* enum variant
|
||||
* constant
|
||||
* static
|
||||
* typedef
|
||||
2. If one of the previously listed items has a code example, then it'll be counted.
|
||||
|
||||
### `--with-examples`: include examples of uses of items as documentation
|
||||
|
||||
This option, combined with `--scrape-examples-target-crate` and
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Functi
|
|||
let asyncness = cx.tcx.asyncness(did);
|
||||
let predicates = cx.tcx.predicates_of(did);
|
||||
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics need to be cleaned before the decl!
|
||||
((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
|
||||
});
|
||||
clean::Function {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,10 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
|
|||
};
|
||||
|
||||
GenericBound::TraitBound(
|
||||
PolyTrait { trait_: (trait_ref, &*bindings).clean(cx), generic_params: vec![] },
|
||||
PolyTrait {
|
||||
trait_: (trait_ref, &bindings[..]).clean(cx),
|
||||
generic_params: vec![],
|
||||
},
|
||||
hir::TraitBoundModifier::None,
|
||||
)
|
||||
}
|
||||
|
|
@ -456,9 +459,7 @@ impl Clean<Generics> for hir::Generics<'_> {
|
|||
// scans them first.
|
||||
fn is_impl_trait(param: &hir::GenericParam<'_>) -> bool {
|
||||
match param.kind {
|
||||
hir::GenericParamKind::Type { synthetic, .. } => {
|
||||
synthetic == Some(hir::SyntheticTyParamKind::ImplTrait)
|
||||
}
|
||||
hir::GenericParamKind::Type { synthetic, .. } => synthetic,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -557,7 +558,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
|||
assert_eq!(param.index, 0);
|
||||
return None;
|
||||
}
|
||||
if synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
|
||||
if synthetic {
|
||||
impl_trait.insert(param.index.into(), vec![]);
|
||||
return None;
|
||||
}
|
||||
|
|
@ -761,8 +762,13 @@ fn clean_fn_or_proc_macro(
|
|||
|
||||
impl<'a> Clean<Function> for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Function {
|
||||
let (generics, decl) =
|
||||
enter_impl_trait(cx, |cx| (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
|
||||
let (generics, decl) = enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generics = self.1.clean(cx);
|
||||
let args = (self.0.decl.inputs, self.2).clean(cx);
|
||||
let decl = clean_fn_decl_with_args(cx, self.0.decl, args);
|
||||
(generics, decl)
|
||||
});
|
||||
Function { decl, generics, header: self.0.header }
|
||||
}
|
||||
}
|
||||
|
|
@ -804,17 +810,12 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], hir::BodyId) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl<'a>, A)
|
||||
where
|
||||
(&'a [hir::Ty<'a>], A): Clean<Arguments>,
|
||||
{
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl {
|
||||
FnDecl {
|
||||
inputs: (self.0.inputs, self.1).clean(cx),
|
||||
output: self.0.output.clean(cx),
|
||||
c_variadic: self.0.c_variadic,
|
||||
}
|
||||
}
|
||||
fn clean_fn_decl_with_args(
|
||||
cx: &mut DocContext<'_>,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
args: Arguments,
|
||||
) -> FnDecl {
|
||||
FnDecl { inputs: args, output: decl.output.clean(cx), c_variadic: decl.c_variadic }
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
|
||||
|
|
@ -894,7 +895,11 @@ impl Clean<Item> for hir::TraitItem<'_> {
|
|||
}
|
||||
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
|
||||
let (generics, decl) = enter_impl_trait(cx, |cx| {
|
||||
(self.generics.clean(cx), (sig.decl, names).clean(cx))
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generics = self.generics.clean(cx);
|
||||
let args = (sig.decl.inputs, names).clean(cx);
|
||||
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
|
||||
(generics, decl)
|
||||
});
|
||||
let mut t = Function { header: sig.header, decl, generics };
|
||||
if t.header.constness == hir::Constness::Const
|
||||
|
|
@ -1727,8 +1732,10 @@ impl Clean<PathSegment> for hir::PathSegment<'_> {
|
|||
impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl {
|
||||
let (generic_params, decl) = enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generic_params = self.generic_params.iter().map(|x| x.clean(cx)).collect();
|
||||
let decl = (self.decl, self.param_names).clean(cx);
|
||||
let args = (self.decl.inputs, self.param_names).clean(cx);
|
||||
let decl = clean_fn_decl_with_args(cx, self.decl, args);
|
||||
(generic_params, decl)
|
||||
});
|
||||
BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
|
||||
|
|
@ -2029,8 +2036,13 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
|
|||
let kind = match item.kind {
|
||||
hir::ForeignItemKind::Fn(decl, names, ref generics) => {
|
||||
let abi = cx.tcx.hir().get_foreign_abi(item.hir_id());
|
||||
let (generics, decl) =
|
||||
enter_impl_trait(cx, |cx| (generics.clean(cx), (decl, names).clean(cx)));
|
||||
let (generics, decl) = enter_impl_trait(cx, |cx| {
|
||||
// NOTE: generics must be cleaned before args
|
||||
let generics = generics.clean(cx);
|
||||
let args = (decl.inputs, names).clean(cx);
|
||||
let decl = clean_fn_decl_with_args(cx, decl, args);
|
||||
(generics, decl)
|
||||
});
|
||||
ForeignFunctionItem(Function {
|
||||
decl,
|
||||
generics,
|
||||
|
|
|
|||
|
|
@ -1238,20 +1238,9 @@ impl WherePredicate {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
crate enum GenericParamDefKind {
|
||||
Lifetime {
|
||||
outlives: Vec<Lifetime>,
|
||||
},
|
||||
Type {
|
||||
did: DefId,
|
||||
bounds: Vec<GenericBound>,
|
||||
default: Option<Box<Type>>,
|
||||
synthetic: Option<hir::SyntheticTyParamKind>,
|
||||
},
|
||||
Const {
|
||||
did: DefId,
|
||||
ty: Box<Type>,
|
||||
default: Option<Box<String>>,
|
||||
},
|
||||
Lifetime { outlives: Vec<Lifetime> },
|
||||
Type { did: DefId, bounds: Vec<GenericBound>, default: Option<Box<Type>>, synthetic: bool },
|
||||
Const { did: DefId, ty: Box<Type>, default: Option<Box<String>> },
|
||||
}
|
||||
|
||||
impl GenericParamDefKind {
|
||||
|
|
@ -1285,7 +1274,7 @@ impl GenericParamDef {
|
|||
crate fn is_synthetic_type_param(&self) -> bool {
|
||||
match self.kind {
|
||||
GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false,
|
||||
GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
|
||||
GenericParamDefKind::Type { synthetic, .. } => synthetic,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
// no-prefer-dynamic
|
||||
//[cfail1] compile-flags: -lbar -lfoo --crate-type lib
|
||||
//[cfail2] compile-flags: -lfoo -lbar --crate-type lib
|
||||
//[cfail1] compile-flags: -lbar -lfoo --crate-type lib -Zassert-incr-state=not-loaded
|
||||
//[cfail2] compile-flags: -lfoo -lbar --crate-type lib -Zassert-incr-state=not-loaded
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
// revisions:rpass1 cfail2
|
||||
// compile-flags: -Z query-dep-graph
|
||||
// [cfail2] compile-flags: -Z query-dep-graph -Z assert-incr-state=loaded
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
|
|
|
|||
3
src/test/ui/suggestions/issue-90974.rs
Normal file
3
src/test/ui/suggestions/issue-90974.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("{}", (3.).recip()); //~ERROR
|
||||
}
|
||||
14
src/test/ui/suggestions/issue-90974.stderr
Normal file
14
src/test/ui/suggestions/issue-90974.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
|
||||
--> $DIR/issue-90974.rs:2:25
|
||||
|
|
||||
LL | println!("{}", (3.).recip());
|
||||
| ^^^^^
|
||||
|
|
||||
help: you must specify a concrete type for this numeric value, like `f32`
|
||||
|
|
||||
LL | println!("{}", (3_f32).recip());
|
||||
| ~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0689`.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#![feature(rustc_attrs)]
|
||||
|
||||
fn func<#[rustc_synthetic] T>(_: T) {}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
pub fn func<#[rustc_synthetic] T>(_: T) {}
|
||||
}
|
||||
|
||||
struct Bar<S> {
|
||||
t: S
|
||||
}
|
||||
|
||||
impl<S> Bar<S> {
|
||||
pub fn func<#[rustc_synthetic] T>(_: T) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
func::<u8>(42); //~ ERROR cannot provide explicit generic arguments
|
||||
func(42); // Ok
|
||||
|
||||
Foo::func::<u8>(42); //~ ERROR cannot provide explicit generic arguments
|
||||
Foo::func(42); // Ok
|
||||
|
||||
Bar::<i8>::func::<u8>(42); //~ ERROR cannot provide explicit generic arguments
|
||||
Bar::<i8>::func(42); // Ok
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
|
||||
--> $DIR/synthetic-param.rs:20:12
|
||||
|
|
||||
LL | func::<u8>(42);
|
||||
| ^^ explicit generic argument not allowed
|
||||
|
|
||||
= note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
|
||||
= help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
|
||||
--> $DIR/synthetic-param.rs:23:17
|
||||
|
|
||||
LL | Foo::func::<u8>(42);
|
||||
| ^^ explicit generic argument not allowed
|
||||
|
|
||||
= note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
|
||||
= help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
|
||||
--> $DIR/synthetic-param.rs:26:23
|
||||
|
|
||||
LL | Bar::<i8>::func::<u8>(42);
|
||||
| ^^ explicit generic argument not allowed
|
||||
|
|
||||
= note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
|
||||
= help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0632`.
|
||||
|
|
@ -3,10 +3,8 @@ use clippy_utils::source::snippet;
|
|||
use clippy_utils::{match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{
|
||||
self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, MutTy, Mutability, Node, QPath,
|
||||
SyntheticTyParamKind, TyKind,
|
||||
};
|
||||
use rustc_hir::{self as hir, GenericArg, GenericBounds, GenericParamKind};
|
||||
use rustc_hir::{HirId, Lifetime, MutTy, Mutability, Node, QPath, TyKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
||||
use super::BORROWED_BOX;
|
||||
|
|
@ -105,7 +103,7 @@ fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id:
|
|||
if let Some(did) = cx.qpath_res(qpath, id).opt_def_id();
|
||||
if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did);
|
||||
if let GenericParamKind::Type { synthetic, .. } = generic_param.kind;
|
||||
if synthetic == Some(SyntheticTyParamKind::ImplTrait);
|
||||
if synthetic;
|
||||
then {
|
||||
Some(generic_param.bounds)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue