Auto merge of #103344 - Dylan-DPC:rollup-d1rpfvx, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #102287 (Elaborate supertrait bounds when triggering `unused_must_use` on `impl Trait`) - #102922 (Filtering spans when emitting json) - #103051 (translation: doc comments with derives, subdiagnostic-less enum variants, more derive use) - #103111 (Account for hygiene in typo suggestions, and use them to point to shadowed names) - #103260 (Fixup a few tests needing asm support) - #103321 (rustdoc: improve appearance of source page navigation bar) Failed merges: - #103209 (Diagnostic derives: allow specifying multiple alternative suggestions) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
657f246812
@ -1,7 +1,4 @@
|
||||
use rustc_errors::{
|
||||
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay,
|
||||
SubdiagnosticMessage,
|
||||
};
|
||||
use rustc_errors::DiagnosticArgFromDisplay;
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
|
||||
@ -15,25 +12,15 @@ pub struct GenericTypeWithParentheses {
|
||||
pub sub: Option<UseAngleBrackets>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
#[multipart_suggestion(ast_lowering::use_angle_brackets, applicability = "maybe-incorrect")]
|
||||
pub struct UseAngleBrackets {
|
||||
#[suggestion_part(code = "<")]
|
||||
pub open_param: Span,
|
||||
#[suggestion_part(code = ">")]
|
||||
pub close_param: Span,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for UseAngleBrackets {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_lowering::invalid_abi, code = "E0703")]
|
||||
#[note]
|
||||
@ -68,30 +55,20 @@ pub struct AssocTyParentheses {
|
||||
pub sub: AssocTyParenthesesSub,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
pub enum AssocTyParenthesesSub {
|
||||
Empty { parentheses_span: Span },
|
||||
NotEmpty { open_param: Span, close_param: Span },
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for AssocTyParenthesesSub {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
Self::Empty { parentheses_span } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::remove_parentheses,
|
||||
vec![(parentheses_span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
};
|
||||
}
|
||||
#[multipart_suggestion(ast_lowering::remove_parentheses)]
|
||||
Empty {
|
||||
#[suggestion_part(code = "")]
|
||||
parentheses_span: Span,
|
||||
},
|
||||
#[multipart_suggestion(ast_lowering::use_angle_brackets)]
|
||||
NotEmpty {
|
||||
#[suggestion_part(code = "<")]
|
||||
open_param: Span,
|
||||
#[suggestion_part(code = ">")]
|
||||
close_param: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -14,6 +14,7 @@
|
||||
use rustc_ast_pretty::pprust::{self, State};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_session::lint::builtin::{
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
@ -1805,15 +1806,17 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
|
||||
}
|
||||
|
||||
/// Used to forbid `let` expressions in certain syntactic locations.
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
pub(crate) enum ForbiddenLetReason {
|
||||
/// `let` is not valid and the source environment is not important
|
||||
GenericForbidden,
|
||||
/// A let chain with the `||` operator
|
||||
NotSupportedOr(Span),
|
||||
#[note(ast_passes::not_supported_or)]
|
||||
NotSupportedOr(#[primary_span] Span),
|
||||
/// A let chain with invalid parentheses
|
||||
///
|
||||
/// For example, `let 1 = 1 && (expr && expr)` is allowed
|
||||
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
|
||||
NotSupportedParentheses(Span),
|
||||
#[note(ast_passes::not_supported_parentheses)]
|
||||
NotSupportedParentheses(#[primary_span] Span),
|
||||
}
|
||||
|
@ -16,23 +16,6 @@ pub struct ForbiddenLet {
|
||||
pub(crate) reason: ForbiddenLetReason,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for ForbiddenLetReason {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
Self::GenericForbidden => {}
|
||||
Self::NotSupportedOr(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_or);
|
||||
}
|
||||
Self::NotSupportedParentheses(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes::forbidden_let_stable)]
|
||||
#[note]
|
||||
|
@ -164,7 +164,9 @@ infer_region_explanation = {$pref_kind ->
|
||||
}
|
||||
|
||||
infer_mismatched_static_lifetime = incompatible lifetime on type
|
||||
infer_msl_impl_note = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
|
||||
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
|
||||
infer_msl_introduces_static = introduces a `'static` lifetime requirement
|
||||
infer_msl_unmet_req = because this has an unmet lifetime requirement
|
||||
infer_msl_trait_note = this has an implicit `'static` lifetime requirement
|
||||
|
@ -54,3 +54,7 @@ session_crate_name_empty = crate name must not be empty
|
||||
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
|
||||
|
||||
session_expr_parentheses_needed = parentheses are required to parse this as an expression
|
||||
|
||||
session_skipping_const_checks = skipping const checks
|
||||
session_unleashed_feature_help_named = skipping check for `{$gate}` feature
|
||||
session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate
|
||||
|
@ -567,6 +567,11 @@ pub fn multipart_suggestion_with_style(
|
||||
style: SuggestionStyle,
|
||||
) -> &mut Self {
|
||||
assert!(!suggestion.is_empty());
|
||||
debug_assert!(
|
||||
!(suggestion.iter().any(|(sp, text)| sp.is_empty() && text.is_empty())),
|
||||
"Span must not be empty and have no suggestion"
|
||||
);
|
||||
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![Substitution {
|
||||
parts: suggestion
|
||||
@ -644,6 +649,10 @@ pub fn span_suggestion_with_style(
|
||||
applicability: Applicability,
|
||||
style: SuggestionStyle,
|
||||
) -> &mut Self {
|
||||
debug_assert!(
|
||||
!(sp.is_empty() && suggestion.to_string().is_empty()),
|
||||
"Span must not be empty and have no suggestion"
|
||||
);
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: vec![Substitution {
|
||||
parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }],
|
||||
@ -684,6 +693,12 @@ pub fn span_suggestions(
|
||||
) -> &mut Self {
|
||||
let mut suggestions: Vec<_> = suggestions.collect();
|
||||
suggestions.sort();
|
||||
|
||||
debug_assert!(
|
||||
!(sp.is_empty() && suggestions.iter().any(|suggestion| suggestion.is_empty())),
|
||||
"Span must not be empty and have no suggestion"
|
||||
);
|
||||
|
||||
let substitutions = suggestions
|
||||
.into_iter()
|
||||
.map(|snippet| Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] })
|
||||
@ -705,8 +720,18 @@ pub fn multipart_suggestions(
|
||||
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
|
||||
applicability: Applicability,
|
||||
) -> &mut Self {
|
||||
let suggestions: Vec<_> = suggestions.collect();
|
||||
debug_assert!(
|
||||
!(suggestions
|
||||
.iter()
|
||||
.flat_map(|suggs| suggs)
|
||||
.any(|(sp, suggestion)| sp.is_empty() && suggestion.is_empty())),
|
||||
"Span must not be empty and have no suggestion"
|
||||
);
|
||||
|
||||
self.push_suggestion(CodeSuggestion {
|
||||
substitutions: suggestions
|
||||
.into_iter()
|
||||
.map(|sugg| Substitution {
|
||||
parts: sugg
|
||||
.into_iter()
|
||||
|
@ -1,14 +1,14 @@
|
||||
use crate::{
|
||||
fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_target::abi::TargetDataLayoutErrors;
|
||||
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint_defs::Level;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
||||
use rustc_target::abi::TargetDataLayoutErrors;
|
||||
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::num::ParseIntError;
|
||||
@ -155,6 +155,21 @@ fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for Level {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed(match self {
|
||||
Level::Allow => "-A",
|
||||
Level::Warn => "-W",
|
||||
Level::ForceWarn(_) => "--force-warn",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Expect(_) => {
|
||||
unreachable!("lints with the level of `expect` should not run this code");
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
|
||||
let mut diag;
|
||||
|
@ -22,7 +22,7 @@
|
||||
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{FileName, Span, DUMMY_SP};
|
||||
use rustc_span::{BytePos, FileName, Span, DUMMY_SP};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::default::Default;
|
||||
@ -1228,8 +1228,9 @@ pub fn expr_to_spanned_string<'a>(
|
||||
ast::LitKind::Str(s, style) => return Ok((s, style, expr.span)),
|
||||
ast::LitKind::ByteStr(_) => {
|
||||
let mut err = cx.struct_span_err(l.span, err_msg);
|
||||
let span = expr.span.shrink_to_lo();
|
||||
err.span_suggestion(
|
||||
expr.span.shrink_to_lo(),
|
||||
span.with_hi(span.lo() + BytePos(1)),
|
||||
"consider removing the leading `b`",
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -3051,24 +3051,27 @@ fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
|
||||
.map_or(false, |s| s.trim_end().ends_with('<'));
|
||||
|
||||
let is_global = poly_trait_ref.trait_ref.path.is_global();
|
||||
let sugg = Vec::from_iter([
|
||||
(
|
||||
self_ty.span.shrink_to_lo(),
|
||||
format!(
|
||||
"{}dyn {}",
|
||||
if needs_bracket { "<" } else { "" },
|
||||
if is_global { "(" } else { "" },
|
||||
),
|
||||
|
||||
let mut sugg = Vec::from_iter([(
|
||||
self_ty.span.shrink_to_lo(),
|
||||
format!(
|
||||
"{}dyn {}",
|
||||
if needs_bracket { "<" } else { "" },
|
||||
if is_global { "(" } else { "" },
|
||||
),
|
||||
(
|
||||
)]);
|
||||
|
||||
if is_global || needs_bracket {
|
||||
sugg.push((
|
||||
self_ty.span.shrink_to_hi(),
|
||||
format!(
|
||||
"{}{}",
|
||||
if is_global { ")" } else { "" },
|
||||
if needs_bracket { ">" } else { "" },
|
||||
),
|
||||
),
|
||||
]);
|
||||
));
|
||||
}
|
||||
|
||||
if self_ty.span.edition() >= Edition::Edition2021 {
|
||||
let msg = "trait objects must include the `dyn` keyword";
|
||||
let label = "add `dyn` keyword before this trait";
|
||||
|
@ -459,47 +459,34 @@ fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ImplNote {
|
||||
pub impl_span: Option<Span>,
|
||||
// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum DoesNotOutliveStaticFromImpl {
|
||||
#[note(infer::does_not_outlive_static_from_impl)]
|
||||
Spanned {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(infer::does_not_outlive_static_from_impl)]
|
||||
Unspanned,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for ImplNote {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self.impl_span {
|
||||
Some(span) => diag.span_note(span, fluent::infer::msl_impl_note),
|
||||
None => diag.note(fluent::infer::msl_impl_note),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TraitSubdiag {
|
||||
Note { span: Span },
|
||||
Sugg { span: Span },
|
||||
}
|
||||
|
||||
// FIXME(#100717) used in `Vec<TraitSubdiag>` so requires eager translation/list support
|
||||
impl AddToDiagnostic for TraitSubdiag {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
TraitSubdiag::Note { span } => {
|
||||
diag.span_note(span, "this has an implicit `'static` lifetime requirement");
|
||||
}
|
||||
TraitSubdiag::Sugg { span } => {
|
||||
diag.span_suggestion_verbose(
|
||||
span,
|
||||
"consider relaxing the implicit `'static` requirement",
|
||||
" + '_".to_owned(),
|
||||
rustc_errors::Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum ImplicitStaticLifetimeSubdiag {
|
||||
#[note(infer::implicit_static_lifetime_note)]
|
||||
Note {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[suggestion_verbose(
|
||||
infer::implicit_static_lifetime_suggestion,
|
||||
code = " + '_",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
Sugg {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -512,7 +499,7 @@ pub struct MismatchedStaticLifetime<'a> {
|
||||
#[subdiagnostic]
|
||||
pub expl: Option<note_and_explain::RegionExplanation<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub impl_note: ImplNote,
|
||||
#[subdiagnostic]
|
||||
pub trait_subdiags: Vec<TraitSubdiag>,
|
||||
pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
|
||||
#[subdiagnostic(eager)]
|
||||
pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
//! to hold.
|
||||
|
||||
use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
|
||||
use crate::errors::{ImplNote, MismatchedStaticLifetime, TraitSubdiag};
|
||||
use crate::errors::{
|
||||
DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
|
||||
};
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
use crate::infer::{SubregionOrigin, TypeTrace};
|
||||
@ -56,7 +58,7 @@ pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorGuaran
|
||||
note_and_explain::SuffixKind::Continues,
|
||||
);
|
||||
let mut impl_span = None;
|
||||
let mut trait_subdiags = Vec::new();
|
||||
let mut implicit_static_lifetimes = Vec::new();
|
||||
if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
|
||||
// If an impl is local, then maybe this isn't what they want. Try to
|
||||
// be as helpful as possible with implicit lifetimes.
|
||||
@ -90,10 +92,12 @@ pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorGuaran
|
||||
// Otherwise, point at all implicit static lifetimes
|
||||
|
||||
for span in &traits {
|
||||
trait_subdiags.push(TraitSubdiag::Note { span: *span });
|
||||
implicit_static_lifetimes
|
||||
.push(ImplicitStaticLifetimeSubdiag::Note { span: *span });
|
||||
// It would be nice to put this immediately under the above note, but they get
|
||||
// pushed to the end.
|
||||
trait_subdiags.push(TraitSubdiag::Sugg { span: span.shrink_to_hi() });
|
||||
implicit_static_lifetimes
|
||||
.push(ImplicitStaticLifetimeSubdiag::Sugg { span: span.shrink_to_hi() });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -105,8 +109,10 @@ pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorGuaran
|
||||
cause_span: cause.span,
|
||||
unmet_lifetime_reqs: multispan_subdiag,
|
||||
expl,
|
||||
impl_note: ImplNote { impl_span },
|
||||
trait_subdiags,
|
||||
does_not_outlive_static_from_impl: impl_span
|
||||
.map(|span| DoesNotOutliveStaticFromImpl::Spanned { span })
|
||||
.unwrap_or(DoesNotOutliveStaticFromImpl::Unspanned),
|
||||
implicit_static_lifetimes,
|
||||
};
|
||||
let reported = self.tcx().sess.emit_err(err);
|
||||
Some(reported)
|
||||
|
@ -3176,6 +3176,7 @@ fn is_zero(expr: &hir::Expr<'_>) -> bool {
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// # #![feature(asm_experimental_arch)]
|
||||
/// use std::arch::asm;
|
||||
///
|
||||
/// fn main() {
|
||||
|
@ -88,34 +88,13 @@ pub struct BuiltinEllpisisInclusiveRangePatterns {
|
||||
pub replace: String,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(lint::requested_level)]
|
||||
pub struct RequestedLevel {
|
||||
pub level: Level,
|
||||
pub lint_name: String,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for RequestedLevel {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
diag.note(fluent::lint::requested_level);
|
||||
diag.set_arg(
|
||||
"level",
|
||||
match self.level {
|
||||
Level::Allow => "-A",
|
||||
Level::Warn => "-W",
|
||||
Level::ForceWarn(_) => "--force-warn",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Expect(_) => {
|
||||
unreachable!("lints with the level of `expect` should not run this code");
|
||||
}
|
||||
},
|
||||
);
|
||||
diag.set_arg("lint_name", self.lint_name);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(lint::unsupported_group, code = "E0602")]
|
||||
pub struct UnsupportedGroup {
|
||||
|
@ -7,6 +7,7 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::traits::util::elaborate_predicates_with_span;
|
||||
use rustc_middle::ty::adjustment;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -204,10 +205,13 @@ fn check_must_use_ty<'tcx>(
|
||||
ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post),
|
||||
ty::Opaque(def, _) => {
|
||||
let mut has_emitted = false;
|
||||
for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
|
||||
for obligation in elaborate_predicates_with_span(
|
||||
cx.tcx,
|
||||
cx.tcx.explicit_item_bounds(def).iter().cloned(),
|
||||
) {
|
||||
// We only look at the `DefId`, so it is safe to skip the binder here.
|
||||
if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
|
||||
predicate.kind().skip_binder()
|
||||
obligation.predicate.kind().skip_binder()
|
||||
{
|
||||
let def_id = poly_trait_predicate.trait_ref.def_id;
|
||||
let descr_pre =
|
||||
|
@ -2878,7 +2878,7 @@
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(naked_functions)]
|
||||
/// #![feature(asm_experimental_arch, naked_functions)]
|
||||
///
|
||||
/// use std::arch::asm;
|
||||
///
|
||||
|
@ -5,7 +5,7 @@
|
||||
DiagnosticDeriveError,
|
||||
};
|
||||
use crate::diagnostics::utils::{
|
||||
build_field_mapping, report_error_if_not_applied_to_span, report_type_error,
|
||||
build_field_mapping, is_doc_comment, report_error_if_not_applied_to_span, report_type_error,
|
||||
should_generate_set_arg, type_is_unit, type_matches_path, FieldInfo, FieldInnerTy, FieldMap,
|
||||
HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
|
||||
};
|
||||
@ -152,8 +152,12 @@ pub fn body<'s>(&mut self, variant: &VariantInfo<'s>) -> TokenStream {
|
||||
fn parse_subdiag_attribute(
|
||||
&self,
|
||||
attr: &Attribute,
|
||||
) -> Result<(SubdiagnosticKind, Path), DiagnosticDeriveError> {
|
||||
let (subdiag, slug) = SubdiagnosticKind::from_attr(attr, self)?;
|
||||
) -> Result<Option<(SubdiagnosticKind, Path)>, DiagnosticDeriveError> {
|
||||
let Some((subdiag, slug)) = SubdiagnosticKind::from_attr(attr, self)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
if let SubdiagnosticKind::MultipartSuggestion { .. } = subdiag {
|
||||
let meta = attr.parse_meta()?;
|
||||
@ -170,7 +174,7 @@ fn parse_subdiag_attribute(
|
||||
SubdiagnosticKind::MultipartSuggestion { .. } => unreachable!(),
|
||||
});
|
||||
|
||||
Ok((subdiag, slug))
|
||||
Ok(Some((subdiag, slug)))
|
||||
}
|
||||
|
||||
/// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct
|
||||
@ -182,6 +186,11 @@ fn generate_structure_code_for_attr(
|
||||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let diag = &self.parent.diag;
|
||||
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return Ok(quote! {});
|
||||
}
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
let name = name.as_str();
|
||||
let meta = attr.parse_meta()?;
|
||||
@ -250,7 +259,11 @@ fn generate_structure_code_for_attr(
|
||||
return Ok(tokens);
|
||||
}
|
||||
|
||||
let (subdiag, slug) = self.parse_subdiag_attribute(attr)?;
|
||||
let Some((subdiag, slug)) = self.parse_subdiag_attribute(attr)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(quote! {});
|
||||
};
|
||||
let fn_ident = format_ident!("{}", subdiag);
|
||||
match subdiag {
|
||||
SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
|
||||
@ -291,6 +304,11 @@ fn generate_field_attrs_code(&mut self, binding_info: &BindingInfo<'_>) -> Token
|
||||
.attrs
|
||||
.iter()
|
||||
.map(move |attr| {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return quote! {};
|
||||
}
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
let needs_clone =
|
||||
name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
|
||||
@ -397,8 +415,11 @@ fn generate_inner_field_code(
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let (subdiag, slug) = self.parse_subdiag_attribute(attr)?;
|
||||
|
||||
let Some((subdiag, slug)) = self.parse_subdiag_attribute(attr)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(quote! {});
|
||||
};
|
||||
let fn_ident = format_ident!("{}", subdiag);
|
||||
match subdiag {
|
||||
SubdiagnosticKind::Label => {
|
||||
|
@ -5,9 +5,9 @@
|
||||
DiagnosticDeriveError,
|
||||
};
|
||||
use crate::diagnostics::utils::{
|
||||
build_field_mapping, new_code_ident, report_error_if_not_applied_to_applicability,
|
||||
report_error_if_not_applied_to_span, FieldInfo, FieldInnerTy, FieldMap, HasFieldMap, SetOnce,
|
||||
SpannedOption, SubdiagnosticKind,
|
||||
build_field_mapping, is_doc_comment, new_code_ident,
|
||||
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo,
|
||||
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
@ -41,8 +41,14 @@ pub(crate) fn into_tokens<'a>(self, mut structure: Structure<'a>) -> TokenStream
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(ast.data, syn::Data::Enum(..)) {
|
||||
let is_enum = matches!(ast.data, syn::Data::Enum(..));
|
||||
if is_enum {
|
||||
for attr in &ast.attrs {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
span_err(
|
||||
attr.span().unwrap(),
|
||||
"unsupported type attribute for subdiagnostic enum",
|
||||
@ -62,6 +68,7 @@ pub(crate) fn into_tokens<'a>(self, mut structure: Structure<'a>) -> TokenStream
|
||||
span_field: None,
|
||||
applicability: None,
|
||||
has_suggestion_parts: false,
|
||||
is_enum,
|
||||
};
|
||||
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
|
||||
});
|
||||
@ -79,7 +86,7 @@ pub(crate) fn into_tokens<'a>(self, mut structure: Structure<'a>) -> TokenStream
|
||||
gen impl rustc_errors::AddToDiagnostic for @Self {
|
||||
fn add_to_diagnostic_with<__F>(self, #diag: &mut rustc_errors::Diagnostic, #f: __F)
|
||||
where
|
||||
__F: Fn(
|
||||
__F: core::ops::Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
@ -122,6 +129,9 @@ struct SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
||||
/// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
|
||||
/// during finalization if still `false`.
|
||||
has_suggestion_parts: bool,
|
||||
|
||||
/// Set to true when this variant is an enum variant rather than just the body of a struct.
|
||||
is_enum: bool,
|
||||
}
|
||||
|
||||
impl<'parent, 'a> HasFieldMap for SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
||||
@ -173,7 +183,11 @@ fn identify_kind(&mut self) -> Result<Vec<(SubdiagnosticKind, Path)>, Diagnostic
|
||||
let mut kind_slugs = vec![];
|
||||
|
||||
for attr in self.variant.ast().attrs {
|
||||
let (kind, slug) = SubdiagnosticKind::from_attr(attr, self)?;
|
||||
let Some((kind, slug)) = SubdiagnosticKind::from_attr(attr, self)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(slug) = slug else {
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
@ -227,6 +241,11 @@ fn generate_field_attr_code(
|
||||
ast.attrs
|
||||
.iter()
|
||||
.map(|attr| {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return quote! {};
|
||||
}
|
||||
|
||||
let info = FieldInfo {
|
||||
binding,
|
||||
ty: inner_ty.inner_type().unwrap_or(&ast.ty),
|
||||
@ -290,6 +309,8 @@ fn generate_field_code_inner_path(
|
||||
report_error_if_not_applied_to_span(attr, &info)?;
|
||||
|
||||
let binding = info.binding.binding.clone();
|
||||
// FIXME(#100717): support `Option<Span>` on `primary_span` like in the
|
||||
// diagnostic derive
|
||||
self.span_field.set_once(binding, span);
|
||||
}
|
||||
|
||||
@ -443,10 +464,16 @@ fn generate_field_code_inner_list(
|
||||
pub fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let kind_slugs = self.identify_kind()?;
|
||||
if kind_slugs.is_empty() {
|
||||
throw_span_err!(
|
||||
self.variant.ast().ident.span().unwrap(),
|
||||
"subdiagnostic kind not specified"
|
||||
);
|
||||
if self.is_enum {
|
||||
// It's okay for a variant to not be a subdiagnostic at all..
|
||||
return Ok(quote! {});
|
||||
} else {
|
||||
// ..but structs should always be _something_.
|
||||
throw_span_err!(
|
||||
self.variant.ast().ident.span().unwrap(),
|
||||
"subdiagnostic kind not specified"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect();
|
||||
|
@ -477,7 +477,12 @@ impl SubdiagnosticKind {
|
||||
pub(super) fn from_attr(
|
||||
attr: &Attribute,
|
||||
fields: &impl HasFieldMap,
|
||||
) -> Result<(SubdiagnosticKind, Option<Path>), DiagnosticDeriveError> {
|
||||
) -> Result<Option<(SubdiagnosticKind, Option<Path>)>, DiagnosticDeriveError> {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let span = attr.span().unwrap();
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
@ -526,7 +531,9 @@ pub(super) fn from_attr(
|
||||
| SubdiagnosticKind::Note
|
||||
| SubdiagnosticKind::Help
|
||||
| SubdiagnosticKind::Warn
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => return Ok((kind, None)),
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => {
|
||||
return Ok(Some((kind, None)));
|
||||
}
|
||||
SubdiagnosticKind::Suggestion { .. } => {
|
||||
throw_span_err!(span, "suggestion without `code = \"...\"`")
|
||||
}
|
||||
@ -626,7 +633,7 @@ pub(super) fn from_attr(
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
|
||||
}
|
||||
|
||||
Ok((kind, slug))
|
||||
Ok(Some((kind, slug)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -654,3 +661,7 @@ fn span(&self) -> Option<proc_macro2::Span> {
|
||||
pub(super) fn should_generate_set_arg(field: &Field) -> bool {
|
||||
field.attrs.is_empty()
|
||||
}
|
||||
|
||||
pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
|
||||
attr.path.segments.last().unwrap().ident.to_string() == "doc"
|
||||
}
|
||||
|
@ -1374,9 +1374,17 @@ fn inc_dec_standalone_suggest(
|
||||
kind: IncDecRecovery,
|
||||
(pre_span, post_span): (Span, Span),
|
||||
) -> MultiSugg {
|
||||
let mut patches = Vec::new();
|
||||
|
||||
if !pre_span.is_empty() {
|
||||
patches.push((pre_span, String::new()));
|
||||
}
|
||||
|
||||
patches.push((post_span, format!(" {}= 1", kind.op.chr())));
|
||||
|
||||
MultiSugg {
|
||||
msg: format!("use `{}= 1` instead", kind.op.chr()),
|
||||
patches: vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))],
|
||||
patches,
|
||||
applicability: Applicability::MachineApplicable,
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use rustc_span::{BytePos, Span, SyntaxContext};
|
||||
|
||||
use crate::imports::{Import, ImportKind, ImportResolver};
|
||||
use crate::late::{PatternSource, Rib};
|
||||
@ -47,6 +47,7 @@
|
||||
/// similarly named label and whether or not it is reachable.
|
||||
pub(crate) type LabelSuggestion = (Ident, bool);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum SuggestionTarget {
|
||||
/// The target has a similar name as the name used by the programmer (probably a typo)
|
||||
SimilarlyNamed,
|
||||
@ -54,6 +55,7 @@ pub(crate) enum SuggestionTarget {
|
||||
SingleItem,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TypoSuggestion {
|
||||
pub candidate: Symbol,
|
||||
pub res: Res,
|
||||
@ -482,11 +484,12 @@ pub(crate) fn add_module_candidates(
|
||||
module: Module<'a>,
|
||||
names: &mut Vec<TypoSuggestion>,
|
||||
filter_fn: &impl Fn(Res) -> bool,
|
||||
ctxt: Option<SyntaxContext>,
|
||||
) {
|
||||
for (key, resolution) in self.resolutions(module).borrow().iter() {
|
||||
if let Some(binding) = resolution.borrow().binding {
|
||||
let res = binding.res();
|
||||
if filter_fn(res) {
|
||||
if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
|
||||
names.push(TypoSuggestion::typo_from_res(key.ident.name, res));
|
||||
}
|
||||
}
|
||||
@ -1181,10 +1184,10 @@ fn early_lookup_typo_candidate(
|
||||
Scope::CrateRoot => {
|
||||
let root_ident = Ident::new(kw::PathRoot, ident.span);
|
||||
let root_module = this.resolve_crate_root(root_ident);
|
||||
this.add_module_candidates(root_module, &mut suggestions, filter_fn);
|
||||
this.add_module_candidates(root_module, &mut suggestions, filter_fn, None);
|
||||
}
|
||||
Scope::Module(module, _) => {
|
||||
this.add_module_candidates(module, &mut suggestions, filter_fn);
|
||||
this.add_module_candidates(module, &mut suggestions, filter_fn, None);
|
||||
}
|
||||
Scope::MacroUsePrelude => {
|
||||
suggestions.extend(this.macro_use_prelude.iter().filter_map(
|
||||
@ -1221,7 +1224,7 @@ fn early_lookup_typo_candidate(
|
||||
Scope::StdLibPrelude => {
|
||||
if let Some(prelude) = this.prelude {
|
||||
let mut tmp_suggestions = Vec::new();
|
||||
this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
|
||||
this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn, None);
|
||||
suggestions.extend(
|
||||
tmp_suggestions
|
||||
.into_iter()
|
||||
|
@ -131,6 +131,7 @@ pub(super) enum LifetimeElisionCandidate {
|
||||
}
|
||||
|
||||
/// Only used for diagnostics.
|
||||
#[derive(Debug)]
|
||||
struct BaseError {
|
||||
msg: String,
|
||||
fallback_label: String,
|
||||
@ -140,6 +141,22 @@ struct BaseError {
|
||||
suggestion: Option<(Span, &'static str, String)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TypoCandidate {
|
||||
Typo(TypoSuggestion),
|
||||
Shadowed(Res),
|
||||
None,
|
||||
}
|
||||
|
||||
impl TypoCandidate {
|
||||
fn to_opt_suggestion(self) -> Option<TypoSuggestion> {
|
||||
match self {
|
||||
TypoCandidate::Typo(sugg) => Some(sugg),
|
||||
TypoCandidate::Shadowed(_) | TypoCandidate::None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||
fn def_span(&self, def_id: DefId) -> Option<Span> {
|
||||
match def_id.krate {
|
||||
@ -496,7 +513,8 @@ fn try_lookup_name_relaxed(
|
||||
}
|
||||
|
||||
// Try Levenshtein algorithm.
|
||||
let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
|
||||
let typo_sugg =
|
||||
self.lookup_typo_candidate(path, source.namespace(), is_expected).to_opt_suggestion();
|
||||
if path.len() == 1 && self.self_type_is_available() {
|
||||
if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
|
||||
let self_is_available = self.self_value_is_available(path[0].ident.span);
|
||||
@ -660,7 +678,18 @@ fn suggest_typo(
|
||||
let is_expected = &|res| source.is_expected(res);
|
||||
let ident_span = path.last().map_or(span, |ident| ident.ident.span);
|
||||
let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected);
|
||||
if let TypoCandidate::Shadowed(res) = typo_sugg
|
||||
&& let Some(id) = res.opt_def_id()
|
||||
&& let Some(sugg_span) = self.r.opt_span(id)
|
||||
{
|
||||
err.span_label(
|
||||
sugg_span,
|
||||
format!("you might have meant to refer to this {}", res.descr()),
|
||||
);
|
||||
return true;
|
||||
}
|
||||
let mut fallback = false;
|
||||
let typo_sugg = typo_sugg.to_opt_suggestion();
|
||||
if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) {
|
||||
fallback = true;
|
||||
match self.diagnostic_metadata.current_let_binding {
|
||||
@ -1581,22 +1610,38 @@ fn lookup_typo_candidate(
|
||||
path: &[Segment],
|
||||
ns: Namespace,
|
||||
filter_fn: &impl Fn(Res) -> bool,
|
||||
) -> Option<TypoSuggestion> {
|
||||
) -> TypoCandidate {
|
||||
let mut names = Vec::new();
|
||||
if path.len() == 1 {
|
||||
let mut ctxt = path.last().unwrap().ident.span.ctxt();
|
||||
|
||||
// Search in lexical scope.
|
||||
// Walk backwards up the ribs in scope and collect candidates.
|
||||
for rib in self.ribs[ns].iter().rev() {
|
||||
let rib_ctxt = if rib.kind.contains_params() {
|
||||
ctxt.normalize_to_macros_2_0()
|
||||
} else {
|
||||
ctxt.normalize_to_macro_rules()
|
||||
};
|
||||
|
||||
// Locals and type parameters
|
||||
for (ident, &res) in &rib.bindings {
|
||||
if filter_fn(res) {
|
||||
if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
|
||||
names.push(TypoSuggestion::typo_from_res(ident.name, res));
|
||||
}
|
||||
}
|
||||
|
||||
if let RibKind::MacroDefinition(def) = rib.kind && def == self.r.macro_def(ctxt) {
|
||||
// If an invocation of this macro created `ident`, give up on `ident`
|
||||
// and switch to `ident`'s source from the macro definition.
|
||||
ctxt.remove_mark();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Items in scope
|
||||
if let RibKind::ModuleRibKind(module) = rib.kind {
|
||||
// Items from this module
|
||||
self.r.add_module_candidates(module, &mut names, &filter_fn);
|
||||
self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
|
||||
|
||||
if let ModuleKind::Block = module.kind {
|
||||
// We can see through blocks
|
||||
@ -1622,7 +1667,7 @@ fn lookup_typo_candidate(
|
||||
}));
|
||||
|
||||
if let Some(prelude) = self.r.prelude {
|
||||
self.r.add_module_candidates(prelude, &mut names, &filter_fn);
|
||||
self.r.add_module_candidates(prelude, &mut names, &filter_fn, None);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1641,7 +1686,7 @@ fn lookup_typo_candidate(
|
||||
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
|
||||
self.resolve_path(mod_path, Some(TypeNS), None)
|
||||
{
|
||||
self.r.add_module_candidates(module, &mut names, &filter_fn);
|
||||
self.r.add_module_candidates(module, &mut names, &filter_fn, None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1654,10 +1699,17 @@ fn lookup_typo_candidate(
|
||||
name,
|
||||
None,
|
||||
) {
|
||||
Some(found) if found != name => {
|
||||
names.into_iter().find(|suggestion| suggestion.candidate == found)
|
||||
Some(found) => {
|
||||
let Some(sugg) = names.into_iter().find(|suggestion| suggestion.candidate == found) else {
|
||||
return TypoCandidate::None;
|
||||
};
|
||||
if found == name {
|
||||
TypoCandidate::Shadowed(sugg.res)
|
||||
} else {
|
||||
TypoCandidate::Typo(sugg)
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
_ => TypoCandidate::None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use crate::cgu_reuse_tracker::CguReuse;
|
||||
use rustc_errors::{
|
||||
fluent, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
|
||||
@ -148,24 +146,15 @@ pub struct CrateNameEmpty {
|
||||
pub span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session::invalid_character_in_create_name)]
|
||||
pub struct InvalidCharacterInCrateName<'a> {
|
||||
#[primary_span]
|
||||
pub span: Option<Span>,
|
||||
pub character: char,
|
||||
pub crate_name: &'a str,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for InvalidCharacterInCrateName<'_> {
|
||||
fn into_diagnostic(self, sess: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = sess.struct_err(fluent::session::invalid_character_in_create_name);
|
||||
if let Some(sp) = self.span {
|
||||
diag.set_span(sp);
|
||||
}
|
||||
diag.set_arg("character", self.character);
|
||||
diag.set_arg("crate_name", self.crate_name);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(session::expr_parentheses_needed, applicability = "machine-applicable")]
|
||||
pub struct ExprParenthesesNeeded {
|
||||
@ -180,3 +169,25 @@ pub fn surrounding(s: Span) -> Self {
|
||||
ExprParenthesesNeeded { left: s.shrink_to_lo(), right: s.shrink_to_hi() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session::skipping_const_checks)]
|
||||
pub struct SkippingConstChecks {
|
||||
#[subdiagnostic(eager)]
|
||||
pub unleashed_features: Vec<UnleashedFeatureHelp>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum UnleashedFeatureHelp {
|
||||
#[help(session::unleashed_feature_help_named)]
|
||||
Named {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
gate: Symbol,
|
||||
},
|
||||
#[help(session::unleashed_feature_help_unnamed)]
|
||||
Unnamed {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
@ -5,9 +5,10 @@
|
||||
use crate::errors::{
|
||||
CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
|
||||
NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
|
||||
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
|
||||
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported, SkippingConstChecks,
|
||||
SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
|
||||
TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
|
||||
TargetRequiresUnwindTables, UnleashedFeatureHelp, UnstableVirtualFunctionElimination,
|
||||
UnsupportedDwarfVersion,
|
||||
};
|
||||
use crate::parse::{add_feature_diagnostics, ParseSess};
|
||||
use crate::search_paths::{PathKind, SearchPath};
|
||||
@ -232,21 +233,19 @@ fn check_miri_unleashed_features(&self) {
|
||||
if !unleashed_features.is_empty() {
|
||||
let mut must_err = false;
|
||||
// Create a diagnostic pointing at where things got unleashed.
|
||||
// FIXME(#100717): needs eager translation/lists
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
let mut diag = self.struct_warn("skipping const checks");
|
||||
for &(span, feature_gate) in unleashed_features.iter() {
|
||||
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
|
||||
if let Some(gate) = feature_gate {
|
||||
diag.span_help(span, &format!("skipping check for `{gate}` feature"));
|
||||
// The unleash flag must *not* be used to just "hack around" feature gates.
|
||||
must_err = true;
|
||||
} else {
|
||||
diag.span_help(span, "skipping check that does not even have a feature gate");
|
||||
}
|
||||
}
|
||||
diag.emit();
|
||||
self.emit_warning(SkippingConstChecks {
|
||||
unleashed_features: unleashed_features
|
||||
.iter()
|
||||
.map(|(span, gate)| {
|
||||
gate.map(|gate| {
|
||||
must_err = true;
|
||||
UnleashedFeatureHelp::Named { span: *span, gate }
|
||||
})
|
||||
.unwrap_or(UnleashedFeatureHelp::Unnamed { span: *span })
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
|
||||
// If we should err, make sure we did.
|
||||
if must_err && self.has_errors().is_none() {
|
||||
// We have skipped a feature gate, and not run into other errors... reject.
|
||||
|
@ -14,7 +14,7 @@ rules.
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sub {
|
||||
nav.sub {
|
||||
/* The search bar and related controls don't work without JS */
|
||||
display: none;
|
||||
}
|
||||
|
@ -365,15 +365,8 @@ img {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.sub-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.sub-logo-container {
|
||||
display: block;
|
||||
margin-right: 20px;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.sub-logo-container > img {
|
||||
@ -696,14 +689,21 @@ pre, .rustdoc.source .example-wrap {
|
||||
}
|
||||
|
||||
nav.sub {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
margin-bottom: 25px;
|
||||
flex-flow: row nowrap;
|
||||
margin: 4px 0 25px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
nav.sub form {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.source nav.sub {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
.source nav.sub form {
|
||||
margin-left: 32px;
|
||||
}
|
||||
nav.sub form { display: inline; }
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
@ -796,7 +796,6 @@ table,
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 34px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.search-results-title {
|
||||
margin-top: 0;
|
||||
@ -1822,10 +1821,6 @@ in storage.js
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.source .content {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
display: none !important;
|
||||
}
|
||||
@ -1934,6 +1929,11 @@ in storage.js
|
||||
.impl-items > .item-info {
|
||||
margin-left: 34px;
|
||||
}
|
||||
|
||||
.source nav.sub {
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
@ -1962,12 +1962,12 @@ in storage.js
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.sub-container {
|
||||
nav.sub {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sub-logo-container {
|
||||
align-self: center;
|
||||
nav.sub form {
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.sub-logo-container > img {
|
||||
|
@ -102,7 +102,7 @@
|
||||
</nav> {#- -#}
|
||||
<main> {#- -#}
|
||||
<div class="width-limiter"> {#- -#}
|
||||
<div class="sub-container"> {#- -#}
|
||||
<nav class="sub"> {#- -#}
|
||||
{%- if page.css_class == "source" -%}
|
||||
<a class="sub-logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {#- -#}
|
||||
{%- if !layout.logo.is_empty() %}
|
||||
@ -112,30 +112,28 @@
|
||||
{%- endif -%}
|
||||
</a> {#- -#}
|
||||
{%- endif -%}
|
||||
<nav class="sub"> {#- -#}
|
||||
<form class="search-form"> {#- -#}
|
||||
<div class="search-container"> {#- -#}
|
||||
<span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
|
||||
<input {# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
spellcheck="false" {# -#}
|
||||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
|
||||
type="search"> {#- -#}
|
||||
<div id="help-button" title="help" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
<div id="settings-menu" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
|
||||
<img width="22" height="22" alt="Change settings" {# -#}
|
||||
src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
|
||||
</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
<form class="search-form"> {#- -#}
|
||||
<div class="search-container"> {#- -#}
|
||||
<span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
|
||||
<input {# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
spellcheck="false" {# -#}
|
||||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
|
||||
type="search"> {#- -#}
|
||||
<div id="help-button" title="help" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
</form> {#- -#}
|
||||
</nav> {#- -#}
|
||||
</div> {#- -#}
|
||||
<div id="settings-menu" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
|
||||
<img width="22" height="22" alt="Change settings" {# -#}
|
||||
src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
|
||||
</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
</div> {#- -#}
|
||||
</form> {#- -#}
|
||||
</nav> {#- -#}
|
||||
<section id="main-content" class="content">{{- content|safe -}}</section> {#- -#}
|
||||
</div> {#- -#}
|
||||
</main> {#- -#}
|
||||
|
@ -1,3 +1,4 @@
|
||||
// needs-asm-support
|
||||
// pp-exact
|
||||
|
||||
#[cfg(foo = r#"just parse this"#)]
|
||||
|
@ -1,5 +1,6 @@
|
||||
include ../tools.mk
|
||||
|
||||
# needs-asm-support
|
||||
# ignore-windows-msvc
|
||||
#
|
||||
# Because of Windows exception handling, the code is not necessarily any shorter.
|
||||
|
@ -5,12 +5,12 @@ wait-for: "#help"
|
||||
assert-css: ("#help", {"display": "block"})
|
||||
click: "#help-button > a"
|
||||
assert-css: ("#help", {"display": "block"})
|
||||
compare-elements-property: (".sub-container", "#help", ["offsetWidth"])
|
||||
compare-elements-position: (".sub-container", "#help", ("x"))
|
||||
compare-elements-property: (".sub", "#help", ["offsetWidth"])
|
||||
compare-elements-position: (".sub", "#help", ("x"))
|
||||
size: (500, 1000) // Try mobile next.
|
||||
assert-css: ("#help", {"display": "block"})
|
||||
compare-elements-property: (".sub-container", "#help", ["offsetWidth"])
|
||||
compare-elements-position: (".sub-container", "#help", ("x"))
|
||||
compare-elements-property: (".sub", "#help", ["offsetWidth"])
|
||||
compare-elements-position: (".sub", "#help", ("x"))
|
||||
|
||||
// This test ensures that opening the help popover without switching pages works.
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
@ -20,5 +20,5 @@ click: "#help-button > a"
|
||||
assert-css: ("#help", {"display": "block"})
|
||||
click: "#help-button > a"
|
||||
assert-css: ("#help", {"display": "none"})
|
||||
compare-elements-property-false: (".sub-container", "#help", ["offsetWidth"])
|
||||
compare-elements-position-false: (".sub-container", "#help", ("x"))
|
||||
compare-elements-property-false: (".sub", "#help", ["offsetWidth"])
|
||||
compare-elements-position-false: (".sub", "#help", ("x"))
|
||||
|
@ -147,7 +147,7 @@ assert-css: (
|
||||
)
|
||||
|
||||
assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
|
||||
compare-elements-position: (".sub-container", "#settings", ("x"))
|
||||
compare-elements-position: (".sub form", "#settings", ("x"))
|
||||
|
||||
// We now check the display with JS disabled.
|
||||
assert-false: "noscript section"
|
||||
|
@ -23,7 +23,7 @@ assert-css: (".src-line-numbers", {"text-align": "right"})
|
||||
show-text: true
|
||||
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
||||
// We use this assert-position to know where we will click.
|
||||
assert-position: ("//*[@id='1']", {"x": 104, "y": 103})
|
||||
assert-position: ("//*[@id='1']", {"x": 104, "y": 112})
|
||||
// We click on the left of the "1" span but still in the "src-line-number" `<pre>`.
|
||||
click: (103, 103)
|
||||
assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
|
||||
@ -47,3 +47,25 @@ assert-property: ("#source-sidebar details:first-of-type", {"open": "false"})
|
||||
|
||||
// Check the spacing.
|
||||
assert-css: ("#source-sidebar > details.dir-entry", {"padding-left": "4px"})
|
||||
|
||||
// Check the search form
|
||||
assert-css: ("nav.sub", {"flex-direction": "row"})
|
||||
// The goal of this test is to ensure the search input is perfectly centered
|
||||
// between the top of the page and the top of the gray code block.
|
||||
// To check this, we maintain the invariant:
|
||||
//
|
||||
// offsetTop[nav.sub form] = offsetTop[#main-content] - offsetHeight[nav.sub form] - offsetTop[nav.sub form]
|
||||
assert-property: ("nav.sub form", {"offsetTop": 28, "offsetHeight": 34})
|
||||
assert-property: ("#main-content", {"offsetTop": 90})
|
||||
// 28 = 90 - 34 - 28
|
||||
|
||||
// Now do the same check on moderately-sized mobile.
|
||||
size: (700, 700)
|
||||
assert-css: ("nav.sub", {"flex-direction": "row"})
|
||||
assert-property: ("nav.sub form", {"offsetTop": 21, "offsetHeight": 34})
|
||||
assert-property: ("#main-content", {"offsetTop": 76})
|
||||
// 21 = 76 - 34 - 21
|
||||
|
||||
// Tiny mobile gets a different display where the logo is stacked on top.
|
||||
size: (450, 700)
|
||||
assert-css: ("nav.sub", {"flex-direction": "column"})
|
||||
|
@ -749,3 +749,12 @@ struct SubdiagnosticEagerSuggestion {
|
||||
#[subdiagnostic(eager)]
|
||||
sub: SubdiagnosticWithSuggestion,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(compiletest::example, code = "E0123")]
|
||||
struct WithDocComment {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
@ -237,7 +237,6 @@ enum V {
|
||||
var: String,
|
||||
},
|
||||
B {
|
||||
//~^ ERROR subdiagnostic kind not specified
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
var: String,
|
||||
@ -641,3 +640,24 @@ struct BJ {
|
||||
span: Span,
|
||||
r#type: String,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(parser::add_paren)]
|
||||
struct BK {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Subdiagnostic)]
|
||||
enum BL {
|
||||
/// ..and the variant..
|
||||
#[label(parser::add_paren)]
|
||||
Foo {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
}
|
||||
|
@ -134,20 +134,14 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||
LL | #[label(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: subdiagnostic kind not specified
|
||||
--> $DIR/subdiagnostic-derive.rs:239:5
|
||||
|
|
||||
LL | B {
|
||||
| ^
|
||||
|
||||
error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:251:5
|
||||
--> $DIR/subdiagnostic-derive.rs:250:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: label without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:248:1
|
||||
--> $DIR/subdiagnostic-derive.rs:247:1
|
||||
|
|
||||
LL | / #[label(parser::add_paren)]
|
||||
LL | |
|
||||
@ -159,13 +153,13 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: `#[applicability]` is only valid on suggestions
|
||||
--> $DIR/subdiagnostic-derive.rs:261:5
|
||||
--> $DIR/subdiagnostic-derive.rs:260:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[bar]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:271:5
|
||||
--> $DIR/subdiagnostic-derive.rs:270:5
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^^^^
|
||||
@ -173,13 +167,13 @@ LL | #[bar]
|
||||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||
|
||||
error: `#[bar = ...]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:282:5
|
||||
--> $DIR/subdiagnostic-derive.rs:281:5
|
||||
|
|
||||
LL | #[bar = "..."]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[bar(...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:293:5
|
||||
--> $DIR/subdiagnostic-derive.rs:292:5
|
||||
|
|
||||
LL | #[bar("...")]
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -187,7 +181,7 @@ LL | #[bar("...")]
|
||||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||
|
||||
error: unexpected unsupported untagged union
|
||||
--> $DIR/subdiagnostic-derive.rs:309:1
|
||||
--> $DIR/subdiagnostic-derive.rs:308:1
|
||||
|
|
||||
LL | / union AC {
|
||||
LL | |
|
||||
@ -197,7 +191,7 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: `#[label(parser::add_paren)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:324:28
|
||||
--> $DIR/subdiagnostic-derive.rs:323:28
|
||||
|
|
||||
LL | #[label(parser::add_paren, parser::add_paren)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
@ -205,67 +199,67 @@ LL | #[label(parser::add_paren, parser::add_paren)]
|
||||
= help: a diagnostic slug must be the first argument to the attribute
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:337:5
|
||||
--> $DIR/subdiagnostic-derive.rs:336:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:334:5
|
||||
--> $DIR/subdiagnostic-derive.rs:333:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: subdiagnostic kind not specified
|
||||
--> $DIR/subdiagnostic-derive.rs:343:8
|
||||
--> $DIR/subdiagnostic-derive.rs:342:8
|
||||
|
|
||||
LL | struct AG {
|
||||
| ^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:380:47
|
||||
--> $DIR/subdiagnostic-derive.rs:379:47
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:380:33
|
||||
--> $DIR/subdiagnostic-derive.rs:379:33
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:398:5
|
||||
--> $DIR/subdiagnostic-derive.rs:397:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:395:5
|
||||
--> $DIR/subdiagnostic-derive.rs:394:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
|
||||
--> $DIR/subdiagnostic-derive.rs:408:5
|
||||
--> $DIR/subdiagnostic-derive.rs:407:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: suggestion without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:421:1
|
||||
--> $DIR/subdiagnostic-derive.rs:420:1
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid applicability
|
||||
--> $DIR/subdiagnostic-derive.rs:431:46
|
||||
--> $DIR/subdiagnostic-derive.rs:430:46
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: suggestion without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:449:1
|
||||
--> $DIR/subdiagnostic-derive.rs:448:1
|
||||
|
|
||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||
LL | |
|
||||
@ -275,25 +269,25 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: unsupported type attribute for subdiagnostic enum
|
||||
--> $DIR/subdiagnostic-derive.rs:463:1
|
||||
--> $DIR/subdiagnostic-derive.rs:462:1
|
||||
|
|
||||
LL | #[label]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `var` doesn't refer to a field on this type
|
||||
--> $DIR/subdiagnostic-derive.rs:483:39
|
||||
--> $DIR/subdiagnostic-derive.rs:482:39
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `var` doesn't refer to a field on this type
|
||||
--> $DIR/subdiagnostic-derive.rs:502:43
|
||||
--> $DIR/subdiagnostic-derive.rs:501:43
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `#[suggestion_part]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:525:5
|
||||
--> $DIR/subdiagnostic-derive.rs:524:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
@ -301,7 +295,7 @@ LL | #[suggestion_part]
|
||||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
|
||||
|
||||
error: `#[suggestion_part(...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:528:5
|
||||
--> $DIR/subdiagnostic-derive.rs:527:5
|
||||
|
|
||||
LL | #[suggestion_part(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -309,7 +303,7 @@ LL | #[suggestion_part(code = "...")]
|
||||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
|
||||
|
||||
error: suggestion without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:522:1
|
||||
--> $DIR/subdiagnostic-derive.rs:521:1
|
||||
|
|
||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||
LL | |
|
||||
@ -321,7 +315,7 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:537:43
|
||||
--> $DIR/subdiagnostic-derive.rs:536:43
|
||||
|
|
||||
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||
| ^^^^^^^^^^^^
|
||||
@ -329,7 +323,7 @@ LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "ma
|
||||
= help: only `applicability` is a valid nested attributes
|
||||
|
||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||
--> $DIR/subdiagnostic-derive.rs:537:1
|
||||
--> $DIR/subdiagnostic-derive.rs:536:1
|
||||
|
|
||||
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||
LL | |
|
||||
@ -340,19 +334,19 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:547:5
|
||||
--> $DIR/subdiagnostic-derive.rs:546:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:555:5
|
||||
--> $DIR/subdiagnostic-derive.rs:554:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[primary_span]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:564:5
|
||||
--> $DIR/subdiagnostic-derive.rs:563:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
@ -360,7 +354,7 @@ LL | #[primary_span]
|
||||
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
|
||||
|
||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||
--> $DIR/subdiagnostic-derive.rs:561:1
|
||||
--> $DIR/subdiagnostic-derive.rs:560:1
|
||||
|
|
||||
LL | / #[multipart_suggestion(parser::add_paren)]
|
||||
LL | |
|
||||
@ -372,19 +366,19 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:572:5
|
||||
--> $DIR/subdiagnostic-derive.rs:571:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:575:5
|
||||
--> $DIR/subdiagnostic-derive.rs:574:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:578:23
|
||||
--> $DIR/subdiagnostic-derive.rs:577:23
|
||||
|
|
||||
LL | #[suggestion_part(foo = "bar")]
|
||||
| ^^^^^^^^^^^
|
||||
@ -392,31 +386,31 @@ LL | #[suggestion_part(foo = "bar")]
|
||||
= help: `code` is the only valid nested attribute
|
||||
|
||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:581:5
|
||||
--> $DIR/subdiagnostic-derive.rs:580:5
|
||||
|
|
||||
LL | #[suggestion_part(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:584:5
|
||||
--> $DIR/subdiagnostic-derive.rs:583:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:592:37
|
||||
--> $DIR/subdiagnostic-derive.rs:591:37
|
||||
|
|
||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:592:23
|
||||
--> $DIR/subdiagnostic-derive.rs:591:23
|
||||
|
|
||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:621:5
|
||||
--> $DIR/subdiagnostic-derive.rs:620:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
@ -458,19 +452,19 @@ LL | #[bar("...")]
|
||||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:271:7
|
||||
--> $DIR/subdiagnostic-derive.rs:270:7
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:282:7
|
||||
--> $DIR/subdiagnostic-derive.rs:281:7
|
||||
|
|
||||
LL | #[bar = "..."]
|
||||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:293:7
|
||||
--> $DIR/subdiagnostic-derive.rs:292:7
|
||||
|
|
||||
LL | #[bar("...")]
|
||||
| ^^^
|
||||
@ -481,6 +475,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
|
||||
LL | #[label(slug)]
|
||||
| ^^^^ not found in `rustc_errors::fluent`
|
||||
|
||||
error: aborting due to 68 previous errors
|
||||
error: aborting due to 67 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
@ -1,3 +1,4 @@
|
||||
// needs-asm-support
|
||||
// check-pass
|
||||
// compile-flags: -Zunpretty=expanded
|
||||
core::arch::global_asm!("x: .byte 42");
|
||||
|
@ -4,6 +4,7 @@
|
||||
use ::std::prelude::rust_2015::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
// needs-asm-support
|
||||
// check-pass
|
||||
// compile-flags: -Zunpretty=expanded
|
||||
global_asm! ("x: .byte 42");
|
||||
|
@ -1,21 +1,8 @@
|
||||
// needs-asm-support
|
||||
// run-pass
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use std::arch::global_asm;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
global_asm!("");
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
global_asm!("");
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
global_asm!("");
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
global_asm!("");
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
global_asm!("");
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,16 @@
|
||||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/globs.rs:22:9
|
||||
|
|
||||
LL | pub fn g() {}
|
||||
| ---------- similarly named function `g` defined here
|
||||
...
|
||||
LL | f();
|
||||
| ^ not found in this scope
|
||||
| ^
|
||||
|
|
||||
help: a function with a similar name exists
|
||||
|
|
||||
LL | g();
|
||||
| ~
|
||||
help: consider importing this function
|
||||
|
|
||||
LL | use foo::f;
|
||||
@ -12,8 +19,11 @@ LL | use foo::f;
|
||||
error[E0425]: cannot find function `g` in this scope
|
||||
--> $DIR/globs.rs:15:5
|
||||
|
|
||||
LL | pub fn f() {}
|
||||
| ---------- similarly named function `f` defined here
|
||||
...
|
||||
LL | g();
|
||||
| ^ not found in this scope
|
||||
| ^
|
||||
...
|
||||
LL | / m! {
|
||||
LL | | use bar::*;
|
||||
@ -23,6 +33,10 @@ LL | | }
|
||||
| |_____- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: a function with a similar name exists
|
||||
|
|
||||
LL | f();
|
||||
| ~
|
||||
help: consider importing this function
|
||||
|
|
||||
LL | use bar::g;
|
||||
|
@ -19,14 +19,8 @@ LL | semitransparent;
|
||||
error[E0423]: expected value, found macro `opaque`
|
||||
--> $DIR/rustc-macro-transparency.rs:30:5
|
||||
|
|
||||
LL | struct Opaque;
|
||||
| -------------- similarly named unit struct `Opaque` defined here
|
||||
...
|
||||
LL | opaque;
|
||||
| ^^^^^^
|
||||
| |
|
||||
| not a value
|
||||
| help: a unit struct with a similar name exists (notice the capitalization): `Opaque`
|
||||
| ^^^^^^ not a value
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0574]: expected struct, variant or union type, found type parameter `T`
|
||||
--> $DIR/lexical-scopes.rs:3:13
|
||||
|
|
||||
LL | struct T { i: i32 }
|
||||
| ------------------- you might have meant to refer to this struct
|
||||
LL | fn f<T>() {
|
||||
| - found this type parameter
|
||||
LL | let t = T { i: 0 };
|
||||
|
11
src/test/ui/lint/unused/unused-supertrait.rs
Normal file
11
src/test/ui/lint/unused/unused-supertrait.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![deny(unused_must_use)]
|
||||
|
||||
fn it() -> impl ExactSizeIterator<Item = ()> {
|
||||
let x: Box<dyn ExactSizeIterator<Item = ()>> = todo!();
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
it();
|
||||
//~^ ERROR unused implementer of `Iterator` that must be used
|
||||
}
|
15
src/test/ui/lint/unused/unused-supertrait.stderr
Normal file
15
src/test/ui/lint/unused/unused-supertrait.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error: unused implementer of `Iterator` that must be used
|
||||
--> $DIR/unused-supertrait.rs:9:5
|
||||
|
|
||||
LL | it();
|
||||
| ^^^^^
|
||||
|
|
||||
= note: iterators are lazy and do nothing unless consumed
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-supertrait.rs:1:9
|
||||
|
|
||||
LL | #![deny(unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -57,7 +57,7 @@ error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/macro-context.rs:3:13
|
||||
|
|
||||
LL | () => ( i ; typeof );
|
||||
| ^ help: a local variable with a similar name exists: `a`
|
||||
| ^ not found in this scope
|
||||
...
|
||||
LL | let i = m!();
|
||||
| ---- in this macro invocation
|
||||
|
@ -13,7 +13,7 @@ error[E0425]: cannot find value `local_use` in this scope
|
||||
--> $DIR/gen-macro-rules-hygiene.rs:12:1
|
||||
|
|
||||
LL | gen_macro_rules!();
|
||||
| ^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def`
|
||||
...
|
||||
LL | generated!();
|
||||
| ------------ in this macro invocation
|
||||
@ -24,7 +24,7 @@ error[E0425]: cannot find value `local_def` in this scope
|
||||
--> $DIR/gen-macro-rules-hygiene.rs:21:9
|
||||
|
|
||||
LL | local_def;
|
||||
| ^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^^ help: a local variable with a similar name exists: `local_use`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -10,7 +10,7 @@ error[E0425]: cannot find value `local_use` in this scope
|
||||
--> $DIR/mixed-site-span.rs:13:9
|
||||
|
|
||||
LL | proc_macro_rules!();
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def`
|
||||
|
|
||||
= note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
@ -18,7 +18,7 @@ error[E0425]: cannot find value `local_def` in this scope
|
||||
--> $DIR/mixed-site-span.rs:17:9
|
||||
|
|
||||
LL | local_def;
|
||||
| ^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^^ help: a local variable with a similar name exists: `local_use`
|
||||
|
||||
error[E0412]: cannot find type `ItemUse` in crate `$crate`
|
||||
--> $DIR/mixed-site-span.rs:24:1
|
||||
|
@ -1,11 +1,16 @@
|
||||
error[E0574]: expected struct, variant or union type, found type parameter `Baz`
|
||||
--> $DIR/point-at-type-parameter-shadowing-another-type.rs:16:13
|
||||
|
|
||||
LL | impl<Baz> Foo<Baz> for Bar {
|
||||
| --- found this type parameter
|
||||
LL | / struct Baz {
|
||||
LL | | num: usize,
|
||||
LL | | }
|
||||
| |_- you might have meant to refer to this struct
|
||||
LL |
|
||||
LL | impl<Baz> Foo<Baz> for Bar {
|
||||
| --- found this type parameter
|
||||
...
|
||||
LL | Baz { num } => num,
|
||||
| ^^^ not a struct, variant or union type
|
||||
LL | Baz { num } => num,
|
||||
| ^^^ not a struct, variant or union type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -69,11 +69,13 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
|
||||
"only a `panic!` in `if`-then statement",
|
||||
|diag| {
|
||||
// comments can be noisy, do not show them to the user
|
||||
diag.tool_only_span_suggestion(
|
||||
expr.span.shrink_to_lo(),
|
||||
"add comments back",
|
||||
comments,
|
||||
applicability);
|
||||
if !comments.is_empty() {
|
||||
diag.tool_only_span_suggestion(
|
||||
expr.span.shrink_to_lo(),
|
||||
"add comments back",
|
||||
comments,
|
||||
applicability);
|
||||
}
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try instead",
|
||||
|
@ -180,10 +180,13 @@ fn assignment_suggestions<'tcx>(
|
||||
let suggestions = assignments
|
||||
.iter()
|
||||
.flat_map(|assignment| {
|
||||
[
|
||||
assignment.span.until(assignment.rhs_span),
|
||||
assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()),
|
||||
]
|
||||
let mut spans = vec![assignment.span.until(assignment.rhs_span)];
|
||||
|
||||
if assignment.rhs_span.hi() != assignment.span.hi() {
|
||||
spans.push(assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()));
|
||||
}
|
||||
|
||||
spans
|
||||
})
|
||||
.map(|span| (span, String::new()))
|
||||
.collect::<Vec<(Span, String)>>();
|
||||
|
@ -1,3 +1,4 @@
|
||||
// needs-asm-support
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
|
||||
|
@ -1,3 +1,4 @@
|
||||
// needs-asm-support
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:24:5
|
||||
--> $DIR/entry.rs:25:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | m.insert(k, v);
|
||||
@ -9,7 +9,7 @@ LL | | }
|
||||
= note: `-D clippy::map-entry` implied by `-D warnings`
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:29:5
|
||||
--> $DIR/entry.rs:30:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | if true {
|
||||
@ -32,7 +32,7 @@ LL + });
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:38:5
|
||||
--> $DIR/entry.rs:39:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | if true {
|
||||
@ -55,7 +55,7 @@ LL + });
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:47:5
|
||||
--> $DIR/entry.rs:48:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | if true {
|
||||
@ -79,7 +79,7 @@ LL + }
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:57:5
|
||||
--> $DIR/entry.rs:58:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | foo();
|
||||
@ -96,7 +96,7 @@ LL + });
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:63:5
|
||||
--> $DIR/entry.rs:64:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | match 0 {
|
||||
@ -122,7 +122,7 @@ LL + });
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:75:5
|
||||
--> $DIR/entry.rs:76:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | match 0 {
|
||||
@ -146,7 +146,7 @@ LL + }
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:85:5
|
||||
--> $DIR/entry.rs:86:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | foo();
|
||||
@ -187,7 +187,7 @@ LL + });
|
||||
|
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:119:5
|
||||
--> $DIR/entry.rs:120:5
|
||||
|
|
||||
LL | / if !m.contains_key(&m!(k)) {
|
||||
LL | | m.insert(m!(k), m!(v));
|
||||
@ -195,7 +195,7 @@ LL | | }
|
||||
| |_____^ help: try this: `m.entry(m!(k)).or_insert_with(|| m!(v));`
|
||||
|
||||
error: usage of `contains_key` followed by `insert` on a `HashMap`
|
||||
--> $DIR/entry.rs:151:5
|
||||
--> $DIR/entry.rs:152:5
|
||||
|
|
||||
LL | / if !m.contains_key(&k) {
|
||||
LL | | let x = (String::new(), String::new());
|
||||
|
@ -4,13 +4,9 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qaqaq{:?}", a);
|
||||
LL | | }
|
||||
| |_____^
|
||||
| |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);`
|
||||
|
|
||||
= note: `-D clippy::manual-assert` implied by `-D warnings`
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(a.is_empty(), "qaqaq{:?}", a);
|
||||
|
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:34:5
|
||||
@ -18,12 +14,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qwqwq");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(a.is_empty(), "qwqwq");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:51:5
|
||||
@ -31,12 +22,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() {
|
||||
LL | | panic!("panic1");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!b.is_empty(), "panic1");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:54:5
|
||||
@ -44,12 +30,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() && a.is_empty() {
|
||||
LL | | panic!("panic2");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(b.is_empty() && a.is_empty()), "panic2");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:57:5
|
||||
@ -57,12 +38,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() && !b.is_empty() {
|
||||
LL | | panic!("panic3");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(a.is_empty() && !b.is_empty()), "panic3");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:60:5
|
||||
@ -70,12 +46,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() || a.is_empty() {
|
||||
LL | | panic!("panic4");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(b.is_empty() || a.is_empty()), "panic4");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:63:5
|
||||
@ -83,12 +54,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() || !b.is_empty() {
|
||||
LL | | panic!("panic5");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(a.is_empty() || !b.is_empty()), "panic5");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:66:5
|
||||
@ -96,12 +62,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() {
|
||||
LL | | panic!("with expansion {}", one!())
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!a.is_empty(), "with expansion {}", one!());
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:73:5
|
||||
|
@ -4,13 +4,9 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qaqaq{:?}", a);
|
||||
LL | | }
|
||||
| |_____^
|
||||
| |_____^ help: try instead: `assert!(a.is_empty(), "qaqaq{:?}", a);`
|
||||
|
|
||||
= note: `-D clippy::manual-assert` implied by `-D warnings`
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(a.is_empty(), "qaqaq{:?}", a);
|
||||
|
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:34:5
|
||||
@ -18,12 +14,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if !a.is_empty() {
|
||||
LL | | panic!("qwqwq");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(a.is_empty(), "qwqwq");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(a.is_empty(), "qwqwq");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:51:5
|
||||
@ -31,12 +22,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() {
|
||||
LL | | panic!("panic1");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!b.is_empty(), "panic1");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!b.is_empty(), "panic1");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:54:5
|
||||
@ -44,12 +30,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() && a.is_empty() {
|
||||
LL | | panic!("panic2");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(b.is_empty() && a.is_empty()), "panic2");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:57:5
|
||||
@ -57,12 +38,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() && !b.is_empty() {
|
||||
LL | | panic!("panic3");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(a.is_empty() && !b.is_empty()), "panic3");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:60:5
|
||||
@ -70,12 +46,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if b.is_empty() || a.is_empty() {
|
||||
LL | | panic!("panic4");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(b.is_empty() || a.is_empty()), "panic4");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:63:5
|
||||
@ -83,12 +54,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() || !b.is_empty() {
|
||||
LL | | panic!("panic5");
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!(a.is_empty() || !b.is_empty()), "panic5");
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:66:5
|
||||
@ -96,12 +62,7 @@ error: only a `panic!` in `if`-then statement
|
||||
LL | / if a.is_empty() {
|
||||
LL | | panic!("with expansion {}", one!())
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
help: try instead
|
||||
|
|
||||
LL | assert!(!a.is_empty(), "with expansion {}", one!());
|
||||
|
|
||||
| |_____^ help: try instead: `assert!(!a.is_empty(), "with expansion {}", one!());`
|
||||
|
||||
error: only a `panic!` in `if`-then statement
|
||||
--> $DIR/manual_assert.rs:73:5
|
||||
|
@ -1,3 +1,4 @@
|
||||
// needs-asm-support
|
||||
// aux-build: proc_macro_with_span.rs
|
||||
|
||||
#![warn(clippy::missing_docs_in_private_items)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: missing documentation for a type alias
|
||||
--> $DIR/missing_doc.rs:15:1
|
||||
--> $DIR/missing_doc.rs:16:1
|
||||
|
|
||||
LL | type Typedef = String;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -7,37 +7,37 @@ LL | type Typedef = String;
|
||||
= note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings`
|
||||
|
||||
error: missing documentation for a type alias
|
||||
--> $DIR/missing_doc.rs:16:1
|
||||
--> $DIR/missing_doc.rs:17:1
|
||||
|
|
||||
LL | pub type PubTypedef = String;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a module
|
||||
--> $DIR/missing_doc.rs:18:1
|
||||
--> $DIR/missing_doc.rs:19:1
|
||||
|
|
||||
LL | mod module_no_dox {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a module
|
||||
--> $DIR/missing_doc.rs:19:1
|
||||
--> $DIR/missing_doc.rs:20:1
|
||||
|
|
||||
LL | pub mod pub_module_no_dox {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:23:1
|
||||
--> $DIR/missing_doc.rs:24:1
|
||||
|
|
||||
LL | pub fn foo2() {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:24:1
|
||||
--> $DIR/missing_doc.rs:25:1
|
||||
|
|
||||
LL | fn foo3() {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for an enum
|
||||
--> $DIR/missing_doc.rs:38:1
|
||||
--> $DIR/missing_doc.rs:39:1
|
||||
|
|
||||
LL | / enum Baz {
|
||||
LL | | BazA { a: isize, b: isize },
|
||||
@ -46,31 +46,31 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: missing documentation for a variant
|
||||
--> $DIR/missing_doc.rs:39:5
|
||||
--> $DIR/missing_doc.rs:40:5
|
||||
|
|
||||
LL | BazA { a: isize, b: isize },
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a struct field
|
||||
--> $DIR/missing_doc.rs:39:12
|
||||
--> $DIR/missing_doc.rs:40:12
|
||||
|
|
||||
LL | BazA { a: isize, b: isize },
|
||||
| ^^^^^^^^
|
||||
|
||||
error: missing documentation for a struct field
|
||||
--> $DIR/missing_doc.rs:39:22
|
||||
--> $DIR/missing_doc.rs:40:22
|
||||
|
|
||||
LL | BazA { a: isize, b: isize },
|
||||
| ^^^^^^^^
|
||||
|
||||
error: missing documentation for a variant
|
||||
--> $DIR/missing_doc.rs:40:5
|
||||
--> $DIR/missing_doc.rs:41:5
|
||||
|
|
||||
LL | BarB,
|
||||
| ^^^^
|
||||
|
||||
error: missing documentation for an enum
|
||||
--> $DIR/missing_doc.rs:43:1
|
||||
--> $DIR/missing_doc.rs:44:1
|
||||
|
|
||||
LL | / pub enum PubBaz {
|
||||
LL | | PubBazA { a: isize },
|
||||
@ -78,43 +78,43 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: missing documentation for a variant
|
||||
--> $DIR/missing_doc.rs:44:5
|
||||
--> $DIR/missing_doc.rs:45:5
|
||||
|
|
||||
LL | PubBazA { a: isize },
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a struct field
|
||||
--> $DIR/missing_doc.rs:44:15
|
||||
--> $DIR/missing_doc.rs:45:15
|
||||
|
|
||||
LL | PubBazA { a: isize },
|
||||
| ^^^^^^^^
|
||||
|
||||
error: missing documentation for a constant
|
||||
--> $DIR/missing_doc.rs:64:1
|
||||
--> $DIR/missing_doc.rs:65:1
|
||||
|
|
||||
LL | const FOO: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a constant
|
||||
--> $DIR/missing_doc.rs:71:1
|
||||
--> $DIR/missing_doc.rs:72:1
|
||||
|
|
||||
LL | pub const FOO4: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a static
|
||||
--> $DIR/missing_doc.rs:73:1
|
||||
--> $DIR/missing_doc.rs:74:1
|
||||
|
|
||||
LL | static BAR: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a static
|
||||
--> $DIR/missing_doc.rs:80:1
|
||||
--> $DIR/missing_doc.rs:81:1
|
||||
|
|
||||
LL | pub static BAR4: u32 = 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a module
|
||||
--> $DIR/missing_doc.rs:82:1
|
||||
--> $DIR/missing_doc.rs:83:1
|
||||
|
|
||||
LL | / mod internal_impl {
|
||||
LL | | /// dox
|
||||
@ -126,31 +126,31 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:85:5
|
||||
--> $DIR/missing_doc.rs:86:5
|
||||
|
|
||||
LL | pub fn undocumented1() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:86:5
|
||||
--> $DIR/missing_doc.rs:87:5
|
||||
|
|
||||
LL | pub fn undocumented2() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:87:5
|
||||
--> $DIR/missing_doc.rs:88:5
|
||||
|
|
||||
LL | fn undocumented3() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:92:9
|
||||
--> $DIR/missing_doc.rs:93:9
|
||||
|
|
||||
LL | pub fn also_undocumented1() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing documentation for a function
|
||||
--> $DIR/missing_doc.rs:93:9
|
||||
--> $DIR/missing_doc.rs:94:9
|
||||
|
|
||||
LL | fn also_undocumented2() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user