Skip to main content

luaur_analysis/methods/
subtyping_is_invariant_with_subtyping.rs

1use crate::enums::subtyping_suppression_policy::SubtypingSuppressionPolicy;
2use crate::enums::subtyping_variance::SubtypingVariance;
3use crate::functions::assert_reasoning_valid_subtyping::assert_reasoning_valid;
4use crate::functions::merge_reasonings::k_empty_reasoning;
5use crate::methods::subtyping_is_contravariant_with_subtyping::IntoCovOperand;
6use crate::records::scope::Scope;
7use crate::records::subtyping::Subtyping;
8use crate::records::subtyping_environment::SubtypingEnvironment;
9use crate::records::subtyping_reasoning::SubtypingReasoning;
10use crate::records::subtyping_result::SubtypingResult;
11use crate::type_aliases::path::Path;
12use crate::type_aliases::subtyping_reasonings::SubtypingReasonings;
13
14impl Subtyping {
15    pub fn is_invariant_with_subtyping_environment_sub_ty_super_ty_not_null_scope<SubTy, SuperTy>(
16        &mut self,
17        env: &mut SubtypingEnvironment,
18        sub_ty: SubTy,
19        super_ty: SuperTy,
20        scope: *mut Scope,
21    ) -> SubtypingResult
22    where
23        SubTy: IntoCovOperand,
24        SuperTy: IntoCovOperand,
25    {
26        // C++: isCovariantWith(env, subTy, superTy, scope).
27        let mut result = self.covariant_dispatch(
28            env,
29            sub_ty.into_cov_operand(),
30            super_ty.into_cov_operand(),
31            scope,
32        );
33        let contra = self
34            .is_contravariant_with_subtyping_environment_sub_ty_super_ty_not_null_scope(
35                env, sub_ty, super_ty, scope,
36            );
37        result.and_also(contra, SubtypingSuppressionPolicy::Any);
38
39        if result.reasoning.empty() {
40            result.reasoning.insert(SubtypingReasoning {
41                sub_path: Path::default(),
42                super_path: Path::default(),
43                variance: SubtypingVariance::Invariant,
44                is_property_modifier_violation: false,
45            });
46        } else {
47            let mut updated = SubtypingReasonings::new(k_empty_reasoning());
48            for r in result.reasoning.iter() {
49                let mut r = r.clone();
50                r.variance = SubtypingVariance::Invariant;
51                updated.insert(r);
52            }
53            result.reasoning = updated;
54        }
55
56        // `assertReasoningValid` is a debug-only no-op; pass `sub_ty` for both args to
57        // satisfy the single `TID` parameter (see the contravariant port for details).
58        assert_reasoning_valid(sub_ty, sub_ty, &result, self.builtin_types, self.arena);
59
60        result
61    }
62}