Skip to content

Commit

Permalink
Make return type a hard upper bound
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Feb 2, 2024
1 parent 6a25ff4 commit 5699bc2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
48 changes: 48 additions & 0 deletions src/analyzer/expr/call_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ pub(crate) fn reconcile_lower_bounds_with_upper_bounds(

let relevant_lower_bounds = get_relevant_bounds(lower_bounds);

// println!("{:#?}", lower_bounds);
// println!("{:#?}", upper_bounds);

let mut union_comparison_result = TypeComparisonResult::new();

let mut has_issue = false;
Expand Down Expand Up @@ -216,6 +219,7 @@ pub(crate) fn reconcile_lower_bounds_with_upper_bounds(
.collect::<Vec<_>>();

if equality_strings.len() > 1 {
has_issue = true;
analysis_data.maybe_add_issue(
Issue::new(
IssueKind::IncompatibleTypeParameters,
Expand Down Expand Up @@ -247,6 +251,7 @@ pub(crate) fn reconcile_lower_bounds_with_upper_bounds(
}
}

has_issue = true;
analysis_data.maybe_add_issue(
Issue::new(
IssueKind::IncompatibleTypeParameters,
Expand All @@ -266,6 +271,49 @@ pub(crate) fn reconcile_lower_bounds_with_upper_bounds(
}
}
}

if !has_issue && upper_bounds.len() > 1 {
let upper_bounds_with_equality = upper_bounds
.iter()
.filter(|bound| bound.equality_bound_classlike.is_some())
.enumerate()
.collect::<Vec<_>>();

if upper_bounds_with_equality.is_empty() {
return;
}

for (i, upper_bound_with_equality) in upper_bounds_with_equality {
for (j, upper_bound) in upper_bounds.iter().enumerate() {
if i == j {
continue;
}

if !union_type_comparator::can_expression_types_be_identical(
codebase,
&upper_bound_with_equality.bound_type,
&upper_bound.bound_type,
false,
) {
analysis_data.maybe_add_issue(
Issue::new(
IssueKind::IncompatibleTypeParameters,
format!(
"Incompatible types found for {} ({} is not in {})",
"type variable",
upper_bound.bound_type.get_id(Some(interner)),
upper_bound_with_equality.bound_type.get_id(Some(interner)),
),
pos,
&None,
),
statements_analyzer.get_config(),
statements_analyzer.get_file_path_actual(),
);
}
}
}
}
}

pub(crate) fn get_generic_param_for_offset(
Expand Down
4 changes: 4 additions & 0 deletions src/analyzer/stmt/return_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ pub(crate) fn analyze(
if let Some((_, upper_bounds)) =
analysis_data.type_variable_bounds.get_mut(&name)
{
if bound.equality_bound_classlike.is_none() {
// bit of a hack but this ensures that we add strict checks
bound.equality_bound_classlike = Some(StrId::EMPTY);
}
bound.pos = Some(statements_analyzer.get_hpos(&return_expr.1));
upper_bounds.push(bound);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ttype/template/standin_type_replacer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1998,7 +1998,7 @@ pub fn get_most_specific_type_from_bounds(

pub fn get_relevant_bounds(lower_bounds: &Vec<TemplateBound>) -> Vec<&TemplateBound> {
if lower_bounds.len() == 1 {
return vec![lower_bounds.first().unwrap()];
return vec![&lower_bounds[0]];
}

let mut lower_bounds = lower_bounds.iter().collect::<Vec<_>>();
Expand Down

0 comments on commit 5699bc2

Please sign in to comment.