about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2023-06-14 08:03:35 +0000
committerLukas Markeffsky <@>2023-06-15 12:00:57 +0200
commitee7e717322f83d4b055e15b9948c07dd59118a5c (patch)
treebfe36a3d02f50d0bdc18e8ba3f038efe7ec05ad2 /compiler
parent5a65be815211a059b08ee3b786583308377372fa (diff)
downloadrust-ee7e717322f83d4b055e15b9948c07dd59118a5c.tar.gz
rust-ee7e717322f83d4b055e15b9948c07dd59118a5c.zip
tweak suggestion for argument-position `impl ?Sized`
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs41
1 files changed, 29 insertions, 12 deletions
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 9c948dba1e4..1c80692c306 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::WherePredicate;
-use rustc_span::Span;
+use rustc_hir::{PredicateOrigin, WherePredicate};
+use rustc_span::{BytePos, Span};
 use rustc_type_ir::sty::TyKind::*;
 
 impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
@@ -156,10 +156,11 @@ enum SuggestChangingConstraintsMessage<'a> {
     RestrictBoundFurther,
     RestrictType { ty: &'a str },
     RestrictTypeFurther { ty: &'a str },
-    RemovingQSized,
+    RemoveMaybeUnsized,
+    ReplaceMaybeUnsizedWithSized,
 }
 
-fn suggest_removing_unsized_bound(
+fn suggest_changing_unsized_bound(
     generics: &hir::Generics<'_>,
     suggestions: &mut Vec<(Span, String, SuggestChangingConstraintsMessage<'_>)>,
     param: &hir::GenericParam<'_>,
@@ -183,12 +184,25 @@ fn suggest_removing_unsized_bound(
             if poly.trait_ref.trait_def_id() != def_id {
                 continue;
             }
-            let sp = generics.span_for_bound_removal(where_pos, pos);
-            suggestions.push((
-                sp,
-                String::new(),
-                SuggestChangingConstraintsMessage::RemovingQSized,
-            ));
+            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);
+                suggestions.push((
+                    sp,
+                    String::new(),
+                    SuggestChangingConstraintsMessage::RemoveMaybeUnsized,
+                ));
+            }
         }
     }
 }
@@ -245,7 +259,7 @@ pub fn suggest_constraining_type_params<'a>(
                     param.span,
                     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 } => {
                 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`")
             }
+            SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => {
+                Cow::from("consider replacing `?Sized` with `Sized`")
+            }
         };
 
         err.span_suggestion_verbose(span, msg, suggestion, applicability);