Make ProjectionTy::trait_ref truncate substs again
Also make sure that type arguments of associated types are printed in some error messages.
This commit is contained in:
parent
79f6f11816
commit
dfee89f755
12 changed files with 216 additions and 49 deletions
|
@ -1,5 +1,6 @@
|
|||
use crate::traits::{ObligationCause, ObligationCauseCode};
|
||||
use crate::ty::diagnostics::suggest_constraining_type_param;
|
||||
use crate::ty::print::{FmtPrinter, Printer};
|
||||
use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{pluralize, DiagnosticBuilder};
|
||||
|
@ -400,14 +401,22 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
{
|
||||
// Synthesize the associated type restriction `Add<Output = Expected>`.
|
||||
// FIXME: extract this logic for use in other diagnostics.
|
||||
let trait_ref = proj.trait_ref(self);
|
||||
let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(self);
|
||||
let path =
|
||||
self.def_path_str_with_substs(trait_ref.def_id, trait_ref.substs);
|
||||
let item_name = self.item_name(proj.item_def_id);
|
||||
let item_args = self.format_generic_args(assoc_substs);
|
||||
|
||||
let path = if path.ends_with('>') {
|
||||
format!("{}, {} = {}>", &path[..path.len() - 1], item_name, p)
|
||||
format!(
|
||||
"{}, {}{} = {}>",
|
||||
&path[..path.len() - 1],
|
||||
item_name,
|
||||
item_args,
|
||||
p
|
||||
)
|
||||
} else {
|
||||
format!("{}<{} = {}>", path, item_name, p)
|
||||
format!("{}<{}{} = {}>", path, item_name, item_args, p)
|
||||
};
|
||||
note = !suggest_constraining_type_param(
|
||||
self,
|
||||
|
@ -556,7 +565,7 @@ impl<T> Trait<T> for X {
|
|||
ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let assoc = self.associated_item(proj_ty.item_def_id);
|
||||
let trait_ref = proj_ty.trait_ref(self);
|
||||
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
|
||||
if let Some(item) = self.hir().get_if_local(body_owner_def_id) {
|
||||
if let Some(hir_generics) = item.generics() {
|
||||
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
|
||||
|
@ -590,6 +599,7 @@ impl<T> Trait<T> for X {
|
|||
&trait_ref,
|
||||
pred.bounds,
|
||||
&assoc,
|
||||
assoc_substs,
|
||||
ty,
|
||||
msg,
|
||||
) {
|
||||
|
@ -607,6 +617,7 @@ impl<T> Trait<T> for X {
|
|||
&trait_ref,
|
||||
param.bounds,
|
||||
&assoc,
|
||||
assoc_substs,
|
||||
ty,
|
||||
msg,
|
||||
);
|
||||
|
@ -692,6 +703,7 @@ impl<T> Trait<T> for X {
|
|||
db,
|
||||
self.def_span(def_id),
|
||||
&assoc,
|
||||
proj_ty.trait_ref_and_own_substs(self).1,
|
||||
values.found,
|
||||
&msg,
|
||||
) {
|
||||
|
@ -856,6 +868,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
trait_ref: &ty::TraitRef<'tcx>,
|
||||
bounds: hir::GenericBounds<'_>,
|
||||
assoc: &ty::AssocItem,
|
||||
assoc_substs: &[ty::GenericArg<'tcx>],
|
||||
ty: Ty<'tcx>,
|
||||
msg: &str,
|
||||
) -> bool {
|
||||
|
@ -865,7 +878,12 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
// Relate the type param against `T` in `<A as T>::Foo`.
|
||||
ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id)
|
||||
&& self.constrain_associated_type_structured_suggestion(
|
||||
db, ptr.span, assoc, ty, msg,
|
||||
db,
|
||||
ptr.span,
|
||||
assoc,
|
||||
assoc_substs,
|
||||
ty,
|
||||
msg,
|
||||
)
|
||||
}
|
||||
_ => false,
|
||||
|
@ -879,6 +897,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
db: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
assoc: &ty::AssocItem,
|
||||
assoc_substs: &[ty::GenericArg<'tcx>],
|
||||
ty: Ty<'tcx>,
|
||||
msg: &str,
|
||||
) -> bool {
|
||||
|
@ -890,11 +909,20 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
let span = Span::new(pos, pos, span.ctxt());
|
||||
(span, format!(", {} = {}", assoc.ident, ty))
|
||||
} else {
|
||||
(span.shrink_to_hi(), format!("<{} = {}>", assoc.ident, ty))
|
||||
let item_args = self.format_generic_args(assoc_substs);
|
||||
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident, item_args, ty))
|
||||
};
|
||||
db.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn format_generic_args(self, args: &[ty::GenericArg<'tcx>]) -> String {
|
||||
let mut item_args = String::new();
|
||||
FmtPrinter::new(self, &mut item_args, hir::def::Namespace::TypeNS)
|
||||
.path_generic_args(Ok, args)
|
||||
.expect("could not write to `String`.");
|
||||
item_args
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue