When writing `Vec<A:B>`, suggest `Vec<A::B>`.
/// 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> {
}
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 => {
}
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(
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,
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
use std::iter;
+use std::ops::Deref;
use tracing::debug;
}
}
+ 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));
(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],
--- /dev/null
+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
+}
--- /dev/null
+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`.