@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
4848 }
4949
5050 let ty = cx. tables . expr_ty ( & expr) ;
51- let type_permits_lack_of_use = check_must_use_ty ( cx, ty, & expr, s. span , "" , "" ) ;
51+ let type_permits_lack_of_use = check_must_use_ty ( cx, ty, & expr, s. span , "" , "" , false ) ;
5252
5353 let mut fn_warned = false ;
5454 let mut op_warned = false ;
@@ -133,32 +133,39 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
133133 ty : Ty < ' tcx > ,
134134 expr : & hir:: Expr ,
135135 span : Span ,
136- descr_pre_path : & str ,
137- descr_post_path : & str ,
136+ descr_pre : & str ,
137+ descr_post : & str ,
138+ plural : bool ,
138139 ) -> bool {
139140 if ty. is_unit ( ) || cx. tcx . is_ty_uninhabited_from (
140141 cx. tcx . hir ( ) . get_module_parent ( expr. hir_id ) , ty)
141142 {
142143 return true ;
143144 }
144145
146+ let plural_suffix = if plural { "s" } else { "" } ;
147+
145148 match ty. sty {
146149 ty:: Adt ( ..) if ty. is_box ( ) => {
147150 let boxed_ty = ty. boxed_ty ( ) ;
148- let descr_pre_path = & format ! ( "{}boxed " , descr_pre_path ) ;
149- check_must_use_ty ( cx, boxed_ty, expr, span, descr_pre_path , descr_post_path )
151+ let descr_pre = & format ! ( "{}boxed " , descr_pre ) ;
152+ check_must_use_ty ( cx, boxed_ty, expr, span, descr_pre , descr_post , plural )
150153 }
151154 ty:: Adt ( def, _) => {
152- check_must_use_def ( cx, def. did , span, descr_pre_path , descr_post_path )
155+ check_must_use_def ( cx, def. did , span, descr_pre , descr_post )
153156 }
154157 ty:: Opaque ( def, _) => {
155158 let mut has_emitted = false ;
156159 for ( predicate, _) in & cx. tcx . predicates_of ( def) . predicates {
157160 if let ty:: Predicate :: Trait ( ref poly_trait_predicate) = predicate {
158161 let trait_ref = poly_trait_predicate. skip_binder ( ) . trait_ref ;
159162 let def_id = trait_ref. def_id ;
160- let descr_pre = & format ! ( "{}implementer of " , descr_pre_path) ;
161- if check_must_use_def ( cx, def_id, span, descr_pre, descr_post_path) {
163+ let descr_pre = & format ! (
164+ "{}implementer{} of " ,
165+ descr_pre,
166+ plural_suffix,
167+ ) ;
168+ if check_must_use_def ( cx, def_id, span, descr_pre, descr_post) {
162169 has_emitted = true ;
163170 break ;
164171 }
@@ -171,8 +178,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
171178 for predicate in binder. skip_binder ( ) . iter ( ) {
172179 if let ty:: ExistentialPredicate :: Trait ( ref trait_ref) = predicate {
173180 let def_id = trait_ref. def_id ;
174- let descr_post = & format ! ( " trait object{}" , descr_post_path) ;
175- if check_must_use_def ( cx, def_id, span, descr_pre_path, descr_post) {
181+ let descr_post = & format ! (
182+ " trait object{}{}" ,
183+ plural_suffix,
184+ descr_post,
185+ ) ;
186+ if check_must_use_def ( cx, def_id, span, descr_pre, descr_post) {
176187 has_emitted = true ;
177188 break ;
178189 }
@@ -189,14 +200,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
189200 vec ! [ ]
190201 } ;
191202 for ( i, ty) in tys. iter ( ) . map ( |k| k. expect_ty ( ) ) . enumerate ( ) {
192- let descr_post_path = & format ! ( " in tuple element {}" , i) ;
203+ let descr_post = & format ! ( " in tuple element {}" , i) ;
193204 let span = * spans. get ( i) . unwrap_or ( & span) ;
194- if check_must_use_ty ( cx, ty, expr, span, descr_pre_path , descr_post_path ) {
205+ if check_must_use_ty ( cx, ty, expr, span, descr_pre , descr_post , plural ) {
195206 has_emitted = true ;
196207 }
197208 }
198209 has_emitted
199210 }
211+ ty:: Array ( ty, len) => match len. assert_usize ( cx. tcx ) {
212+ // If the array is definitely non-empty, we can do `#[must_use]` checking.
213+ Some ( n) if n != 0 => {
214+ let descr_pre = & format ! (
215+ "{}array{} of " ,
216+ descr_pre,
217+ plural_suffix,
218+ ) ;
219+ check_must_use_ty ( cx, ty, expr, span, descr_pre, descr_post, true )
220+ }
221+ // Otherwise, we don't lint, to avoid false positives.
222+ _ => false ,
223+ }
200224 _ => false ,
201225 }
202226 }
0 commit comments