Skip to content

Commit

Permalink
Clean up AstConv
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Mar 15, 2024
1 parent e61dcc7 commit 5beda81
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 208 deletions.
114 changes: 113 additions & 1 deletion compiler/rustc_hir_analysis/src/astconv/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol, DUMMY_SP};
use rustc_trait_selection::traits::object_safety_violations_for_assoc_item;

impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
impl<'tcx> dyn AstConv<'tcx> + '_ {
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
/// the type parameter's name as a placeholder.
pub(crate) fn complain_about_missing_type_params(
Expand Down Expand Up @@ -349,6 +349,118 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
})
}

pub(super) fn report_ambiguous_associated_type(
&self,
span: Span,
types: &[String],
traits: &[String],
name: Symbol,
) -> ErrorGuaranteed {
let mut err =
struct_span_code_err!(self.tcx().dcx(), span, E0223, "ambiguous associated type");
if self
.tcx()
.resolutions(())
.confused_type_with_std_module
.keys()
.any(|full_span| full_span.contains(span))
{
err.span_suggestion_verbose(
span.shrink_to_lo(),
"you are looking for the module in `std`, not the primitive type",
"std::",
Applicability::MachineApplicable,
);
} else {
let mut types = types.to_vec();
types.sort();
let mut traits = traits.to_vec();
traits.sort();
match (&types[..], &traits[..]) {
([], []) => {
err.span_suggestion_verbose(
span,
format!(
"if there were a type named `Type` that implements a trait named \
`Trait` with associated type `{name}`, you could use the \
fully-qualified path",
),
format!("<Type as Trait>::{name}"),
Applicability::HasPlaceholders,
);
}
([], [trait_str]) => {
err.span_suggestion_verbose(
span,
format!(
"if there were a type named `Example` that implemented `{trait_str}`, \
you could use the fully-qualified path",
),
format!("<Example as {trait_str}>::{name}"),
Applicability::HasPlaceholders,
);
}
([], traits) => {
err.span_suggestions(
span,
format!(
"if there were a type named `Example` that implemented one of the \
traits with associated type `{name}`, you could use the \
fully-qualified path",
),
traits
.iter()
.map(|trait_str| format!("<Example as {trait_str}>::{name}"))
.collect::<Vec<_>>(),
Applicability::HasPlaceholders,
);
}
([type_str], []) => {
err.span_suggestion_verbose(
span,
format!(
"if there were a trait named `Example` with associated type `{name}` \
implemented for `{type_str}`, you could use the fully-qualified path",
),
format!("<{type_str} as Example>::{name}"),
Applicability::HasPlaceholders,
);
}
(types, []) => {
err.span_suggestions(
span,
format!(
"if there were a trait named `Example` with associated type `{name}` \
implemented for one of the types, you could use the fully-qualified \
path",
),
types
.into_iter()
.map(|type_str| format!("<{type_str} as Example>::{name}")),
Applicability::HasPlaceholders,
);
}
(types, traits) => {
let mut suggestions = vec![];
for type_str in types {
for trait_str in traits {
suggestions.push(format!("<{type_str} as {trait_str}>::{name}"));
}
}
err.span_suggestions(
span,
"use fully-qualified syntax",
suggestions,
Applicability::MachineApplicable,
);
}
}
}
let reported = err.emit();
self.set_tainted_by_errors(reported);
reported
}

pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
&self,
name: Ident,
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,15 +409,12 @@ pub fn check_generic_arg_count_for_call(
seg: &hir::PathSegment<'_>,
is_method_call: IsMethodCall,
) -> GenericArgCountResult {
let empty_args = hir::GenericArgs::none();
let gen_args = seg.args.unwrap_or(&empty_args);
let gen_pos = match is_method_call {
IsMethodCall::Yes => GenericArgPosition::MethodCall,
IsMethodCall::No => GenericArgPosition::Value,
};
let has_self = generics.parent.is_none() && generics.has_self;

check_generic_arg_count(tcx, def_id, seg, generics, gen_args, gen_pos, has_self, seg.infer_args)
check_generic_arg_count(tcx, def_id, seg, generics, gen_pos, has_self)
}

/// Checks that the correct number of generic arguments have been provided.
Expand All @@ -428,11 +425,10 @@ pub(crate) fn check_generic_arg_count(
def_id: DefId,
seg: &hir::PathSegment<'_>,
gen_params: &ty::Generics,
gen_args: &hir::GenericArgs<'_>,
gen_pos: GenericArgPosition,
has_self: bool,
infer_args: bool,
) -> GenericArgCountResult {
let gen_args = seg.args();
let default_counts = gen_params.own_defaults();
let param_counts = gen_params.own_counts();

Expand All @@ -453,7 +449,7 @@ pub(crate) fn check_generic_arg_count(
.count();
let named_const_param_count = param_counts.consts - synth_const_param_count;
let infer_lifetimes =
(gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
(gen_pos != GenericArgPosition::Type || seg.infer_args) && !gen_args.has_lifetime_params();

if gen_pos != GenericArgPosition::Type
&& let Some(b) = gen_args.bindings.first()
Expand Down Expand Up @@ -586,7 +582,7 @@ pub(crate) fn check_generic_arg_count(
};

let args_correct = {
let expected_min = if infer_args {
let expected_min = if seg.infer_args {
0
} else {
param_counts.consts + named_type_param_count
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamNa

use super::AstConv;

impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
impl<'tcx> dyn AstConv<'tcx> + '_ {
/// Make sure that we are in the condition to suggest the blanket implementation.
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
&self,
Expand Down
Loading

0 comments on commit 5beda81

Please sign in to comment.