mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
Fix incorrect handling of cfg'd varargs
This commit is contained in:
parent
9cbafa2d49
commit
f2fa456a8c
8 changed files with 37 additions and 16 deletions
|
@ -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()),
|
||||
|
|
|
@ -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! {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, "...");
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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(", ")?;
|
||||
|
|
|
@ -56,6 +56,7 @@ macro_rules! define_symbols {
|
|||
define_symbols! {
|
||||
@WITH_NAME:
|
||||
|
||||
dotdotdot = "...",
|
||||
INTEGER_0 = "0",
|
||||
INTEGER_1 = "1",
|
||||
INTEGER_2 = "2",
|
||||
|
|
Loading…
Reference in a new issue