Skip to main content

luaur_analysis/methods/
overload_resolution_get_unambiguous_overload.rs

1use crate::records::overload_resolution::OverloadResolution;
2use crate::records::selected_overload::SelectedOverload;
3
4use luaur_common::macros::luau_assert::LUAU_ASSERT;
5
6impl OverloadResolution {
7    pub fn get_unambiguous_overload(&self) -> SelectedOverload {
8        if self.ok.len() == 1 && self.potential_overloads.len() == 0 {
9            return SelectedOverload {
10                overload: Some(self.ok[0]),
11                assumed_constraints: vec![],
12                should_retry: false,
13            };
14        }
15
16        if self.ok.len() == 0 && self.potential_overloads.len() == 1 {
17            return SelectedOverload {
18                overload: Some(self.potential_overloads[0].0),
19                assumed_constraints: self.potential_overloads[0].1.clone(),
20                should_retry: false,
21            };
22        }
23
24        if self.ok.len() > 1 {
25            return SelectedOverload {
26                overload: None,
27                assumed_constraints: vec![],
28                should_retry: false,
29            };
30        }
31
32        if self.potential_overloads.len() + self.ok.len() > 1 {
33            // This is a first case of "ambiguous" overloads: we have at least
34            // one overload that matches without constraints, and one that matches
35            // with extra constraints.
36            if self.ok.is_empty() {
37                return SelectedOverload {
38                    overload: Some(self.potential_overloads[0].0),
39                    assumed_constraints: self.potential_overloads[0].1.clone(),
40                    should_retry: true,
41                };
42            } else {
43                LUAU_ASSERT!(self.ok.len() == 1);
44                return SelectedOverload {
45                    overload: Some(self.ok[0]),
46                    assumed_constraints: vec![],
47                    should_retry: true,
48                };
49            }
50        }
51
52        LUAU_ASSERT!(self.potential_overloads.len() + self.ok.len() == 0);
53
54        // In this case, no overloads are valid. Let's try to pick the one that
55        // will cause us to report the most legible errors.
56        if self.incompatible_overloads.len() == 1 {
57            // There's exactly one incompatible overload, but it has
58            // the right arity, so just use that. We'll fail type checking
59            // but that's ok.
60            return SelectedOverload {
61                overload: Some(self.incompatible_overloads[0].0),
62                assumed_constraints: vec![],
63                should_retry: false,
64            };
65        }
66
67        SelectedOverload {
68            overload: None,
69            assumed_constraints: vec![],
70            should_retry: false,
71        }
72    }
73}