Improve spans for RPITIT object-safety errors

This commit is contained in:
Michael Goulet 2022-11-19 02:32:55 +00:00
parent c4165f3a96
commit 9a9d0f40b8
5 changed files with 69 additions and 14 deletions

View file

@ -375,6 +375,7 @@ fn object_safety_violation_for_method(
let span = match (&v, node) {
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
}
@ -437,8 +438,8 @@ fn virtual_call_violation_for_method<'tcx>(
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}
if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
return Some(MethodViolationCode::ReferencesImplTraitInTrait);
if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
return Some(code);
}
// We can't monomorphize things like `fn foo<A>(...)`.
@ -864,16 +865,24 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
pub fn contains_illegal_impl_trait_in_trait<'tcx>(
tcx: TyCtxt<'tcx>,
fn_def_id: DefId,
ty: ty::Binder<'tcx, Ty<'tcx>>,
) -> bool {
) -> Option<MethodViolationCode> {
// This would be caught below, but rendering the error as a separate
// `async-specific` message is better.
if tcx.asyncness(fn_def_id).is_async() {
return Some(MethodViolationCode::AsyncFn);
}
// FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().any(|arg| {
ty.skip_binder().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
{
tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
} else {
false
None
}
})
}