@@ -1976,65 +1976,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19761976 ( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
19771977 suggestions. extend ( self . suggest_let_for_letchains ( & trace. cause , span) ) ;
19781978 }
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- suggestions. push ( TypeErrorAdditionalDiags :: ConsiderSpecifyingLength { span, length : sz. found } ) ;
2036- }
2037- }
1979+ ( ty:: Array ( _, _) , ty:: Array ( _, _) ) => suggestions. extend ( self . specify_actual_length ( terr, trace, span) ) ,
20381980 _ => { }
20391981 }
20401982 }
@@ -2048,6 +1990,66 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20481990 suggestions
20491991 }
20501992
1993+ fn specify_actual_length (
1994+ & self ,
1995+ terr : TypeError < ' _ > ,
1996+ trace : & TypeTrace < ' _ > ,
1997+ span : Span ,
1998+ ) -> Option < TypeErrorAdditionalDiags > {
1999+ let hir = self . tcx . hir ( ) ;
2000+ let TypeError :: FixedArraySize ( sz) = terr else {
2001+ return None ;
2002+ } ;
2003+ let tykind = match hir. find_by_def_id ( trace. cause . body_id ) {
2004+ Some ( hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Fn ( _, _, body_id) , .. } ) ) => {
2005+ let body = hir. body ( * body_id) ;
2006+ struct LetVisitor < ' v > {
2007+ span : Span ,
2008+ result : Option < & ' v hir:: Ty < ' v > > ,
2009+ }
2010+ impl < ' v > Visitor < ' v > for LetVisitor < ' v > {
2011+ fn visit_stmt ( & mut self , s : & ' v hir:: Stmt < ' v > ) {
2012+ if self . result . is_some ( ) {
2013+ return ;
2014+ }
2015+ // Find a local statement where the initializer has
2016+ // the same span as the error and the type is specified.
2017+ if let hir:: Stmt {
2018+ kind : hir:: StmtKind :: Local ( hir:: Local {
2019+ init : Some ( hir:: Expr {
2020+ span : init_span,
2021+ ..
2022+ } ) ,
2023+ ty : Some ( array_ty) ,
2024+ ..
2025+ } ) ,
2026+ ..
2027+ } = s
2028+ && init_span == & self . span {
2029+ self . result = Some ( * array_ty) ;
2030+ }
2031+ }
2032+ }
2033+ let mut visitor = LetVisitor { span, result : None } ;
2034+ visitor. visit_body ( body) ;
2035+ visitor. result . map ( |r| & r. peel_refs ( ) . kind )
2036+ }
2037+ Some ( hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Const ( ty, _) , .. } ) ) => {
2038+ Some ( & ty. peel_refs ( ) . kind )
2039+ }
2040+ _ => None ,
2041+ } ;
2042+ if let Some ( tykind) = tykind
2043+ && let hir:: TyKind :: Array ( _, length) = tykind
2044+ && let hir:: ArrayLen :: Body ( hir:: AnonConst { hir_id, .. } ) = length
2045+ && let Some ( span) = self . tcx . hir ( ) . opt_span ( * hir_id)
2046+ {
2047+ Some ( TypeErrorAdditionalDiags :: ConsiderSpecifyingLength { span, length : sz. found } )
2048+ } else {
2049+ None
2050+ }
2051+ }
2052+
20512053 pub fn report_and_explain_type_error (
20522054 & self ,
20532055 trace : TypeTrace < ' tcx > ,
0 commit comments