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