tweak suggestion for argument-position impl ?Sized

This commit is contained in:
Lukas Markeffsky 2023-06-14 08:03:35 +00:00
parent 5a65be8152
commit ee7e717322
3 changed files with 74 additions and 12 deletions

View File

@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::WherePredicate; use rustc_hir::{PredicateOrigin, WherePredicate};
use rustc_span::Span; use rustc_span::{BytePos, Span};
use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::sty::TyKind::*;
impl<'tcx> IntoDiagnosticArg for Ty<'tcx> { impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
@ -156,10 +156,11 @@ enum SuggestChangingConstraintsMessage<'a> {
RestrictBoundFurther, RestrictBoundFurther,
RestrictType { ty: &'a str }, RestrictType { ty: &'a str },
RestrictTypeFurther { ty: &'a str }, RestrictTypeFurther { ty: &'a str },
RemovingQSized, RemoveMaybeUnsized,
ReplaceMaybeUnsizedWithSized,
} }
fn suggest_removing_unsized_bound( fn suggest_changing_unsized_bound(
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
suggestions: &mut Vec<(Span, String, SuggestChangingConstraintsMessage<'_>)>, suggestions: &mut Vec<(Span, String, SuggestChangingConstraintsMessage<'_>)>,
param: &hir::GenericParam<'_>, param: &hir::GenericParam<'_>,
@ -183,15 +184,28 @@ fn suggest_removing_unsized_bound(
if poly.trait_ref.trait_def_id() != def_id { if poly.trait_ref.trait_def_id() != def_id {
continue; continue;
} }
if predicate.origin == PredicateOrigin::ImplTrait && predicate.bounds.len() == 1 {
// For `impl ?Sized` with no other bounds, suggest `impl Sized` instead.
let bound_span = bound.span();
if bound_span.can_be_used_for_suggestions() {
let question_span = bound_span.with_hi(bound_span.lo() + BytePos(1));
suggestions.push((
question_span,
String::new(),
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized,
));
}
} else {
let sp = generics.span_for_bound_removal(where_pos, pos); let sp = generics.span_for_bound_removal(where_pos, pos);
suggestions.push(( suggestions.push((
sp, sp,
String::new(), String::new(),
SuggestChangingConstraintsMessage::RemovingQSized, SuggestChangingConstraintsMessage::RemoveMaybeUnsized,
)); ));
} }
} }
} }
}
/// Suggest restricting a type param with a new bound. /// Suggest restricting a type param with a new bound.
/// ///
@ -245,7 +259,7 @@ pub fn suggest_constraining_type_params<'a>(
param.span, param.span,
format!("this type parameter needs to be `{}`", constraint), format!("this type parameter needs to be `{}`", constraint),
); );
suggest_removing_unsized_bound(generics, &mut suggestions, param, def_id); suggest_changing_unsized_bound(generics, &mut suggestions, param, def_id);
} }
} }
@ -395,9 +409,12 @@ pub fn suggest_constraining_type_params<'a>(
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => { SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => {
Cow::from(format!("consider further restricting type parameter `{}`", ty)) Cow::from(format!("consider further restricting type parameter `{}`", ty))
} }
SuggestChangingConstraintsMessage::RemovingQSized => { SuggestChangingConstraintsMessage::RemoveMaybeUnsized => {
Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`") Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`")
} }
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => {
Cow::from("consider replacing `?Sized` with `Sized`")
}
}; };
err.span_suggestion_verbose(span, msg, suggestion, applicability); err.span_suggestion_verbose(span, msg, suggestion, applicability);

View File

@ -0,0 +1,4 @@
fn foo(_: impl Iterator<Item = i32> + ?Sized) {} //~ ERROR [E0277]
fn bar(_: impl ?Sized) {} //~ ERROR [E0277]
fn main() {}

View File

@ -0,0 +1,41 @@
error[E0277]: the size for values of type `impl Iterator<Item = i32> + ?Sized` cannot be known at compilation time
--> $DIR/apit-unsized.rs:1:8
|
LL | fn foo(_: impl Iterator<Item = i32> + ?Sized) {}
| ^ ---------------------------------- this type parameter needs to be `std::marker::Sized`
| |
| doesn't have a size known at compile-time
|
= help: unsized fn params are gated as an unstable feature
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
LL - fn foo(_: impl Iterator<Item = i32> + ?Sized) {}
LL + fn foo(_: impl Iterator<Item = i32>) {}
|
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | fn foo(_: &impl Iterator<Item = i32> + ?Sized) {}
| +
error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time
--> $DIR/apit-unsized.rs:2:8
|
LL | fn bar(_: impl ?Sized) {}
| ^ ----------- this type parameter needs to be `std::marker::Sized`
| |
| doesn't have a size known at compile-time
|
= help: unsized fn params are gated as an unstable feature
help: consider replacing `?Sized` with `Sized`
|
LL - fn bar(_: impl ?Sized) {}
LL + fn bar(_: impl Sized) {}
|
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | fn bar(_: &impl ?Sized) {}
| +
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.