@@ -278,10 +278,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
278278 pats : & [ hir:: PatField < ' _ > ] ,
279279 ) {
280280 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) ,
285282 _ => span_bug ! ( lhs. span, "non-ADT in struct pattern" ) ,
286283 } ;
287284 for pat in pats {
@@ -301,10 +298,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
301298 dotdot : hir:: DotDotPos ,
302299 ) {
303300 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) ,
308302 _ => {
309303 self . tcx . dcx ( ) . span_delayed_bug ( lhs. span , "non-ADT in tuple struct pattern" ) ;
310304 return ;
@@ -409,6 +403,31 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
409403 return false ;
410404 }
411405
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+
412431 if let Some ( trait_of) = self . tcx . trait_id_of_impl ( impl_of)
413432 && self . tcx . has_attr ( trait_of, sym:: rustc_trivial_field_reads)
414433 {
@@ -672,9 +691,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
672691 self . handle_field_pattern_match ( pat, res, fields) ;
673692 }
674693 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- }
678694 let res = self . typeck_results ( ) . qpath_res ( qpath, pat. hir_id ) ;
679695 self . handle_res ( res) ;
680696 }
@@ -830,7 +846,7 @@ fn check_item<'tcx>(
830846 // mark the method live if the self_ty is public,
831847 // or the method is public and may construct self
832848 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)
834850 {
835851 // if the impl item is public,
836852 // and the ty may be constructed or can be constructed in foreign crates,
0 commit comments