diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/expr.rs | 428 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/lower.rs | 84 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 38 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 26 |
7 files changed, 73 insertions, 528 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 53da7f0bf..ddf605111 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -6,35 +6,22 @@ pub(crate) mod validation; | |||
6 | 6 | ||
7 | use std::{ops::Index, sync::Arc}; | 7 | use std::{ops::Index, sync::Arc}; |
8 | 8 | ||
9 | use hir_def::{ | 9 | use ra_arena::{map::ArenaMap, Arena}; |
10 | path::GenericArgs, | ||
11 | type_ref::{Mutability, TypeRef}, | ||
12 | }; | ||
13 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | ||
14 | use ra_syntax::{ast, AstPtr}; | 10 | use ra_syntax::{ast, AstPtr}; |
15 | use rustc_hash::FxHashMap; | 11 | use rustc_hash::FxHashMap; |
16 | 12 | ||
17 | use crate::{ | 13 | use crate::{db::HirDatabase, DefWithBody, Either, HasSource, Resolver, Source}; |
18 | db::HirDatabase, | ||
19 | ty::primitive::{UncertainFloatTy, UncertainIntTy}, | ||
20 | DefWithBody, Either, HasSource, Name, Path, Resolver, Source, | ||
21 | }; | ||
22 | 14 | ||
23 | pub use self::scope::ExprScopes; | 15 | pub use self::scope::ExprScopes; |
24 | 16 | ||
25 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 17 | pub use hir_def::expr::{ |
26 | pub struct ExprId(RawId); | 18 | ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, MatchArm, |
27 | impl_arena_id!(ExprId); | 19 | Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, |
28 | 20 | }; | |
29 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
30 | pub struct PatId(RawId); | ||
31 | impl_arena_id!(PatId); | ||
32 | 21 | ||
33 | /// The body of an item (function, const etc.). | 22 | /// The body of an item (function, const etc.). |
34 | #[derive(Debug, Eq, PartialEq)] | 23 | #[derive(Debug, Eq, PartialEq)] |
35 | pub struct Body { | 24 | pub struct Body { |
36 | /// The def of the item this body belongs to | ||
37 | owner: DefWithBody, | ||
38 | exprs: Arena<ExprId, Expr>, | 25 | exprs: Arena<ExprId, Expr>, |
39 | pats: Arena<PatId, Pat>, | 26 | pats: Arena<PatId, Pat>, |
40 | /// The patterns for the function's parameters. While the parameter types are | 27 | /// The patterns for the function's parameters. While the parameter types are |
@@ -97,7 +84,7 @@ impl Body { | |||
97 | } | 84 | } |
98 | }; | 85 | }; |
99 | 86 | ||
100 | let (body, source_map) = lower::lower(db, def.resolver(db), file_id, def, params, body); | 87 | let (body, source_map) = lower::lower(db, def.resolver(db), file_id, params, body); |
101 | (Arc::new(body), Arc::new(source_map)) | 88 | (Arc::new(body), Arc::new(source_map)) |
102 | } | 89 | } |
103 | 90 | ||
@@ -113,10 +100,6 @@ impl Body { | |||
113 | self.body_expr | 100 | self.body_expr |
114 | } | 101 | } |
115 | 102 | ||
116 | pub fn owner(&self) -> DefWithBody { | ||
117 | self.owner | ||
118 | } | ||
119 | |||
120 | pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> { | 103 | pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> { |
121 | self.exprs.iter() | 104 | self.exprs.iter() |
122 | } | 105 | } |
@@ -128,21 +111,21 @@ impl Body { | |||
128 | 111 | ||
129 | // needs arbitrary_self_types to be a method... or maybe move to the def? | 112 | // needs arbitrary_self_types to be a method... or maybe move to the def? |
130 | pub(crate) fn resolver_for_expr( | 113 | pub(crate) fn resolver_for_expr( |
131 | body: Arc<Body>, | ||
132 | db: &impl HirDatabase, | 114 | db: &impl HirDatabase, |
115 | owner: DefWithBody, | ||
133 | expr_id: ExprId, | 116 | expr_id: ExprId, |
134 | ) -> Resolver { | 117 | ) -> Resolver { |
135 | let scopes = db.expr_scopes(body.owner); | 118 | let scopes = db.expr_scopes(owner); |
136 | resolver_for_scope(body, db, scopes.scope_for(expr_id)) | 119 | resolver_for_scope(db, owner, scopes.scope_for(expr_id)) |
137 | } | 120 | } |
138 | 121 | ||
139 | pub(crate) fn resolver_for_scope( | 122 | pub(crate) fn resolver_for_scope( |
140 | body: Arc<Body>, | ||
141 | db: &impl HirDatabase, | 123 | db: &impl HirDatabase, |
124 | owner: DefWithBody, | ||
142 | scope_id: Option<scope::ScopeId>, | 125 | scope_id: Option<scope::ScopeId>, |
143 | ) -> Resolver { | 126 | ) -> Resolver { |
144 | let mut r = body.owner.resolver(db); | 127 | let mut r = owner.resolver(db); |
145 | let scopes = db.expr_scopes(body.owner); | 128 | let scopes = db.expr_scopes(owner); |
146 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | 129 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); |
147 | for scope in scope_chain.into_iter().rev() { | 130 | for scope in scope_chain.into_iter().rev() { |
148 | r = r.push_expr_scope(Arc::clone(&scopes), scope); | 131 | r = r.push_expr_scope(Arc::clone(&scopes), scope); |
@@ -187,388 +170,3 @@ impl BodySourceMap { | |||
187 | self.field_map[&(expr, field)] | 170 | self.field_map[&(expr, field)] |
188 | } | 171 | } |
189 | } | 172 | } |
190 | |||
191 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
192 | pub enum Literal { | ||
193 | String(String), | ||
194 | ByteString(Vec<u8>), | ||
195 | Char(char), | ||
196 | Bool(bool), | ||
197 | Int(u64, UncertainIntTy), | ||
198 | Float(u64, UncertainFloatTy), // FIXME: f64 is not Eq | ||
199 | } | ||
200 | |||
201 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
202 | pub enum Expr { | ||
203 | /// This is produced if syntax tree does not have a required expression piece. | ||
204 | Missing, | ||
205 | Path(Path), | ||
206 | If { | ||
207 | condition: ExprId, | ||
208 | then_branch: ExprId, | ||
209 | else_branch: Option<ExprId>, | ||
210 | }, | ||
211 | Block { | ||
212 | statements: Vec<Statement>, | ||
213 | tail: Option<ExprId>, | ||
214 | }, | ||
215 | Loop { | ||
216 | body: ExprId, | ||
217 | }, | ||
218 | While { | ||
219 | condition: ExprId, | ||
220 | body: ExprId, | ||
221 | }, | ||
222 | For { | ||
223 | iterable: ExprId, | ||
224 | pat: PatId, | ||
225 | body: ExprId, | ||
226 | }, | ||
227 | Call { | ||
228 | callee: ExprId, | ||
229 | args: Vec<ExprId>, | ||
230 | }, | ||
231 | MethodCall { | ||
232 | receiver: ExprId, | ||
233 | method_name: Name, | ||
234 | args: Vec<ExprId>, | ||
235 | generic_args: Option<GenericArgs>, | ||
236 | }, | ||
237 | Match { | ||
238 | expr: ExprId, | ||
239 | arms: Vec<MatchArm>, | ||
240 | }, | ||
241 | Continue, | ||
242 | Break { | ||
243 | expr: Option<ExprId>, | ||
244 | }, | ||
245 | Return { | ||
246 | expr: Option<ExprId>, | ||
247 | }, | ||
248 | RecordLit { | ||
249 | path: Option<Path>, | ||
250 | fields: Vec<RecordLitField>, | ||
251 | spread: Option<ExprId>, | ||
252 | }, | ||
253 | Field { | ||
254 | expr: ExprId, | ||
255 | name: Name, | ||
256 | }, | ||
257 | Await { | ||
258 | expr: ExprId, | ||
259 | }, | ||
260 | Try { | ||
261 | expr: ExprId, | ||
262 | }, | ||
263 | TryBlock { | ||
264 | body: ExprId, | ||
265 | }, | ||
266 | Cast { | ||
267 | expr: ExprId, | ||
268 | type_ref: TypeRef, | ||
269 | }, | ||
270 | Ref { | ||
271 | expr: ExprId, | ||
272 | mutability: Mutability, | ||
273 | }, | ||
274 | Box { | ||
275 | expr: ExprId, | ||
276 | }, | ||
277 | UnaryOp { | ||
278 | expr: ExprId, | ||
279 | op: UnaryOp, | ||
280 | }, | ||
281 | BinaryOp { | ||
282 | lhs: ExprId, | ||
283 | rhs: ExprId, | ||
284 | op: Option<BinaryOp>, | ||
285 | }, | ||
286 | Index { | ||
287 | base: ExprId, | ||
288 | index: ExprId, | ||
289 | }, | ||
290 | Lambda { | ||
291 | args: Vec<PatId>, | ||
292 | arg_types: Vec<Option<TypeRef>>, | ||
293 | body: ExprId, | ||
294 | }, | ||
295 | Tuple { | ||
296 | exprs: Vec<ExprId>, | ||
297 | }, | ||
298 | Array(Array), | ||
299 | Literal(Literal), | ||
300 | } | ||
301 | |||
302 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
303 | pub enum BinaryOp { | ||
304 | LogicOp(LogicOp), | ||
305 | ArithOp(ArithOp), | ||
306 | CmpOp(CmpOp), | ||
307 | Assignment { op: Option<ArithOp> }, | ||
308 | } | ||
309 | |||
310 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
311 | pub enum LogicOp { | ||
312 | And, | ||
313 | Or, | ||
314 | } | ||
315 | |||
316 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
317 | pub enum CmpOp { | ||
318 | Eq { negated: bool }, | ||
319 | Ord { ordering: Ordering, strict: bool }, | ||
320 | } | ||
321 | |||
322 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
323 | pub enum Ordering { | ||
324 | Less, | ||
325 | Greater, | ||
326 | } | ||
327 | |||
328 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
329 | pub enum ArithOp { | ||
330 | Add, | ||
331 | Mul, | ||
332 | Sub, | ||
333 | Div, | ||
334 | Rem, | ||
335 | Shl, | ||
336 | Shr, | ||
337 | BitXor, | ||
338 | BitOr, | ||
339 | BitAnd, | ||
340 | } | ||
341 | |||
342 | pub use ra_syntax::ast::PrefixOp as UnaryOp; | ||
343 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
344 | pub enum Array { | ||
345 | ElementList(Vec<ExprId>), | ||
346 | Repeat { initializer: ExprId, repeat: ExprId }, | ||
347 | } | ||
348 | |||
349 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
350 | pub struct MatchArm { | ||
351 | pub pats: Vec<PatId>, | ||
352 | pub guard: Option<ExprId>, | ||
353 | pub expr: ExprId, | ||
354 | } | ||
355 | |||
356 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
357 | pub struct RecordLitField { | ||
358 | pub name: Name, | ||
359 | pub expr: ExprId, | ||
360 | } | ||
361 | |||
362 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
363 | pub enum Statement { | ||
364 | Let { pat: PatId, type_ref: Option<TypeRef>, initializer: Option<ExprId> }, | ||
365 | Expr(ExprId), | ||
366 | } | ||
367 | |||
368 | impl Expr { | ||
369 | pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) { | ||
370 | match self { | ||
371 | Expr::Missing => {} | ||
372 | Expr::Path(_) => {} | ||
373 | Expr::If { condition, then_branch, else_branch } => { | ||
374 | f(*condition); | ||
375 | f(*then_branch); | ||
376 | if let Some(else_branch) = else_branch { | ||
377 | f(*else_branch); | ||
378 | } | ||
379 | } | ||
380 | Expr::Block { statements, tail } => { | ||
381 | for stmt in statements { | ||
382 | match stmt { | ||
383 | Statement::Let { initializer, .. } => { | ||
384 | if let Some(expr) = initializer { | ||
385 | f(*expr); | ||
386 | } | ||
387 | } | ||
388 | Statement::Expr(e) => f(*e), | ||
389 | } | ||
390 | } | ||
391 | if let Some(expr) = tail { | ||
392 | f(*expr); | ||
393 | } | ||
394 | } | ||
395 | Expr::TryBlock { body } => f(*body), | ||
396 | Expr::Loop { body } => f(*body), | ||
397 | Expr::While { condition, body } => { | ||
398 | f(*condition); | ||
399 | f(*body); | ||
400 | } | ||
401 | Expr::For { iterable, body, .. } => { | ||
402 | f(*iterable); | ||
403 | f(*body); | ||
404 | } | ||
405 | Expr::Call { callee, args } => { | ||
406 | f(*callee); | ||
407 | for arg in args { | ||
408 | f(*arg); | ||
409 | } | ||
410 | } | ||
411 | Expr::MethodCall { receiver, args, .. } => { | ||
412 | f(*receiver); | ||
413 | for arg in args { | ||
414 | f(*arg); | ||
415 | } | ||
416 | } | ||
417 | Expr::Match { expr, arms } => { | ||
418 | f(*expr); | ||
419 | for arm in arms { | ||
420 | f(arm.expr); | ||
421 | } | ||
422 | } | ||
423 | Expr::Continue => {} | ||
424 | Expr::Break { expr } | Expr::Return { expr } => { | ||
425 | if let Some(expr) = expr { | ||
426 | f(*expr); | ||
427 | } | ||
428 | } | ||
429 | Expr::RecordLit { fields, spread, .. } => { | ||
430 | for field in fields { | ||
431 | f(field.expr); | ||
432 | } | ||
433 | if let Some(expr) = spread { | ||
434 | f(*expr); | ||
435 | } | ||
436 | } | ||
437 | Expr::Lambda { body, .. } => { | ||
438 | f(*body); | ||
439 | } | ||
440 | Expr::BinaryOp { lhs, rhs, .. } => { | ||
441 | f(*lhs); | ||
442 | f(*rhs); | ||
443 | } | ||
444 | Expr::Index { base, index } => { | ||
445 | f(*base); | ||
446 | f(*index); | ||
447 | } | ||
448 | Expr::Field { expr, .. } | ||
449 | | Expr::Await { expr } | ||
450 | | Expr::Try { expr } | ||
451 | | Expr::Cast { expr, .. } | ||
452 | | Expr::Ref { expr, .. } | ||
453 | | Expr::UnaryOp { expr, .. } | ||
454 | | Expr::Box { expr } => { | ||
455 | f(*expr); | ||
456 | } | ||
457 | Expr::Tuple { exprs } => { | ||
458 | for expr in exprs { | ||
459 | f(*expr); | ||
460 | } | ||
461 | } | ||
462 | Expr::Array(a) => match a { | ||
463 | Array::ElementList(exprs) => { | ||
464 | for expr in exprs { | ||
465 | f(*expr); | ||
466 | } | ||
467 | } | ||
468 | Array::Repeat { initializer, repeat } => { | ||
469 | f(*initializer); | ||
470 | f(*repeat) | ||
471 | } | ||
472 | }, | ||
473 | Expr::Literal(_) => {} | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | |||
478 | /// Explicit binding annotations given in the HIR for a binding. Note | ||
479 | /// that this is not the final binding *mode* that we infer after type | ||
480 | /// inference. | ||
481 | #[derive(Clone, PartialEq, Eq, Debug, Copy)] | ||
482 | pub enum BindingAnnotation { | ||
483 | /// No binding annotation given: this means that the final binding mode | ||
484 | /// will depend on whether we have skipped through a `&` reference | ||
485 | /// when matching. For example, the `x` in `Some(x)` will have binding | ||
486 | /// mode `None`; if you do `let Some(x) = &Some(22)`, it will | ||
487 | /// ultimately be inferred to be by-reference. | ||
488 | Unannotated, | ||
489 | |||
490 | /// Annotated with `mut x` -- could be either ref or not, similar to `None`. | ||
491 | Mutable, | ||
492 | |||
493 | /// Annotated as `ref`, like `ref x` | ||
494 | Ref, | ||
495 | |||
496 | /// Annotated as `ref mut x`. | ||
497 | RefMut, | ||
498 | } | ||
499 | |||
500 | impl BindingAnnotation { | ||
501 | fn new(is_mutable: bool, is_ref: bool) -> Self { | ||
502 | match (is_mutable, is_ref) { | ||
503 | (true, true) => BindingAnnotation::RefMut, | ||
504 | (false, true) => BindingAnnotation::Ref, | ||
505 | (true, false) => BindingAnnotation::Mutable, | ||
506 | (false, false) => BindingAnnotation::Unannotated, | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | |||
511 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
512 | pub struct RecordFieldPat { | ||
513 | pub(crate) name: Name, | ||
514 | pub(crate) pat: PatId, | ||
515 | } | ||
516 | |||
517 | /// Close relative to rustc's hir::PatKind | ||
518 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
519 | pub enum Pat { | ||
520 | Missing, | ||
521 | Wild, | ||
522 | Tuple(Vec<PatId>), | ||
523 | Record { | ||
524 | path: Option<Path>, | ||
525 | args: Vec<RecordFieldPat>, | ||
526 | // FIXME: 'ellipsis' option | ||
527 | }, | ||
528 | Range { | ||
529 | start: ExprId, | ||
530 | end: ExprId, | ||
531 | }, | ||
532 | Slice { | ||
533 | prefix: Vec<PatId>, | ||
534 | rest: Option<PatId>, | ||
535 | suffix: Vec<PatId>, | ||
536 | }, | ||
537 | Path(Path), | ||
538 | Lit(ExprId), | ||
539 | Bind { | ||
540 | mode: BindingAnnotation, | ||
541 | name: Name, | ||
542 | subpat: Option<PatId>, | ||
543 | }, | ||
544 | TupleStruct { | ||
545 | path: Option<Path>, | ||
546 | args: Vec<PatId>, | ||
547 | }, | ||
548 | Ref { | ||
549 | pat: PatId, | ||
550 | mutability: Mutability, | ||
551 | }, | ||
552 | } | ||
553 | |||
554 | impl Pat { | ||
555 | pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) { | ||
556 | match self { | ||
557 | Pat::Range { .. } | Pat::Lit(..) | Pat::Path(..) | Pat::Wild | Pat::Missing => {} | ||
558 | Pat::Bind { subpat, .. } => { | ||
559 | subpat.iter().copied().for_each(f); | ||
560 | } | ||
561 | Pat::Tuple(args) | Pat::TupleStruct { args, .. } => { | ||
562 | args.iter().copied().for_each(f); | ||
563 | } | ||
564 | Pat::Ref { pat, .. } => f(*pat), | ||
565 | Pat::Slice { prefix, rest, suffix } => { | ||
566 | let total_iter = prefix.iter().chain(rest.iter()).chain(suffix.iter()); | ||
567 | total_iter.copied().for_each(f); | ||
568 | } | ||
569 | Pat::Record { args, .. } => { | ||
570 | args.iter().map(|f| f.pat).for_each(f); | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | } | ||
diff --git a/crates/ra_hir/src/expr/lower.rs b/crates/ra_hir/src/expr/lower.rs index 6463dd65e..adc68b23c 100644 --- a/crates/ra_hir/src/expr/lower.rs +++ b/crates/ra_hir/src/expr/lower.rs | |||
@@ -1,6 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{path::GenericArgs, type_ref::TypeRef}; | 3 | use hir_def::{ |
4 | builtin_type::{BuiltinFloat, BuiltinInt}, | ||
5 | path::GenericArgs, | ||
6 | type_ref::TypeRef, | ||
7 | }; | ||
4 | use hir_expand::{ | 8 | use hir_expand::{ |
5 | hygiene::Hygiene, | 9 | hygiene::Hygiene, |
6 | name::{self, AsName, Name}, | 10 | name::{self, AsName, Name}, |
@@ -16,22 +20,19 @@ use ra_syntax::{ | |||
16 | use test_utils::tested_by; | 20 | use test_utils::tested_by; |
17 | 21 | ||
18 | use crate::{ | 22 | use crate::{ |
19 | db::HirDatabase, | 23 | db::HirDatabase, AstId, Either, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, |
20 | ty::primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, | 24 | Resolver, Source, |
21 | AstId, DefWithBody, Either, HirFileId, MacroCallLoc, MacroFileKind, Mutability, Path, Resolver, | ||
22 | Source, | ||
23 | }; | 25 | }; |
24 | 26 | ||
25 | use super::{ | 27 | use super::{ |
26 | ArithOp, Array, BinaryOp, BindingAnnotation, Body, BodySourceMap, CmpOp, Expr, ExprId, Literal, | 28 | Array, BinaryOp, BindingAnnotation, Body, BodySourceMap, Expr, ExprId, Literal, MatchArm, Pat, |
27 | LogicOp, MatchArm, Ordering, Pat, PatId, PatPtr, RecordFieldPat, RecordLitField, Statement, | 29 | PatId, PatPtr, RecordFieldPat, RecordLitField, Statement, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | pub(super) fn lower( | 32 | pub(super) fn lower( |
31 | db: &impl HirDatabase, | 33 | db: &impl HirDatabase, |
32 | resolver: Resolver, | 34 | resolver: Resolver, |
33 | file_id: HirFileId, | 35 | file_id: HirFileId, |
34 | owner: DefWithBody, | ||
35 | params: Option<ast::ParamList>, | 36 | params: Option<ast::ParamList>, |
36 | body: Option<ast::Expr>, | 37 | body: Option<ast::Expr>, |
37 | ) -> (Body, BodySourceMap) { | 38 | ) -> (Body, BodySourceMap) { |
@@ -42,11 +43,10 @@ pub(super) fn lower( | |||
42 | current_file_id: file_id, | 43 | current_file_id: file_id, |
43 | source_map: BodySourceMap::default(), | 44 | source_map: BodySourceMap::default(), |
44 | body: Body { | 45 | body: Body { |
45 | owner, | ||
46 | exprs: Arena::default(), | 46 | exprs: Arena::default(), |
47 | pats: Arena::default(), | 47 | pats: Arena::default(), |
48 | params: Vec::new(), | 48 | params: Vec::new(), |
49 | body_expr: ExprId((!0).into()), | 49 | body_expr: ExprId::dummy(), |
50 | }, | 50 | }, |
51 | } | 51 | } |
52 | .collect(params, body) | 52 | .collect(params, body) |
@@ -423,28 +423,18 @@ where | |||
423 | ast::Expr::Literal(e) => { | 423 | ast::Expr::Literal(e) => { |
424 | let lit = match e.kind() { | 424 | let lit = match e.kind() { |
425 | LiteralKind::IntNumber { suffix } => { | 425 | LiteralKind::IntNumber { suffix } => { |
426 | let known_name = suffix | 426 | let known_name = suffix.and_then(|it| BuiltinInt::from_suffix(&it)); |
427 | .and_then(|it| IntTy::from_suffix(&it).map(UncertainIntTy::Known)); | ||
428 | 427 | ||
429 | Literal::Int( | 428 | Literal::Int(Default::default(), known_name) |
430 | Default::default(), | ||
431 | known_name.unwrap_or(UncertainIntTy::Unknown), | ||
432 | ) | ||
433 | } | 429 | } |
434 | LiteralKind::FloatNumber { suffix } => { | 430 | LiteralKind::FloatNumber { suffix } => { |
435 | let known_name = suffix | 431 | let known_name = suffix.and_then(|it| BuiltinFloat::from_suffix(&it)); |
436 | .and_then(|it| FloatTy::from_suffix(&it).map(UncertainFloatTy::Known)); | ||
437 | 432 | ||
438 | Literal::Float( | 433 | Literal::Float(Default::default(), known_name) |
439 | Default::default(), | ||
440 | known_name.unwrap_or(UncertainFloatTy::Unknown), | ||
441 | ) | ||
442 | } | 434 | } |
443 | LiteralKind::ByteString => Literal::ByteString(Default::default()), | 435 | LiteralKind::ByteString => Literal::ByteString(Default::default()), |
444 | LiteralKind::String => Literal::String(Default::default()), | 436 | LiteralKind::String => Literal::String(Default::default()), |
445 | LiteralKind::Byte => { | 437 | LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), |
446 | Literal::Int(Default::default(), UncertainIntTy::Known(IntTy::u8())) | ||
447 | } | ||
448 | LiteralKind::Bool => Literal::Bool(Default::default()), | 438 | LiteralKind::Bool => Literal::Bool(Default::default()), |
449 | LiteralKind::Char => Literal::Char(Default::default()), | 439 | LiteralKind::Char => Literal::Char(Default::default()), |
450 | }; | 440 | }; |
@@ -601,47 +591,3 @@ where | |||
601 | Path::from_src(path, &hygiene) | 591 | Path::from_src(path, &hygiene) |
602 | } | 592 | } |
603 | } | 593 | } |
604 | |||
605 | impl From<ast::BinOp> for BinaryOp { | ||
606 | fn from(ast_op: ast::BinOp) -> Self { | ||
607 | match ast_op { | ||
608 | ast::BinOp::BooleanOr => BinaryOp::LogicOp(LogicOp::Or), | ||
609 | ast::BinOp::BooleanAnd => BinaryOp::LogicOp(LogicOp::And), | ||
610 | ast::BinOp::EqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: false }), | ||
611 | ast::BinOp::NegatedEqualityTest => BinaryOp::CmpOp(CmpOp::Eq { negated: true }), | ||
612 | ast::BinOp::LesserEqualTest => { | ||
613 | BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: false }) | ||
614 | } | ||
615 | ast::BinOp::GreaterEqualTest => { | ||
616 | BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: false }) | ||
617 | } | ||
618 | ast::BinOp::LesserTest => { | ||
619 | BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Less, strict: true }) | ||
620 | } | ||
621 | ast::BinOp::GreaterTest => { | ||
622 | BinaryOp::CmpOp(CmpOp::Ord { ordering: Ordering::Greater, strict: true }) | ||
623 | } | ||
624 | ast::BinOp::Addition => BinaryOp::ArithOp(ArithOp::Add), | ||
625 | ast::BinOp::Multiplication => BinaryOp::ArithOp(ArithOp::Mul), | ||
626 | ast::BinOp::Subtraction => BinaryOp::ArithOp(ArithOp::Sub), | ||
627 | ast::BinOp::Division => BinaryOp::ArithOp(ArithOp::Div), | ||
628 | ast::BinOp::Remainder => BinaryOp::ArithOp(ArithOp::Rem), | ||
629 | ast::BinOp::LeftShift => BinaryOp::ArithOp(ArithOp::Shl), | ||
630 | ast::BinOp::RightShift => BinaryOp::ArithOp(ArithOp::Shr), | ||
631 | ast::BinOp::BitwiseXor => BinaryOp::ArithOp(ArithOp::BitXor), | ||
632 | ast::BinOp::BitwiseOr => BinaryOp::ArithOp(ArithOp::BitOr), | ||
633 | ast::BinOp::BitwiseAnd => BinaryOp::ArithOp(ArithOp::BitAnd), | ||
634 | ast::BinOp::Assignment => BinaryOp::Assignment { op: None }, | ||
635 | ast::BinOp::AddAssign => BinaryOp::Assignment { op: Some(ArithOp::Add) }, | ||
636 | ast::BinOp::DivAssign => BinaryOp::Assignment { op: Some(ArithOp::Div) }, | ||
637 | ast::BinOp::MulAssign => BinaryOp::Assignment { op: Some(ArithOp::Mul) }, | ||
638 | ast::BinOp::RemAssign => BinaryOp::Assignment { op: Some(ArithOp::Rem) }, | ||
639 | ast::BinOp::ShlAssign => BinaryOp::Assignment { op: Some(ArithOp::Shl) }, | ||
640 | ast::BinOp::ShrAssign => BinaryOp::Assignment { op: Some(ArithOp::Shr) }, | ||
641 | ast::BinOp::SubAssign => BinaryOp::Assignment { op: Some(ArithOp::Sub) }, | ||
642 | ast::BinOp::BitOrAssign => BinaryOp::Assignment { op: Some(ArithOp::BitOr) }, | ||
643 | ast::BinOp::BitAndAssign => BinaryOp::Assignment { op: Some(ArithOp::BitAnd) }, | ||
644 | ast::BinOp::BitXorAssign => BinaryOp::Assignment { op: Some(ArithOp::BitXor) }, | ||
645 | } | ||
646 | } | ||
647 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index fe4211819..f28e9c931 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -150,7 +150,7 @@ impl SourceAnalyzer { | |||
150 | None => scope_for(&scopes, &source_map, &node), | 150 | None => scope_for(&scopes, &source_map, &node), |
151 | Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), | 151 | Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset), |
152 | }; | 152 | }; |
153 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); | 153 | let resolver = expr::resolver_for_scope(db, def, scope); |
154 | SourceAnalyzer { | 154 | SourceAnalyzer { |
155 | resolver, | 155 | resolver, |
156 | body_owner: Some(def), | 156 | body_owner: Some(def), |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 2370e8d4f..f17c6c614 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -43,7 +43,7 @@ use crate::{ | |||
43 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 43 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
44 | resolve::{Resolver, TypeNs}, | 44 | resolve::{Resolver, TypeNs}, |
45 | ty::infer::diagnostics::InferenceDiagnostic, | 45 | ty::infer::diagnostics::InferenceDiagnostic, |
46 | Adt, AssocItem, ConstData, DefWithBody, FnData, Function, HasBody, Path, StructField, | 46 | Adt, AssocItem, ConstData, DefWithBody, FnData, Function, Path, StructField, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | macro_rules! ty_app { | 49 | macro_rules! ty_app { |
@@ -64,9 +64,8 @@ mod coerce; | |||
64 | /// The entry point of type inference. | 64 | /// The entry point of type inference. |
65 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 65 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
66 | let _p = profile("infer_query"); | 66 | let _p = profile("infer_query"); |
67 | let body = def.body(db); | ||
68 | let resolver = def.resolver(db); | 67 | let resolver = def.resolver(db); |
69 | let mut ctx = InferenceContext::new(db, body, resolver); | 68 | let mut ctx = InferenceContext::new(db, def, resolver); |
70 | 69 | ||
71 | match def { | 70 | match def { |
72 | DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), | 71 | DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)), |
@@ -187,6 +186,7 @@ impl Index<PatId> for InferenceResult { | |||
187 | #[derive(Clone, Debug)] | 186 | #[derive(Clone, Debug)] |
188 | struct InferenceContext<'a, D: HirDatabase> { | 187 | struct InferenceContext<'a, D: HirDatabase> { |
189 | db: &'a D, | 188 | db: &'a D, |
189 | owner: DefWithBody, | ||
190 | body: Arc<Body>, | 190 | body: Arc<Body>, |
191 | resolver: Resolver, | 191 | resolver: Resolver, |
192 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 192 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
@@ -204,7 +204,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
204 | } | 204 | } |
205 | 205 | ||
206 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 206 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
207 | fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self { | 207 | fn new(db: &'a D, owner: DefWithBody, resolver: Resolver) -> Self { |
208 | InferenceContext { | 208 | InferenceContext { |
209 | result: InferenceResult::default(), | 209 | result: InferenceResult::default(), |
210 | var_unification_table: InPlaceUnificationTable::new(), | 210 | var_unification_table: InPlaceUnificationTable::new(), |
@@ -213,7 +213,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
213 | trait_env: lower::trait_env(db, &resolver), | 213 | trait_env: lower::trait_env(db, &resolver), |
214 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), | 214 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), |
215 | db, | 215 | db, |
216 | body, | 216 | owner, |
217 | body: db.body(owner), | ||
217 | resolver, | 218 | resolver, |
218 | } | 219 | } |
219 | } | 220 | } |
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 4af1d65ee..c6802487a 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -130,10 +130,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
130 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, | 130 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, |
131 | Substs(sig_tys.into()), | 131 | Substs(sig_tys.into()), |
132 | ); | 132 | ); |
133 | let closure_ty = Ty::apply_one( | 133 | let closure_ty = |
134 | TypeCtor::Closure { def: self.body.owner(), expr: tgt_expr }, | 134 | Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); |
135 | sig_ty, | ||
136 | ); | ||
137 | 135 | ||
138 | // Eagerly try to relate the closure type with the expected | 136 | // Eagerly try to relate the closure type with the expected |
139 | // type, otherwise we often won't have enough information to | 137 | // type, otherwise we often won't have enough information to |
@@ -184,7 +182,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
184 | } | 182 | } |
185 | Expr::Path(p) => { | 183 | Expr::Path(p) => { |
186 | // FIXME this could be more efficient... | 184 | // FIXME this could be more efficient... |
187 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); | 185 | let resolver = expr::resolver_for_expr(self.db, self.owner, tgt_expr); |
188 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 186 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) |
189 | } | 187 | } |
190 | Expr::Continue => Ty::simple(TypeCtor::Never), | 188 | Expr::Continue => Ty::simple(TypeCtor::Never), |
@@ -452,8 +450,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
452 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) | 450 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), slice_type) |
453 | } | 451 | } |
454 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 452 | Literal::Char(..) => Ty::simple(TypeCtor::Char), |
455 | Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int(*ty)), | 453 | Literal::Int(_v, ty) => Ty::simple(TypeCtor::Int((*ty).into())), |
456 | Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float(*ty)), | 454 | Literal::Float(_v, ty) => Ty::simple(TypeCtor::Float((*ty).into())), |
457 | }, | 455 | }, |
458 | }; | 456 | }; |
459 | // use a new type variable if we got Ty::Unknown here | 457 | // use a new type variable if we got Ty::Unknown here |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 52d24e24d..1832fcf50 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -25,7 +25,7 @@ use crate::{ | |||
25 | generics::{GenericDef, WherePredicate}, | 25 | generics::{GenericDef, WherePredicate}, |
26 | resolve::{Resolver, TypeNs}, | 26 | resolve::{Resolver, TypeNs}, |
27 | ty::{ | 27 | ty::{ |
28 | primitive::{FloatTy, IntTy}, | 28 | primitive::{FloatTy, IntTy, UncertainFloatTy, UncertainIntTy}, |
29 | Adt, | 29 | Adt, |
30 | }, | 30 | }, |
31 | util::make_mut_slice, | 31 | util::make_mut_slice, |
@@ -657,13 +657,41 @@ fn type_for_builtin(def: BuiltinType) -> Ty { | |||
657 | BuiltinType::Char => TypeCtor::Char, | 657 | BuiltinType::Char => TypeCtor::Char, |
658 | BuiltinType::Bool => TypeCtor::Bool, | 658 | BuiltinType::Bool => TypeCtor::Bool, |
659 | BuiltinType::Str => TypeCtor::Str, | 659 | BuiltinType::Str => TypeCtor::Str, |
660 | BuiltinType::Int(BuiltinInt { signedness, bitness }) => { | 660 | BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), |
661 | TypeCtor::Int(IntTy { signedness, bitness }.into()) | 661 | BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), |
662 | } | ||
663 | BuiltinType::Float(BuiltinFloat { bitness }) => TypeCtor::Float(FloatTy { bitness }.into()), | ||
664 | }) | 662 | }) |
665 | } | 663 | } |
666 | 664 | ||
665 | impl From<BuiltinInt> for IntTy { | ||
666 | fn from(t: BuiltinInt) -> Self { | ||
667 | IntTy { signedness: t.signedness, bitness: t.bitness } | ||
668 | } | ||
669 | } | ||
670 | |||
671 | impl From<BuiltinFloat> for FloatTy { | ||
672 | fn from(t: BuiltinFloat) -> Self { | ||
673 | FloatTy { bitness: t.bitness } | ||
674 | } | ||
675 | } | ||
676 | |||
677 | impl From<Option<BuiltinInt>> for UncertainIntTy { | ||
678 | fn from(t: Option<BuiltinInt>) -> Self { | ||
679 | match t { | ||
680 | None => UncertainIntTy::Unknown, | ||
681 | Some(t) => UncertainIntTy::Known(t.into()), | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | |||
686 | impl From<Option<BuiltinFloat>> for UncertainFloatTy { | ||
687 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
688 | match t { | ||
689 | None => UncertainFloatTy::Unknown, | ||
690 | Some(t) => UncertainFloatTy::Known(t.into()), | ||
691 | } | ||
692 | } | ||
693 | } | ||
694 | |||
667 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | 695 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { |
668 | let struct_data = db.struct_data(def.id.into()); | 696 | let struct_data = db.struct_data(def.id.into()); |
669 | let fields = match struct_data.variant_data.fields() { | 697 | let fields = match struct_data.variant_data.fields() { |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 1749752f1..7362de4c3 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -129,24 +129,6 @@ impl IntTy { | |||
129 | (Signedness::Unsigned, IntBitness::X128) => "u128", | 129 | (Signedness::Unsigned, IntBitness::X128) => "u128", |
130 | } | 130 | } |
131 | } | 131 | } |
132 | |||
133 | pub(crate) fn from_suffix(suffix: &str) -> Option<IntTy> { | ||
134 | match suffix { | ||
135 | "isize" => Some(IntTy::isize()), | ||
136 | "i8" => Some(IntTy::i8()), | ||
137 | "i16" => Some(IntTy::i16()), | ||
138 | "i32" => Some(IntTy::i32()), | ||
139 | "i64" => Some(IntTy::i64()), | ||
140 | "i128" => Some(IntTy::i128()), | ||
141 | "usize" => Some(IntTy::usize()), | ||
142 | "u8" => Some(IntTy::u8()), | ||
143 | "u16" => Some(IntTy::u16()), | ||
144 | "u32" => Some(IntTy::u32()), | ||
145 | "u64" => Some(IntTy::u64()), | ||
146 | "u128" => Some(IntTy::u128()), | ||
147 | _ => None, | ||
148 | } | ||
149 | } | ||
150 | } | 132 | } |
151 | 133 | ||
152 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | 134 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] |
@@ -181,12 +163,4 @@ impl FloatTy { | |||
181 | FloatBitness::X64 => "f64", | 163 | FloatBitness::X64 => "f64", |
182 | } | 164 | } |
183 | } | 165 | } |
184 | |||
185 | pub(crate) fn from_suffix(suffix: &str) -> Option<FloatTy> { | ||
186 | match suffix { | ||
187 | "f32" => Some(FloatTy::f32()), | ||
188 | "f64" => Some(FloatTy::f64()), | ||
189 | _ => None, | ||
190 | } | ||
191 | } | ||
192 | } | 166 | } |