diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir_def/src/type_ref.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics/expr.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/display.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 8 |
12 files changed, 100 insertions, 34 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index aa335f1e3..88a8ef9bf 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -27,6 +27,7 @@ pub struct FunctionData { | |||
27 | /// can be called as a method. | 27 | /// can be called as a method. |
28 | pub has_self_param: bool, | 28 | pub has_self_param: bool, |
29 | pub is_unsafe: bool, | 29 | pub is_unsafe: bool, |
30 | pub is_varargs: bool, | ||
30 | pub visibility: RawVisibility, | 31 | pub visibility: RawVisibility, |
31 | } | 32 | } |
32 | 33 | ||
@@ -43,6 +44,7 @@ impl FunctionData { | |||
43 | attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), | 44 | attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), |
44 | has_self_param: func.has_self_param, | 45 | has_self_param: func.has_self_param, |
45 | is_unsafe: func.is_unsafe, | 46 | is_unsafe: func.is_unsafe, |
47 | is_varargs: func.is_varargs, | ||
46 | visibility: item_tree[func.visibility].clone(), | 48 | visibility: item_tree[func.visibility].clone(), |
47 | }) | 49 | }) |
48 | } | 50 | } |
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 3e603bd55..da79d8ffd 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -503,6 +503,7 @@ pub struct Function { | |||
503 | pub has_self_param: bool, | 503 | pub has_self_param: bool, |
504 | pub is_unsafe: bool, | 504 | pub is_unsafe: bool, |
505 | pub params: Box<[TypeRef]>, | 505 | pub params: Box<[TypeRef]>, |
506 | pub is_varargs: bool, | ||
506 | pub ret_type: TypeRef, | 507 | pub ret_type: TypeRef, |
507 | pub ast_id: FileAstId<ast::FnDef>, | 508 | pub ast_id: FileAstId<ast::FnDef>, |
508 | } | 509 | } |
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index 4182a9e3b..f79b8fca3 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs | |||
@@ -313,6 +313,14 @@ impl Ctx { | |||
313 | params.push(type_ref); | 313 | params.push(type_ref); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | |||
317 | let mut is_varargs = false; | ||
318 | if let Some(params) = func.param_list() { | ||
319 | if let Some(last) = params.params().last() { | ||
320 | is_varargs = last.dotdotdot_token().is_some(); | ||
321 | } | ||
322 | } | ||
323 | |||
316 | let ret_type = match func.ret_type().and_then(|rt| rt.type_ref()) { | 324 | let ret_type = match func.ret_type().and_then(|rt| rt.type_ref()) { |
317 | Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), | 325 | Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref), |
318 | _ => TypeRef::unit(), | 326 | _ => TypeRef::unit(), |
@@ -334,6 +342,7 @@ impl Ctx { | |||
334 | has_self_param, | 342 | has_self_param, |
335 | is_unsafe: func.unsafe_token().is_some(), | 343 | is_unsafe: func.unsafe_token().is_some(), |
336 | params: params.into_boxed_slice(), | 344 | params: params.into_boxed_slice(), |
345 | is_varargs, | ||
337 | ret_type, | 346 | ret_type, |
338 | ast_id, | 347 | ast_id, |
339 | }; | 348 | }; |
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs index a0431dbce..f26982985 100644 --- a/crates/ra_hir_def/src/item_tree/tests.rs +++ b/crates/ra_hir_def/src/item_tree/tests.rs | |||
@@ -240,9 +240,9 @@ fn smoke() { | |||
240 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }] | 240 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }] |
241 | > Const { name: Some(Name(Text("CONST"))), visibility: RawVisibilityId("pub(self)"), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ConstDef>(9) } | 241 | > Const { name: Some(Name(Text("CONST"))), visibility: RawVisibilityId("pub(self)"), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ConstDef>(9) } |
242 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }] | 242 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }] |
243 | > Function { name: Name(Text("method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Shared)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(10) } | 243 | > Function { name: Name(Text("method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Shared)], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(10) } |
244 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_dfl_method"))] }, input: None }]) }] | 244 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_dfl_method"))] }, input: None }]) }] |
245 | > Function { name: Name(Text("dfl_method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Mut)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(11) } | 245 | > Function { name: Name(Text("dfl_method")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Mut)], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(11) } |
246 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }] | 246 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }] |
247 | Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } | 247 | Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } |
248 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }] | 248 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }] |
@@ -275,12 +275,12 @@ fn simple_inner_items() { | |||
275 | 275 | ||
276 | top-level items: | 276 | top-level items: |
277 | Impl { generic_params: GenericParamsId(0), target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | 277 | Impl { generic_params: GenericParamsId(0), target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } |
278 | > Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | 278 | > Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } |
279 | 279 | ||
280 | inner items: | 280 | inner items: |
281 | 281 | ||
282 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): | 282 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): |
283 | Function { name: Name(Text("end")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 283 | Function { name: Name(Text("end")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } |
284 | 284 | ||
285 | "#]], | 285 | "#]], |
286 | ); | 286 | ); |
@@ -303,9 +303,9 @@ fn extern_attrs() { | |||
303 | 303 | ||
304 | top-level items: | 304 | top-level items: |
305 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] | 305 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] |
306 | Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | 306 | Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } |
307 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] | 307 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] |
308 | Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 308 | Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: true, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } |
309 | "##]], | 309 | "##]], |
310 | ); | 310 | ); |
311 | } | 311 | } |
@@ -329,9 +329,9 @@ fn trait_attrs() { | |||
329 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }] | 329 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }] |
330 | Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(0) } | 330 | Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(0), auto: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(0) } |
331 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] | 331 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] |
332 | > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | 332 | > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } |
333 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] | 333 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] |
334 | > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 334 | > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } |
335 | "##]], | 335 | "##]], |
336 | ); | 336 | ); |
337 | } | 337 | } |
@@ -355,9 +355,9 @@ fn impl_attrs() { | |||
355 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }] | 355 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }] |
356 | Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Ty"))] }, generic_args: [None] }), is_negative: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | 356 | Impl { generic_params: GenericParamsId(4294967295), target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Ty"))] }, generic_args: [None] }), is_negative: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } |
357 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] | 357 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] |
358 | > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | 358 | > Function { name: Name(Text("a")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } |
359 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] | 359 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] |
360 | > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 360 | > Function { name: Name(Text("b")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } |
361 | "##]], | 361 | "##]], |
362 | ); | 362 | ); |
363 | } | 363 | } |
@@ -408,13 +408,13 @@ fn inner_item_attrs() { | |||
408 | inner attrs: Attrs { entries: None } | 408 | inner attrs: Attrs { entries: None } |
409 | 409 | ||
410 | top-level items: | 410 | top-level items: |
411 | Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(0) } | 411 | Function { name: Name(Text("foo")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(0) } |
412 | 412 | ||
413 | inner items: | 413 | inner items: |
414 | 414 | ||
415 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(1): | 415 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(1): |
416 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_inner"))] }, input: None }]) }] | 416 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_inner"))] }, input: None }]) }] |
417 | Function { name: Name(Text("inner")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | 417 | Function { name: Name(Text("inner")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), has_self_param: false, is_unsafe: false, params: [], is_varargs: false, ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } |
418 | 418 | ||
419 | "##]], | 419 | "##]], |
420 | ); | 420 | ); |
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs index 86a77b704..e90b2a0b9 100644 --- a/crates/ra_hir_def/src/type_ref.rs +++ b/crates/ra_hir_def/src/type_ref.rs | |||
@@ -63,7 +63,7 @@ pub enum TypeRef { | |||
63 | Array(Box<TypeRef> /*, Expr*/), | 63 | Array(Box<TypeRef> /*, Expr*/), |
64 | Slice(Box<TypeRef>), | 64 | Slice(Box<TypeRef>), |
65 | /// A fn pointer. Last element of the vector is the return type. | 65 | /// A fn pointer. Last element of the vector is the return type. |
66 | Fn(Vec<TypeRef>), | 66 | Fn(Vec<TypeRef>, bool /*varargs*/), |
67 | // For | 67 | // For |
68 | ImplTrait(Vec<TypeBound>), | 68 | ImplTrait(Vec<TypeBound>), |
69 | DynTrait(Vec<TypeBound>), | 69 | DynTrait(Vec<TypeBound>), |
@@ -118,7 +118,12 @@ impl TypeRef { | |||
118 | .and_then(|rt| rt.type_ref()) | 118 | .and_then(|rt| rt.type_ref()) |
119 | .map(|it| TypeRef::from_ast(ctx, it)) | 119 | .map(|it| TypeRef::from_ast(ctx, it)) |
120 | .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); | 120 | .unwrap_or_else(|| TypeRef::Tuple(Vec::new())); |
121 | let mut is_varargs = false; | ||
121 | let mut params = if let Some(pl) = inner.param_list() { | 122 | let mut params = if let Some(pl) = inner.param_list() { |
123 | if let Some(param) = pl.params().last() { | ||
124 | is_varargs = param.dotdotdot_token().is_some(); | ||
125 | } | ||
126 | |||
122 | pl.params() | 127 | pl.params() |
123 | .map(|p| p.ascribed_type()) | 128 | .map(|p| p.ascribed_type()) |
124 | .map(|it| TypeRef::from_ast_opt(&ctx, it)) | 129 | .map(|it| TypeRef::from_ast_opt(&ctx, it)) |
@@ -127,7 +132,7 @@ impl TypeRef { | |||
127 | Vec::new() | 132 | Vec::new() |
128 | }; | 133 | }; |
129 | params.push(ret_ty); | 134 | params.push(ret_ty); |
130 | TypeRef::Fn(params) | 135 | TypeRef::Fn(params, is_varargs) |
131 | } | 136 | } |
132 | // for types are close enough for our purposes to the inner type for now... | 137 | // for types are close enough for our purposes to the inner type for now... |
133 | ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), | 138 | ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(&ctx, inner.type_ref()), |
@@ -158,7 +163,9 @@ impl TypeRef { | |||
158 | fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) { | 163 | fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) { |
159 | f(type_ref); | 164 | f(type_ref); |
160 | match type_ref { | 165 | match type_ref { |
161 | TypeRef::Fn(types) | TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)), | 166 | TypeRef::Fn(types, _) | TypeRef::Tuple(types) => { |
167 | types.iter().for_each(|t| go(t, f)) | ||
168 | } | ||
162 | TypeRef::RawPtr(type_ref, _) | 169 | TypeRef::RawPtr(type_ref, _) |
163 | | TypeRef::Reference(type_ref, _) | 170 | | TypeRef::Reference(type_ref, _) |
164 | | TypeRef::Array(type_ref) | 171 | | TypeRef::Array(type_ref) |
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/diagnostics/expr.rs index 21ff99a8c..557d01cdc 100644 --- a/crates/ra_hir_ty/src/diagnostics/expr.rs +++ b/crates/ra_hir_ty/src/diagnostics/expr.rs | |||
@@ -175,6 +175,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
175 | }; | 175 | }; |
176 | 176 | ||
177 | let sig = db.callable_item_signature(callee); | 177 | let sig = db.callable_item_signature(callee); |
178 | if sig.value.is_varargs { | ||
179 | return None; | ||
180 | } | ||
181 | |||
178 | let params = sig.value.params(); | 182 | let params = sig.value.params(); |
179 | 183 | ||
180 | let mut param_count = params.len(); | 184 | let mut param_count = params.len(); |
@@ -512,4 +516,30 @@ impl Foo { | |||
512 | "#, | 516 | "#, |
513 | ); | 517 | ); |
514 | } | 518 | } |
519 | |||
520 | #[test] | ||
521 | fn varargs() { | ||
522 | check_diagnostics( | ||
523 | r#" | ||
524 | extern "C" { | ||
525 | fn fixed(fixed: u8); | ||
526 | fn varargs(fixed: u8, ...); | ||
527 | fn varargs2(...); | ||
528 | } | ||
529 | |||
530 | fn f() { | ||
531 | unsafe { | ||
532 | fixed(0); | ||
533 | fixed(0, 1); | ||
534 | //^^^^^^^^^^^ Expected 1 argument, found 2 | ||
535 | varargs(0); | ||
536 | varargs(0, 1); | ||
537 | varargs2(); | ||
538 | varargs2(0); | ||
539 | varargs2(0, 1); | ||
540 | } | ||
541 | } | ||
542 | "#, | ||
543 | ) | ||
544 | } | ||
515 | } | 545 | } |
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index ac68c5661..c860c254c 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs | |||
@@ -243,10 +243,17 @@ impl HirDisplay for ApplicationTy { | |||
243 | write!(f, ")")?; | 243 | write!(f, ")")?; |
244 | } | 244 | } |
245 | } | 245 | } |
246 | TypeCtor::FnPtr { .. } => { | 246 | TypeCtor::FnPtr { is_varargs, .. } => { |
247 | let sig = FnSig::from_fn_ptr_substs(&self.parameters); | 247 | let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); |
248 | write!(f, "fn(")?; | 248 | write!(f, "fn(")?; |
249 | f.write_joined(sig.params(), ", ")?; | 249 | f.write_joined(sig.params(), ", ")?; |
250 | if is_varargs { | ||
251 | if sig.params().is_empty() { | ||
252 | write!(f, "...")?; | ||
253 | } else { | ||
254 | write!(f, ", ...")?; | ||
255 | } | ||
256 | } | ||
250 | write!(f, ")")?; | 257 | write!(f, ")")?; |
251 | let ret = sig.ret(); | 258 | let ret = sig.ret(); |
252 | if *ret != Ty::unit() { | 259 | if *ret != Ty::unit() { |
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index bd9a387f5..ab586b018 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -220,7 +220,7 @@ impl<'a> InferenceContext<'a> { | |||
220 | }; | 220 | }; |
221 | sig_tys.push(ret_ty.clone()); | 221 | sig_tys.push(ret_ty.clone()); |
222 | let sig_ty = Ty::apply( | 222 | let sig_ty = Ty::apply( |
223 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, | 223 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, |
224 | Substs(sig_tys.clone().into()), | 224 | Substs(sig_tys.clone().into()), |
225 | ); | 225 | ); |
226 | let closure_ty = | 226 | let closure_ty = |
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index d54568e67..c4c24a83b 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -112,7 +112,7 @@ pub enum TypeCtor { | |||
112 | /// fn foo() -> i32 { 1 } | 112 | /// fn foo() -> i32 { 1 } |
113 | /// let bar: fn() -> i32 = foo; | 113 | /// let bar: fn() -> i32 = foo; |
114 | /// ``` | 114 | /// ``` |
115 | FnPtr { num_args: u16 }, | 115 | FnPtr { num_args: u16, is_varargs: bool }, |
116 | 116 | ||
117 | /// The never type `!`. | 117 | /// The never type `!`. |
118 | Never, | 118 | Never, |
@@ -187,7 +187,7 @@ impl TypeCtor { | |||
187 | } | 187 | } |
188 | } | 188 | } |
189 | } | 189 | } |
190 | TypeCtor::FnPtr { num_args } => num_args as usize + 1, | 190 | TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1, |
191 | TypeCtor::Tuple { cardinality } => cardinality as usize, | 191 | TypeCtor::Tuple { cardinality } => cardinality as usize, |
192 | } | 192 | } |
193 | } | 193 | } |
@@ -667,19 +667,20 @@ pub enum TyKind { | |||
667 | #[derive(Clone, PartialEq, Eq, Debug)] | 667 | #[derive(Clone, PartialEq, Eq, Debug)] |
668 | pub struct FnSig { | 668 | pub struct FnSig { |
669 | params_and_return: Arc<[Ty]>, | 669 | params_and_return: Arc<[Ty]>, |
670 | is_varargs: bool, | ||
670 | } | 671 | } |
671 | 672 | ||
672 | /// A polymorphic function signature. | 673 | /// A polymorphic function signature. |
673 | pub type PolyFnSig = Binders<FnSig>; | 674 | pub type PolyFnSig = Binders<FnSig>; |
674 | 675 | ||
675 | impl FnSig { | 676 | impl FnSig { |
676 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig { | 677 | pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { |
677 | params.push(ret); | 678 | params.push(ret); |
678 | FnSig { params_and_return: params.into() } | 679 | FnSig { params_and_return: params.into(), is_varargs } |
679 | } | 680 | } |
680 | 681 | ||
681 | pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig { | 682 | pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { |
682 | FnSig { params_and_return: Arc::clone(&substs.0) } | 683 | FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } |
683 | } | 684 | } |
684 | 685 | ||
685 | pub fn params(&self) -> &[Ty] { | 686 | pub fn params(&self) -> &[Ty] { |
@@ -724,7 +725,7 @@ impl Ty { | |||
724 | } | 725 | } |
725 | pub fn fn_ptr(sig: FnSig) -> Self { | 726 | pub fn fn_ptr(sig: FnSig) -> Self { |
726 | Ty::apply( | 727 | Ty::apply( |
727 | TypeCtor::FnPtr { num_args: sig.params().len() as u16 }, | 728 | TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, |
728 | Substs(sig.params_and_return), | 729 | Substs(sig.params_and_return), |
729 | ) | 730 | ) |
730 | } | 731 | } |
@@ -821,7 +822,9 @@ impl Ty { | |||
821 | fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { | 822 | fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { |
822 | match self { | 823 | match self { |
823 | Ty::Apply(a_ty) => match a_ty.ctor { | 824 | Ty::Apply(a_ty) => match a_ty.ctor { |
824 | TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)), | 825 | TypeCtor::FnPtr { is_varargs, .. } => { |
826 | Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) | ||
827 | } | ||
825 | TypeCtor::FnDef(def) => { | 828 | TypeCtor::FnDef(def) => { |
826 | let sig = db.callable_item_signature(def); | 829 | let sig = db.callable_item_signature(def); |
827 | Some(sig.subst(&a_ty.parameters)) | 830 | Some(sig.subst(&a_ty.parameters)) |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 101b8aebe..6f4398e84 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -176,9 +176,12 @@ impl Ty { | |||
176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 176 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
177 | } | 177 | } |
178 | TypeRef::Placeholder => Ty::Unknown, | 178 | TypeRef::Placeholder => Ty::Unknown, |
179 | TypeRef::Fn(params) => { | 179 | TypeRef::Fn(params, is_varargs) => { |
180 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); | 180 | let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); |
181 | Ty::apply(TypeCtor::FnPtr { num_args: sig.len() as u16 - 1 }, sig) | 181 | Ty::apply( |
182 | TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, | ||
183 | sig, | ||
184 | ) | ||
182 | } | 185 | } |
183 | TypeRef::DynTrait(bounds) => { | 186 | TypeRef::DynTrait(bounds) => { |
184 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 187 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); |
@@ -996,7 +999,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
996 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 999 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); |
997 | let generics = generics(db.upcast(), def.into()); | 1000 | let generics = generics(db.upcast(), def.into()); |
998 | let num_binders = generics.len(); | 1001 | let num_binders = generics.len(); |
999 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret)) | 1002 | Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) |
1000 | } | 1003 | } |
1001 | 1004 | ||
1002 | /// Build the declared type of a function. This should not need to look at the | 1005 | /// Build the declared type of a function. This should not need to look at the |
@@ -1047,7 +1050,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1047 | let params = | 1050 | let params = |
1048 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1051 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1049 | let ret = type_for_adt(db, def.into()); | 1052 | let ret = type_for_adt(db, def.into()); |
1050 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value)) | 1053 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) |
1051 | } | 1054 | } |
1052 | 1055 | ||
1053 | /// Build the type of a tuple struct constructor. | 1056 | /// Build the type of a tuple struct constructor. |
@@ -1071,7 +1074,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1071 | let params = | 1074 | let params = |
1072 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | 1075 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); |
1073 | let ret = type_for_adt(db, def.parent.into()); | 1076 | let ret = type_for_adt(db, def.parent.into()); |
1074 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value)) | 1077 | Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) |
1075 | } | 1078 | } |
1076 | 1079 | ||
1077 | /// Build the type of a tuple enum variant constructor. | 1080 | /// Build the type of a tuple enum variant constructor. |
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs index 86e22e459..60cc9a9f5 100644 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ b/crates/ra_hir_ty/src/traits/builtin.rs | |||
@@ -121,7 +121,7 @@ fn closure_fn_trait_impl_datum( | |||
121 | .build(), | 121 | .build(), |
122 | ); | 122 | ); |
123 | let sig_ty = Ty::apply( | 123 | let sig_ty = Ty::apply( |
124 | TypeCtor::FnPtr { num_args }, | 124 | TypeCtor::FnPtr { num_args, is_varargs: false }, |
125 | Substs::builder(num_args as usize + 1) | 125 | Substs::builder(num_args as usize + 1) |
126 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) | 126 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) |
127 | .build(), | 127 | .build(), |
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 06453ef82..3ebb55f77 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs | |||
@@ -30,7 +30,8 @@ impl ToChalk for Ty { | |||
30 | Ty::Apply(apply_ty) => match apply_ty.ctor { | 30 | Ty::Apply(apply_ty) => match apply_ty.ctor { |
31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), | 31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), |
32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), | 32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), |
33 | TypeCtor::FnPtr { num_args: _ } => { | 33 | TypeCtor::FnPtr { num_args: _, is_varargs: _ } => { |
34 | // FIXME: handle is_varargs | ||
34 | let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); | 35 | let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); |
35 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) | 36 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) |
36 | .intern(&Interner) | 37 | .intern(&Interner) |
@@ -124,7 +125,10 @@ impl ToChalk for Ty { | |||
124 | substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), | 125 | substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), |
125 | ); | 126 | ); |
126 | Ty::Apply(ApplicationTy { | 127 | Ty::Apply(ApplicationTy { |
127 | ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, | 128 | ctor: TypeCtor::FnPtr { |
129 | num_args: (parameters.len() - 1) as u16, | ||
130 | is_varargs: false, | ||
131 | }, | ||
128 | parameters, | 132 | parameters, |
129 | }) | 133 | }) |
130 | } | 134 | } |