@@ -277,10 +277,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
277277 pats : & [ hir:: PatField < ' _ > ] ,
278278 ) {
279279 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) ,
284281 _ => span_bug ! ( lhs. span, "non-ADT in struct pattern" ) ,
285282 } ;
286283 for pat in pats {
@@ -300,10 +297,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
300297 dotdot : hir:: DotDotPos ,
301298 ) {
302299 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) ,
307301 _ => {
308302 self . tcx . dcx ( ) . span_delayed_bug ( lhs. span , "non-ADT in tuple struct pattern" ) ;
309303 return ;
@@ -408,6 +402,31 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
408402 return false ;
409403 }
410404
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+
411430 if let Some ( trait_of) = self . tcx . trait_id_of_impl ( impl_of)
412431 && self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads)
413432 {
@@ -671,9 +690,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
671690 self . handle_field_pattern_match ( pat, res, fields) ;
672691 }
673692 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- }
677693 let res = self . typeck_results ( ) . qpath_res ( qpath, pat. hir_id ) ;
678694 self . handle_res ( res) ;
679695 }
@@ -829,7 +845,7 @@ fn check_item<'tcx>(
829845 // mark the method live if the self_ty is public,
830846 // or the method is public and may construct self
831847 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)
833849 {
834850 // if the impl item is public,
835851 // and the ty may be constructed or can be constructed in foreign crates,
0 commit comments