Auto merge of #80615 - m-ou-se:rollup-xz67at2, r=m-ou-se

Rollup of 6 pull requests

Successful merges:

 - #80546 (clippy fixes for librustdoc)
 - #80555 (Improve library tracking issue template)
 - #80574 (Clean bootstrap artifacts on `x.py clean`)
 - #80578 (improve unconditional_panic description)
 - #80599 (`const_generics_defaults`: don't ICE in the unimplemented parts)
 - #80613 (Diag: print enum variant instead of enum type)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-01-02 12:40:32 +00:00
commit 90ccf4f5ad
24 changed files with 149 additions and 118 deletions

View File

@ -33,21 +33,41 @@ For most library features, it'd be useful to include a summarized version of the
-->
```rust
...
// core::magic
pub struct Magic;
impl Magic {
pub fn magic(self);
}
```
### Steps / History
<!--
In the simplest case, this is a PR implementing the feature followed by a PR
that stabilises the feature. However it's not uncommon for the feature to be
changed before stabilization. For larger features, the implementation could be
split up in multiple steps.
For larger features, more steps might be involved.
If the feature is changed later, please add those PRs here as well.
-->
- [ ] Implementation: ...
- [ ] Implementation: #...
- [ ] Final commenting period (FCP)
- [ ] Stabilization PR
<!--
Once the feature has gone through a few release cycles and there are no
unresolved questions left, the feature might be ready for stabilization.
If this feature didn't go through the RFC process, a final commenting period
(FCP) is always needed before stabilization. This works as follows:
A library team member can kick off the stabilization process, at which point
the rfcbot will ask all the team members to verify they agree with
stabilization. Once enough members agree and there are no concerns, the final
commenting period begins: this issue will be marked as such and will be listed
in the next This Week in Rust newsletter. If no blocking concerns are raised in
that period of 10 days, a stabilzation PR can be opened by anyone.
-->
### Unresolved Questions
<!--

View File

@ -2677,7 +2677,6 @@ impl<'a> State<'a> {
s.print_type_bounds(":", &param.bounds);
if let Some(ref _default) = default {
// FIXME(const_generics_defaults): print the `default` value here
todo!();
}
}
}

View File

@ -2210,7 +2210,6 @@ impl<'a> State<'a> {
self.print_type(ty);
if let Some(ref _default) = default {
// FIXME(const_generics_defaults): print the `default` value here
todo!();
}
}
}

View File

