@@ -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 ;
@@ -1975,6 +1976,70 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19751976 ( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
19761977 self . suggest_let_for_letchains ( & mut err, & trace. cause , span) ;
19771978 }
1979+ ( ty:: Array ( _, _) , ty:: Array ( _, _) ) => ' block: {
1980+ let hir = self . tcx . hir ( ) ;
1981+ let TypeError :: FixedArraySize ( sz) = terr else {
1982+ break ' block;
1983+ } ;
1984+ let tykind = match hir. find_by_def_id ( trace. cause . body_id ) {
1985+ Some ( hir:: Node :: Item ( hir:: Item {
1986+ kind : hir:: ItemKind :: Fn ( _, _, body_id) ,
1987+ ..
1988+ } ) ) => {
1989+ let body = hir. body ( * body_id) ;
1990+ struct LetVisitor < ' v > {
1991+ span : Span ,
1992+ result : Option < & ' v hir:: Ty < ' v > > ,
1993+ }
1994+ impl < ' v > Visitor < ' v > for LetVisitor < ' v > {
1995+ fn visit_stmt ( & mut self , s : & ' v hir:: Stmt < ' v > ) {
1996+ if self . result . is_some ( ) {
1997+ return ;
1998+ }
1999+ // Find a local statement where the initializer has
2000+ // the same span as the error and the type is specified.
2001+ if let hir:: Stmt {
2002+ kind : hir:: StmtKind :: Local ( hir:: Local {
2003+ init : Some ( hir:: Expr {
2004+ span : init_span,
2005+ ..
2006+ } ) ,
2007+ ty : Some ( array_ty) ,
2008+ ..
2009+ } ) ,
2010+ ..
2011+ } = s
2012+ && init_span == & self . span {
2013+ self . result = Some ( * array_ty) ;
2014+ }
2015+ }
2016+ }
2017+ let mut visitor = LetVisitor { span, result : None } ;
2018+ visitor. visit_body ( body) ;
2019+ visitor. result . map ( |r| & r. peel_refs ( ) . kind )
2020+ }
2021+ Some ( hir:: Node :: Item ( hir:: Item {
2022+ kind : hir:: ItemKind :: Const ( ty, _) ,
2023+ ..
2024+ } ) ) => {
2025+ Some ( & ty. peel_refs ( ) . kind )
2026+ }
2027+ _ => None
2028+ } ;
2029+
2030+ if let Some ( tykind) = tykind
2031+ && let hir:: TyKind :: Array ( _, length) = tykind
2032+ && let hir:: ArrayLen :: Body ( hir:: AnonConst { hir_id, .. } ) = length
2033+ && let Some ( span) = self . tcx . hir ( ) . opt_span ( * hir_id)
2034+ {
2035+ err. span_suggestion (
2036+ span,
2037+ "consider specifying the actual array length" ,
2038+ sz. found ,
2039+ Applicability :: MaybeIncorrect ,
2040+ ) ;
2041+ }
2042+ }
19782043 _ => { }
19792044 }
19802045 }
0 commit comments