@@ -64,6 +64,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
6464use rustc_hir as hir;
6565use rustc_hir:: def:: DefKind ;
6666use rustc_hir:: def_id:: { DefId , LocalDefId } ;
67+ use rustc_hir:: intravisit:: Visitor ;
6768use rustc_hir:: lang_items:: LangItem ;
6869use rustc_hir:: Node ;
6970use rustc_middle:: dep_graph:: DepContext ;
@@ -1985,6 +1986,70 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19851986 ( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
19861987 self . suggest_let_for_letchains ( & mut err, & trace. cause , span) ;
19871988 }
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+ }
19882053 _ => { }
19892054 }
19902055 }
0 commit comments