Detect ::
-> :
typo in type argument
When writing `Vec<A:B>`, suggest `Vec<A::B>`.
This commit is contained in:
parent
2681f253bc
commit
b26ad8d10f
4 changed files with 102 additions and 1 deletions
|
@ -400,6 +400,8 @@ struct DiagnosticMetadata<'ast> {
|
|||
|
||||
/// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
|
||||
current_where_predicate: Option<&'ast WherePredicate>,
|
||||
|
||||
current_type_path: Option<&'ast Ty>,
|
||||
}
|
||||
|
||||
struct LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
|
@ -472,8 +474,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
fn visit_ty(&mut self, ty: &'ast Ty) {
|
||||
let prev = self.diagnostic_metadata.current_trait_object;
|
||||
let prev_ty = self.diagnostic_metadata.current_type_path;
|
||||
match ty.kind {
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
self.diagnostic_metadata.current_type_path = Some(ty);
|
||||
self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
|
||||
}
|
||||
TyKind::ImplicitSelf => {
|
||||
|
@ -490,6 +494,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
visit::walk_ty(self, ty);
|
||||
self.diagnostic_metadata.current_trait_object = prev;
|
||||
self.diagnostic_metadata.current_type_path = prev_ty;
|
||||
}
|
||||
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
|
||||
self.smart_resolve_path(
|
||||
|
@ -1936,7 +1941,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
let instead = res.is_some();
|
||||
let suggestion =
|
||||
if res.is_none() { this.report_missing_type_error(path) } else { None };
|
||||
// get_from_node_id
|
||||
|
||||
this.r.use_injections.push(UseError {
|
||||
err,
|
||||
|
|
|
@ -26,6 +26,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
|||
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
|
||||
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -265,6 +266,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
self.detect_assoct_type_constraint_meant_as_path(base_span, &mut err);
|
||||
|
||||
// Emit special messages for unresolved `Self` and `self`.
|
||||
if is_self_type(path, ns) {
|
||||
err.code(rustc_errors::error_code!(E0411));
|
||||
|
@ -603,6 +606,40 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
|||
(err, candidates)
|
||||
}
|
||||
|
||||
fn detect_assoct_type_constraint_meant_as_path(
|
||||
&self,
|
||||
base_span: Span,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
) {
|
||||
let Some(ty) = self.diagnostic_metadata.current_type_path else { return; };
|
||||
let TyKind::Path(_, path) = &ty.kind else { return; };
|
||||
for segment in &path.segments {
|
||||
let Some(params) = &segment.args else { continue; };
|
||||
let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; };
|
||||
for param in ¶ms.args {
|
||||
let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; };
|
||||
let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else {
|
||||
continue;
|
||||
};
|
||||
for bound in bounds {
|
||||
let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)
|
||||
= bound else
|
||||
{
|
||||
continue;
|
||||
};
|
||||
if base_span == trait_ref.span {
|
||||
err.span_suggestion_verbose(
|
||||
constraint.ident.span.between(trait_ref.span),
|
||||
"you might have meant to write a path instead of an associated type bound",
|
||||
"::".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_single_associated_item(
|
||||
&mut self,
|
||||
path: &[Segment],
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
enum A {
|
||||
B,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Vec<A:B> = A::B;
|
||||
//~^ ERROR cannot find trait `B` in this scope
|
||||
//~| HELP you might have meant to write a path instead of an associated type bound
|
||||
//~| ERROR associated type bounds are unstable
|
||||
//~| HELP add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
//~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied
|
||||
//~| HELP add missing generic argument
|
||||
//~| ERROR associated type bindings are not allowed here
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
error[E0405]: cannot find trait `B` in this scope
|
||||
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:18
|
||||
|
|
||||
LL | let _: Vec<A:B> = A::B;
|
||||
| ^ not found in this scope
|
||||
|
|
||||
help: you might have meant to write a path instead of an associated type bound
|
||||
|
|
||||
LL | let _: Vec<A::B> = A::B;
|
||||
| ~~
|
||||
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:16
|
||||
|
|
||||
LL | let _: Vec<A:B> = A::B;
|
||||
| ^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
error[E0107]: this struct takes at least 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:12
|
||||
|
|
||||
LL | let _: Vec<A:B> = A::B;
|
||||
| ^^^ expected at least 1 generic argument
|
||||
|
|
||||
note: struct defined here, with at least 1 generic parameter: `T`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
|
||||
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
|
||||
| ^^^ -
|
||||
help: add missing generic argument
|
||||
|
|
||||
LL | let _: Vec<T, A:B> = A::B;
|
||||
| ++
|
||||
|
||||
error[E0229]: associated type bindings are not allowed here
|
||||
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:16
|
||||
|
|
||||
LL | let _: Vec<A:B> = A::B;
|
||||
| ^^^ associated type not allowed here
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0229, E0405, E0658.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
Loading…
Add table
Reference in a new issue