Substitute missing item suggestion correctly
This commit is contained in:
parent
de96f3d873
commit
204c516293
@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>(
|
|||||||
if !missing_items.is_empty() {
|
if !missing_items.is_empty() {
|
||||||
let full_impl_span =
|
let full_impl_span =
|
||||||
tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
|
tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
|
||||||
missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
|
missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(missing_items) = must_implement_one_of {
|
if let Some(missing_items) = must_implement_one_of {
|
||||||
|
@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
|
|||||||
|
|
||||||
fn missing_items_err(
|
fn missing_items_err(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl_span: Span,
|
impl_def_id: LocalDefId,
|
||||||
missing_items: &[ty::AssocItem],
|
missing_items: &[ty::AssocItem],
|
||||||
full_impl_span: Span,
|
full_impl_span: Span,
|
||||||
) {
|
) {
|
||||||
@ -211,6 +211,7 @@ fn missing_items_err(
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("`, `");
|
.join("`, `");
|
||||||
|
|
||||||
|
let impl_span = tcx.def_span(impl_def_id);
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
impl_span,
|
impl_span,
|
||||||
@ -229,7 +230,11 @@ fn missing_items_err(
|
|||||||
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
|
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
|
||||||
|
|
||||||
for &trait_item in missing_items {
|
for &trait_item in missing_items {
|
||||||
let snippet = suggestion_signature(trait_item, tcx);
|
let snippet = suggestion_signature(
|
||||||
|
tcx,
|
||||||
|
trait_item,
|
||||||
|
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
|
||||||
|
);
|
||||||
let code = format!("{}{}\n{}", padding, snippet, padding);
|
let code = format!("{}{}\n{}", padding, snippet, padding);
|
||||||
let msg = format!("implement the missing item: `{snippet}`");
|
let msg = format!("implement the missing item: `{snippet}`");
|
||||||
let appl = Applicability::HasPlaceholders;
|
let appl = Applicability::HasPlaceholders;
|
||||||
@ -301,11 +306,11 @@ fn default_body_is_unstable(
|
|||||||
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
|
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
|
||||||
fn bounds_from_generic_predicates<'tcx>(
|
fn bounds_from_generic_predicates<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
||||||
) -> (String, String) {
|
) -> (String, String) {
|
||||||
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
|
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
|
||||||
let mut projections = vec![];
|
let mut projections = vec![];
|
||||||
for (predicate, _) in predicates.predicates {
|
for (predicate, _) in predicates {
|
||||||
debug!("predicate {:?}", predicate);
|
debug!("predicate {:?}", predicate);
|
||||||
let bound_predicate = predicate.kind();
|
let bound_predicate = predicate.kind();
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
sig: ty::FnSig<'tcx>,
|
sig: ty::FnSig<'tcx>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
||||||
assoc: ty::AssocItem,
|
assoc: ty::AssocItem,
|
||||||
) -> String {
|
) -> String {
|
||||||
let args = sig
|
let args = sig
|
||||||
@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
|||||||
/// Return placeholder code for the given associated item.
|
/// Return placeholder code for the given associated item.
|
||||||
/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
|
/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
|
||||||
/// structured suggestion.
|
/// structured suggestion.
|
||||||
fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
fn suggestion_signature<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
assoc: ty::AssocItem,
|
||||||
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
|
) -> String {
|
||||||
|
let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
|
||||||
|
tcx,
|
||||||
|
assoc.container_id(tcx),
|
||||||
|
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
|
||||||
|
);
|
||||||
|
|
||||||
match assoc.kind {
|
match assoc.kind {
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
// We skip the binder here because the binder would deanonymize all
|
// We skip the binder here because the binder would deanonymize all
|
||||||
@ -445,9 +460,9 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
|||||||
// regions just fine, showing `fn(&MyType)`.
|
// regions just fine, showing `fn(&MyType)`.
|
||||||
fn_sig_suggestion(
|
fn_sig_suggestion(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(),
|
tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
|
||||||
assoc.ident(tcx),
|
assoc.ident(tcx),
|
||||||
tcx.predicates_of(assoc.def_id),
|
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
|
||||||
assoc,
|
assoc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ LL | impl TryFrom<OtherStream> for MyStream {}
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation
|
||||||
|
|
|
|
||||||
= help: implement the missing item: `type Error = Type;`
|
= help: implement the missing item: `type Error = Type;`
|
||||||
= help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }`
|
= help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
|
|||||||
LL | impl PartialOrd for Thing {
|
LL | impl PartialOrd for Thing {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
|
||||||
|
|
|
|
||||||
= help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }`
|
= help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
|
|||||||
LL | impl FromIterator<()> for X {
|
LL | impl FromIterator<()> for X {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
|
||||||
|
|
|
|
||||||
= help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }`
|
= help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user