| 373 | } |
| 374 | |
| 375 | fn path(&mut self, path: Path<'heap>) -> Option<NodeKind<'heap>> { |
| 376 | let span = path.span; |
| 377 | let variable = match path.into_generic_ident() { |
| 378 | Ok((ident, args)) => { |
| 379 | // undeclared variables should have been resolved in the AST (import resolution) |
| 380 | let binder = self.binder_scope[&ident.value]; |
| 381 | |
| 382 | Variable::Local(LocalVariable { |
| 383 | id: Spanned { |
| 384 | span: ident.span, |
| 385 | value: binder, |
| 386 | }, |
| 387 | arguments: self.path_segment_arguments(args)?, |
| 388 | }) |
| 389 | } |
| 390 | Err(mut path) => { |
| 391 | if !path.rooted { |
| 392 | self.diagnostics.push(internal_error( |
| 393 | span, |
| 394 | "relative paths should have been resolved during import resolution", |
| 395 | )); |
| 396 | return None; |
| 397 | } |
| 398 | |
| 399 | let arguments = mem::replace( |
| 400 | &mut path |
| 401 | .segments |
| 402 | .last_mut() |
| 403 | .unwrap_or_else(|| unreachable!()) |
| 404 | .arguments, |
| 405 | Vec::new_in(self.context.heap), // capacity of 0 does not allocate |
| 406 | ); |
| 407 | |
| 408 | let mut segments = SmallVec::with_capacity(path.segments.len()); |
| 409 | for segment in path.segments { |
| 410 | segments.push(segment.name); |
| 411 | } |
| 412 | |
| 413 | Variable::Qualified(QualifiedVariable { |
| 414 | path: QualifiedPath::new_unchecked( |
| 415 | self.context.interner.intern_idents(&segments), |
| 416 | ), |
| 417 | arguments: self.path_segment_arguments(arguments)?, |
| 418 | }) |
| 419 | } |
| 420 | }; |
| 421 | |
| 422 | Some(NodeKind::Variable(variable)) |
| 423 | } |
| 424 | |
| 425 | fn let_expr( |
| 426 | &mut self, |