@@ -64,6 +64,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
64
64
use rustc_hir as hir;
65
65
use rustc_hir:: def:: DefKind ;
66
66
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
67
+ use rustc_hir:: intravisit:: Visitor ;
67
68
use rustc_hir:: lang_items:: LangItem ;
68
69
use rustc_hir:: Node ;
69
70
use rustc_middle:: dep_graph:: DepContext ;
@@ -1985,6 +1986,70 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1985
1986
( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
1986
1987
self . suggest_let_for_letchains ( & mut err, & trace. cause , span) ;
1987
1988
}
1989
+ ( ty:: Array ( _, _) , ty:: Array ( _, _) ) => ' block: {
1990
+ let hir = self . tcx . hir ( ) ;
1991
+ let TypeError :: FixedArraySize ( sz) = terr else {
1992
+ break ' block;
1993
+ } ;
1994
+ let tykind = match hir. find_by_def_id ( trace. cause . body_id ) {
1995
+ Some ( hir:: Node :: Item ( hir:: Item {
1996
+ kind : hir:: ItemKind :: Fn ( _, _, body_id) ,
1997
+ ..
1998
+ } ) ) => {
1999
+ let body = hir. body ( * body_id) ;
2000
+ struct LetVisitor < ' v > {
2001
+ span : Span ,
2002
+ result : Option < & ' v hir:: Ty < ' v > > ,
2003
+ }
2004
+ impl < ' v > Visitor < ' v > for LetVisitor < ' v > {
2005
+ fn visit_stmt ( & mut self , s : & ' v hir:: Stmt < ' v > ) {
2006
+ if self . result . is_some ( ) {
2007
+ return ;
2008
+ }
2009
+ // Find a local statement where the initializer has
2010
+ // the same span as the error and the type is specified.
2011
+ if let hir:: Stmt {
2012
+ kind : hir:: StmtKind :: Local ( hir:: Local {
2013
+ init : Some ( hir:: Expr {
2014
+ span : init_span,
2015
+ ..
2016
+ } ) ,
2017
+ ty : Some ( array_ty) ,
2018
+ ..
2019
+ } ) ,
2020
+ ..
2021
+ } = s
2022
+ && init_span == & self . span {
2023
+ self . result = Some ( * array_ty) ;
2024
+ }
2025
+ }
2026
+ }
2027
+ let mut visitor = LetVisitor { span, result : None } ;
2028
+ visitor. visit_body ( body) ;
2029
+ visitor. result . map ( |r| & r. peel_refs ( ) . kind )
2030
+ }
2031
+ Some ( hir:: Node :: Item ( hir:: Item {
2032
+ kind : hir:: ItemKind :: Const ( ty, _) ,
2033
+ ..
2034
+ } ) ) => {
2035
+ Some ( & ty. peel_refs ( ) . kind )
2036
+ }
2037
+ _ => None
2038
+ } ;
2039
+
2040
+ if let Some ( tykind) = tykind
2041
+ && let hir:: TyKind :: Array ( _, length) = tykind
2042
+ && let hir:: ArrayLen :: Body ( hir:: AnonConst { hir_id, .. } ) = length
2043
+ && let Some ( span) = self . tcx . hir ( ) . opt_span ( * hir_id)
2044
+ {
2045
+ err. span_suggestion (
2046
+ span,
2047
+ "consider specifying the actual array length" ,
2048
+ sz. found ,
2049
+ Applicability :: MaybeIncorrect ,
2050
+ ) ;
2051
+ }
2052
+ }
1988
2053
_ => { }
1989
2054
}
1990
2055
}
0 commit comments