Suggest adding return
if the type of unused semi return value can c… · rust-lang/rust@25d38c4 (original) (raw)
`@@ -11,7 +11,7 @@ use crate::{
`
11
11
`use rustc_ast as ast;
`
12
12
`use rustc_data_structures::fx::FxIndexSet;
`
13
13
`use rustc_errors::{
`
14
``
`-
pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan,
`
``
14
`+
pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan, StashKey,
`
15
15
`};
`
16
16
`use rustc_hir as hir;
`
17
17
`use rustc_hir::def::{CtorOf, DefKind, Res};
`
`@@ -27,6 +27,7 @@ use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
`
27
27
`use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
`
28
28
`use rustc_infer::infer::TypeTrace;
`
29
29
`use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
`
``
30
`+
use rustc_middle::traits::ObligationCauseCode::ExprBindingObligation;
`
30
31
`use rustc_middle::ty::adjustment::AllowTwoPhase;
`
31
32
`use rustc_middle::ty::visit::TypeVisitableExt;
`
32
33
`use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
`
`@@ -1375,7 +1376,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
`
1375
1376
`}
`
1376
1377
` _ => bug!("unexpected type: {:?}", ty.normalized),
`
1377
1378
`},
`
1378
``
`-
Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
`
``
1379
`+
Res::Def(
`
``
1380
`+
DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
`
``
1381
`+
_,
`
``
1382
`+
)
`
1379
1383
` | Res::SelfTyParam { .. }
`
1380
1384
` | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() {
`
1381
1385
`Some(adt) if !adt.is_enum() => {
`
`@@ -1845,6 +1849,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
`
1845
1849
`}
`
1846
1850
`}
`
1847
1851
``
``
1852
`+
pub(super) fn collect_unused_stmts_for_coerce_return_ty(
`
``
1853
`+
&self,
`
``
1854
`+
errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>,
`
``
1855
`+
) {
`
``
1856
`+
for (span, code) in errors_causecode {
`
``
1857
`+
let Some(mut diag) =
`
``
1858
`+
self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::MaybeForgetReturn)
`
``
1859
`+
else {
`
``
1860
`+
continue;
`
``
1861
`+
};
`
``
1862
+
``
1863
`+
if let Some(fn_sig) = self.body_fn_sig()
`
``
1864
`+
&& let ExprBindingObligation(_, _, hir_id, ..) = code
`
``
1865
`+
&& !fn_sig.output().is_unit()
`
``
1866
`+
{
`
``
1867
`+
let mut block_num = 0;
`
``
1868
`+
let mut found_semi = false;
`
``
1869
`+
for (_, node) in self.tcx.hir().parent_iter(hir_id) {
`
``
1870
`+
match node {
`
``
1871
`+
hir::Node::Stmt(stmt) => if let hir::StmtKind::Semi(ref expr) = stmt.kind {
`
``
1872
`+
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
`
``
1873
`+
let return_ty = fn_sig.output();
`
``
1874
`+
if !matches!(expr.kind, hir::ExprKind::Ret(..)) &&
`
``
1875
`+
self.can_coerce(expr_ty, return_ty) {
`
``
1876
`+
found_semi = true;
`
``
1877
`+
}
`
``
1878
`+
},
`
``
1879
`+
hir::Node::Block(_block) => if found_semi {
`
``
1880
`+
block_num += 1;
`
``
1881
`+
}
`
``
1882
`+
hir::Node::Item(item) => if let hir::ItemKind::Fn(..) = item.kind {
`
``
1883
`+
break;
`
``
1884
`+
}
`
``
1885
`+
_ => {}
`
``
1886
`+
}
`
``
1887
`+
}
`
``
1888
`+
if block_num > 1 && found_semi {
`
``
1889
`+
diag.span_suggestion_verbose(
`
``
1890
`+
span.shrink_to_lo(),
`
``
1891
`+
"you might have meant to return this to infer its type parameters",
`
``
1892
`+
"return ",
`
``
1893
`+
Applicability::MaybeIncorrect,
`
``
1894
`+
);
`
``
1895
`+
}
`
``
1896
`+
}
`
``
1897
`+
diag.emit();
`
``
1898
`+
}
`
``
1899
`+
}
`
``
1900
+
1848
1901
`/// Given a vector of fulfillment errors, try to adjust the spans of the
`
1849
1902
`/// errors to more accurately point at the cause of the failure.
`
1850
1903
`///
`