Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/data.rs13
-rw-r--r--crates/hir-def/src/item_tree.rs2
-rw-r--r--crates/hir-def/src/item_tree/lower.rs6
-rw-r--r--crates/hir-def/src/item_tree/pretty.rs2
-rw-r--r--crates/hir-ty/src/infer.rs4
-rw-r--r--crates/hir-ty/src/tests/patterns.rs17
-rw-r--r--crates/hir/src/display.rs8
-rw-r--r--crates/intern/src/symbol/symbols.rs1
8 files changed, 37 insertions, 16 deletions
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index a03140e2a9..3f862f69f8 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -73,6 +73,17 @@ impl FunctionData {
flags.remove(FnFlags::HAS_SELF_PARAM);
}
}
+ if flags.contains(FnFlags::IS_VARARGS) {
+ if let Some((_, param)) = func.params.iter().enumerate().rev().find(|&(idx, _)| {
+ item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
+ }) {
+ if param.type_ref.is_some() {
+ flags.remove(FnFlags::IS_VARARGS);
+ }
+ } else {
+ flags.remove(FnFlags::IS_VARARGS);
+ }
+ }
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
let legacy_const_generics_indices = attrs
@@ -92,7 +103,7 @@ impl FunctionData {
.filter(|&(idx, _)| {
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
})
- .map(|(_, param)| param.type_ref.clone())
+ .filter_map(|(_, param)| param.type_ref.clone())
.collect(),
ret_type: func.ret_type.clone(),
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index f6709680d0..28eebb286e 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -741,7 +741,7 @@ pub struct Function {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
- pub type_ref: Interned<TypeRef>,
+ pub type_ref: Option<Interned<TypeRef>>,
}
bitflags::bitflags! {
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index c9e9719c90..7aac383ab4 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -380,7 +380,7 @@ impl<'a> Ctx<'a> {
}
};
let type_ref = Interned::new(self_type);
- params.push(Param { type_ref });
+ params.push(Param { type_ref: Some(type_ref) });
has_self_param = true;
}
for param in param_list.params() {
@@ -388,12 +388,12 @@ impl<'a> Ctx<'a> {
let param = match param.dotdotdot_token() {
Some(_) => {
has_var_args = true;
- Param { type_ref: Interned::new(TypeRef::Error) }
+ Param { type_ref: None }
}
None => {
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
let ty = Interned::new(type_ref);
- Param { type_ref: ty }
+ Param { type_ref: Some(ty) }
}
};
params.push(param);
diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs
index 5eeb8607b9..740759e6e3 100644
--- a/crates/hir-def/src/item_tree/pretty.rs
+++ b/crates/hir-def/src/item_tree/pretty.rs
@@ -291,7 +291,7 @@ impl Printer<'_> {
if idx == 0 && flags.contains(FnFlags::HAS_SELF_PARAM) {
w!(this, "self: ");
}
- if idx != params.len() {
+ if let Some(type_ref) = type_ref {
this.print_type_ref(type_ref);
} else {
wln!(this, "...");
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 284291bb9a..804bc53905 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -812,9 +812,7 @@ impl<'a> InferenceContext<'a> {
None => self.err_ty(),
};
- if let Some(ty) = param_tys.last_mut() {
- *ty = va_list_ty;
- }
+ param_tys.push(va_list_ty);
}
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
if let Some(self_param) = self.body.self_param {
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index 1c1f7055ef..57866acc06 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -1126,6 +1126,23 @@ fn var_args() {
pub struct VaListImpl<'f>;
fn my_fn(foo: ...) {}
//^^^ VaListImpl<'?>
+fn my_fn2(bar: u32, foo: ...) {}
+ //^^^ VaListImpl<'?>
+"#,
+ );
+}
+
+#[test]
+fn var_args_cond() {
+ check_types(
+ r#"
+#[lang = "va_list"]
+pub struct VaListImpl<'f>;
+fn my_fn(bar: u32, #[cfg(FALSE)] foo: ..., #[cfg(not(FALSE))] foo: u32) {
+ foo;
+ //^^^ u32
+
+}
"#,
);
}
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index a40022c43a..7def828e95 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -99,13 +99,7 @@ impl HirDisplay for Function {
}
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
- for (type_ref, param) in data
- .params
- .iter()
- .zip(self.assoc_fn_params(db))
- .take(data.params.len() - data.is_varargs() as usize)
- .skip(skip_self)
- {
+ for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
let local = param.as_local(db).map(|it| it.name(db));
if !first {
f.write_str(", ")?;
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index d810fac36a..2feca32ff8 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -56,6 +56,7 @@ macro_rules! define_symbols {
define_symbols! {
@WITH_NAME:
+ dotdotdot = "...",
INTEGER_0 = "0",
INTEGER_1 = "1",
INTEGER_2 = "2",