@@ -53,10 +53,10 @@ use hir_def::{
53
53
resolver:: { HasResolver , Resolver } ,
54
54
src:: HasSource as _,
55
55
AssocItemId , AssocItemLoc , AttrDefId , ConstId , ConstParamId , CrateRootModuleId , DefWithBodyId ,
56
- EnumId , EnumVariantId , ExternCrateId , FunctionId , GenericDefId , HasModule , ImplId ,
57
- InTypeConstId , ItemContainerId , LifetimeParamId , LocalEnumVariantId , LocalFieldId , Lookup ,
58
- MacroExpander , MacroId , ModuleId , StaticId , StructId , TraitAliasId , TraitId , TypeAliasId ,
59
- TypeOrConstParamId , TypeParamId , UnionId ,
56
+ EnumId , EnumVariantId , ExternCrateId , FunctionId , GenericDefId , GenericParamId , HasModule ,
57
+ ImplId , InTypeConstId , ItemContainerId , LifetimeParamId , LocalEnumVariantId , LocalFieldId ,
58
+ Lookup , MacroExpander , MacroId , ModuleId , StaticId , StructId , TraitAliasId , TraitId ,
59
+ TypeAliasId , TypeOrConstParamId , TypeParamId , UnionId ,
60
60
} ;
61
61
use hir_expand:: { name:: name, MacroCallKind } ;
62
62
use hir_ty:: {
@@ -89,17 +89,7 @@ use crate::db::{DefDatabase, HirDatabase};
89
89
90
90
pub use crate :: {
91
91
attrs:: { resolve_doc_path_on, HasAttrs } ,
92
- diagnostics:: {
93
- AnyDiagnostic , BreakOutsideOfLoop , CaseType , ExpectedFunction , InactiveCode ,
94
- IncoherentImpl , IncorrectCase , InvalidDeriveTarget , MacroDefError , MacroError ,
95
- MacroExpansionParseError , MalformedDerive , MismatchedArgCount ,
96
- MismatchedTupleStructPatArgCount , MissingFields , MissingMatchArms , MissingUnsafe ,
97
- MovedOutOfRef , NeedMut , NoSuchField , PrivateAssocItem , PrivateField ,
98
- ReplaceFilterMapNextWithFindMap , TraitImplOrphan , TypeMismatch , TypedHole , UndeclaredLabel ,
99
- UnimplementedBuiltinMacro , UnreachableLabel , UnresolvedExternCrate , UnresolvedField ,
100
- UnresolvedImport , UnresolvedMacroCall , UnresolvedMethodCall , UnresolvedModule ,
101
- UnresolvedProcMacro , UnusedMut , UnusedVariable ,
102
- } ,
92
+ diagnostics:: * ,
103
93
has_source:: HasSource ,
104
94
semantics:: { PathResolution , Semantics , SemanticsScope , TypeInfo , VisibleTraits } ,
105
95
} ;
@@ -613,22 +603,64 @@ impl Module {
613
603
// FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
614
604
continue ;
615
605
}
606
+ let ast_id_map = db. ast_id_map ( file_id) ;
616
607
617
608
for diag in db. impl_data_with_diagnostics ( impl_def. id ) . 1 . iter ( ) {
618
609
emit_def_diagnostic ( db, acc, diag) ;
619
610
}
620
611
621
612
if inherent_impls. invalid_impls ( ) . contains ( & impl_def. id ) {
622
- let ast_id_map = db. ast_id_map ( file_id) ;
623
-
624
613
acc. push ( IncoherentImpl { impl_ : ast_id_map. get ( node. ast_id ( ) ) , file_id } . into ( ) )
625
614
}
626
615
627
616
if !impl_def. check_orphan_rules ( db) {
628
- let ast_id_map = db. ast_id_map ( file_id) ;
629
617
acc. push ( TraitImplOrphan { impl_ : ast_id_map. get ( node. ast_id ( ) ) , file_id } . into ( ) )
630
618
}
631
619
620
+ let trait_ = impl_def. trait_ ( db) ;
621
+ let trait_is_unsafe = trait_. map_or ( false , |t| t. is_unsafe ( db) ) ;
622
+ let impl_is_negative = impl_def. is_negative ( db) ;
623
+ let impl_is_unsafe = impl_def. is_unsafe ( db) ;
624
+
625
+ let drop_maybe_dangle = ( || {
626
+ // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper
627
+ let trait_ = trait_?;
628
+ let drop_trait = db. lang_item ( self . krate ( ) . into ( ) , LangItem :: Drop ) ?. as_trait ( ) ?;
629
+ if drop_trait != trait_. into ( ) {
630
+ return None ;
631
+ }
632
+ let parent = impl_def. id . into ( ) ;
633
+ let generic_params = db. generic_params ( parent) ;
634
+ let lifetime_params = generic_params. lifetimes . iter ( ) . map ( |( local_id, _) | {
635
+ GenericParamId :: LifetimeParamId ( LifetimeParamId { parent, local_id } )
636
+ } ) ;
637
+ let type_params = generic_params
638
+ . iter ( )
639
+ . filter ( |( _, it) | it. type_param ( ) . is_some ( ) )
640
+ . map ( |( local_id, _) | {
641
+ GenericParamId :: TypeParamId ( TypeParamId :: from_unchecked (
642
+ TypeOrConstParamId { parent, local_id } ,
643
+ ) )
644
+ } ) ;
645
+ let res = type_params
646
+ . chain ( lifetime_params)
647
+ . any ( |p| db. attrs ( AttrDefId :: GenericParamId ( p) ) . by_key ( "may_dangle" ) . exists ( ) ) ;
648
+ Some ( res)
649
+ } ) ( )
650
+ . unwrap_or ( false ) ;
651
+
652
+ match ( impl_is_unsafe, trait_is_unsafe, impl_is_negative, drop_maybe_dangle) {
653
+ // unsafe negative impl
654
+ ( true , _, true , _) |
655
+ // unsafe impl for safe trait
656
+ ( true , false , _, false ) => acc. push ( TraitImplIncorrectSafety { impl_ : ast_id_map. get ( node. ast_id ( ) ) , file_id, should_be_safe : true } . into ( ) ) ,
657
+ // safe impl for unsafe trait
658
+ ( false , true , false , _) |
659
+ // safe impl of dangling drop
660
+ ( false , false , _, true ) => acc. push ( TraitImplIncorrectSafety { impl_ : ast_id_map. get ( node. ast_id ( ) ) , file_id, should_be_safe : false } . into ( ) ) ,
661
+ _ => ( ) ,
662
+ } ;
663
+
632
664
for item in impl_def. items ( db) {
633
665
let def: DefWithBody = match item {
634
666
AssocItem :: Function ( it) => it. into ( ) ,
@@ -3404,7 +3436,7 @@ impl Impl {
3404
3436
}
3405
3437
3406
3438
pub fn is_unsafe ( self , db : & dyn HirDatabase ) -> bool {
3407
- db. impl_data ( self . id ) . is_unique ( )
3439
+ db. impl_data ( self . id ) . is_unsafe
3408
3440
}
3409
3441
3410
3442
pub fn module ( self , db : & dyn HirDatabase ) -> Module {
0 commit comments