mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #155682 - Unique-Usman:ua/box-impl, r=mejrs
Add boxing suggestions for `impl Trait` return type mismatches A sort of a follow up pr to this -> https://github.com/rust-lang/rust/pull/155546
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_errors::{Applicability, Diag, MultiSpan, listify, msg};
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{
|
||||
self as hir, Arm, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind,
|
||||
@@ -26,13 +27,14 @@
|
||||
use rustc_span::{ExpnKind, Ident, MacroKind, Span, Spanned, Symbol, sym};
|
||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
|
||||
use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use super::FnCtxt;
|
||||
use crate::errors;
|
||||
use crate::errors::{self, SuggestBoxingForReturnImplTrait};
|
||||
use crate::fn_ctxt::rustc_span::BytePos;
|
||||
use crate::method::probe;
|
||||
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
|
||||
@@ -963,6 +965,40 @@ pub(in super::super) fn suggest_missing_return_type(
|
||||
);
|
||||
}
|
||||
|
||||
let trait_def_id = trait_ref.trait_ref.path.res.def_id();
|
||||
if self.tcx.is_dyn_compatible(trait_def_id) {
|
||||
err.subdiagnostic(SuggestBoxingForReturnImplTrait::ChangeReturnType {
|
||||
start_sp: hir_ty.span.with_hi(hir_ty.span.lo() + BytePos(4)),
|
||||
end_sp: hir_ty.span.shrink_to_hi(),
|
||||
});
|
||||
|
||||
let body = self.tcx.hir_body_owned_by(fn_id);
|
||||
let mut visitor = ReturnsVisitor::default();
|
||||
visitor.visit_body(&body);
|
||||
|
||||
if !visitor.returns.is_empty() {
|
||||
let starts: Vec<Span> = visitor
|
||||
.returns
|
||||
.iter()
|
||||
.filter(|expr| expr.span.can_be_used_for_suggestions())
|
||||
.map(|expr| expr.span.shrink_to_lo())
|
||||
.collect();
|
||||
let ends: Vec<Span> = visitor
|
||||
.returns
|
||||
.iter()
|
||||
.filter(|expr| expr.span.can_be_used_for_suggestions())
|
||||
.map(|expr| expr.span.shrink_to_hi())
|
||||
.collect();
|
||||
|
||||
if !starts.is_empty() {
|
||||
err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr {
|
||||
starts,
|
||||
ends,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.try_suggest_return_impl_trait(err, expected, found, fn_id);
|
||||
self.try_note_caller_chooses_ty_for_ty_param(err, expected, found);
|
||||
return true;
|
||||
|
||||
@@ -21,6 +21,18 @@ LL | return A;
|
||||
LL | }
|
||||
LL | B
|
||||
| ^ expected `A`, found `B`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn cat() -> impl DynCompatible {
|
||||
LL + fn cat() -> Box<dyn DynCompatible> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ return Box::new(A);
|
||||
LL | }
|
||||
LL ~ Box::new(B)
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -72,6 +72,17 @@ LL | }
|
||||
LL | 1u32
|
||||
| ^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn foo() -> impl std::fmt::Display {
|
||||
LL + fn foo() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ return Box::new(0i32);
|
||||
LL | }
|
||||
LL ~ Box::new(1u32)
|
||||
|
|
||||
help: change the type of the numeric literal from `u32` to `i32`
|
||||
|
|
||||
LL - 1u32
|
||||
@@ -90,6 +101,17 @@ LL | } else {
|
||||
LL | return 1u32;
|
||||
| ^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn bar() -> impl std::fmt::Display {
|
||||
LL + fn bar() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ return Box::new(0i32);
|
||||
LL | } else {
|
||||
LL ~ return Box::new(1u32);
|
||||
|
|
||||
help: change the type of the numeric literal from `u32` to `i32`
|
||||
|
|
||||
LL - return 1u32;
|
||||
@@ -108,6 +130,17 @@ LL | } else {
|
||||
LL | 1u32
|
||||
| ^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn baz() -> impl std::fmt::Display {
|
||||
LL + fn baz() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ return Box::new(0i32);
|
||||
LL | } else {
|
||||
LL ~ Box::new(1u32)
|
||||
|
|
||||
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | }.try_into().unwrap()
|
||||
@@ -153,6 +186,16 @@ LL | 0 => return 0i32,
|
||||
LL | _ => 1u32,
|
||||
| ^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn bat() -> impl std::fmt::Display {
|
||||
LL + fn bat() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ 0 => return Box::new(0i32),
|
||||
LL ~ _ => Box::new(1u32),
|
||||
|
|
||||
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | }.try_into().unwrap()
|
||||
@@ -171,6 +214,17 @@ LL | | _ => 2u32,
|
||||
LL | | }
|
||||
| |_____^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn can() -> impl std::fmt::Display {
|
||||
LL + fn can() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ 0 => return Box::new(0i32),
|
||||
LL ~ 1 => Box::new(1u32),
|
||||
LL ~ _ => Box::new(2u32),
|
||||
|
|
||||
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | }.try_into().unwrap()
|
||||
@@ -188,6 +242,18 @@ LL | return 0i32;
|
||||
LL | 1u32
|
||||
| ^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
help: you could change the return type to be a boxed trait object
|
||||
|
|
||||
LL - fn cat() -> impl std::fmt::Display {
|
||||
LL + fn cat() -> Box<dyn std::fmt::Display> {
|
||||
|
|
||||
help: if you change the return type to expect trait objects, box the returned expressions
|
||||
|
|
||||
LL ~ return Box::new(0i32);
|
||||
LL | }
|
||||
LL | _ => {
|
||||
LL ~ Box::new(1u32)
|
||||
|
|
||||
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
||||
|
|
||||
LL | }.try_into().unwrap()
|
||||
|
||||
Reference in New Issue
Block a user