diff options
| author | bors <bors@rust-lang.org> | 2022-11-29 07:55:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-11-29 07:55:57 +0000 |
| commit | acd06de16a89d837afd79a83713a104644c1b616 (patch) | |
| tree | 1fa9c1eb9811980bbccab1d617bbf1b97428c881 | |
| parent | 3769cc35fa3fc28f6d6d5ecb40ba72bb16f63e0c (diff) | |
| parent | b3bd5a471e314841fb1d2d94fdc50ef3c8d8548f (diff) | |
| download | rust-acd06de16a89d837afd79a83713a104644c1b616.tar.gz rust-acd06de16a89d837afd79a83713a104644c1b616.zip | |
Auto merge of #13690 - Crauzer:vararg-type, r=Veykril
feat: Implement vararg parameter type inference This PR implements the "collection" of the `va_list` type into the function parameter types list.
| -rw-r--r-- | crates/hir-expand/src/name.rs | 1 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 19 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/patterns.rs | 12 |
3 files changed, 31 insertions, 1 deletions
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs index 2679a1c3602..259fe1327f8 100644 --- a/crates/hir-expand/src/name.rs +++ b/crates/hir-expand/src/name.rs @@ -419,6 +419,7 @@ pub mod known { shr, sub_assign, sub, + va_list ); // self/Self cannot be used as an identifier diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 0b3c23f5747..112eb5bd84c 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -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); @@ -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 diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs index 74de33117ee..9333e269352 100644 --- a/crates/hir-ty/src/tests/patterns.rs +++ b/crates/hir-ty/src/tests/patterns.rs @@ -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 +"#, + ); +} |
