@@ -278,10 +278,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
278
278
pats : & [ hir:: PatField < ' _ > ] ,
279
279
) {
280
280
let variant = match self . typeck_results ( ) . node_type ( lhs. hir_id ) . kind ( ) {
281
- ty:: Adt ( adt, _) => {
282
- self . check_def_id ( adt. did ( ) ) ;
283
- adt. variant_of_res ( res)
284
- }
281
+ ty:: Adt ( adt, _) => adt. variant_of_res ( res) ,
285
282
_ => span_bug ! ( lhs. span, "non-ADT in struct pattern" ) ,
286
283
} ;
287
284
for pat in pats {
@@ -301,10 +298,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
301
298
dotdot : hir:: DotDotPos ,
302
299
) {
303
300
let variant = match self . typeck_results ( ) . node_type ( lhs. hir_id ) . kind ( ) {
304
- ty:: Adt ( adt, _) => {
305
- self . check_def_id ( adt. did ( ) ) ;
306
- adt. variant_of_res ( res)
307
- }
301
+ ty:: Adt ( adt, _) => adt. variant_of_res ( res) ,
308
302
_ => {
309
303
self . tcx . dcx ( ) . span_delayed_bug ( lhs. span , "non-ADT in tuple struct pattern" ) ;
310
304
return ;
@@ -409,6 +403,31 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
409
403
return false ;
410
404
}
411
405
406
+ // don't ignore impls for Enums and pub Structs whose methods don't have self receiver,
407
+ // cause external crate may call such methods to construct values of these types
408
+ if let Some ( local_impl_of) = impl_of. as_local ( )
409
+ && let Some ( local_def_id) = def_id. as_local ( )
410
+ && let Some ( fn_sig) =
411
+ self . tcx . hir ( ) . fn_sig_by_hir_id ( self . tcx . local_def_id_to_hir_id ( local_def_id) )
412
+ && matches ! ( fn_sig. decl. implicit_self, hir:: ImplicitSelfKind :: None )
413
+ && let TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) =
414
+ self . tcx . hir ( ) . expect_item ( local_impl_of) . expect_impl ( ) . self_ty . kind
415
+ && let Res :: Def ( def_kind, did) = path. res
416
+ {
417
+ match def_kind {
418
+ // for example, #[derive(Default)] pub struct T(i32);
419
+ // external crate can call T::default() to construct T,
420
+ // so that don't ignore impl Default for pub Enum and Structs
421
+ DefKind :: Struct | DefKind :: Union if self . tcx . visibility ( did) . is_public ( ) => {
422
+ return false ;
423
+ }
424
+ // don't ignore impl Default for Enums,
425
+ // cause we don't know which variant is constructed
426
+ DefKind :: Enum => return false ,
427
+ _ => ( ) ,
428
+ } ;
429
+ }
430
+
412
431
if let Some ( trait_of) = self . tcx . trait_id_of_impl ( impl_of)
413
432
&& self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads)
414
433
{
@@ -672,9 +691,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
672
691
self . handle_field_pattern_match ( pat, res, fields) ;
673
692
}
674
693
PatKind :: Path ( ref qpath) => {
675
- if let ty:: Adt ( adt, _) = self . typeck_results ( ) . node_type ( pat. hir_id ) . kind ( ) {
676
- self . check_def_id ( adt. did ( ) ) ;
677
- }
678
694
let res = self . typeck_results ( ) . qpath_res ( qpath, pat. hir_id ) ;
679
695
self . handle_res ( res) ;
680
696
}
@@ -830,7 +846,7 @@ fn check_item<'tcx>(
830
846
// mark the method live if the self_ty is public,
831
847
// or the method is public and may construct self
832
848
if tcx. visibility ( local_def_id) . is_public ( )
833
- && ( ty_and_all_fields_are_public || ( ty_is_public && may_construct_self) )
849
+ && ( ty_and_all_fields_are_public || may_construct_self)
834
850
{
835
851
// if the impl item is public,
836
852
// and the ty may be constructed or can be constructed in foreign crates,
0 commit comments