Skip to content

Commit d744b7c

Browse files
committed
Fix incorrect handling of cfg'd varargs
1 parent 8e0d60e commit d744b7c

File tree

8 files changed

+37
-16
lines changed

8 files changed

+37
-16
lines changed

src/tools/rust-analyzer/crates/hir-def/src/data.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ impl FunctionData {
7373
flags.remove(FnFlags::HAS_SELF_PARAM);
7474
}
7575
}
76+
if flags.contains(FnFlags::IS_VARARGS) {
77+
if let Some((_, param)) = func.params.iter().enumerate().rev().find(|&(idx, _)| {
78+
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
79+
}) {
80+
if param.type_ref.is_some() {
81+
flags.remove(FnFlags::IS_VARARGS);
82+
}
83+
} else {
84+
flags.remove(FnFlags::IS_VARARGS);
85+
}
86+
}
7687

7788
let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
7889
let legacy_const_generics_indices = attrs
@@ -92,7 +103,7 @@ impl FunctionData {
92103
.filter(|&(idx, _)| {
93104
item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options)
94105
})
95-
.map(|(_, param)| param.type_ref.clone())
106+
.filter_map(|(_, param)| param.type_ref.clone())
96107
.collect(),
97108
ret_type: func.ret_type.clone(),
98109
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),

src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ pub struct Function {
741741

742742
#[derive(Debug, Clone, PartialEq, Eq)]
743743
pub struct Param {
744-
pub type_ref: Interned<TypeRef>,
744+
pub type_ref: Option<Interned<TypeRef>>,
745745
}
746746

747747
bitflags::bitflags! {

src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,20 +380,20 @@ impl<'a> Ctx<'a> {
380380
}
381381
};
382382
let type_ref = Interned::new(self_type);
383-
params.push(Param { type_ref });
383+
params.push(Param { type_ref: Some(type_ref) });
384384
has_self_param = true;
385385
}
386386
for param in param_list.params() {
387387
push_attr(params.len(), RawAttrs::new(self.db.upcast(), &param, self.span_map()));
388388
let param = match param.dotdotdot_token() {
389389
Some(_) => {
390390
has_var_args = true;
391-
Param { type_ref: Interned::new(TypeRef::Error) }
391+
Param { type_ref: None }
392392
}
393393
None => {
394394
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
395395
let ty = Interned::new(type_ref);
396-
Param { type_ref: ty }
396+
Param { type_ref: Some(ty) }
397397
}
398398
};
399399
params.push(param);

src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl Printer<'_> {
291291
if idx == 0 && flags.contains(FnFlags::HAS_SELF_PARAM) {
292292
w!(this, "self: ");
293293
}
294-
if idx != params.len() {
294+
if let Some(type_ref) = type_ref {
295295
this.print_type_ref(type_ref);
296296
} else {
297297
wln!(this, "...");

src/tools/rust-analyzer/crates/hir-ty/src/infer.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -812,9 +812,7 @@ impl<'a> InferenceContext<'a> {
812812
None => self.err_ty(),
813813
};
814814

815-
if let Some(ty) = param_tys.last_mut() {
816-
*ty = va_list_ty;
817-
}
815+
param_tys.push(va_list_ty);
818816
}
819817
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
820818
if let Some(self_param) = self.body.self_param {

src/tools/rust-analyzer/crates/hir-ty/src/tests/patterns.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,23 @@ fn var_args() {
11261126
pub struct VaListImpl<'f>;
11271127
fn my_fn(foo: ...) {}
11281128
//^^^ VaListImpl<'?>
1129+
fn my_fn2(bar: u32, foo: ...) {}
1130+
//^^^ VaListImpl<'?>
1131+
"#,
1132+
);
1133+
}
1134+
1135+
#[test]
1136+
fn var_args_cond() {
1137+
check_types(
1138+
r#"
1139+
#[lang = "va_list"]
1140+
pub struct VaListImpl<'f>;
1141+
fn my_fn(bar: u32, #[cfg(FALSE)] foo: ..., #[cfg(not(FALSE))] foo: u32) {
1142+
foo;
1143+
//^^^ u32
1144+
1145+
}
11291146
"#,
11301147
);
11311148
}

src/tools/rust-analyzer/crates/hir/src/display.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,7 @@ impl HirDisplay for Function {
9999
}
100100

101101
// FIXME: Use resolved `param.ty` once we no longer discard lifetimes
102-
for (type_ref, param) in data
103-
.params
104-
.iter()
105-
.zip(self.assoc_fn_params(db))
106-
.take(data.params.len() - data.is_varargs() as usize)
107-
.skip(skip_self)
108-
{
102+
for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
109103
let local = param.as_local(db).map(|it| it.name(db));
110104
if !first {
111105
f.write_str(", ")?;

src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ macro_rules! define_symbols {
5656
define_symbols! {
5757
@WITH_NAME:
5858

59+
dotdotdot = "...",
5960
INTEGER_0 = "0",
6061
INTEGER_1 = "1",
6162
INTEGER_2 = "2",

0 commit comments

Comments
 (0)