diff --git a/src/codegen/llvm/mod.rs b/src/codegen/llvm/mod.rs index 02f1858..df7c637 100644 --- a/src/codegen/llvm/mod.rs +++ b/src/codegen/llvm/mod.rs @@ -6,7 +6,7 @@ use inkwell::{ builder::Builder, context::Context, module::Module as LlvmModule, - types::{BasicType, BasicTypeEnum}, + types::{BasicType as _, BasicTypeEnum}, values::{BasicValue, FunctionValue, IntValue, PointerValue}, IntPredicate, }; @@ -19,8 +19,8 @@ use crate::{ BasicBlockIdx, BinaryOp, ConstantValue, Function, Terminator, Triple, TripleRef, UnaryOp, Value, }, - ty::Ty, }, + ty::Ty, }; /// A single LLVM module. diff --git a/src/compiler/function_manager.rs b/src/compiler/function_manager.rs index f908105..36ad8e1 100644 --- a/src/compiler/function_manager.rs +++ b/src/compiler/function_manager.rs @@ -1,13 +1,11 @@ +use crate::ty::Ty; use std::collections::HashMap; use index_vec::IndexVec; use crate::{ - repr::{ - identifier::{FunctionIdx, ScopedBinding}, - ty::Ty, - }, - stage::type_check::FunctionSignature, + repr::identifier::{FunctionIdx, ScopedBinding}, + ty::FunctionSignature, }; use super::Symbol; diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index 96edaf0..9442614 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -7,7 +7,8 @@ use self::function_manager::*; use crate::{ hir::SolveType, repr::ir, - stage::{self, parse::ParseError, type_check::TyError}, + stage::{self, parse::ParseError}, + ty::TyError, }; /// A symbol represents an interned string. diff --git a/src/hir/expression/array.rs b/src/hir/expression/array.rs index 2978aef..ed2b198 100644 --- a/src/hir/expression/array.rs +++ b/src/hir/expression/array.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -70,7 +68,7 @@ impl SolveType for Array { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Type check each of the init items let init = self .init diff --git a/src/hir/expression/assign.rs b/src/hir/expression/assign.rs index c4e8d62..75bf09e 100644 --- a/src/hir/expression/assign.rs +++ b/src/hir/expression/assign.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -58,7 +56,7 @@ impl SolveType for Assign { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Work out what type the variable has to be let (binding, ty) = state .resolve(self.binding) diff --git a/src/hir/expression/block.rs b/src/hir/expression/block.rs index dc5eaa4..44412fd 100644 --- a/src/hir/expression/block.rs +++ b/src/hir/expression/block.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -66,7 +64,7 @@ impl SolveType for Block { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Enter a new scope let block_scope = state.enter(); diff --git a/src/hir/expression/boolean.rs b/src/hir/expression/boolean.rs index 839f19b..875d5a9 100644 --- a/src/hir/expression/boolean.rs +++ b/src/hir/expression/boolean.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{Lexer, ParseError}; - use super::*; ast_node! { @@ -52,7 +50,7 @@ impl SolveType for Boolean { self, _compiler: &mut crate::compiler::Compiler, _state: &mut Self::State, - ) -> Result { + ) -> Result { Ok(Boolean { value: self.value, span: self.span, diff --git a/src/hir/expression/call.rs b/src/hir/expression/call.rs index 9e0945d..9e51b74 100644 --- a/src/hir/expression/call.rs +++ b/src/hir/expression/call.rs @@ -1,7 +1,3 @@ -use std::iter; - -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -29,7 +25,7 @@ impl Parsable for Call { }; // Consume the args - let args = iter::from_fn(|| { + let args = std::iter::from_fn(|| { match lexer.peek_token()? { Token::RightParen => None, Token::LeftParen | Token::Comma => { diff --git a/src/hir/expression/cast.rs b/src/hir/expression/cast.rs index 25497ea..ff692f6 100644 --- a/src/hir/expression/cast.rs +++ b/src/hir/expression/cast.rs @@ -1,4 +1,4 @@ -use crate::stage::parse::{parse_ty, ParseError}; +use crate::ty::TySpanned; use super::*; @@ -15,7 +15,7 @@ impl Parsable for Cast { fn register(parser: &mut Parser) { assert!(parser.register_infix::>( Token::As, - |_, _, lexer, left| { + |parser, compiler, lexer, left| { let as_span = match lexer.next_spanned().unwrap() { (Token::As, span) => span, (token, _) => { @@ -28,12 +28,12 @@ impl Parsable for Cast { }; // Parse out type from right hand side - let (target_ty, target_ty_span) = parse_ty(lexer)?; + let ty: TySpanned = parser.parse(compiler, lexer, Precedence::Lowest)?; Ok(Expression::Cast(Cast { value: Box::new(left), - target_ty, - span: as_span.start..target_ty_span.end, + target_ty: ty.ty, + span: as_span.start..ty.span.end, ty_info: None, })) } @@ -48,7 +48,7 @@ impl SolveType for Cast { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { let value = self.value.solve(compiler, state)?; // Make sure that the value can be cast to the desired type @@ -87,6 +87,7 @@ mod test { // Helper parsers Integer::::register(&mut parser); + TySpanned::register(&mut parser); parser } diff --git a/src/hir/expression/ident.rs b/src/hir/expression/ident.rs index cdc0dbb..2c6fd34 100644 --- a/src/hir/expression/ident.rs +++ b/src/hir/expression/ident.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::ParseError; - use super::*; use std::hash::Hash; @@ -47,7 +45,7 @@ impl SolveType for Ident { self, _compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { let (binding, ty) = state .resolve(self.binding) .ok_or(TyError::SymbolNotFound(self.binding))?; diff --git a/src/hir/expression/if_else.rs b/src/hir/expression/if_else.rs index 3a03dde..dfa48e7 100644 --- a/src/hir/expression/if_else.rs +++ b/src/hir/expression/if_else.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -75,7 +73,7 @@ impl SolveType for If { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Make sure the condition is correctly typed let condition = self.condition.solve(compiler, state)?; let condition_ty = condition.get_ty_info(); diff --git a/src/hir/expression/index.rs b/src/hir/expression/index.rs index 716b9bf..24a187e 100644 --- a/src/hir/expression/index.rs +++ b/src/hir/expression/index.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -71,7 +69,7 @@ impl SolveType for Index { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Ensure the inner parts are correct let index = self.index.solve(compiler, state)?; diff --git a/src/hir/expression/infix.rs b/src/hir/expression/infix.rs index 27a9668..554cb18 100644 --- a/src/hir/expression/infix.rs +++ b/src/hir/expression/infix.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{Lexer, ParseError, Precedence}; - use super::*; #[derive(Debug, Clone, Copy, Eq, PartialEq)] diff --git a/src/hir/expression/integer.rs b/src/hir/expression/integer.rs index b35abaf..0bc1f09 100644 --- a/src/hir/expression/integer.rs +++ b/src/hir/expression/integer.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::ParseError; - use super::*; ast_node! { diff --git a/src/hir/expression/loop_block.rs b/src/hir/expression/loop_block.rs index 41d20ee..5c82a67 100644 --- a/src/hir/expression/loop_block.rs +++ b/src/hir/expression/loop_block.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { @@ -53,7 +51,7 @@ impl SolveType for Loop { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { // Type check the body let body = self.body.solve(compiler, state)?; diff --git a/src/hir/expression/mod.rs b/src/hir/expression/mod.rs index 1f19ecd..4c0e3db 100644 --- a/src/hir/expression/mod.rs +++ b/src/hir/expression/mod.rs @@ -116,7 +116,7 @@ impl SolveType for Expression { self, compiler: &mut crate::compiler::Compiler, state: &mut Self::State, - ) -> Result { + ) -> Result { Ok(match self { Expression::Infix(e) => Expression::Infix(e.solve(compiler, state)?), Expression::Integer(e) => Expression::Integer(e.solve(compiler, state)?), diff --git a/src/hir/function.rs b/src/hir/function.rs index a57a779..3f574b7 100644 --- a/src/hir/function.rs +++ b/src/hir/function.rs @@ -1,11 +1,4 @@ -use crate::{ - ast_node, - repr::{ast::untyped::UntypedAstMetadata, ty::Ty}, - stage::type_check::TyError, - util::scope::Scope, -}; - -use super::{expression::Block, SolveType}; +use super::*; ast_node! { Function { diff --git a/src/hir/mod.rs b/src/hir/mod.rs index b18e3b2..853317c 100644 --- a/src/hir/mod.rs +++ b/src/hir/mod.rs @@ -7,11 +7,11 @@ use crate::{ ast_node, compiler::Compiler, repr::{ - ast::{typed::TyInfo, untyped::UntypedAstMetadata, AstMetadata}, + ast::{untyped::UntypedAstMetadata, AstMetadata}, token::Token, - ty::Ty, }, - stage::{parse::parser::Parser, type_check::TyError}, + stage::parse::{parser::Parser, Lexer, ParseError, Precedence}, + ty::{Ty, TyError, TyInfo}, util::{scope::Scope, span::Span}, }; diff --git a/src/hir/program.rs b/src/hir/program.rs index 3003e61..13f5354 100644 --- a/src/hir/program.rs +++ b/src/hir/program.rs @@ -1,10 +1,6 @@ -use crate::{ - ast_node, - repr::{ast::untyped::UntypedAstMetadata, ty::Ty}, - stage::type_check::{FunctionSignature, TyError}, -}; +use crate::ty::FunctionSignature; -use super::{function::Function, SolveType}; +use super::*; ast_node! { Program { diff --git a/src/hir/statement/s_break.rs b/src/hir/statement/s_break.rs index d687306..6a2d273 100644 --- a/src/hir/statement/s_break.rs +++ b/src/hir/statement/s_break.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::ParseError; - use super::*; ast_node! { diff --git a/src/hir/statement/s_continue.rs b/src/hir/statement/s_continue.rs index cd6ac28..74025fd 100644 --- a/src/hir/statement/s_continue.rs +++ b/src/hir/statement/s_continue.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::ParseError; - use super::*; ast_node! { diff --git a/src/hir/statement/s_expression.rs b/src/hir/statement/s_expression.rs index 70abb00..863de67 100644 --- a/src/hir/statement/s_expression.rs +++ b/src/hir/statement/s_expression.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::Precedence; - use super::*; ast_node! { diff --git a/src/hir/statement/s_let.rs b/src/hir/statement/s_let.rs index 670465c..91c8983 100644 --- a/src/hir/statement/s_let.rs +++ b/src/hir/statement/s_let.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { diff --git a/src/hir/statement/s_return.rs b/src/hir/statement/s_return.rs index 4530fca..82c9ec5 100644 --- a/src/hir/statement/s_return.rs +++ b/src/hir/statement/s_return.rs @@ -1,5 +1,3 @@ -use crate::stage::parse::{ParseError, Precedence}; - use super::*; ast_node! { diff --git a/src/lib.rs b/src/lib.rs index ff22b2c..4a0992e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ pub mod compiler; mod hir; pub mod repr; pub mod stage; +mod ty; pub mod util; pub fn compile_and_run(source: &'static str, debug: bool) -> i64 { diff --git a/src/repr/ast/typed.rs b/src/repr/ast/typed.rs index 0cc2781..dd0aa09 100644 --- a/src/repr/ast/typed.rs +++ b/src/repr/ast/typed.rs @@ -1,20 +1,12 @@ use crate::{ generate_ast, - repr::{ - identifier::{FunctionIdx, ScopedBinding}, - ty::Ty, - }, + repr::identifier::{FunctionIdx, ScopedBinding}, + ty::TyInfo, util::span::Span, }; use super::AstMetadata; -#[derive(Clone, Debug)] -pub struct TyInfo { - pub ty: Ty, - pub return_ty: Option, -} - pub struct TypedAstMetadata; impl AstMetadata for TypedAstMetadata { type FnIdentifier = FunctionIdx; diff --git a/src/repr/ast/untyped.rs b/src/repr/ast/untyped.rs index 025b3c0..81195e7 100644 --- a/src/repr/ast/untyped.rs +++ b/src/repr/ast/untyped.rs @@ -1,4 +1,4 @@ -use crate::{compiler::Symbol, generate_ast, repr::ty::Ty, util::span::Span}; +use crate::{compiler::Symbol, generate_ast, ty::Ty, util::span::Span}; use super::AstMetadata; diff --git a/src/repr/ir/function.rs b/src/repr/ir/function.rs index 66a8416..92d4b70 100644 --- a/src/repr/ir/function.rs +++ b/src/repr/ir/function.rs @@ -4,7 +4,7 @@ use index_vec::IndexVec; use crate::{ repr::identifier::{FunctionIdx, ScopedBinding}, - stage::type_check::FunctionSignature, + ty::FunctionSignature, }; use super::BasicBlock; diff --git a/src/repr/mod.rs b/src/repr/mod.rs index 188c8f8..5031b24 100644 --- a/src/repr/mod.rs +++ b/src/repr/mod.rs @@ -2,4 +2,3 @@ pub mod ast; pub mod identifier; pub mod ir; pub mod token; -pub mod ty; diff --git a/src/repr/ty.rs b/src/repr/ty.rs deleted file mode 100644 index 2e235dd..0000000 --- a/src/repr/ty.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum Ty { - Int, - Uint, - Boolean, - Unit, - Never, - Array { inner: Box, size: u32 }, -} - -impl Ty { - pub fn check(&self, other: &Ty) -> bool { - match (self, other) { - (lhs, rhs) if lhs == rhs => true, - (Ty::Never, _) | (_, Ty::Never) => true, - _ => false, - } - } -} diff --git a/src/stage/lower_ir/lowering/mod.rs b/src/stage/lower_ir/lowering/mod.rs index 4ad8b60..4c026db 100644 --- a/src/stage/lower_ir/lowering/mod.rs +++ b/src/stage/lower_ir/lowering/mod.rs @@ -6,9 +6,8 @@ use crate::{ ast::typed as ast, identifier::{FunctionIdx, ScopedBinding}, ir::{self, *}, - ty::Ty, }, - stage::type_check::FunctionSignature, + ty::{FunctionSignature, Ty}, }; pub fn lower(compiler: &mut Compiler, program: ast::Program) -> Vec { diff --git a/src/stage/mod.rs b/src/stage/mod.rs index c2a9eaa..5717892 100644 --- a/src/stage/mod.rs +++ b/src/stage/mod.rs @@ -1,3 +1,2 @@ pub mod lower_ir; pub mod parse; -pub mod type_check; diff --git a/src/stage/parse/function.rs b/src/stage/parse/function.rs index a4cdc3d..bcddf24 100644 --- a/src/stage/parse/function.rs +++ b/src/stage/parse/function.rs @@ -1,6 +1,6 @@ use std::iter; -use ty::parse_ty; +use crate::ty::TySpanned; use super::*; @@ -92,12 +92,13 @@ pub fn parse_function( } // Extract the type - let (ty, _) = match parse_ty(lexer) { - Ok(ty) => ty, - Err(e) => { - return Some(Err(e)); - } - }; + let TySpanned { ty, .. } = + match parser.parse(compiler, lexer, Precedence::Lowest) { + Ok(ty) => ty, + Err(e) => { + return Some(Err(e)); + } + }; parse_state = ParseState::Comma; @@ -128,7 +129,7 @@ pub fn parse_function( } // return type - let (return_ty, _) = parse_ty(lexer)?; + let ty: TySpanned = parser.parse(compiler, lexer, Precedence::Lowest)?; // Parse out the body let Expression::::Block(body) = @@ -143,7 +144,7 @@ pub fn parse_function( Ok(Function::new( compiler.symbols.get_or_intern(fn_name), parameters, - return_ty, + ty.ty, body, span, )) diff --git a/src/stage/parse/mod.rs b/src/stage/parse/mod.rs index bfeea6c..3c9e9e6 100644 --- a/src/stage/parse/mod.rs +++ b/src/stage/parse/mod.rs @@ -1,6 +1,5 @@ mod function; pub mod parser; -mod ty; use std::collections::HashMap; use std::iter::Peekable; @@ -13,10 +12,10 @@ use parser::Parser; use crate::compiler::Compiler; use crate::hir::{Expression, Parsable, Statement}; use crate::repr::token::*; +use crate::ty::TySpanned; use crate::util::span::*; use self::function::*; -pub use self::ty::parse_ty; use crate::repr::ast::untyped::*; @@ -119,6 +118,7 @@ pub fn parse(compiler: &mut Compiler, source: &str) -> Result::register(&mut parser); Expression::::register(&mut parser); diff --git a/src/stage/parse/ty.rs b/src/stage/parse/ty.rs deleted file mode 100644 index 63734cf..0000000 --- a/src/stage/parse/ty.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::repr::ty::Ty; - -use super::{Lexer, ParseError, Span, Token}; - -pub fn parse_ty(lexer: &mut Lexer) -> Result<(Ty, Span), ParseError> { - let (token, span) = lexer.next_spanned().ok_or(ParseError::UnexpectedEOF)?; - - Ok(( - match token { - Token::Int => Ty::Int, - Token::Uint => Ty::Uint, - Token::Bool => Ty::Boolean, - token => { - return Err(ParseError::ExpectedToken { - // WARN: This should be any of the primitive type tokens - expected: Box::new(Token::Int), - found: Box::new(token), - reason: "expected valid type".to_string(), - }); - } - }, - span, - )) -} diff --git a/src/ty/error.rs b/src/ty/error.rs new file mode 100644 index 0000000..44e4c21 --- /dev/null +++ b/src/ty/error.rs @@ -0,0 +1,24 @@ +use crate::compiler::Symbol; + +use super::*; + +#[derive(Debug, thiserror::Error)] +pub enum TyError { + #[error("mismatched types: {0:?} and {1:?}")] + Mismatch(Ty, Ty), + + #[error("invalid return type, expected {expected:?} but found {found:?}")] + Return { + expected: Option, + found: Option, + }, + + #[error("cannot cast {0:?} to {1:?}")] + Cast(Ty, Ty), + + #[error("cannot perform index on {0:?}")] + Index(Ty), + + #[error("symbol not found: {0:?}")] + SymbolNotFound(Symbol), +} diff --git a/src/ty/function.rs b/src/ty/function.rs new file mode 100644 index 0000000..7adcb94 --- /dev/null +++ b/src/ty/function.rs @@ -0,0 +1,22 @@ +use crate::{hir, repr::ast::AstMetadata}; + +use super::*; + +#[derive(Clone, Debug)] +pub struct FunctionSignature { + pub arguments: Vec, + pub return_ty: Ty, +} + +impl From<&hir::Function> for FunctionSignature { + fn from(function: &hir::Function) -> Self { + Self { + arguments: function + .parameters + .iter() + .map(|(_, ty)| ty.clone()) + .collect(), + return_ty: function.return_ty.clone(), + } + } +} diff --git a/src/ty/mod.rs b/src/ty/mod.rs new file mode 100644 index 0000000..11ec1f3 --- /dev/null +++ b/src/ty/mod.rs @@ -0,0 +1,55 @@ +mod error; +mod function; +mod ty_info; + +use std::ops::Range; + +use crate::{hir::Parsable, repr::token::Token, stage::parse::parser::Parser}; + +pub use self::{error::TyError, function::FunctionSignature, ty_info::TyInfo}; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum Ty { + Int, + Uint, + Boolean, + Unit, + Never, + Array { inner: Box, size: u32 }, +} + +impl Ty { + pub fn check(&self, other: &Ty) -> bool { + match (self, other) { + (lhs, rhs) if lhs == rhs => true, + (Ty::Never, _) | (_, Ty::Never) => true, + _ => false, + } + } +} + +pub struct TySpanned { + pub ty: Ty, + pub span: Range, +} + +impl Parsable for TySpanned { + fn register(parser: &mut Parser) { + [ + (Token::Int, Ty::Int), + (Token::Uint, Ty::Uint), + (Token::Bool, Ty::Boolean), + ] + .into_iter() + .for_each(|(token, ty)| { + assert!(parser.register_prefix(token, move |_, _, lexer| { + let (_, span) = lexer.next_spanned().unwrap(); + + Ok(TySpanned { + ty: ty.clone(), + span, + }) + })); + }); + } +} diff --git a/src/stage/type_check/mod.rs b/src/ty/ty_info.rs similarity index 62% rename from src/stage/type_check/mod.rs rename to src/ty/ty_info.rs index 2e68827..bf15483 100644 --- a/src/stage/type_check/mod.rs +++ b/src/ty/ty_info.rs @@ -1,49 +1,11 @@ use itertools::Itertools; -use crate::compiler::Symbol; -use crate::hir; -use crate::repr::ast::typed::*; -use crate::repr::ast::AstMetadata; -use crate::repr::ty::Ty; +use super::*; #[derive(Clone, Debug)] -pub struct FunctionSignature { - pub arguments: Vec, - pub return_ty: Ty, -} - -impl From<&hir::Function> for FunctionSignature { - fn from(function: &hir::Function) -> Self { - Self { - arguments: function - .parameters - .iter() - .map(|(_, ty)| ty.clone()) - .collect(), - return_ty: function.return_ty.clone(), - } - } -} - -#[derive(Debug, thiserror::Error)] -pub enum TyError { - #[error("mismatched types: {0:?} and {1:?}")] - Mismatch(Ty, Ty), - - #[error("invalid return type, expected {expected:?} but found {found:?}")] - Return { - expected: Option, - found: Option, - }, - - #[error("cannot cast {0:?} to {1:?}")] - Cast(Ty, Ty), - - #[error("cannot perform index on {0:?}")] - Index(Ty), - - #[error("symbol not found: {0:?}")] - SymbolNotFound(Symbol), +pub struct TyInfo { + pub ty: Ty, + pub return_ty: Option, } impl TyInfo { diff --git a/src/util/scope.rs b/src/util/scope.rs index 2fbe924..fb1e351 100644 --- a/src/util/scope.rs +++ b/src/util/scope.rs @@ -2,10 +2,7 @@ use std::vec; use index_vec::IndexVec; -use crate::{ - compiler::Symbol, - repr::{identifier::*, ty::Ty}, -}; +use crate::{compiler::Symbol, repr::identifier::*, ty::Ty}; pub struct ScopePart { /// Indicates that this scope (and potentially a descendant) is active.