Auto merge of #104573 - matthiaskrgr:rollup-k36ybtp, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #101162 (Migrate rustc_resolve to use SessionDiagnostic, part # 1) - #103386 (Don't allow `CoerceUnsized` into `dyn*` (except for trait upcasting)) - #103405 (Detect incorrect chaining of if and if let conditions and recover) - #103594 (Fix non-associativity of `Instant` math on `aarch64-apple-darwin` targets) - #104006 (Add variant_name function to `LangItem`) - #104494 (Migrate GUI test to use functions) - #104516 (rustdoc: clean up sidebar width CSS) - #104550 (fix a typo) Failed merges: - #104554 (Use `ErrorGuaranteed::unchecked_claim_error_was_emitted` less) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b833ad56f4
@ -4047,6 +4047,7 @@ dependencies = [
|
||||
"rustc_feature",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_metadata",
|
||||
"rustc_middle",
|
||||
"rustc_query_system",
|
||||
|
@ -54,6 +54,9 @@ parser_invalid_logical_operator = `{$incorrect}` is not a logical operator
|
||||
parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator
|
||||
.suggestion = use `!` to perform bitwise not
|
||||
|
||||
parser_unexpected_if_with_if = unexpected `if` in the condition expression
|
||||
.suggestion = remove the `if`
|
||||
|
||||
parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier
|
||||
parser_unexpected_token_after_not_bitwise = use `!` to perform bitwise not
|
||||
parser_unexpected_token_after_not_logical = use `!` to perform logical negation
|
||||
|
211
compiler/rustc_error_messages/locales/en-US/resolve.ftl
Normal file
211
compiler/rustc_error_messages/locales/en-US/resolve.ftl
Normal file
@ -0,0 +1,211 @@
|
||||
resolve_parent_module_reset_for_binding =
|
||||
parent module is reset for binding
|
||||
|
||||
resolve_ampersand_used_without_explicit_lifetime_name =
|
||||
`&` without an explicit lifetime name cannot be used here
|
||||
.note = explicit lifetime name needed here
|
||||
|
||||
resolve_underscore_lifetime_name_cannot_be_used_here =
|
||||
`'_` cannot be used here
|
||||
.note = `'_` is a reserved lifetime name
|
||||
|
||||
resolve_crate_may_not_be_imported =
|
||||
`$crate` may not be imported
|
||||
|
||||
resolve_crate_root_imports_must_be_named_explicitly =
|
||||
crate root imports need to be explicitly named: `use crate as name;`
|
||||
|
||||
resolve_generic_params_from_outer_function =
|
||||
can't use generic parameters from outer function
|
||||
.label = use of generic parameter from outer function
|
||||
.suggestion = try using a local generic parameter instead
|
||||
|
||||
resolve_self_type_implicitly_declared_by_impl =
|
||||
`Self` type implicitly declared here, by this `impl`
|
||||
|
||||
resolve_cannot_use_self_type_here =
|
||||
can't use `Self` here
|
||||
|
||||
resolve_use_a_type_here_instead =
|
||||
use a type here instead
|
||||
|
||||
resolve_type_param_from_outer_fn =
|
||||
type parameter from outer function
|
||||
|
||||
resolve_const_param_from_outer_fn =
|
||||
const parameter from outer function
|
||||
|
||||
resolve_try_using_local_generic_parameter =
|
||||
try using a local generic parameter instead
|
||||
|
||||
resolve_try_adding_local_generic_param_on_method =
|
||||
try adding a local generic parameter in this method instead
|
||||
|
||||
resolve_help_try_using_local_generic_param =
|
||||
try using a local generic paramter instead
|
||||
|
||||
resolve_name_is_already_used_as_generic_parameter =
|
||||
the name `{$name}` is already used for a generic parameter in this item's generic parameters
|
||||
.label = already used
|
||||
.first_use_of_name = first use of `{$name}`
|
||||
|
||||
resolve_method_not_member_of_trait =
|
||||
method `{$method}` is not a member of trait `{$trait_}`
|
||||
.label = not a member of trait `{$trait_}`
|
||||
|
||||
resolve_associated_fn_with_similar_name_exists =
|
||||
there is an associated function with a similar name
|
||||
|
||||
resolve_type_not_member_of_trait =
|
||||
type `{$type_}` is not a member of trait `{$trait_}`
|
||||
.label = not a member of trait `{$trait_}`
|
||||
|
||||
resolve_associated_type_with_similar_name_exists =
|
||||
there is an associated type with a similar name
|
||||
|
||||
resolve_const_not_member_of_trait =
|
||||
const `{$const_}` is not a member of trait `{$trait_}`
|
||||
.label = not a member of trait `{$trait_}`
|
||||
|
||||
resolve_associated_const_with_similar_name_exists =
|
||||
there is an associated constant with a similar name
|
||||
|
||||
resolve_variable_bound_with_different_mode =
|
||||
variable `{$variable_name}` is bound inconsistently across alternatives separated by `|`
|
||||
.label = bound in different ways
|
||||
.first_binding_span = first binding
|
||||
|
||||
resolve_ident_bound_more_than_once_in_parameter_list =
|
||||
identifier `{$identifier}` is bound more than once in this parameter list
|
||||
.label = used as parameter more than once
|
||||
|
||||
resolve_ident_bound_more_than_once_in_same_pattern =
|
||||
identifier `{$identifier}` is bound more than once in the same pattern
|
||||
.label = used in a pattern more than once
|
||||
|
||||
resolve_undeclared_label =
|
||||
use of undeclared label `{$name}`
|
||||
.label = undeclared label `{$name}`
|
||||
|
||||
resolve_label_with_similar_name_reachable =
|
||||
a label with a similar name is reachable
|
||||
|
||||
resolve_try_using_similarly_named_label =
|
||||
try using similarly named label
|
||||
|
||||
resolve_unreachable_label_with_similar_name_exists =
|
||||
a label with a similar name exists but is unreachable
|
||||
|
||||
resolve_self_import_can_only_appear_once_in_the_list =
|
||||
`self` import can only appear once in an import list
|
||||
.label = can only appear once in an import list
|
||||
|
||||
resolve_self_import_only_in_import_list_with_non_empty_prefix =
|
||||
`self` import can only appear in an import list with a non-empty prefix
|
||||
.label = can only appear in an import list with a non-empty prefix
|
||||
|
||||
resolve_cannot_capture_dynamic_environment_in_fn_item =
|
||||
can't capture dynamic environment in a fn item
|
||||
.help = use the `|| {"{"} ... {"}"}` closure form instead
|
||||
|
||||
resolve_attempt_to_use_non_constant_value_in_constant =
|
||||
attempt to use a non-constant value in a constant
|
||||
|
||||
resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion =
|
||||
consider using `{$suggestion}` instead of `{$current}`
|
||||
|
||||
resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion =
|
||||
non-constant value
|
||||
|
||||
resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion =
|
||||
this would need to be a `{$suggestion}`
|
||||
|
||||
resolve_self_imports_only_allowed_within =
|
||||
`self` imports are only allowed within a {"{"} {"}"} list
|
||||
|
||||
resolve_self_imports_only_allowed_within_suggestion =
|
||||
consider importing the module directly
|
||||
|
||||
resolve_self_imports_only_allowed_within_multipart_suggestion =
|
||||
alternatively, use the multi-path `use` syntax to import `self`
|
||||
|
||||
resolve_binding_shadows_something_unacceptable =
|
||||
{$shadowing_binding}s cannot shadow {$shadowed_binding}s
|
||||
.label = cannot be named the same as {$article} {$shadowed_binding}
|
||||
.label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here
|
||||
|
||||
resolve_binding_shadows_something_unacceptable_suggestion =
|
||||
try specify the pattern arguments
|
||||
|
||||
resolve_forward_declared_generic_param =
|
||||
generic parameters with a default cannot use forward declared identifiers
|
||||
.label = defaulted generic parameters cannot be forward declared
|
||||
|
||||
resolve_param_in_ty_of_const_param =
|
||||
the type of const parameters must not depend on other generic parameters
|
||||
.label = the type must not depend on the parameter `{$name}`
|
||||
|
||||
resolve_self_in_generic_param_default =
|
||||
generic parameters cannot use `Self` in their defaults
|
||||
.label = `Self` in generic parameter default
|
||||
|
||||
resolve_param_in_non_trivial_anon_const =
|
||||
generic parameters may not be used in const operations
|
||||
.label = cannot perform const operation using `{$name}`
|
||||
|
||||
resolve_param_in_non_trivial_anon_const_help =
|
||||
use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
resolve_param_in_non_trivial_anon_const_sub_type =
|
||||
type parameters may not be used in const expressions
|
||||
|
||||
resolve_param_in_non_trivial_anon_const_sub_non_type =
|
||||
const parameters may only be used as standalone arguments, i.e. `{$name}`
|
||||
|
||||
resolve_unreachable_label =
|
||||
use of unreachable label `{$name}`
|
||||
.label = unreachable label `{$name}`
|
||||
.label_definition_span = unreachable label defined here
|
||||
.note = labels are unreachable through functions, closures, async blocks and modules
|
||||
|
||||
resolve_unreachable_label_suggestion_use_similarly_named =
|
||||
try using similarly named label
|
||||
|
||||
resolve_unreachable_label_similar_name_reachable =
|
||||
a label with a similar name is reachable
|
||||
|
||||
resolve_unreachable_label_similar_name_unreachable =
|
||||
a label with a similar name exists but is also unreachable
|
||||
|
||||
resolve_trait_impl_mismatch =
|
||||
item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}`
|
||||
.label = does not match trait
|
||||
.label_trait_item = item in trait
|
||||
|
||||
resolve_invalid_asm_sym =
|
||||
invalid `sym` operand
|
||||
.label = is a local variable
|
||||
.help = `sym` operands must refer to either a function or a static
|
||||
|
||||
resolve_trait_impl_duplicate =
|
||||
duplicate definitions with name `{$name}`:
|
||||
.label = duplicate definition
|
||||
.old_span_label = previous definition here
|
||||
.trait_item_span = item in trait
|
||||
|
||||
resolve_relative_2018 =
|
||||
relative paths are not supported in visibilities in 2018 edition or later
|
||||
.suggestion = try
|
||||
|
||||
resolve_ancestor_only =
|
||||
visibilities can only be restricted to ancestor modules
|
||||
|
||||
resolve_expected_found =
|
||||
expected module, found {$res} `{$path_str}`
|
||||
.label = not a module
|
||||
|
||||
resolve_indeterminate =
|
||||
cannot determine resolution for the visibility
|
||||
|
||||
resolve_module_only =
|
||||
visibility must resolve to a module
|
@ -63,6 +63,7 @@ fluent_messages! {
|
||||
plugin_impl => "../locales/en-US/plugin_impl.ftl",
|
||||
privacy => "../locales/en-US/privacy.ftl",
|
||||
query_system => "../locales/en-US/query_system.ftl",
|
||||
resolve => "../locales/en-US/resolve.ftl",
|
||||
save_analysis => "../locales/en-US/save_analysis.ftl",
|
||||
session => "../locales/en-US/session.ftl",
|
||||
symbol_mangling => "../locales/en-US/symbol_mangling.ftl",
|
||||
|
@ -211,6 +211,12 @@ impl IntoDiagnosticArg for DiagnosticSymbolList {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
|
||||
let mut diag;
|
||||
|
@ -95,6 +95,14 @@ macro_rules! language_item_table {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the name of the `LangItem` enum variant.
|
||||
// This method is used by Clippy for internal lints.
|
||||
pub fn variant_name(self) -> &'static str {
|
||||
match self {
|
||||
$( LangItem::$variant => stringify!($variant), )*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn target(self) -> Target {
|
||||
match self {
|
||||
$( LangItem::$variant => $target, )*
|
||||
|
@ -144,7 +144,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
|
||||
AlreadyReported(ErrorGuaranteed { .. }) => {
|
||||
write!(
|
||||
f,
|
||||
"an error has already been reported elsewhere (this sould not usually be printed)"
|
||||
"an error has already been reported elsewhere (this should not usually be printed)"
|
||||
)
|
||||
}
|
||||
Layout(ref err) => write!(f, "{err}"),
|
||||
|
@ -1219,3 +1219,11 @@ pub(crate) struct FnPtrWithGenericsSugg {
|
||||
pub arity: usize,
|
||||
pub for_param_list_exists: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parser_unexpected_if_with_if)]
|
||||
pub(crate) struct UnexpectedIfWithIf(
|
||||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
|
||||
pub Span,
|
||||
);
|
||||
|
@ -21,8 +21,8 @@ use crate::errors::{
|
||||
NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub,
|
||||
OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields,
|
||||
RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere,
|
||||
StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
|
||||
UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
|
||||
StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf,
|
||||
UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
|
||||
};
|
||||
use crate::maybe_recover_from_interpolated_ty_qpath;
|
||||
use core::mem;
|
||||
@ -2239,6 +2239,7 @@ impl<'a> Parser<'a> {
|
||||
if let Some(block) = recover_block_from_condition(self) {
|
||||
block
|
||||
} else {
|
||||
self.error_on_extra_if(&cond)?;
|
||||
// Parse block, which will always fail, but we can add a nice note to the error
|
||||
self.parse_block().map_err(|mut err| {
|
||||
err.span_note(
|
||||
@ -2375,6 +2376,16 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> {
|
||||
if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind &&
|
||||
let BinOpKind::And = binop &&
|
||||
let ExprKind::If(cond, ..) = &right.kind {
|
||||
Err(self.sess.create_err(UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo()))))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
|
||||
fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
|
||||
// Record whether we are about to parse `for (`.
|
||||
|
@ -17,6 +17,7 @@ rustc_expand = { path = "../rustc_expand" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_metadata = { path = "../rustc_metadata" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_query_system = { path = "../rustc_query_system" }
|
||||
|
@ -27,6 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, Span, SyntaxContext};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
use crate::errors as errs;
|
||||
use crate::imports::{Import, ImportKind, ImportResolver};
|
||||
use crate::late::{PatternSource, Rib};
|
||||
use crate::path_names_to_string;
|
||||
@ -598,78 +599,41 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
err
|
||||
}
|
||||
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0403,
|
||||
"the name `{}` is already used for a generic \
|
||||
parameter in this item's generic parameters",
|
||||
name,
|
||||
);
|
||||
err.span_label(span, "already used");
|
||||
err.span_label(first_use_span, format!("first use of `{}`", name));
|
||||
err
|
||||
}
|
||||
ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self
|
||||
.session
|
||||
.create_err(errs::NameAlreadyUsedInParameterList { span, first_use_span, name }),
|
||||
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
self.session.create_err(errs::MethodNotMemberOfTrait {
|
||||
span,
|
||||
E0407,
|
||||
"method `{}` is not a member of trait `{}`",
|
||||
method,
|
||||
trait_
|
||||
);
|
||||
err.span_label(span, format!("not a member of trait `{}`", trait_));
|
||||
if let Some(candidate) = candidate {
|
||||
err.span_suggestion(
|
||||
method.span,
|
||||
"there is an associated function with a similar name",
|
||||
candidate.to_ident_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err
|
||||
trait_,
|
||||
sub: candidate.map(|c| errs::AssociatedFnWithSimilarNameExists {
|
||||
span: method.span,
|
||||
candidate: c,
|
||||
}),
|
||||
})
|
||||
}
|
||||
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
self.session.create_err(errs::TypeNotMemberOfTrait {
|
||||
span,
|
||||
E0437,
|
||||
"type `{}` is not a member of trait `{}`",
|
||||
type_,
|
||||
trait_
|
||||
);
|
||||
err.span_label(span, format!("not a member of trait `{}`", trait_));
|
||||
if let Some(candidate) = candidate {
|
||||
err.span_suggestion(
|
||||
type_.span,
|
||||
"there is an associated type with a similar name",
|
||||
candidate.to_ident_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err
|
||||
trait_,
|
||||
sub: candidate.map(|c| errs::AssociatedTypeWithSimilarNameExists {
|
||||
span: type_.span,
|
||||
candidate: c,
|
||||
}),
|
||||
})
|
||||
}
|
||||
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
self.session.create_err(errs::ConstNotMemberOfTrait {
|
||||
span,
|
||||
E0438,
|
||||
"const `{}` is not a member of trait `{}`",
|
||||
const_,
|
||||
trait_
|
||||
);
|
||||
err.span_label(span, format!("not a member of trait `{}`", trait_));
|
||||
if let Some(candidate) = candidate {
|
||||
err.span_suggestion(
|
||||
const_.span,
|
||||
"there is an associated constant with a similar name",
|
||||
candidate.to_ident_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err
|
||||
trait_,
|
||||
sub: candidate.map(|c| errs::AssociatedConstWithSimilarNameExists {
|
||||
span: const_.span,
|
||||
candidate: c,
|
||||
}),
|
||||
})
|
||||
}
|
||||
ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => {
|
||||
let BindingError { name, target, origin, could_be_path } = binding_error;
|
||||
@ -731,128 +695,78 @@ impl<'a> Resolver<'a> {
|
||||
err
|
||||
}
|
||||
ResolutionError::VariableBoundWithDifferentMode(variable_name, first_binding_span) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
self.session.create_err(errs::VariableBoundWithDifferentMode {
|
||||
span,
|
||||
E0409,
|
||||
"variable `{}` is bound inconsistently across alternatives separated by `|`",
|
||||
variable_name
|
||||
);
|
||||
err.span_label(span, "bound in different ways");
|
||||
err.span_label(first_binding_span, "first binding");
|
||||
err
|
||||
}
|
||||
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0415,
|
||||
"identifier `{}` is bound more than once in this parameter list",
|
||||
identifier
|
||||
);
|
||||
err.span_label(span, "used as parameter more than once");
|
||||
err
|
||||
}
|
||||
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0416,
|
||||
"identifier `{}` is bound more than once in the same pattern",
|
||||
identifier
|
||||
);
|
||||
err.span_label(span, "used in a pattern more than once");
|
||||
err
|
||||
first_binding_span,
|
||||
variable_name,
|
||||
})
|
||||
}
|
||||
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => self
|
||||
.session
|
||||
.create_err(errs::IdentifierBoundMoreThanOnceInParameterList { span, identifier }),
|
||||
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => self
|
||||
.session
|
||||
.create_err(errs::IdentifierBoundMoreThanOnceInSamePattern { span, identifier }),
|
||||
ResolutionError::UndeclaredLabel { name, suggestion } => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0426,
|
||||
"use of undeclared label `{}`",
|
||||
name
|
||||
);
|
||||
|
||||
err.span_label(span, format!("undeclared label `{}`", name));
|
||||
|
||||
match suggestion {
|
||||
let ((sub_reachable, sub_reachable_suggestion), sub_unreachable) = match suggestion
|
||||
{
|
||||
// A reachable label with a similar name exists.
|
||||
Some((ident, true)) => {
|
||||
err.span_label(ident.span, "a label with a similar name is reachable");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"try using similarly named label",
|
||||
ident.name,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
Some((ident, true)) => (
|
||||
(
|
||||
Some(errs::LabelWithSimilarNameReachable(ident.span)),
|
||||
Some(errs::TryUsingSimilarlyNamedLabel {
|
||||
span,
|
||||
ident_name: ident.name,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
),
|
||||
// An unreachable label with a similar name exists.
|
||||
Some((ident, false)) => {
|
||||
err.span_label(
|
||||
ident.span,
|
||||
"a label with a similar name exists but is unreachable",
|
||||
);
|
||||
}
|
||||
Some((ident, false)) => (
|
||||
(None, None),
|
||||
Some(errs::UnreachableLabelWithSimilarNameExists {
|
||||
ident_span: ident.span,
|
||||
}),
|
||||
),
|
||||
// No similarly-named labels exist.
|
||||
None => (),
|
||||
}
|
||||
|
||||
err
|
||||
None => ((None, None), None),
|
||||
};
|
||||
self.session.create_err(errs::UndeclaredLabel {
|
||||
span,
|
||||
name,
|
||||
sub_reachable,
|
||||
sub_reachable_suggestion,
|
||||
sub_unreachable,
|
||||
})
|
||||
}
|
||||
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0429,
|
||||
"{}",
|
||||
"`self` imports are only allowed within a { } list"
|
||||
);
|
||||
|
||||
// None of the suggestions below would help with a case like `use self`.
|
||||
if !root {
|
||||
let (suggestion, mpart_suggestion) = if root {
|
||||
(None, None)
|
||||
} else {
|
||||
// use foo::bar::self -> foo::bar
|
||||
// use foo::bar::self as abc -> foo::bar as abc
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider importing the module directly",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
|
||||
|
||||
// use foo::bar::self -> foo::bar::{self}
|
||||
// use foo::bar::self as abc -> foo::bar::{self as abc}
|
||||
let braces = vec![
|
||||
(span_with_rename.shrink_to_lo(), "{".to_string()),
|
||||
(span_with_rename.shrink_to_hi(), "}".to_string()),
|
||||
];
|
||||
err.multipart_suggestion(
|
||||
"alternatively, use the multi-path `use` syntax to import `self`",
|
||||
braces,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err
|
||||
let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
|
||||
multipart_start: span_with_rename.shrink_to_lo(),
|
||||
multipart_end: span_with_rename.shrink_to_hi(),
|
||||
};
|
||||
(Some(suggestion), Some(mpart_suggestion))
|
||||
};
|
||||
self.session.create_err(errs::SelfImportsOnlyAllowedWithin {
|
||||
span,
|
||||
suggestion,
|
||||
mpart_suggestion,
|
||||
})
|
||||
}
|
||||
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0430,
|
||||
"`self` import can only appear once in an import list"
|
||||
);
|
||||
err.span_label(span, "can only appear once in an import list");
|
||||
err
|
||||
self.session.create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span })
|
||||
}
|
||||
ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0431,
|
||||
"`self` import can only appear in an import list with \
|
||||
a non-empty prefix"
|
||||
);
|
||||
err.span_label(span, "can only appear in an import list with a non-empty prefix");
|
||||
err
|
||||
self.session.create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span })
|
||||
}
|
||||
ResolutionError::FailedToResolve { label, suggestion } => {
|
||||
let mut err =
|
||||
@ -870,23 +784,9 @@ impl<'a> Resolver<'a> {
|
||||
err
|
||||
}
|
||||
ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0434,
|
||||
"{}",
|
||||
"can't capture dynamic environment in a fn item"
|
||||
);
|
||||
err.help("use the `|| { ... }` closure form instead");
|
||||
err
|
||||
self.session.create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span })
|
||||
}
|
||||
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0435,
|
||||
"attempt to use a non-constant value in a constant"
|
||||
);
|
||||
ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => {
|
||||
// let foo =...
|
||||
// ^^^ given this Span
|
||||
// ------- get this Span to have an applicable suggestion
|
||||
@ -900,23 +800,34 @@ impl<'a> Resolver<'a> {
|
||||
.source_map()
|
||||
.span_extend_to_prev_str(ident.span, current, true, false);
|
||||
|
||||
match sp {
|
||||
let ((with, with_label), without) = match sp {
|
||||
Some(sp) if !self.session.source_map().is_multiline(sp) => {
|
||||
let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32)));
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
&format!("consider using `{}` instead of `{}`", sugg, current),
|
||||
format!("{} {}", sugg, ident),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_label(span, "non-constant value");
|
||||
(
|
||||
(Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion {
|
||||
span: sp,
|
||||
ident,
|
||||
suggestion,
|
||||
current,
|
||||
}), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})),
|
||||
None,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
err.span_label(ident.span, &format!("this would need to be a `{}`", sugg));
|
||||
}
|
||||
}
|
||||
_ => (
|
||||
(None, None),
|
||||
Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion {
|
||||
ident_span: ident.span,
|
||||
suggestion,
|
||||
}),
|
||||
),
|
||||
};
|
||||
|
||||
err
|
||||
self.session.create_err(errs::AttemptToUseNonConstantValueInConstant {
|
||||
span,
|
||||
with,
|
||||
with_label,
|
||||
without,
|
||||
})
|
||||
}
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable {
|
||||
shadowing_binding,
|
||||
@ -925,135 +836,80 @@ impl<'a> Resolver<'a> {
|
||||
article,
|
||||
shadowed_binding,
|
||||
shadowed_binding_span,
|
||||
} => {
|
||||
let shadowed_binding_descr = shadowed_binding.descr();
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0530,
|
||||
"{}s cannot shadow {}s",
|
||||
shadowing_binding.descr(),
|
||||
shadowed_binding_descr,
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
|
||||
);
|
||||
match (shadowing_binding, shadowed_binding) {
|
||||
} => self.session.create_err(errs::BindingShadowsSomethingUnacceptable {
|
||||
span,
|
||||
shadowing_binding,
|
||||
shadowed_binding,
|
||||
article,
|
||||
sub_suggestion: match (shadowing_binding, shadowed_binding) {
|
||||
(
|
||||
PatternSource::Match,
|
||||
Res::Def(DefKind::Ctor(CtorOf::Variant | CtorOf::Struct, CtorKind::Fn), _),
|
||||
) => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"try specify the pattern arguments",
|
||||
format!("{}(..)", name),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
let msg =
|
||||
format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
|
||||
err.span_label(shadowed_binding_span, msg);
|
||||
err
|
||||
}
|
||||
) => Some(errs::BindingShadowsSomethingUnacceptableSuggestion { span, name }),
|
||||
_ => None,
|
||||
},
|
||||
shadowed_binding_span,
|
||||
participle,
|
||||
name,
|
||||
}),
|
||||
ResolutionError::ForwardDeclaredGenericParam => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0128,
|
||||
"generic parameters with a default cannot use \
|
||||
forward declared identifiers"
|
||||
);
|
||||
err.span_label(span, "defaulted generic parameters cannot be forward declared");
|
||||
err
|
||||
self.session.create_err(errs::ForwardDeclaredGenericParam { span })
|
||||
}
|
||||
ResolutionError::ParamInTyOfConstParam(name) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0770,
|
||||
"the type of const parameters must not depend on other generic parameters"
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
format!("the type must not depend on the parameter `{}`", name),
|
||||
);
|
||||
err
|
||||
self.session.create_err(errs::ParamInTyOfConstParam { span, name })
|
||||
}
|
||||
ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => {
|
||||
let mut err = self.session.struct_span_err(
|
||||
self.session.create_err(errs::ParamInNonTrivialAnonConst {
|
||||
span,
|
||||
"generic parameters may not be used in const operations",
|
||||
);
|
||||
err.span_label(span, &format!("cannot perform const operation using `{}`", name));
|
||||
|
||||
if is_type {
|
||||
err.note("type parameters may not be used in const expressions");
|
||||
} else {
|
||||
err.help(&format!(
|
||||
"const parameters may only be used as standalone arguments, i.e. `{}`",
|
||||
name
|
||||
));
|
||||
}
|
||||
|
||||
if self.session.is_nightly_build() {
|
||||
err.help(
|
||||
"use `#![feature(generic_const_exprs)]` to allow generic const expressions",
|
||||
);
|
||||
}
|
||||
|
||||
err
|
||||
name,
|
||||
sub_is_type: if is_type {
|
||||
errs::ParamInNonTrivialAnonConstIsType::AType
|
||||
} else {
|
||||
errs::ParamInNonTrivialAnonConstIsType::NotAType { name }
|
||||
},
|
||||
help: self
|
||||
.session
|
||||
.is_nightly_build()
|
||||
.then_some(errs::ParamInNonTrivialAnonConstHelp),
|
||||
})
|
||||
}
|
||||
ResolutionError::SelfInGenericParamDefault => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0735,
|
||||
"generic parameters cannot use `Self` in their defaults"
|
||||
);
|
||||
err.span_label(span, "`Self` in generic parameter default");
|
||||
err
|
||||
self.session.create_err(errs::SelfInGenericParamDefault { span })
|
||||
}
|
||||
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
|
||||
match suggestion {
|
||||
// A reachable label with a similar name exists.
|
||||
Some((ident, true)) => (
|
||||
(
|
||||
Some(errs::UnreachableLabelSubLabel { ident_span: ident.span }),
|
||||
Some(errs::UnreachableLabelSubSuggestion {
|
||||
span,
|
||||
// intentionally taking 'ident.name' instead of 'ident' itself, as this
|
||||
// could be used in suggestion context
|
||||
ident_name: ident.name,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
),
|
||||
// An unreachable label with a similar name exists.
|
||||
Some((ident, false)) => (
|
||||
(None, None),
|
||||
Some(errs::UnreachableLabelSubLabelUnreachable {
|
||||
ident_span: ident.span,
|
||||
}),
|
||||
),
|
||||
// No similarly-named labels exist.
|
||||
None => ((None, None), None),
|
||||
};
|
||||
self.session.create_err(errs::UnreachableLabel {
|
||||
span,
|
||||
E0767,
|
||||
"use of unreachable label `{}`",
|
||||
name,
|
||||
);
|
||||
|
||||
err.span_label(definition_span, "unreachable label defined here");
|
||||
err.span_label(span, format!("unreachable label `{}`", name));
|
||||
err.note(
|
||||
"labels are unreachable through functions, closures, async blocks and modules",
|
||||
);
|
||||
|
||||
match suggestion {
|
||||
// A reachable label with a similar name exists.
|
||||
Some((ident, true)) => {
|
||||
err.span_label(ident.span, "a label with a similar name is reachable");
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"try using similarly named label",
|
||||
ident.name,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
// An unreachable label with a similar name exists.
|
||||
Some((ident, false)) => {
|
||||
err.span_label(
|
||||
ident.span,
|
||||
"a label with a similar name exists but is also unreachable",
|
||||
);
|
||||
}
|
||||
// No similarly-named labels exist.
|
||||
None => (),
|
||||
}
|
||||
|
||||
err
|
||||
definition_span,
|
||||
sub_suggestion,
|
||||
sub_suggestion_label,
|
||||
sub_unreachable_label,
|
||||
})
|
||||
}
|
||||
ResolutionError::TraitImplMismatch {
|
||||
name,
|
||||
@ -1074,25 +930,10 @@ impl<'a> Resolver<'a> {
|
||||
err.span_label(trait_item_span, "item in trait");
|
||||
err
|
||||
}
|
||||
ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0201,
|
||||
"duplicate definitions with name `{}`:",
|
||||
name,
|
||||
);
|
||||
err.span_label(old_span, "previous definition here");
|
||||
err.span_label(trait_item_span, "item in trait");
|
||||
err.span_label(span, "duplicate definition");
|
||||
err
|
||||
}
|
||||
ResolutionError::InvalidAsmSym => {
|
||||
let mut err = self.session.struct_span_err(span, "invalid `sym` operand");
|
||||
err.span_label(span, "is a local variable");
|
||||
err.help("`sym` operands must refer to either a function or a static");
|
||||
err
|
||||
}
|
||||
ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self
|
||||
.session
|
||||
.create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }),
|
||||
ResolutionError::InvalidAsmSym => self.session.create_err(errs::InvalidAsmSym { span }),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,48 +943,27 @@ impl<'a> Resolver<'a> {
|
||||
) -> ErrorGuaranteed {
|
||||
match vis_resolution_error {
|
||||
VisResolutionError::Relative2018(span, path) => {
|
||||
let mut err = self.session.struct_span_err(
|
||||
self.session.create_err(errs::Relative2018 {
|
||||
span,
|
||||
"relative paths are not supported in visibilities in 2018 edition or later",
|
||||
);
|
||||
err.span_suggestion(
|
||||
path.span,
|
||||
"try",
|
||||
format!("crate::{}", pprust::path_to_string(&path)),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err
|
||||
path_span: path.span,
|
||||
// intentionally converting to String, as the text would also be used as
|
||||
// in suggestion context
|
||||
path_str: pprust::path_to_string(&path),
|
||||
})
|
||||
}
|
||||
VisResolutionError::AncestorOnly(span) => {
|
||||
self.session.create_err(errs::AncestorOnly(span))
|
||||
}
|
||||
VisResolutionError::AncestorOnly(span) => struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0742,
|
||||
"visibilities can only be restricted to ancestor modules"
|
||||
),
|
||||
VisResolutionError::FailedToResolve(span, label, suggestion) => {
|
||||
self.into_struct_error(span, ResolutionError::FailedToResolve { label, suggestion })
|
||||
}
|
||||
VisResolutionError::ExpectedFound(span, path_str, res) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0577,
|
||||
"expected module, found {} `{}`",
|
||||
res.descr(),
|
||||
path_str
|
||||
);
|
||||
err.span_label(span, "not a module");
|
||||
err
|
||||
self.session.create_err(errs::ExpectedFound { span, res, path_str })
|
||||
}
|
||||
VisResolutionError::Indeterminate(span) => struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0578,
|
||||
"cannot determine resolution for the visibility"
|
||||
),
|
||||
VisResolutionError::ModuleOnly(span) => {
|
||||
self.session.struct_span_err(span, "visibility must resolve to a module")
|
||||
VisResolutionError::Indeterminate(span) => {
|
||||
self.session.create_err(errs::Indeterminate(span))
|
||||
}
|
||||
VisResolutionError::ModuleOnly(span) => self.session.create_err(errs::ModuleOnly(span)),
|
||||
}
|
||||
.emit()
|
||||
}
|
||||
|
474
compiler/rustc_resolve/src/errors.rs
Normal file
474
compiler/rustc_resolve/src/errors.rs
Normal file
@ -0,0 +1,474 @@
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{
|
||||
symbol::{Ident, Symbol},
|
||||
Span,
|
||||
};
|
||||
|
||||
use crate::{late::PatternSource, Res};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_parent_module_reset_for_binding, code = "E0637")]
|
||||
pub(crate) struct ParentModuleResetForBinding;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")]
|
||||
#[note]
|
||||
pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")]
|
||||
#[note]
|
||||
pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_crate_may_not_be_imported)]
|
||||
pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
|
||||
pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_crate_root_imports_must_be_named_explicitly)]
|
||||
pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
|
||||
pub(crate) struct NameAlreadyUsedInParameterList {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[label(first_use_of_name)]
|
||||
pub(crate) first_use_span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_method_not_member_of_trait, code = "E0407")]
|
||||
pub(crate) struct MethodNotMemberOfTrait {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) method: Ident,
|
||||
pub(crate) trait_: String,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub: Option<AssociatedFnWithSimilarNameExists>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_associated_fn_with_similar_name_exists,
|
||||
code = "{candidate}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct AssociatedFnWithSimilarNameExists {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) candidate: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_type_not_member_of_trait, code = "E0437")]
|
||||
pub(crate) struct TypeNotMemberOfTrait {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) type_: Ident,
|
||||
pub(crate) trait_: String,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub: Option<AssociatedTypeWithSimilarNameExists>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_associated_type_with_similar_name_exists,
|
||||
code = "{candidate}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct AssociatedTypeWithSimilarNameExists {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) candidate: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_const_not_member_of_trait, code = "E0438")]
|
||||
pub(crate) struct ConstNotMemberOfTrait {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) const_: Ident,
|
||||
pub(crate) trait_: String,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub: Option<AssociatedConstWithSimilarNameExists>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_associated_const_with_similar_name_exists,
|
||||
code = "{candidate}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct AssociatedConstWithSimilarNameExists {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) candidate: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_variable_bound_with_different_mode, code = "E0409")]
|
||||
pub(crate) struct VariableBoundWithDifferentMode {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[label(first_binding_span)]
|
||||
pub(crate) first_binding_span: Span,
|
||||
pub(crate) variable_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")]
|
||||
pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) identifier: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")]
|
||||
pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) identifier: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_undeclared_label, code = "E0426")]
|
||||
pub(crate) struct UndeclaredLabel {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_reachable: Option<LabelWithSimilarNameReachable>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_reachable_suggestion: Option<TryUsingSimilarlyNamedLabel>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_unreachable: Option<UnreachableLabelWithSimilarNameExists>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_label_with_similar_name_reachable)]
|
||||
pub(crate) struct LabelWithSimilarNameReachable(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_try_using_similarly_named_label,
|
||||
code = "{ident_name}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct TryUsingSimilarlyNamedLabel {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) ident_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_unreachable_label_with_similar_name_exists)]
|
||||
pub(crate) struct UnreachableLabelWithSimilarNameExists {
|
||||
#[primary_span]
|
||||
pub(crate) ident_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")]
|
||||
pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")]
|
||||
pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")]
|
||||
#[help]
|
||||
pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")]
|
||||
pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) with: Option<AttemptToUseNonConstantValueInConstantWithSuggestion<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) with_label: Option<AttemptToUseNonConstantValueInConstantLabelWithSuggestion>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) without: Option<AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion,
|
||||
code = "{suggestion} {ident}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) ident: Ident,
|
||||
pub(crate) suggestion: &'a str,
|
||||
pub(crate) current: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion)]
|
||||
pub(crate) struct AttemptToUseNonConstantValueInConstantLabelWithSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion)]
|
||||
pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
|
||||
#[primary_span]
|
||||
pub(crate) ident_span: Span,
|
||||
pub(crate) suggestion: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_self_imports_only_allowed_within, code = "E0429")]
|
||||
pub(crate) struct SelfImportsOnlyAllowedWithin {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_self_imports_only_allowed_within_suggestion,
|
||||
code = "",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
resolve_self_imports_only_allowed_within_multipart_suggestion,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
|
||||
#[suggestion_part(code = "{{")]
|
||||
pub(crate) multipart_start: Span,
|
||||
#[suggestion_part(code = "}}")]
|
||||
pub(crate) multipart_end: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")]
|
||||
pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) shadowing_binding: PatternSource,
|
||||
pub(crate) shadowed_binding: Res,
|
||||
pub(crate) article: &'a str,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>,
|
||||
#[label(label_shadowed_binding)]
|
||||
pub(crate) shadowed_binding_span: Span,
|
||||
pub(crate) participle: &'a str,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_binding_shadows_something_unacceptable_suggestion,
|
||||
code = "{name}(..)",
|
||||
applicability = "unspecified"
|
||||
)]
|
||||
pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_forward_declared_generic_param, code = "E0128")]
|
||||
pub(crate) struct ForwardDeclaredGenericParam {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_param_in_ty_of_const_param, code = "E0770")]
|
||||
pub(crate) struct ParamInTyOfConstParam {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_self_in_generic_param_default, code = "E0735")]
|
||||
pub(crate) struct SelfInGenericParamDefault {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_param_in_non_trivial_anon_const)]
|
||||
pub(crate) struct ParamInNonTrivialAnonConst {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType,
|
||||
#[subdiagnostic]
|
||||
pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[help(resolve_param_in_non_trivial_anon_const_help)]
|
||||
pub(crate) struct ParamInNonTrivialAnonConstHelp;
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum ParamInNonTrivialAnonConstIsType {
|
||||
#[note(resolve_param_in_non_trivial_anon_const_sub_type)]
|
||||
AType,
|
||||
#[help(resolve_param_in_non_trivial_anon_const_sub_non_type)]
|
||||
NotAType { name: Symbol },
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_unreachable_label, code = "E0767")]
|
||||
#[note]
|
||||
pub(crate) struct UnreachableLabel {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
#[label(label_definition_span)]
|
||||
pub(crate) definition_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_suggestion_label: Option<UnreachableLabelSubLabel>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) sub_unreachable_label: Option<UnreachableLabelSubLabelUnreachable>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
resolve_unreachable_label_suggestion_use_similarly_named,
|
||||
code = "{ident_name}",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct UnreachableLabelSubSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) ident_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_unreachable_label_similar_name_reachable)]
|
||||
pub(crate) struct UnreachableLabelSubLabel {
|
||||
#[primary_span]
|
||||
pub(crate) ident_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(resolve_unreachable_label_similar_name_unreachable)]
|
||||
pub(crate) struct UnreachableLabelSubLabelUnreachable {
|
||||
#[primary_span]
|
||||
pub(crate) ident_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_trait_impl_mismatch, code = "{code}")]
|
||||
pub(crate) struct TraitImplMismatch {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
pub(crate) kind: String,
|
||||
#[label(label_trait_item)]
|
||||
pub(crate) trait_item_span: Span,
|
||||
pub(crate) trait_path: String,
|
||||
pub(crate) code: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_invalid_asm_sym)]
|
||||
#[help]
|
||||
pub(crate) struct InvalidAsmSym {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_trait_impl_duplicate, code = "E0201")]
|
||||
pub(crate) struct TraitImplDuplicate {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
#[label(old_span_label)]
|
||||
pub(crate) old_span: Span,
|
||||
#[label(trait_item_span)]
|
||||
pub(crate) trait_item_span: Span,
|
||||
pub(crate) name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_relative_2018)]
|
||||
pub(crate) struct Relative2018 {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[suggestion(code = "crate::{path_str}", applicability = "maybe-incorrect")]
|
||||
pub(crate) path_span: Span,
|
||||
pub(crate) path_str: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_ancestor_only, code = "E0742")]
|
||||
pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_expected_found, code = "E0577")]
|
||||
pub(crate) struct ExpectedFound {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) res: Res,
|
||||
pub(crate) path_str: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_indeterminate, code = "E0578")]
|
||||
pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_module_only)]
|
||||
pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span);
|
@ -16,7 +16,7 @@ use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_errors::DiagnosticId;
|
||||
use rustc_errors::{DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg};
|
||||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
@ -31,6 +31,7 @@ use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use rustc_span::source_map::{respan, Spanned};
|
||||
use std::assert_matches::debug_assert_matches;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{hash_map::Entry, BTreeSet};
|
||||
use std::mem::{replace, swap, take};
|
||||
|
||||
@ -78,6 +79,12 @@ impl PatternSource {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for PatternSource {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Denotes whether the context for the set of already bound bindings is a `Product`
|
||||
/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
|
||||
/// See those functions for more information.
|
||||
|
@ -73,6 +73,7 @@ mod check_unused;
|
||||
mod def_collector;
|
||||
mod diagnostics;
|
||||
mod effective_visibilities;
|
||||
mod errors;
|
||||
mod ident;
|
||||
mod imports;
|
||||
mod late;
|
||||
|
@ -780,7 +780,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
match (source.kind(), target.kind()) {
|
||||
// Trait+Kx+'a -> Trait+Ky+'b (upcasts).
|
||||
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
|
||||
(&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b))
|
||||
if dyn_a == dyn_b =>
|
||||
{
|
||||
// Upcast coercions permit several things:
|
||||
//
|
||||
// 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
|
||||
@ -841,7 +843,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
// `T` -> `Trait`
|
||||
(_, &ty::Dynamic(..)) => {
|
||||
(_, &ty::Dynamic(_, _, ty::Dyn)) => {
|
||||
candidates.vec.push(BuiltinUnsizeCandidate);
|
||||
}
|
||||
|
||||
|
@ -912,7 +912,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let mut nested = vec![];
|
||||
match (source.kind(), target.kind()) {
|
||||
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
|
||||
(&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => {
|
||||
(&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
|
||||
if dyn_a == dyn_b =>
|
||||
{
|
||||
// See `assemble_candidates_for_unsizing` for more info.
|
||||
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
|
||||
let iter = data_a
|
||||
@ -931,7 +933,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.map(ty::Binder::dummy),
|
||||
);
|
||||
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
|
||||
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn);
|
||||
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
|
||||
|
||||
// Require that the traits involved in this upcast are **equal**;
|
||||
// only the **lifetime bound** is changed.
|
||||
@ -1140,7 +1142,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}));
|
||||
}
|
||||
|
||||
_ => bug!(),
|
||||
_ => bug!("source: {source}, target: {target}"),
|
||||
};
|
||||
|
||||
Ok(ImplSourceBuiltinData { nested })
|
||||
|
@ -149,7 +149,11 @@ impl From<libc::timespec> for Timespec {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", any(not(target_arch = "aarch64"), miri)),
|
||||
target_os = "ios",
|
||||
target_os = "watchos"
|
||||
))]
|
||||
mod inner {
|
||||
use crate::sync::atomic::{AtomicU64, Ordering};
|
||||
use crate::sys::cvt;
|
||||
@ -265,7 +269,11 @@ mod inner {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
|
||||
#[cfg(not(any(
|
||||
all(target_os = "macos", any(not(target_arch = "aarch64"), miri)),
|
||||
target_os = "ios",
|
||||
target_os = "watchos"
|
||||
)))]
|
||||
mod inner {
|
||||
use crate::fmt;
|
||||
use crate::mem::MaybeUninit;
|
||||
@ -281,7 +289,11 @@ mod inner {
|
||||
|
||||
impl Instant {
|
||||
pub fn now() -> Instant {
|
||||
Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
|
||||
#[cfg(target_os = "macos")]
|
||||
const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
|
||||
Instant { t: Timespec::now(clock_id) }
|
||||
}
|
||||
|
||||
pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
|
||||
@ -312,13 +324,8 @@ mod inner {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon")))]
|
||||
pub type clock_t = libc::c_int;
|
||||
#[cfg(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon"))]
|
||||
pub type clock_t = libc::c_ulong;
|
||||
|
||||
impl Timespec {
|
||||
pub fn now(clock: clock_t) -> Timespec {
|
||||
pub fn now(clock: libc::clockid_t) -> Timespec {
|
||||
// Try to use 64-bit time in preparation for Y2038.
|
||||
#[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))]
|
||||
{
|
||||
|
@ -88,6 +88,14 @@ fn instant_math_is_associative() {
|
||||
// Changing the order of instant math shouldn't change the results,
|
||||
// especially when the expression reduces to X + identity.
|
||||
assert_eq!((now + offset) - now, (now - now) + offset);
|
||||
|
||||
// On any platform, `Instant` should have the same resolution as `Duration` (e.g. 1 nanosecond)
|
||||
// or better. Otherwise, math will be non-associative (see #91417).
|
||||
let now = Instant::now();
|
||||
let provided_offset = Duration::from_nanos(1);
|
||||
let later = now + provided_offset;
|
||||
let measured_offset = later - now;
|
||||
assert_eq!(measured_offset, provided_offset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -384,8 +384,7 @@ img {
|
||||
|
||||
.sidebar {
|
||||
font-size: 0.875rem;
|
||||
width: 200px;
|
||||
min-width: 200px;
|
||||
flex: 0 0 200px;
|
||||
overflow-y: scroll;
|
||||
position: sticky;
|
||||
height: 100vh;
|
||||
@ -394,12 +393,7 @@ img {
|
||||
}
|
||||
|
||||
.rustdoc.source .sidebar {
|
||||
width: 50px;
|
||||
min-width: 0px;
|
||||
max-width: 300px;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: auto;
|
||||
flex-basis: 50px;
|
||||
border-right: 1px solid;
|
||||
overflow-x: hidden;
|
||||
/* The sidebar is by default hidden */
|
||||
@ -420,7 +414,7 @@ img {
|
||||
|
||||
.source-sidebar-expanded .source .sidebar {
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
flex-basis: 300px;
|
||||
}
|
||||
|
||||
.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
|
||||
@ -1701,6 +1695,7 @@ in storage.js
|
||||
z-index: 11;
|
||||
/* Reduce height slightly to account for mobile topbar. */
|
||||
height: calc(100vh - 45px);
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
/* The source view uses a different design for the sidebar toggle, and doesn't have a topbar,
|
||||
|
@ -29,170 +29,95 @@ assert-local-storage: {"rustdoc-source-sidebar-show": "true"}
|
||||
// Now we check the display of the sidebar items.
|
||||
show-text: true
|
||||
|
||||
// First we start with the light theme.
|
||||
local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
// Waiting for the sidebar to be displayed...
|
||||
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a.selected",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
|
||||
)
|
||||
// Without hover or focus.
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
|
||||
// With focus.
|
||||
focus: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(224, 224, 224)"})
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
|
||||
)
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .folders > details > summary"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(0, 0, 0)", "background-color": "rgb(224, 224, 224)"},
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(
|
||||
theme, color, color_hover, background, background_hover, background_toggle,
|
||||
background_toggle_hover,
|
||||
),
|
||||
[
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
("reload"),
|
||||
("wait-for-css", ("#sidebar-toggle", {"visibility": "visible"})),
|
||||
("assert-css", (
|
||||
"#source-sidebar details[open] > .files a.selected",
|
||||
{"color": |color_hover|, "background-color": |background|},
|
||||
)),
|
||||
// Without hover or focus.
|
||||
("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle|})),
|
||||
// With focus.
|
||||
("focus", "#sidebar-toggle > button"),
|
||||
("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
|
||||
("focus", ".search-input"),
|
||||
// With hover.
|
||||
("move-cursor-to", "#sidebar-toggle > button"),
|
||||
("assert-css", ("#sidebar-toggle > button", {"background-color": |background_toggle_hover|})),
|
||||
// Without hover.
|
||||
("assert-css", (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": |color|, "background-color": |background_toggle|},
|
||||
)),
|
||||
// With focus.
|
||||
("focus", "#source-sidebar details[open] > .files a:not(.selected)"),
|
||||
("wait-for-css", (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
// With hover.
|
||||
("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"),
|
||||
("assert-css", (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
// Without hover.
|
||||
("assert-css", (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": |color|, "background-color": |background_toggle|},
|
||||
)),
|
||||
// With focus.
|
||||
("focus", "#source-sidebar details[open] > .folders > details > summary"),
|
||||
("wait-for-css", (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
("focus", ".search-input"),
|
||||
// With hover.
|
||||
("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"),
|
||||
("assert-css", (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": |color_hover|, "background-color": |background_hover|},
|
||||
)),
|
||||
],
|
||||
)
|
||||
|
||||
// Now with the dark theme.
|
||||
local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
// Waiting for the sidebar to be displayed...
|
||||
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files > a.selected",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
|
||||
)
|
||||
// Without hover or focus.
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
|
||||
// With focus.
|
||||
focus: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgb(103, 103, 103)"})
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files > a:not(.selected)",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
|
||||
)
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .folders > details > summary"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(221, 221, 221)", "background-color": "rgb(68, 68, 68)"},
|
||||
)
|
||||
|
||||
// And finally with the ayu theme.
|
||||
local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
|
||||
reload:
|
||||
// Waiting for the sidebar to be displayed...
|
||||
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a.selected",
|
||||
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
|
||||
)
|
||||
// Without hover or focus.
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(0, 0, 0, 0)"})
|
||||
// With focus.
|
||||
focus: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#sidebar-toggle > button"
|
||||
assert-css: ("#sidebar-toggle > button", {"background-color": "rgba(70, 70, 70, 0.33)"})
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .files a:not(.selected)",
|
||||
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
|
||||
)
|
||||
// Without hover.
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(197, 197, 197)", "background-color": "rgba(0, 0, 0, 0)"},
|
||||
)
|
||||
// With focus.
|
||||
focus: "#source-sidebar details[open] > .folders > details > summary"
|
||||
wait-for-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
|
||||
)
|
||||
focus: ".search-input"
|
||||
// With hover.
|
||||
move-cursor-to: "#source-sidebar details[open] > .folders > details > summary"
|
||||
assert-css: (
|
||||
"#source-sidebar details[open] > .folders > details > summary",
|
||||
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
|
||||
)
|
||||
call-function: ("check-colors", {
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"color_hover": "rgb(0, 0, 0)",
|
||||
"background": "rgb(255, 255, 255)",
|
||||
"background_hover": "rgb(224, 224, 224)",
|
||||
"background_toggle": "rgba(0, 0, 0, 0)",
|
||||
"background_toggle_hover": "rgb(224, 224, 224)",
|
||||
})
|
||||
call-function: ("check-colors", {
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"color_hover": "rgb(221, 221, 221)",
|
||||
"background": "rgb(51, 51, 51)",
|
||||
"background_hover": "rgb(68, 68, 68)",
|
||||
"background_toggle": "rgba(0, 0, 0, 0)",
|
||||
"background_toggle_hover": "rgb(103, 103, 103)",
|
||||
})
|
||||
call-function: ("check-colors", {
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"color_hover": "rgb(255, 180, 76)",
|
||||
"background": "rgb(20, 25, 31)",
|
||||
"background_hover": "rgb(20, 25, 31)",
|
||||
"background_toggle": "rgba(0, 0, 0, 0)",
|
||||
"background_toggle_hover": "rgba(70, 70, 70, 0.33)",
|
||||
})
|
||||
|
||||
// Now checking on mobile devices.
|
||||
size: (500, 700)
|
||||
|
26
src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
Normal file
26
src/test/ui/dyn-star/dont-unsize-coerce-dyn-star.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(dyn_star)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait AddOne {
|
||||
fn add1(&mut self) -> usize;
|
||||
}
|
||||
|
||||
impl AddOne for usize {
|
||||
fn add1(&mut self) -> usize {
|
||||
*self += 1;
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
fn add_one(i: &mut (dyn* AddOne + '_)) -> usize {
|
||||
i.add1()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut x = 42usize as dyn* AddOne;
|
||||
|
||||
println!("{}", add_one(&mut x));
|
||||
println!("{}", add_one(&mut x));
|
||||
}
|
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
Normal file
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#![feature(dyn_star)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {
|
||||
let i = 42 as &dyn* Debug;
|
||||
//~^ ERROR non-primitive cast: `i32` as `&dyn* Debug`
|
||||
}
|
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
Normal file
9
src/test/ui/dyn-star/unsize-into-ref-dyn-star.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0605]: non-primitive cast: `i32` as `&dyn* Debug`
|
||||
--> $DIR/unsize-into-ref-dyn-star.rs:7:13
|
||||
|
|
||||
LL | let i = 42 as &dyn* Debug;
|
||||
| ^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0605`.
|
59
src/test/ui/parser/issue-103381.fixed
Normal file
59
src/test/ui/parser/issue-103381.fixed
Normal file
@ -0,0 +1,59 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
fn err_some(b: bool, x: Option<u32>) {
|
||||
if b && let Some(x) = x {}
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_none(b: bool, x: Option<u32>) {
|
||||
if b && let None = x {}
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_bool_1() {
|
||||
if true && true { true } else { false };
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_bool_2() {
|
||||
if true && false { true } else { false };
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn should_ok_1() {
|
||||
if true && if let x = 1 { true } else { true } {}
|
||||
}
|
||||
|
||||
fn should_ok_2() {
|
||||
if true && if let 1 = 1 { true } else { true } {}
|
||||
}
|
||||
|
||||
fn should_ok_3() {
|
||||
if true && if true { true } else { false } {}
|
||||
}
|
||||
|
||||
fn shoule_match_ok() {
|
||||
#[cfg(feature = "full")]
|
||||
{
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
if match a {
|
||||
1 if b == 1 => true,
|
||||
_ => false,
|
||||
} && if a > 1 { true } else { false }
|
||||
{
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn should_ok_in_nested() {
|
||||
if true && if true { true } else { false } { true } else { false };
|
||||
}
|
||||
|
||||
fn main() {}
|
59
src/test/ui/parser/issue-103381.rs
Normal file
59
src/test/ui/parser/issue-103381.rs
Normal file
@ -0,0 +1,59 @@
|
||||
// run-rustfix
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(irrefutable_let_patterns)]
|
||||
|
||||
fn err_some(b: bool, x: Option<u32>) {
|
||||
if b && if let Some(x) = x {}
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_none(b: bool, x: Option<u32>) {
|
||||
if b && if let None = x {}
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_bool_1() {
|
||||
if true && if true { true } else { false };
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn err_bool_2() {
|
||||
if true && if false { true } else { false };
|
||||
//~^ ERROR unexpected `if` in the condition expression
|
||||
}
|
||||
|
||||
fn should_ok_1() {
|
||||
if true && if let x = 1 { true } else { true } {}
|
||||
}
|
||||
|
||||
fn should_ok_2() {
|
||||
if true && if let 1 = 1 { true } else { true } {}
|
||||
}
|
||||
|
||||
fn should_ok_3() {
|
||||
if true && if true { true } else { false } {}
|
||||
}
|
||||
|
||||
fn shoule_match_ok() {
|
||||
#[cfg(feature = "full")]
|
||||
{
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
if match a {
|
||||
1 if b == 1 => true,
|
||||
_ => false,
|
||||
} && if a > 1 { true } else { false }
|
||||
{
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn should_ok_in_nested() {
|
||||
if true && if true { true } else { false } { true } else { false };
|
||||
}
|
||||
|
||||
fn main() {}
|
50
src/test/ui/parser/issue-103381.stderr
Normal file
50
src/test/ui/parser/issue-103381.stderr
Normal file
@ -0,0 +1,50 @@
|
||||
error: unexpected `if` in the condition expression
|
||||
--> $DIR/issue-103381.rs:9:12
|
||||
|
|
||||
LL | if b && if let Some(x) = x {}
|
||||
| ^^^^
|
||||
|
|
||||
help: remove the `if`
|
||||
|
|
||||
LL - if b && if let Some(x) = x {}
|
||||
LL + if b && let Some(x) = x {}
|
||||
|
|
||||
|
||||
error: unexpected `if` in the condition expression
|
||||
--> $DIR/issue-103381.rs:14:12
|
||||
|
|
||||
LL | if b && if let None = x {}
|
||||
| ^^^^
|
||||
|
|
||||
help: remove the `if`
|
||||
|
|
||||
LL - if b && if let None = x {}
|
||||
LL + if b && let None = x {}
|
||||
|
|
||||
|
||||
error: unexpected `if` in the condition expression
|
||||
--> $DIR/issue-103381.rs:19:15
|
||||
|
|
||||
LL | if true && if true { true } else { false };
|
||||
| ^^^^
|
||||
|
|
||||
help: remove the `if`
|
||||
|
|
||||
LL - if true && if true { true } else { false };
|
||||
LL + if true && true { true } else { false };
|
||||
|
|
||||
|
||||
error: unexpected `if` in the condition expression
|
||||
--> $DIR/issue-103381.rs:24:15
|
||||
|
|
||||
LL | if true && if false { true } else { false };
|
||||
| ^^^^
|
||||
|
|
||||
help: remove the `if`
|
||||
|
|
||||
LL - if true && if false { true } else { false };
|
||||
LL + if true && false { true } else { false };
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
@ -79,22 +79,22 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
|
||||
SimplifiedTypeGen::StrSimplifiedType,
|
||||
]
|
||||
.iter()
|
||||
.flat_map(|&ty| cx.tcx.incoherent_impls(ty));
|
||||
for item_def_id in lang_items.items().iter().flatten().chain(incoherent_impls) {
|
||||
let lang_item_path = cx.get_def_path(*item_def_id);
|
||||
.flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
|
||||
for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
|
||||
let lang_item_path = cx.get_def_path(item_def_id);
|
||||
if path_syms.starts_with(&lang_item_path) {
|
||||
if let [item] = &path_syms[lang_item_path.len()..] {
|
||||
if matches!(
|
||||
cx.tcx.def_kind(*item_def_id),
|
||||
cx.tcx.def_kind(item_def_id),
|
||||
DefKind::Mod | DefKind::Enum | DefKind::Trait
|
||||
) {
|
||||
for child in cx.tcx.module_children(*item_def_id) {
|
||||
for child in cx.tcx.module_children(item_def_id) {
|
||||
if child.ident.name == *item {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for child in cx.tcx.associated_item_def_ids(*item_def_id) {
|
||||
for child in cx.tcx.associated_item_def_ids(item_def_id) {
|
||||
if cx.tcx.item_name(*child) == *item {
|
||||
return true;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use rustc_ast::ast::LitKind;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Namespace, Res};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -91,7 +91,7 @@ impl UnnecessaryDefPath {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn check_call(&mut self, cx: &LateContext<'_>, func: &Expr<'_>, args: &[Expr<'_>], span: Span) {
|
||||
enum Item {
|
||||
LangItem(Symbol),
|
||||
LangItem(&'static str),
|
||||
DiagnosticItem(Symbol),
|
||||
}
|
||||
static PATHS: &[&[&str]] = &[
|
||||
@ -325,18 +325,9 @@ fn inherent_def_path_res(cx: &LateContext<'_>, segments: &[&str]) -> Option<DefI
|
||||
})
|
||||
}
|
||||
|
||||
fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<Symbol> {
|
||||
if let Some(lang_item) = cx.tcx.lang_items().items().iter().position(|id| *id == Some(def_id)) {
|
||||
let lang_items = def_path_res(cx, &["rustc_hir", "lang_items", "LangItem"], Some(Namespace::TypeNS)).def_id();
|
||||
let item_name = cx
|
||||
.tcx
|
||||
.adt_def(lang_items)
|
||||
.variants()
|
||||
.iter()
|
||||
.nth(lang_item)
|
||||
.unwrap()
|
||||
.name;
|
||||
Some(item_name)
|
||||
fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
|
||||
if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {
|
||||
Some(lang_item.variant_name())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -48,14 +48,14 @@ fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
|
||||
let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
|
||||
let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
|
||||
|
||||
let _ = cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did);
|
||||
let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
|
||||
let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
|
||||
let _ = cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did);
|
||||
let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
|
||||
|
||||
let _ = is_trait_method(cx, expr, sym::AsRef);
|
||||
|
||||
let _ = is_path_diagnostic_item(cx, expr, sym::Option);
|
||||
let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id));
|
||||
let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
|
||||
let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ error: use of a def path to a `LangItem`
|
||||
--> $DIR/unnecessary_def_path.rs:51:13
|
||||
|
|
||||
LL | let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OwnedBox).ok() == Some(did)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
|
||||
|
||||
error: use of a def path to a diagnostic item
|
||||
--> $DIR/unnecessary_def_path.rs:52:13
|
||||
@ -69,7 +69,7 @@ error: use of a def path to a `LangItem`
|
||||
--> $DIR/unnecessary_def_path.rs:53:13
|
||||
|
|
||||
LL | let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().require(LangItem::OptionSome).ok() == Some(did)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
|
||||
|
|
||||
= help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
|
||||
|
||||
@ -89,7 +89,7 @@ error: use of a def path to a `LangItem`
|
||||
--> $DIR/unnecessary_def_path.rs:58:13
|
||||
|
|
||||
LL | let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().require(LangItem::IteratorNext).ok() == Some(id))`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
|
||||
|
||||
error: use of a def path to a `LangItem`
|
||||
--> $DIR/unnecessary_def_path.rs:59:13
|
||||
|
@ -1,10 +1,10 @@
|
||||
error: hardcoded path to a language item
|
||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
||||
error: hardcoded path to a diagnostic item
|
||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
||||
|
|
||||
LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: convert all references to use `LangItem::DerefMut`
|
||||
= help: convert all references to use `sym::Deref`
|
||||
= note: `-D clippy::unnecessary-def-path` implied by `-D warnings`
|
||||
|
||||
error: hardcoded path to a diagnostic item
|
||||
@ -15,13 +15,13 @@ LL | const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref",
|
||||
|
|
||||
= help: convert all references to use `sym::deref_method`
|
||||
|
||||
error: hardcoded path to a diagnostic item
|
||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:10:36
|
||||
error: hardcoded path to a language item
|
||||
--> $DIR/unnecessary_def_path_hardcoded_path.rs:11:40
|
||||
|
|
||||
LL | const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: convert all references to use `sym::Deref`
|
||||
= help: convert all references to use `LangItem::DerefMut`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user