mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
implement vararg type collection from function params
This commit is contained in:
parent
6d61be8e65
commit
b3bd5a471e
3 changed files with 31 additions and 1 deletions
|
@ -419,6 +419,7 @@ pub mod known {
|
||||||
shr,
|
shr,
|
||||||
sub_assign,
|
sub_assign,
|
||||||
sub,
|
sub,
|
||||||
|
va_list
|
||||||
);
|
);
|
||||||
|
|
||||||
// self/Self cannot be used as an identifier
|
// self/Self cannot be used as an identifier
|
||||||
|
|
|
@ -537,8 +537,20 @@ impl<'a> InferenceContext<'a> {
|
||||||
let data = self.db.function_data(func);
|
let data = self.db.function_data(func);
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
|
||||||
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
|
.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<_>>();
|
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()) {
|
for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
|
||||||
let ty = self.insert_type_vars(ty);
|
let ty = self.insert_type_vars(ty);
|
||||||
let ty = self.normalize_associated_types_in(ty);
|
let ty = self.normalize_associated_types_in(ty);
|
||||||
|
@ -983,6 +995,11 @@ impl<'a> InferenceContext<'a> {
|
||||||
let trait_ = self.resolve_ops_index()?;
|
let trait_ = self.resolve_ops_index()?;
|
||||||
self.db.trait_data(trait_).associated_type_by_name(&name![Output])
|
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
|
/// When inferring an expression, we propagate downward whatever type hint we
|
||||||
|
|
|
@ -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
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue