36
36
//! ```
37
37
38
38
use crate :: FnCtxt ;
39
- use rustc_errors:: {
40
- struct_span_err, Applicability , Diagnostic , DiagnosticBuilder , ErrorGuaranteed , MultiSpan ,
41
- } ;
39
+ use rustc_errors:: { struct_span_err, Diagnostic , DiagnosticBuilder , ErrorGuaranteed , MultiSpan } ;
42
40
use rustc_hir as hir;
43
41
use rustc_hir:: def_id:: DefId ;
44
42
use rustc_hir:: intravisit:: { self , Visitor } ;
@@ -58,7 +56,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
58
56
use rustc_middle:: ty:: { self , Ty , TypeAndMut } ;
59
57
use rustc_session:: parse:: feature_err;
60
58
use rustc_span:: symbol:: sym;
61
- use rustc_span:: { self , BytePos , DesugaringKind , Span } ;
59
+ use rustc_span:: { self , DesugaringKind } ;
62
60
use rustc_target:: spec:: abi:: Abi ;
63
61
use rustc_trait_selection:: infer:: InferCtxtExt as _;
64
62
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
@@ -1702,9 +1700,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1702
1700
) -> DiagnosticBuilder < ' a , ErrorGuaranteed > {
1703
1701
let mut err = fcx. err_ctxt ( ) . report_mismatched_types ( cause, expected, found, ty_err) ;
1704
1702
1705
- let mut pointing_at_return_type = false ;
1706
- let mut fn_output = None ;
1707
-
1708
1703
let parent_id = fcx. tcx . hir ( ) . parent_id ( id) ;
1709
1704
let parent = fcx. tcx . hir ( ) . get ( parent_id) ;
1710
1705
if let Some ( expr) = expression
@@ -1717,7 +1712,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1717
1712
// label pointing out the cause for the type coercion will be wrong
1718
1713
// as prior return coercions would not be relevant (#57664).
1719
1714
let fn_decl = if let ( Some ( expr) , Some ( blk_id) ) = ( expression, blk_id) {
1720
- pointing_at_return_type =
1715
+ let pointing_at_return_type =
1721
1716
fcx. suggest_mismatched_types_on_tail ( & mut err, expr, expected, found, blk_id) ;
1722
1717
if let ( Some ( cond_expr) , true , false ) = (
1723
1718
fcx. tcx . hir ( ) . get_if_cause ( expr. hir_id ) ,
@@ -1749,7 +1744,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1749
1744
1750
1745
if let Some ( ( fn_id, fn_decl, can_suggest) ) = fn_decl {
1751
1746
if blk_id. is_none ( ) {
1752
- pointing_at_return_type |= fcx. suggest_missing_return_type (
1747
+ fcx. suggest_missing_return_type (
1753
1748
& mut err,
1754
1749
& fn_decl,
1755
1750
expected,
@@ -1758,9 +1753,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1758
1753
fn_id,
1759
1754
) ;
1760
1755
}
1761
- if !pointing_at_return_type {
1762
- fn_output = Some ( & fn_decl. output ) ; // `impl Trait` return type
1763
- }
1764
1756
}
1765
1757
1766
1758
let parent_id = fcx. tcx . hir ( ) . get_parent_item ( id) ;
@@ -1795,106 +1787,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1795
1787
) ;
1796
1788
}
1797
1789
1798
- if let ( Some ( sp) , Some ( fn_output) ) = ( ret_coercion_span, fn_output) {
1799
- self . add_impl_trait_explanation ( & mut err, cause, fcx, expected, sp, fn_output) ;
1800
- }
1801
-
1802
1790
err
1803
1791
}
1804
1792
1805
- fn add_impl_trait_explanation < ' a > (
1806
- & self ,
1807
- err : & mut Diagnostic ,
1808
- cause : & ObligationCause < ' tcx > ,
1809
- fcx : & FnCtxt < ' a , ' tcx > ,
1810
- expected : Ty < ' tcx > ,
1811
- sp : Span ,
1812
- fn_output : & hir:: FnRetTy < ' _ > ,
1813
- ) {
1814
- let return_sp = fn_output. span ( ) ;
1815
- err. span_label ( return_sp, "expected because this return type..." ) ;
1816
- err. span_label (
1817
- sp,
1818
- format ! ( "...is found to be `{}` here" , fcx. resolve_vars_with_obligations( expected) ) ,
1819
- ) ;
1820
- let impl_trait_msg = "for information on `impl Trait`, see \
1821
- <https://doc.rust-lang.org/book/ch10-02-traits.html\
1822
- #returning-types-that-implement-traits>";
1823
- let trait_obj_msg = "for information on trait objects, see \
1824
- <https://doc.rust-lang.org/book/ch17-02-trait-objects.html\
1825
- #using-trait-objects-that-allow-for-values-of-different-types>";
1826
- err. note ( "to return `impl Trait`, all returned values must be of the same type" ) ;
1827
- err. note ( impl_trait_msg) ;
1828
- let snippet = fcx
1829
- . tcx
1830
- . sess
1831
- . source_map ( )
1832
- . span_to_snippet ( return_sp)
1833
- . unwrap_or_else ( |_| "dyn Trait" . to_string ( ) ) ;
1834
- let mut snippet_iter = snippet. split_whitespace ( ) ;
1835
- let has_impl = snippet_iter. next ( ) . is_some_and ( |s| s == "impl" ) ;
1836
- // Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
1837
- let mut is_object_safe = false ;
1838
- if let hir:: FnRetTy :: Return ( ty) = fn_output
1839
- // Get the return type.
1840
- && let hir:: TyKind :: OpaqueDef ( ..) = ty. kind
1841
- {
1842
- let ty = fcx. astconv ( ) . ast_ty_to_ty ( ty) ;
1843
- // Get the `impl Trait`'s `DefId`.
1844
- if let ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) = ty. kind ( )
1845
- // Get the `impl Trait`'s `Item` so that we can get its trait bounds and
1846
- // get the `Trait`'s `DefId`.
1847
- && let hir:: ItemKind :: OpaqueTy ( hir:: OpaqueTy { bounds, .. } ) =
1848
- fcx. tcx . hir ( ) . expect_item ( def_id. expect_local ( ) ) . kind
1849
- {
1850
- // Are of this `impl Trait`'s traits object safe?
1851
- is_object_safe = bounds. iter ( ) . all ( |bound| {
1852
- bound
1853
- . trait_ref ( )
1854
- . and_then ( |t| t. trait_def_id ( ) )
1855
- . is_some_and ( |def_id| {
1856
- fcx. tcx . check_is_object_safe ( def_id)
1857
- } )
1858
- } )
1859
- }
1860
- } ;
1861
- if has_impl {
1862
- if is_object_safe {
1863
- err. multipart_suggestion (
1864
- "you could change the return type to be a boxed trait object" ,
1865
- vec ! [
1866
- ( return_sp. with_hi( return_sp. lo( ) + BytePos ( 4 ) ) , "Box<dyn" . to_string( ) ) ,
1867
- ( return_sp. shrink_to_hi( ) , ">" . to_string( ) ) ,
1868
- ] ,
1869
- Applicability :: MachineApplicable ,
1870
- ) ;
1871
- let sugg = [ sp, cause. span ]
1872
- . into_iter ( )
1873
- . flat_map ( |sp| {
1874
- [
1875
- ( sp. shrink_to_lo ( ) , "Box::new(" . to_string ( ) ) ,
1876
- ( sp. shrink_to_hi ( ) , ")" . to_string ( ) ) ,
1877
- ]
1878
- . into_iter ( )
1879
- } )
1880
- . collect :: < Vec < _ > > ( ) ;
1881
- err. multipart_suggestion (
1882
- "if you change the return type to expect trait objects, box the returned \
1883
- expressions",
1884
- sugg,
1885
- Applicability :: MaybeIncorrect ,
1886
- ) ;
1887
- } else {
1888
- err. help ( format ! (
1889
- "if the trait `{}` were object safe, you could return a boxed trait object" ,
1890
- & snippet[ 5 ..]
1891
- ) ) ;
1892
- }
1893
- err. note ( trait_obj_msg) ;
1894
- }
1895
- err. help ( "you could instead create a new `enum` with a variant for each returned type" ) ;
1896
- }
1897
-
1898
1793
/// Checks whether the return type is unsized via an obligation, which makes
1899
1794
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
1900
1795
/// false but technically valid for typeck.
0 commit comments