@@ -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 ;
@@ -1975,6 +1976,70 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1975
1976
( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
1976
1977
self . suggest_let_for_letchains ( & mut err, & trace. cause , span) ;
1977
1978
}
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
+ }
1978
2043
_ => { }
1979
2044
}
1980
2045
}
0 commit comments