@@ -701,24 +701,27 @@ impl<'db> UseDefMapBuilder<'db> {
701
701
. add_and_constraint ( self . scope_start_visibility , constraint) ;
702
702
}
703
703
704
+ #[ must_use = "A `*`-import visibility constraint must always be negated after it is added" ]
704
705
pub ( super ) fn record_star_import_visibility_constraint (
705
706
& mut self ,
706
707
star_import : StarImportPlaceholderPredicate < ' db > ,
707
708
symbol : ScopedSymbolId ,
708
- ) -> ScopedVisibilityConstraintId {
709
+ ) -> StarImportVisibilityConstraintId {
709
710
let predicate_id = self . add_predicate ( star_import. into ( ) ) ;
710
711
let visibility_id = self . visibility_constraints . add_atom ( predicate_id) ;
711
712
self . symbol_states [ symbol]
712
713
. record_visibility_constraint ( & mut self . visibility_constraints , visibility_id) ;
713
- visibility_id
714
+ StarImportVisibilityConstraintId ( visibility_id)
714
715
}
715
716
716
717
pub ( super ) fn negate_star_import_visibility_constraint (
717
718
& mut self ,
718
719
symbol_id : ScopedSymbolId ,
719
- constraint : ScopedVisibilityConstraintId ,
720
+ constraint : StarImportVisibilityConstraintId ,
720
721
) {
721
- let negated_constraint = self . visibility_constraints . add_not_constraint ( constraint) ;
722
+ let negated_constraint = self
723
+ . visibility_constraints
724
+ . add_not_constraint ( constraint. into_scoped_constraint_id ( ) ) ;
722
725
self . symbol_states [ symbol_id]
723
726
. record_visibility_constraint ( & mut self . visibility_constraints , negated_constraint) ;
724
727
self . scope_start_visibility = self
@@ -925,3 +928,20 @@ impl<'db> UseDefMapBuilder<'db> {
925
928
}
926
929
}
927
930
}
931
+
932
+ /// Newtype wrapper over [`ScopedVisibilityConstraintId`] to improve type safety.
933
+ ///
934
+ /// By returning this type from [`UseDefMapBuilder::record_star_import_visibility_constraint`]
935
+ /// rather than [`ScopedVisibilityConstraintId`] directly, we ensure that
936
+ /// [`UseDefMapBuilder::negate_star_import_visibility_constraint`] must be called after the
937
+ /// visibility constraint has been added, and we ensure that
938
+ /// [`super::SemanticIndexBuilder::record_negated_visibility_constraint`] *cannot* be called with
939
+ /// the narrowing constraint (which would lead to incorrect behaviour).
940
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
941
+ pub ( super ) struct StarImportVisibilityConstraintId ( ScopedVisibilityConstraintId ) ;
942
+
943
+ impl StarImportVisibilityConstraintId {
944
+ fn into_scoped_constraint_id ( self ) -> ScopedVisibilityConstraintId {
945
+ self . 0
946
+ }
947
+ }
0 commit comments