}
fn report_with_use_injections(&mut self, krate: &Crate) {
- for UseError { mut err, candidates, def_id, instead, suggestion } in
+ for UseError { mut err, candidates, def_id, instead, suggestion, path } in
self.use_injections.drain(..)
{
let (span, found_use) = if let Some(def_id) = def_id.as_local() {
if instead { Instead::Yes } else { Instead::No },
found_use,
IsPattern::No,
+ path,
);
} else if let Some((span, msg, sugg, appl)) = suggestion {
err.span_suggestion(span, msg, sugg, appl);
crate fn lint_if_path_starts_with_module(
&mut self,
- finalize: Finalize,
+ finalize: Option<Finalize>,
path: &[Segment],
second_binding: Option<&NameBinding<'_>>,
) {
- let (diag_id, diag_span) = match finalize {
- Finalize::No => return,
- Finalize::SimplePath(id, path_span) => (id, path_span),
- Finalize::UsePath { root_id, root_span, .. } => (root_id, root_span),
- Finalize::QPathTrait { qpath_id, qpath_span, .. } => (qpath_id, qpath_span),
+ let Some(Finalize { node_id, root_span, .. }) = finalize else {
+ return;
};
let first_name = match path.get(0) {
}
}
- let diag = BuiltinLintDiagnostics::AbsPathWithModule(diag_span);
+ let diag = BuiltinLintDiagnostics::AbsPathWithModule(root_span);
self.lint_buffer.buffer_lint_with_diagnostic(
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
- diag_id,
- diag_span,
+ node_id,
+ root_span,
"absolute paths must start with `self`, `super`, \
`crate`, or an external crate name in the 2018 edition",
diag,
Instead::No,
FoundUse::Yes,
IsPattern::Yes,
+ vec![],
);
}
err
segms.push(ast::PathSegment::from_ident(ident));
let path = Path { span: name_binding.span, segments: segms, tokens: None };
let did = match res {
- Res::Def(DefKind::Ctor(..), did) => this.parent(did),
+ Res::Def(DefKind::Ctor(..), did) => this.opt_parent(did),
_ => res.opt_def_id(),
};
Instead::No,
FoundUse::Yes,
IsPattern::No,
+ vec![],
);
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
&parent_scope,
None,
false,
- false,
None,
) {
let desc = match binding.res() {
_,
) = binding.kind
{
- let def_id = self.parent(ctor_def_id).expect("no parent for a constructor");
+ let def_id = self.parent(ctor_def_id);
let fields = self.field_names.get(&def_id)?;
return fields.iter().map(|name| name.span).reduce(Span::to); // None for `struct Foo()`
}
opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>,
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
- unusable_binding: Option<&'a NameBinding<'a>>,
+ ignore_binding: Option<&'a NameBinding<'a>>,
module: Option<ModuleOrUniformRoot<'a>>,
i: usize,
ident: Ident,
ns_to_try,
parent_scope,
None,
- false,
- unusable_binding,
+ ignore_binding,
).ok()
} else if let Some(ribs) = ribs
&& let Some(TypeNS | ValueNS) = opt_ns
ident,
ns_to_try,
parent_scope,
- Finalize::No,
+ None,
&ribs[ns_to_try],
- unusable_binding,
+ ignore_binding,
) {
// we found a locally-imported or available item/module
Some(LexicalScopeBinding::Item(binding)) => Some(binding),
parent_scope,
None,
false,
- false,
- unusable_binding,
+ ignore_binding,
).ok()
};
if let Some(binding) = binding {
ident,
ValueNS,
parent_scope,
- Finalize::No,
+ None,
&ribs[ValueNS],
- unusable_binding,
+ ignore_binding,
)
} else {
None
instead: Instead,
found_use: FoundUse,
is_pattern: IsPattern,
+ path: Vec<Segment>,
) {
if candidates.is_empty() {
return;
accessible_path_strings.into_iter().map(|a| a.0),
Applicability::MaybeIncorrect,
);
+ if let [first, .., last] = &path[..] {
+ err.span_suggestion_verbose(
+ first.ident.span.until(last.ident.span),
+ &format!("if you import `{}`, refer to it directly", last.ident),
+ String::new(),
+ Applicability::Unspecified,
+ );
+ }
} else {
msg.push(':');