Skip to content

Commit

Permalink
Auto merge of #13690 - Crauzer:vararg-type, r=Veykril
Browse files Browse the repository at this point in the history
feat: Implement vararg parameter type inference

This PR implements the "collection" of the `va_list` type into the function parameter types list.
  • Loading branch information
bors committed Nov 29, 2022
2 parents 3769cc3 + b3bd5a4 commit acd06de
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/hir-expand/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ pub mod known {
shr,
sub_assign,
sub,
va_list
);

// self/Self cannot be used as an identifier
Expand Down
19 changes: 18 additions & 1 deletion crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,20 @@ impl<'a> InferenceContext<'a> {
let data = self.db.function_data(func);
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
let param_tys =
let mut param_tys =
data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
// Check if function contains a va_list, if it does then we append it to the parameter types
// that are collected from the function data
if data.is_varargs() {
let va_list_ty = match self.resolve_va_list() {
Some(va_list) => TyBuilder::adt(self.db, va_list)
.fill_with_defaults(self.db, || self.table.new_type_var())
.build(),
None => self.err_ty(),
};

param_tys.push(va_list_ty)
}
for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
let ty = self.insert_type_vars(ty);
let ty = self.normalize_associated_types_in(ty);
Expand Down Expand Up @@ -983,6 +995,11 @@ impl<'a> InferenceContext<'a> {
let trait_ = self.resolve_ops_index()?;
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
}

fn resolve_va_list(&self) -> Option<AdtId> {
let struct_ = self.resolve_lang_item(name![va_list])?.as_struct()?;
Some(struct_.into())
}
}

/// When inferring an expression, we propagate downward whatever type hint we
Expand Down
12 changes: 12 additions & 0 deletions crates/hir-ty/src/tests/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,3 +1080,15 @@ fn my_fn(#[cfg(feature = "feature")] u8: u8, u32: u32) {}
"#,
);
}

#[test]
fn var_args() {
check_types(
r#"
#[lang = "va_list"]
pub struct VaListImpl<'f>;
fn my_fn(foo: ...) {}
//^^^ VaListImpl
"#,
);
}

0 comments on commit acd06de

Please sign in to comment.