@ -221,14 +221,10 @@ declare_lint! {
///
/// ### Explanation
///
/// This lint detects code that is very likely incorrect. When possible,
/// the compiler will attempt to detect situations where code can be
/// evaluated at compile-time to generate more efficient code. While
/// evaluating such code, if it detects that the code will unconditionally
/// panic, this usually indicates that it is doing something incorrectly.
/// If this lint is allowed, then the code will not be evaluated at
/// compile-time, and instead continue to generate code to evaluate at
/// runtime, which may panic during runtime.
/// This lint detects code that is very likely incorrect because it will
/// always panic, such as division by zero and out-of-bounds array
/// accesses. Consider adjusting your code if this is a bug, or using the
/// `panic!` or `unreachable!` macro instead in case the panic is intended.
pub UNCONDITIONAL_PANIC,
Deny,
"operation will cause a panic at runtime"

View File

@ -619,7 +619,6 @@ impl<'hir> Sig for hir::Generics<'hir> {
param_text.push_str(&ty_to_string(&ty));
if let Some(ref _default) = default {
// FIXME(const_generics_defaults): push the `default` value here
todo!();
}
}
if !param.bounds.is_empty() {

View File

@ -1381,19 +1381,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty,
);
match variant.ctor_kind {
CtorKind::Fn => {
err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
err.span_label(field.ident.span, "field does not exist");
err.span_label(
ty_span,
format!(
"`{adt}` is a tuple {kind_name}, \
use the appropriate syntax: `{adt}(/* fields */)`",
adt = ty,
kind_name = kind_name
),
);
}
CtorKind::Fn => match ty.kind() {
ty::Adt(adt, ..) if adt.is_enum() => {
err.span_label(
variant.ident.span,
format!(
"`{adt}::{variant}` defined here",
adt = ty,
variant = variant.ident,
),
);
err.span_label(field.ident.span, "field does not exist");
err.span_label(
ty_span,
format!(
"`{adt}::{variant}` is a tuple {kind_name}, \
use the appropriate syntax: `{adt}::{variant}(/* fields */)`",
adt = ty,
variant = variant.ident,
kind_name = kind_name
),
);
}
_ => {
err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
err.span_label(field.ident.span, "field does not exist");
err.span_label(
ty_span,
format!(
"`{adt}` is a tuple {kind_name}, \
use the appropriate syntax: `{adt}(/* fields */)`",
adt = ty,
kind_name = kind_name
),
);
}
},
_ => {
// prevent all specified fields from being suggested
let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);

View File

@ -21,6 +21,7 @@ pub fn clean(build: &Build, all: bool) {
} else {
rm_rf(&build.out.join("tmp"));
rm_rf(&build.out.join("dist"));
rm_rf(&build.out.join("bootstrap"));
for host in &build.hosts {
let entries = match build.out.join(host.triple).read_dir() {

View File

@ -738,11 +738,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
fn is_fn_ty(&self, tcx: TyCtxt<'_>, ty: &Type) -> bool {
match &ty {
&&Type::ResolvedPath { ref did, .. } => {
*did == tcx.require_lang_item(LangItem::Fn, None)
|| *did == tcx.require_lang_item(LangItem::FnMut, None)
|| *did == tcx.require_lang_item(LangItem::FnOnce, None)
match ty {
&Type::ResolvedPath { did, .. } => {
did == tcx.require_lang_item(LangItem::Fn, None)
|| did == tcx.require_lang_item(LangItem::FnMut, None)
|| did == tcx.require_lang_item(LangItem::FnOnce, None)
}
_ => false,
}

View File

@ -177,10 +177,7 @@ impl Cfg {
Cfg::Any(ref sub_cfgs) | Cfg::All(ref sub_cfgs) => {
sub_cfgs.first().map(Cfg::should_capitalize_first_letter).unwrap_or(false)
}
Cfg::Cfg(name, _) => match name {
sym::debug_assertions | sym::target_endian => true,
_ => false,
},
Cfg::Cfg(name, _) => name == sym::debug_assertions || name == sym::target_endian,
}
}
@ -188,18 +185,13 @@ impl Cfg {
match *self {
Cfg::False | Cfg::True => false,
Cfg::Any(..) | Cfg::All(..) | Cfg::Cfg(..) => true,
Cfg::Not(ref child) => match **child {
Cfg::Cfg(..) => true,
_ => false,
},
Cfg::Not(box Cfg::Cfg(..)) => true,
Cfg::Not(..) => false,
}
}
fn should_use_with_in_description(&self) -> bool {
match *self {
Cfg::Cfg(name, _) if name == sym::target_feature => true,
_ => false,
}
matches!(self, Cfg::Cfg(sym::target_feature, _))
}
/// Attempt to simplify this cfg by assuming that `assume` is already known to be true, will

View File

@ -640,10 +640,10 @@ impl Clean<Generics> for hir::Generics<'_> {
///
/// [`lifetime_to_generic_param`]: rustc_ast_lowering::LoweringContext::lifetime_to_generic_param
fn is_elided_lifetime(param: &hir::GenericParam<'_>) -> bool {
match param.kind {
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided } => true,
_ => false,
}
matches!(
param.kind,
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Elided }
)
}
let impl_trait_params = self
@ -801,7 +801,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
for (param, mut bounds) in impl_trait {
// Move trait bounds to the front.
bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b { false } else { true });
bounds.sort_by_key(|b| !matches!(b, GenericBound::TraitBound(..)));
if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
if let Some(proj) = impl_trait_proj.remove(&idx) {

View File

@ -175,11 +175,9 @@ impl Item {
}
crate fn is_crate(&self) -> bool {
match *self.kind {
matches!(*self.kind,
StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
| ModuleItem(Module { is_crate: true, .. }) => true,
_ => false,
}
| ModuleItem(Module { is_crate: true, .. }))
}
crate fn is_mod(&self) -> bool {
self.type_() == ItemType::Module
@ -378,10 +376,7 @@ impl ItemKind {
}
crate fn is_type_alias(&self) -> bool {
match *self {
ItemKind::TypedefItem(_, _) | ItemKind::AssocTypeItem(_, _) => true,
_ => false,
}
matches!(self, ItemKind::TypedefItem(..) | ItemKind::AssocTypeItem(..))
}
}
@ -674,7 +669,7 @@ impl Attributes {
span: attr.span,
doc: contents,
kind: DocFragmentKind::Include { filename },
parent_module: parent_module,
parent_module,
});
}
}
@ -750,7 +745,7 @@ impl Attributes {
Some(did) => {
if let Some((mut href, ..)) = href(did) {
if let Some(ref fragment) = *fragment {
href.push_str("#");
href.push('#');
href.push_str(fragment);
}
Some(RenderedLink {
@ -945,10 +940,7 @@ crate enum GenericParamDefKind {
impl GenericParamDefKind {
crate fn is_type(&self) -> bool {
match *self {
GenericParamDefKind::Type { .. } => true,
_ => false,
}
matches!(self, GenericParamDefKind::Type { .. })
}
// FIXME(eddyb) this either returns the default of a type parameter, or the
@ -1292,15 +1284,12 @@ impl Type {
}
crate fn is_full_generic(&self) -> bool {
match *self {
Type::Generic(_) => true,
_ => false,
}
matches!(self, Type::Generic(_))
}
crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> {
let (self_, trait_, name) = match self {
QPath { ref self_type, ref trait_, name } => (self_type, trait_, name),
QPath { self_type, trait_, name } => (self_type, trait_, name),
_ => return None,
};
let trait_did = match **trait_ {

View File

@ -37,10 +37,7 @@ crate enum OutputFormat {
impl OutputFormat {
crate fn is_json(&self) -> bool {
match self {
OutputFormat::Json => true,
_ => false,
}
matches!(self, OutputFormat::Json)
}
}

View File

@ -636,15 +636,15 @@ fn partition_source(s: &str) -> (String, String, String) {
match state {
PartitionState::Attrs => {
before.push_str(line);
before.push_str("\n");
before.push('\n');
}
PartitionState::Crates => {
crates.push_str(line);
crates.push_str("\n");
crates.push('\n');
}
PartitionState::Other => {
after.push_str(line);
after.push_str("\n");
after.push('\n');
}
}
}

View File

@ -61,7 +61,7 @@ crate trait DocFolder: Sized {
j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
j.fields_stripped |= num_fields != j.fields.len()
|| j.fields.iter().any(|f| f.is_stripped());
VariantItem(Variant { kind: VariantKind::Struct(j), ..i2 })
VariantItem(Variant { kind: VariantKind::Struct(j) })
}
_ => VariantItem(i2),
}

View File

@ -245,7 +245,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
}
match pred {
&clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
clean::WherePredicate::BoundPredicate { ty, bounds } => {
let bounds = bounds;
if f.alternate() {
clause.push_str(&format!(
@ -261,7 +261,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
));
}
}
&clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => {
clean::WherePredicate::RegionPredicate { lifetime, bounds } => {
clause.push_str(&format!(
"{}: {}",
lifetime.print(),
@ -272,7 +272,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
.join(" + ")
));
}
&clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
clean::WherePredicate::EqPredicate { lhs, rhs } => {
if f.alternate() {
clause.push_str(&format!("{:#} == {:#}", lhs.print(), rhs.print()));
} else {
@ -376,8 +376,8 @@ impl clean::GenericBound {
impl clean::GenericArgs {
fn print(&self) -> impl fmt::Display + '_ {
display_fn(move |f| {
match *self {
clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
match self {
clean::GenericArgs::AngleBracketed { args, bindings } => {
if !args.is_empty() || !bindings.is_empty() {
if f.alternate() {
f.write_str("<")?;
@ -414,7 +414,7 @@ impl clean::GenericArgs {
}
}
}
clean::GenericArgs::Parenthesized { ref inputs, ref output } => {
clean::GenericArgs::Parenthesized { inputs, output } => {
f.write_str("(")?;
let mut comma = false;
for ty in inputs {
@ -501,7 +501,7 @@ crate fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
};
for component in &fqp[..fqp.len() - 1] {
url.push_str(component);
url.push_str("/");
url.push('/');
}
match shortty {
ItemType::Module => {
@ -510,7 +510,7 @@ crate fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
}
_ => {
url.push_str(shortty.as_str());
url.push_str(".");
url.push('.');
url.push_str(fqp.last().unwrap());
url.push_str(".html");
}
@ -1021,7 +1021,7 @@ impl Function<'_> {
} else {
if i > 0 {
args.push_str(" <br>");
args_plain.push_str(" ");
args_plain.push(' ');
}
if !input.name.is_empty() {
args.push_str(&format!("{}: ", input.name));

View File

@ -489,15 +489,10 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
}
fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
match *t {
Tag::Paragraph
| Tag::Item
| Tag::Emphasis
| Tag::Strong
| Tag::Link(..)
| Tag::BlockQuote => true,
_ => false,
}
matches!(
t,
Tag::Paragraph | Tag::Item | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote
)
}
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {

View File

@ -979,7 +979,7 @@ themePicker.onblur = handleThemeButtonsBlur;
.iter()
.map(|s| format!("\"{}\"", s.to_str().expect("invalid osstring conversion")))
.collect::<Vec<_>>();
files.sort_unstable_by(|a, b| a.cmp(b));
files.sort_unstable();
let subs = subs.iter().map(|s| s.to_json_string()).collect::<Vec<_>>().join(",");
let dirs =
if subs.is_empty() { String::new() } else { format!(",\"dirs\":[{}]", subs) };
@ -1428,7 +1428,7 @@ impl Setting {
.map(|opt| format!(
"<option value=\"{}\" {}>{}</option>",
opt.0,
if &opt.0 == default_value { "selected" } else { "" },
if opt.0 == default_value { "selected" } else { "" },
opt.1,
))
.collect::<String>(),
@ -1595,7 +1595,7 @@ impl Context<'_> {
if let Some(&(ref names, ty)) = cache.paths.get(&it.def_id) {
for name in &names[..names.len() - 1] {
url.push_str(name);
url.push_str("/");
url.push('/');
}
url.push_str(&item_path(ty, names.last().unwrap()));
layout::redirect(&url)
@ -2308,7 +2308,7 @@ fn short_item_info(
let since = &since.as_str();
if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
if *since == "TBD" {
format!("Deprecating in a future Rust version")
String::from("Deprecating in a future Rust version")
} else {
format!("Deprecating in {}", Escape(since))
}
@ -4323,9 +4323,11 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
.any(|i| i.inner_impl().trait_.def_id() == c.deref_mut_trait_did);
let inner_impl = target
.def_id()
.or(target
.primitive_type()
.and_then(|prim| c.primitive_locations.get(&prim).cloned()))
.or_else(|| {
target
.primitive_type()
.and_then(|prim| c.primitive_locations.get(&prim).cloned())
})
.and_then(|did| c.impls.get(&did));
if let Some(impls) = inner_impl {
out.push_str("<a class=\"sidebar-title\" href=\"#deref-methods\">");

View File

@ -132,7 +132,7 @@ impl TocBuilder {
}
Some(entry) => {
sec_number = entry.sec_number.clone();
sec_number.push_str(".");
sec_number.push('.');
(entry.level, &entry.children)
}
};

View File

@ -1276,7 +1276,7 @@ impl LinkCollector<'_, '_> {
// This could just be a normal link or a broken link
// we could potentially check if something is
// "intra-doc-link-like" and warn in that case.
return None;
None
}
Err(ErrorKind::AnchorFailure(msg)) => {
anchor_failure(
@ -1287,7 +1287,7 @@ impl LinkCollector<'_, '_> {
diag.link_range,
msg,
);
return None;
None
}
}
}
@ -1383,7 +1383,7 @@ impl LinkCollector<'_, '_> {
diag.link_range,
candidates.present_items().collect(),
);
return None;
None
}
}
Some(MacroNS) => {
@ -1408,7 +1408,7 @@ impl LinkCollector<'_, '_> {
diag.link_range,
smallvec![kind],
);
return None;
None
}
}
}

View File

@ -59,7 +59,7 @@ fn drop_tag(
continue;
}
let last_tag_name_low = last_tag_name.to_lowercase();
if ALLOWED_UNCLOSED.iter().any(|&at| at == &last_tag_name_low) {
if ALLOWED_UNCLOSED.iter().any(|&at| at == last_tag_name_low) {
continue;
}
// `tags` is used as a queue, meaning that everything after `pos` is included inside it.

View File

@ -26,9 +26,7 @@ crate fn strip_hidden(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
// strip all impls referencing stripped items
let mut stripper = ImplStripper { retained: &retained };
let krate = stripper.fold_crate(krate);
krate
stripper.fold_crate(krate)
}
struct Stripper<'a> {

View File

@ -70,15 +70,12 @@ impl Events {
}
fn is_comment(&self) -> bool {
match *self {
Events::StartLineComment(_) | Events::StartComment(_) | Events::EndComment(_) => true,
_ => false,
}
matches!(self, Events::StartLineComment(_) | Events::StartComment(_) | Events::EndComment(_))
}
}
fn previous_is_line_comment(events: &[Events]) -> bool {
if let Some(&Events::StartLineComment(_)) = events.last() { true } else { false }
matches!(events.last(), Some(&Events::StartLineComment(_)))
}
fn is_line_comment(pos: usize, v: &[u8], events: &[Events]) -> bool {

View File

@ -0,0 +1,10 @@
// This tests makes sure the diagnostics print the offending enum variant, not just the type.
pub enum Enum {
V1(i32),
}
pub fn foo(x: i32) -> Enum {
Enum::V1 { x } //~ ERROR `Enum::V1` has no field named `x`
}
fn main() {}

View File

@ -0,0 +1,14 @@
error[E0559]: variant `Enum::V1` has no field named `x`
--> $DIR/issue-80607.rs:7:16
|
LL | V1(i32),
| -- `Enum::V1` defined here
...
LL | Enum::V1 { x }
| -------- ^ field does not exist
| |
| `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0559`.