pub struct Program<'e> { /* private fields */ }Expand description
Several units resolved against each other (Tier 3): the in-memory
multi-unit driver. Each unit may be given a root name, by which every
unit (itself included) can reach its root module as a path’s first
segment (util::helper, import util). Imports may form cycles across
units.
§Examples
use hir_lang::{Builder, Def, Expr, FnDef, Item, ItemKind, Name, Ns, Path, Res, Segment, UnitId, Vis};
use intern_lang::Interner;
use resolve_lang::{Policy, Program};
let mut names = Interner::new();
let (util, helper) = (Name::new(names.intern("util")), Name::new(names.intern("helper")));
// Unit 1, reachable as `util`: pub fn helper() {}
let mut b = Builder::for_unit(UnitId::new(1));
let body = b.block(&[], None);
let f = b.item(Item::new(Some(helper), ItemKind::Fn(FnDef { body: Some(body), ..FnDef::default() })).with_vis(Vis::Public));
let root = b.module(None, &[f]);
let util_hir = b.finish(root)?;
// Unit 2: fn main() { util::helper }
let mut b = Builder::for_unit(UnitId::new(2));
let segs = [Segment::new(util, b.origin()), Segment::new(helper, b.origin())];
let segs = b.list(&segs);
let path = b.path(Path::new(segs, Ns::Value));
let call = b.expr(Expr::Path(path));
let body = b.block(&[], Some(call));
let main = b.func(Name::new(names.intern("main")), &[], body);
let root = b.module(None, &[main]);
let app_hir = b.finish(root)?;
let mut program = Program::new(Policy::kraken());
program.add_unit(Some(util), util_hir);
program.add_unit(None, app_hir);
let res = program.resolve(&names)?;
assert!(res.is_clean());
let app = res.hir(UnitId::new(2)).unwrap();
let Res::Def(d) = app.path(path).res else { panic!("unresolved") };
assert_eq!((d.unit(), d.def()), (UnitId::new(1), Def::Item(f)));Implementations§
Source§impl Program<'_>
impl Program<'_>
Sourcepub fn with_env(self, env: &dyn Env) -> Program<'_>
pub fn with_env(self, env: &dyn Env) -> Program<'_>
Uses env for names outside the program.
§Examples
use resolve_lang::{MapEnv, Policy, Program};
let env = MapEnv::new();
let _p = Program::new(Policy::new()).with_env(&env);Sourcepub fn with_budget(self, budget: Budget) -> Self
pub fn with_budget(self, budget: Budget) -> Self
Sets the budget.
§Examples
use resolve_lang::{Budget, Policy, Program};
let _p = Program::new(Policy::new()).with_budget(Budget::default().with_glob_bindings(10));Sourcepub fn add_unit(&mut self, name: Option<Name>, hir: Hir)
pub fn add_unit(&mut self, name: Option<Name>, hir: Hir)
Adds a unit in package 0, reachable by name (if given) from every
unit.
§Examples
use hir_lang::Builder;
use resolve_lang::{Policy, Program};
let mut b = Builder::new();
let root = b.module(None, &[]);
let mut p = Program::new(Policy::new());
p.add_unit(None, b.finish(root)?);
assert_eq!(p.len(), 1);Sourcepub fn add_unit_in(&mut self, package: u32, name: Option<Name>, hir: Hir)
pub fn add_unit_in(&mut self, package: u32, name: Option<Name>, hir: Hir)
Adds a unit to a package: Vis::Package items are visible across
units of the same package only.
§Examples
use hir_lang::Builder;
use resolve_lang::{Policy, Program};
let mut b = Builder::new();
let root = b.module(None, &[]);
let mut p = Program::new(Policy::new());
p.add_unit_in(7, None, b.finish(root)?);
assert!(!p.is_empty());Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
The number of units added.
§Examples
use resolve_lang::{Policy, Program};
assert_eq!(Program::new(Policy::new()).len(), 0);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether no unit was added.
§Examples
use resolve_lang::{Policy, Program};
assert!(Program::new(Policy::new()).is_empty());Sourcepub fn resolve<L: Lookup>(self, names: &L) -> Result<Resolution, ResolveError>
pub fn resolve<L: Lookup>(self, names: &L) -> Result<Resolution, ResolveError>
Resolves every unit.
§Errors
ResolveError::DuplicateUnitif two units share aUnitId.ResolveError::BudgetExceededif the program exceeds the budget.
§Examples
use hir_lang::{Builder, UnitId};
use intern_lang::Interner;
use resolve_lang::{Policy, Program, ResolveError};
let mut p = Program::new(Policy::new());
for _ in 0..2 {
let mut b = Builder::for_unit(UnitId::new(1));
let root = b.module(None, &[]);
p.add_unit(None, b.finish(root)?);
}
assert_eq!(p.resolve(&Interner::new()).unwrap_err(), ResolveError::DuplicateUnit { unit: UnitId::new(1) });Trait Implementations§
Auto Trait Implementations§
impl<'e> !RefUnwindSafe for Program<'e>
impl<'e> !Send for Program<'e>
impl<'e> !Sync for Program<'e>
impl<'e> !UnwindSafe for Program<'e>
impl<'e> Freeze for Program<'e>
impl<'e> Unpin for Program<'e>
impl<'e> UnsafeUnpin for Program<'e>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more