HIR ty lowering: Refactor the way the projectee ("QSelf") gets passed to diagnostics
This commit is contained in:
parent
ef121f28d8
commit
898448ca58
@ -1,4 +1,4 @@
|
|||||||
hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$ty_param_name}`
|
hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_name}` in bounds of `{$qself}`
|
||||||
.label = ambiguous associated {$assoc_kind} `{$assoc_name}`
|
.label = ambiguous associated {$assoc_kind} `{$assoc_name}`
|
||||||
|
|
||||||
hir_analysis_ambiguous_lifetime_bound =
|
hir_analysis_ambiguous_lifetime_bound =
|
||||||
@ -12,14 +12,14 @@ hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
|
|||||||
.label = private {$kind}
|
.label = private {$kind}
|
||||||
.defined_here_label = the {$kind} is defined here
|
.defined_here_label = the {$kind} is defined here
|
||||||
|
|
||||||
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
|
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$qself}`
|
||||||
|
|
||||||
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
|
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
|
||||||
[true] an
|
[true] an
|
||||||
*[false] a similarly named
|
*[false] a similarly named
|
||||||
} associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
|
} associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
|
||||||
hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
|
hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_name}` not found
|
||||||
hir_analysis_assoc_item_not_found_other_sugg = `{$ty_param_name}` has the following associated {$assoc_kind}
|
hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
|
||||||
hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
|
hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
|
||||||
hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = and also change the associated {$assoc_kind} name
|
hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = and also change the associated {$assoc_kind} name
|
||||||
hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
|
hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
|
||||||
|
@ -22,7 +22,7 @@ pub struct AmbiguousAssocItem<'a> {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub assoc_kind: &'static str,
|
pub assoc_kind: &'static str,
|
||||||
pub assoc_name: Ident,
|
pub assoc_name: Ident,
|
||||||
pub ty_param_name: &'a str,
|
pub qself: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
@ -75,7 +75,7 @@ pub struct AssocItemNotFound<'a> {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub assoc_name: Ident,
|
pub assoc_name: Ident,
|
||||||
pub assoc_kind: &'static str,
|
pub assoc_kind: &'static str,
|
||||||
pub ty_param_name: &'a str,
|
pub qself: &'a str,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub label: Option<AssocItemNotFoundLabel<'a>>,
|
pub label: Option<AssocItemNotFoundLabel<'a>>,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
@ -134,7 +134,7 @@ pub enum AssocItemNotFoundSugg<'a> {
|
|||||||
Other {
|
Other {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
ty_param_name: &'a str,
|
qself: &'a str,
|
||||||
assoc_kind: &'static str,
|
assoc_kind: &'static str,
|
||||||
suggested_name: Symbol,
|
suggested_name: Symbol,
|
||||||
},
|
},
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
|
||||||
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
|
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||||
@ -16,9 +15,8 @@
|
|||||||
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::hir_ty_lowering::{HirTyLowerer, OnlySelfBounds, PredicateFilter};
|
use crate::hir_ty_lowering::HirTyLowerer;
|
||||||
|
use crate::hir_ty_lowering::{AssocItemQSelf, OnlySelfBounds, PredicateFilter, RegionInferReason};
|
||||||
use super::RegionInferReason;
|
|
||||||
|
|
||||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// Add a `Sized` bound to the `bounds` if appropriate.
|
/// Add a `Sized` bound to the `bounds` if appropriate.
|
||||||
@ -288,8 +286,7 @@ pub(super) fn lower_assoc_item_constraint(
|
|||||||
// one that does define it.
|
// one that does define it.
|
||||||
self.probe_single_bound_for_assoc_item(
|
self.probe_single_bound_for_assoc_item(
|
||||||
|| traits::supertraits(tcx, trait_ref),
|
|| traits::supertraits(tcx, trait_ref),
|
||||||
trait_ref.skip_binder().print_only_trait_name(),
|
AssocItemQSelf::Trait(trait_ref.def_id()),
|
||||||
None,
|
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
constraint.ident,
|
constraint.ident,
|
||||||
path_span,
|
path_span,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
|
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
|
||||||
};
|
};
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
use crate::hir_ty_lowering::HirTyLowerer;
|
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
|
||||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||||
use rustc_data_structures::sorted_map::SortedMap;
|
use rustc_data_structures::sorted_map::SortedMap;
|
||||||
use rustc_data_structures::unord::UnordMap;
|
use rustc_data_structures::unord::UnordMap;
|
||||||
@ -11,9 +11,9 @@
|
|||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
|
codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed,
|
||||||
};
|
};
|
||||||
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{self as hir, Node};
|
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Key;
|
use rustc_middle::query::Key;
|
||||||
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
|
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
|
||||||
@ -116,8 +116,7 @@ pub(crate) fn complain_about_internal_fn_trait(
|
|||||||
pub(super) fn complain_about_assoc_item_not_found<I>(
|
pub(super) fn complain_about_assoc_item_not_found<I>(
|
||||||
&self,
|
&self,
|
||||||
all_candidates: impl Fn() -> I,
|
all_candidates: impl Fn() -> I,
|
||||||
ty_param_name: &str,
|
qself: AssocItemQSelf,
|
||||||
ty_param_def_id: Option<LocalDefId>,
|
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -139,7 +138,8 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let assoc_kind_str = super::assoc_kind_str(assoc_kind);
|
let assoc_kind_str = assoc_kind_str(assoc_kind);
|
||||||
|
let qself_str = qself.to_string(tcx);
|
||||||
|
|
||||||
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
|
// The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a
|
||||||
// valid span, so we point at the whole path segment instead.
|
// valid span, so we point at the whole path segment instead.
|
||||||
@ -149,7 +149,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
|
|||||||
span: if is_dummy { span } else { assoc_name.span },
|
span: if is_dummy { span } else { assoc_name.span },
|
||||||
assoc_name,
|
assoc_name,
|
||||||
assoc_kind: assoc_kind_str,
|
assoc_kind: assoc_kind_str,
|
||||||
ty_param_name,
|
qself: &qself_str,
|
||||||
label: None,
|
label: None,
|
||||||
sugg: None,
|
sugg: None,
|
||||||
};
|
};
|
||||||
@ -219,19 +219,28 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
|
|||||||
suggested_name,
|
suggested_name,
|
||||||
identically_named: suggested_name == assoc_name.name,
|
identically_named: suggested_name == assoc_name.name,
|
||||||
});
|
});
|
||||||
let hir = tcx.hir();
|
if let AssocItemQSelf::TyParam(ty_param_def_id) = qself
|
||||||
if let Some(def_id) = ty_param_def_id
|
// Not using `self.item_def_id()` here as that would yield the opaque type itself if we're
|
||||||
&& let parent = hir.get_parent_item(tcx.local_def_id_to_hir_id(def_id))
|
// inside an opaque type while we're interested in the overarching type alias (TAIT).
|
||||||
&& let Some(generics) = hir.get_generics(parent.def_id)
|
// FIXME: However, for trait aliases, this incorrectly returns the enclosing module...
|
||||||
|
&& let item_def_id =
|
||||||
|
tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id))
|
||||||
|
// FIXME: ...which obviously won't have any generics.
|
||||||
|
&& let Some(generics) = tcx.hir().get_generics(item_def_id.def_id)
|
||||||
{
|
{
|
||||||
if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
|
// FIXME: Suggest adding supertrait bounds if we have a `Self` type param.
|
||||||
|b| match b {
|
// FIXME(trait_alias): Suggest adding `Self: Trait` to
|
||||||
|
// `trait Alias = where Self::Proj:;` with `trait Trait { type Proj; }`.
|
||||||
|
if generics
|
||||||
|
.bounds_for_param(ty_param_def_id)
|
||||||
|
.flat_map(|pred| pred.bounds.iter())
|
||||||
|
.any(|b| match b {
|
||||||
hir::GenericBound::Trait(t, ..) => {
|
hir::GenericBound::Trait(t, ..) => {
|
||||||
t.trait_ref.trait_def_id() == Some(best_trait)
|
t.trait_ref.trait_def_id() == Some(best_trait)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
})
|
||||||
) {
|
{
|
||||||
// The type param already has a bound for `trait_name`, we just need to
|
// The type param already has a bound for `trait_name`, we just need to
|
||||||
// change the associated item.
|
// change the associated item.
|
||||||
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
|
err.sugg = Some(errors::AssocItemNotFoundSugg::SimilarInOtherTrait {
|
||||||
@ -247,7 +256,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
|
|||||||
tcx,
|
tcx,
|
||||||
generics,
|
generics,
|
||||||
&mut err,
|
&mut err,
|
||||||
&ty_param_name,
|
&qself_str,
|
||||||
&trait_name,
|
&trait_name,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -273,7 +282,7 @@ pub(super) fn complain_about_assoc_item_not_found<I>(
|
|||||||
if let [candidate_name] = all_candidate_names.as_slice() {
|
if let [candidate_name] = all_candidate_names.as_slice() {
|
||||||
err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
|
err.sugg = Some(errors::AssocItemNotFoundSugg::Other {
|
||||||
span: assoc_name.span,
|
span: assoc_name.span,
|
||||||
ty_param_name,
|
qself: &qself_str,
|
||||||
assoc_kind: assoc_kind_str,
|
assoc_kind: assoc_kind_str,
|
||||||
suggested_name: *candidate_name,
|
suggested_name: *candidate_name,
|
||||||
});
|
});
|
||||||
@ -339,10 +348,10 @@ fn complain_about_assoc_kind_mismatch(
|
|||||||
|
|
||||||
self.dcx().emit_err(errors::AssocKindMismatch {
|
self.dcx().emit_err(errors::AssocKindMismatch {
|
||||||
span,
|
span,
|
||||||
expected: super::assoc_kind_str(expected),
|
expected: assoc_kind_str(expected),
|
||||||
got: super::assoc_kind_str(got),
|
got: assoc_kind_str(got),
|
||||||
expected_because_label,
|
expected_because_label,
|
||||||
assoc_kind: super::assoc_kind_str(assoc_item.kind),
|
assoc_kind: assoc_kind_str(assoc_item.kind),
|
||||||
def_span: tcx.def_span(assoc_item.def_id),
|
def_span: tcx.def_span(assoc_item.def_id),
|
||||||
bound_on_assoc_const_label,
|
bound_on_assoc_const_label,
|
||||||
wrap_in_braces_sugg,
|
wrap_in_braces_sugg,
|
||||||
@ -736,7 +745,7 @@ pub(crate) fn complain_about_missing_assoc_tys(
|
|||||||
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
|
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
|
||||||
let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
|
let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id));
|
||||||
in_expr_or_pat = match grandparent {
|
in_expr_or_pat = match grandparent {
|
||||||
Node::Expr(_) | Node::Pat(_) => true,
|
hir::Node::Expr(_) | hir::Node::Pat(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
match bound.trait_ref.path.segments {
|
match bound.trait_ref.path.segments {
|
||||||
@ -1602,3 +1611,11 @@ fn generics_args_err_extend<'a>(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
|
||||||
|
match kind {
|
||||||
|
ty::AssocKind::Fn => "function",
|
||||||
|
ty::AssocKind::Const => "constant",
|
||||||
|
ty::AssocKind::Type => "type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
use rustc_trait_selection::traits::wf::object_region_bounds;
|
use rustc_trait_selection::traits::wf::object_region_bounds;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
/// A path segment that is semantically allowed to have generic arguments.
|
/// A path segment that is semantically allowed to have generic arguments.
|
||||||
@ -193,6 +192,25 @@ fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The "qualified self" of an associated item path.
|
||||||
|
///
|
||||||
|
/// For diagnostic purposes only.
|
||||||
|
enum AssocItemQSelf {
|
||||||
|
Trait(DefId),
|
||||||
|
TyParam(LocalDefId),
|
||||||
|
SelfTyAlias,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AssocItemQSelf {
|
||||||
|
fn to_string(&self, tcx: TyCtxt<'_>) -> String {
|
||||||
|
match *self {
|
||||||
|
Self::Trait(def_id) => tcx.def_path_str(def_id),
|
||||||
|
Self::TyParam(def_id) => tcx.hir().ty_param_name(def_id).to_string(),
|
||||||
|
Self::SelfTyAlias => kw::SelfUpper.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// New-typed boolean indicating whether explicit late-bound lifetimes
|
/// New-typed boolean indicating whether explicit late-bound lifetimes
|
||||||
/// are present in a set of generic arguments.
|
/// are present in a set of generic arguments.
|
||||||
///
|
///
|
||||||
@ -811,19 +829,14 @@ fn probe_single_ty_param_bound_for_assoc_ty(
|
|||||||
let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
|
let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_name).predicates;
|
||||||
debug!("predicates={:#?}", predicates);
|
debug!("predicates={:#?}", predicates);
|
||||||
|
|
||||||
let param_name = tcx.hir().ty_param_name(ty_param_def_id);
|
|
||||||
self.probe_single_bound_for_assoc_item(
|
self.probe_single_bound_for_assoc_item(
|
||||||
|| {
|
|| {
|
||||||
traits::transitive_bounds_that_define_assoc_item(
|
let trait_refs = predicates
|
||||||
tcx,
|
.iter()
|
||||||
predicates
|
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
|
||||||
.iter()
|
traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_name)
|
||||||
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
|
|
||||||
assoc_name,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
param_name,
|
AssocItemQSelf::TyParam(ty_param_def_id),
|
||||||
Some(ty_param_def_id),
|
|
||||||
ty::AssocKind::Type,
|
ty::AssocKind::Type,
|
||||||
assoc_name,
|
assoc_name,
|
||||||
span,
|
span,
|
||||||
@ -835,12 +848,11 @@ fn probe_single_ty_param_bound_for_assoc_ty(
|
|||||||
///
|
///
|
||||||
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
||||||
/// candidates in which case it reports ambiguity.
|
/// candidates in which case it reports ambiguity.
|
||||||
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]
|
#[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
|
||||||
fn probe_single_bound_for_assoc_item<I>(
|
fn probe_single_bound_for_assoc_item<I>(
|
||||||
&self,
|
&self,
|
||||||
all_candidates: impl Fn() -> I,
|
all_candidates: impl Fn() -> I,
|
||||||
ty_param_name: impl Display,
|
qself: AssocItemQSelf,
|
||||||
ty_param_def_id: Option<LocalDefId>,
|
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -858,8 +870,7 @@ fn probe_single_bound_for_assoc_item<I>(
|
|||||||
let Some(bound) = matching_candidates.next() else {
|
let Some(bound) = matching_candidates.next() else {
|
||||||
let reported = self.complain_about_assoc_item_not_found(
|
let reported = self.complain_about_assoc_item_not_found(
|
||||||
all_candidates,
|
all_candidates,
|
||||||
&ty_param_name.to_string(),
|
qself,
|
||||||
ty_param_def_id,
|
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
assoc_name,
|
assoc_name,
|
||||||
span,
|
span,
|
||||||
@ -872,13 +883,13 @@ fn probe_single_bound_for_assoc_item<I>(
|
|||||||
if let Some(bound2) = matching_candidates.next() {
|
if let Some(bound2) = matching_candidates.next() {
|
||||||
debug!(?bound2);
|
debug!(?bound2);
|
||||||
|
|
||||||
let assoc_kind_str = assoc_kind_str(assoc_kind);
|
let assoc_kind_str = errors::assoc_kind_str(assoc_kind);
|
||||||
let ty_param_name = &ty_param_name.to_string();
|
let qself_str = qself.to_string(tcx);
|
||||||
let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
|
let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
|
||||||
span,
|
span,
|
||||||
assoc_kind: assoc_kind_str,
|
assoc_kind: assoc_kind_str,
|
||||||
assoc_name,
|
assoc_name,
|
||||||
ty_param_name,
|
qself: &qself_str,
|
||||||
});
|
});
|
||||||
// Provide a more specific error code index entry for equality bindings.
|
// Provide a more specific error code index entry for equality bindings.
|
||||||
err.code(
|
err.code(
|
||||||
@ -929,7 +940,7 @@ trait = bound.print_only_trait_path(),
|
|||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span.with_hi(assoc_name.span.lo()),
|
span.with_hi(assoc_name.span.lo()),
|
||||||
"use fully-qualified syntax to disambiguate",
|
"use fully-qualified syntax to disambiguate",
|
||||||
format!("<{ty_param_name} as {}>::", bound.print_only_trait_path()),
|
format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -943,7 +954,7 @@ trait = bound.print_only_trait_path(),
|
|||||||
if !where_bounds.is_empty() {
|
if !where_bounds.is_empty() {
|
||||||
err.help(format!(
|
err.help(format!(
|
||||||
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
"consider introducing a new type parameter `T` and adding `where` constraints:\
|
||||||
\n where\n T: {ty_param_name},\n{}",
|
\n where\n T: {qself_str},\n{}",
|
||||||
where_bounds.join(",\n"),
|
where_bounds.join(",\n"),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -997,11 +1008,6 @@ pub fn lower_assoc_path(
|
|||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let assoc_ident = assoc_segment.ident;
|
let assoc_ident = assoc_segment.ident;
|
||||||
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
|
|
||||||
path.res
|
|
||||||
} else {
|
|
||||||
Res::Err
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if we have an enum variant or an inherent associated type.
|
// Check if we have an enum variant or an inherent associated type.
|
||||||
let mut variant_resolution = None;
|
let mut variant_resolution = None;
|
||||||
@ -1038,6 +1044,12 @@ pub fn lower_assoc_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
|
||||||
|
path.res
|
||||||
|
} else {
|
||||||
|
Res::Err
|
||||||
|
};
|
||||||
|
|
||||||
// Find the type of the associated item, and the trait where the associated
|
// Find the type of the associated item, and the trait where the associated
|
||||||
// item is declared.
|
// item is declared.
|
||||||
let bound = match (&qself_ty.kind(), qself_res) {
|
let bound = match (&qself_ty.kind(), qself_res) {
|
||||||
@ -1056,8 +1068,7 @@ pub fn lower_assoc_path(
|
|||||||
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
kw::SelfUpper,
|
AssocItemQSelf::SelfTyAlias,
|
||||||
None,
|
|
||||||
ty::AssocKind::Type,
|
ty::AssocKind::Type,
|
||||||
assoc_ident,
|
assoc_ident,
|
||||||
span,
|
span,
|
||||||
@ -2522,11 +2533,3 @@ fn compute_object_lifetime_bound(
|
|||||||
Some(r)
|
Some(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
|
|
||||||
match kind {
|
|
||||||
ty::AssocKind::Fn => "function",
|
|
||||||
ty::AssocKind::Const => "constant",
|
|
||||||
ty::AssocKind::Type => "type",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user