Skip to content

Commit 07d56cc

Browse files
committed
add core::result, core::functional, barebones std lib
1 parent 5006217 commit 07d56cc

27 files changed

Lines changed: 1318 additions & 74 deletions

File tree

crates/bench/benches/analysis.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use camino::{Utf8Path, Utf8PathBuf};
2-
use common::{InputDb, core::HasBuiltinCore};
2+
use common::{
3+
InputDb,
4+
stdlib::{HasBuiltinCore, HasBuiltinStd},
5+
};
36
use criterion::{Criterion, SamplingMode, criterion_group, criterion_main};
47
use driver::DriverDataBase;
58
use url::Url;
@@ -20,6 +23,15 @@ fn diagnostics(c: &mut Criterion) {
2023
});
2124
});
2225

26+
g.bench_function("analyze stdlib", |b| {
27+
b.iter_with_large_drop(|| {
28+
let db = DriverDataBase::default();
29+
let std_ingot = db.builtin_std();
30+
db.run_on_ingot(std_ingot);
31+
db
32+
});
33+
});
34+
2335
let files = test_files("../uitest/fixtures/".into());
2436

2537
g.bench_function("uitest parsing", |b| {

crates/common/src/core.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

crates/common/src/ingot.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ pub use radix_immutable::StringPrefixView;
55
use smol_str::SmolStr;
66
use url::Url;
77

8-
use crate::InputDb;
9-
use crate::config::Config;
10-
use crate::core::BUILTIN_CORE_BASE_URL;
11-
use crate::file::{File, Workspace};
12-
use crate::urlext::UrlExt;
8+
use crate::{
9+
InputDb,
10+
config::Config,
11+
file::{File, Workspace},
12+
stdlib::{BUILTIN_CORE_BASE_URL, BUILTIN_STD_BASE_URL},
13+
urlext::UrlExt,
14+
};
1315

1416
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1517
pub enum IngotKind {
@@ -25,6 +27,9 @@ pub enum IngotKind {
2527

2628
/// Core library ingot.
2729
Core,
30+
31+
/// Standard library ingot.
32+
Std,
2833
}
2934

3035
pub trait IngotBaseUrl {
@@ -142,12 +147,23 @@ impl<'db> Ingot<'db> {
142147
None => vec![],
143148
};
144149

145-
if self.kind(db) != IngotKind::Core {
150+
let kind = self.kind(db);
151+
152+
// every ingot has access to `core`
153+
if kind != IngotKind::Core {
146154
deps.push((
147155
"core".into(),
148156
Url::parse(BUILTIN_CORE_BASE_URL).expect("couldn't parse core ingot URL"),
149157
))
150158
}
159+
160+
// every ingot except `core` has access to `std` (until we have a no_std option)
161+
if !matches!(kind, IngotKind::Core | IngotKind::Std) {
162+
deps.push((
163+
"std".into(),
164+
Url::parse(BUILTIN_STD_BASE_URL).expect("couldn't parse std ingot URL"),
165+
));
166+
}
151167
deps
152168
}
153169
}
@@ -204,10 +220,10 @@ impl Workspace {
204220
.directory()
205221
.expect("Config URL should have a directory");
206222

207-
let kind = if base_url.scheme().contains("core") {
208-
IngotKind::Core
209-
} else {
210-
IngotKind::Local
223+
let kind = match base_url.scheme() {
224+
"builtin-core" => IngotKind::Core,
225+
"builtin-std" => IngotKind::Std,
226+
_ => IngotKind::Local,
211227
};
212228

213229
Some(Ingot::new(db, base_url.clone(), None, kind))

crates/common/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
pub mod config;
2-
pub mod core;
32
pub mod dependencies;
43
pub mod diagnostics;
54
pub mod file;
65
pub mod indexmap;
76
pub mod ingot;
7+
pub mod stdlib;
88
pub mod urlext;
99

1010
use dependencies::DependencyGraph;
@@ -46,7 +46,7 @@ macro_rules! impl_db_default {
4646
($db_type:ty) => {
4747
impl Default for $db_type
4848
where
49-
$db_type: $crate::core::HasBuiltinCore,
49+
$db_type: $crate::stdlib::HasBuiltinCore + $crate::stdlib::HasBuiltinStd,
5050
{
5151
fn default() -> Self {
5252
let mut db = Self {
@@ -58,7 +58,8 @@ macro_rules! impl_db_default {
5858
db.index = Some(index);
5959
let graph = $crate::dependencies::DependencyGraph::default(&db);
6060
db.graph = Some(graph);
61-
$crate::core::HasBuiltinCore::initialize_builtin_core(&mut db);
61+
$crate::stdlib::HasBuiltinCore::initialize_builtin_core(&mut db);
62+
$crate::stdlib::HasBuiltinStd::initialize_builtin_std(&mut db);
6263
db
6364
}
6465
}

crates/common/src/stdlib.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use camino::Utf8PathBuf;
2+
use rust_embed::Embed;
3+
use url::Url;
4+
5+
use crate::{
6+
InputDb,
7+
ingot::{Ingot, IngotBaseUrl},
8+
};
9+
10+
pub static BUILTIN_CORE_BASE_URL: &str = "builtin-core:///";
11+
pub static BUILTIN_STD_BASE_URL: &str = "builtin-std:///";
12+
13+
fn initialize_builtin<E: Embed>(db: &mut dyn InputDb, base_url: &str) {
14+
let base = Url::parse(base_url).unwrap();
15+
16+
for (path, contents) in E::iter().filter_map(|path| {
17+
E::get(&path).map(|content| {
18+
let contents = String::from_utf8(content.data.into_owned()).unwrap();
19+
(Utf8PathBuf::from(path.to_string()), contents)
20+
})
21+
}) {
22+
base.touch(db, path, contents.into());
23+
}
24+
}
25+
26+
#[derive(Embed)]
27+
#[folder = "../../library/core"]
28+
pub struct Core;
29+
30+
pub trait HasBuiltinCore: InputDb {
31+
fn initialize_builtin_core(&mut self);
32+
fn builtin_core(&self) -> Ingot<'_>;
33+
}
34+
35+
impl<T: InputDb> HasBuiltinCore for T {
36+
fn initialize_builtin_core(&mut self) {
37+
initialize_builtin::<Core>(self, BUILTIN_CORE_BASE_URL);
38+
}
39+
40+
fn builtin_core(&self) -> Ingot<'_> {
41+
let core = self
42+
.workspace()
43+
.containing_ingot(self, Url::parse(BUILTIN_CORE_BASE_URL).unwrap());
44+
core.expect("Built-in core ingot failed to initialize")
45+
}
46+
}
47+
48+
#[derive(Embed)]
49+
#[folder = "../../library/std"]
50+
pub struct Std;
51+
52+
pub trait HasBuiltinStd: InputDb {
53+
fn initialize_builtin_std(&mut self);
54+
fn builtin_std(&self) -> Ingot<'_>;
55+
}
56+
57+
impl<T: InputDb> HasBuiltinStd for T {
58+
fn initialize_builtin_std(&mut self) {
59+
initialize_builtin::<Std>(self, BUILTIN_STD_BASE_URL);
60+
}
61+
62+
fn builtin_std(&self) -> Ingot<'_> {
63+
let std = self
64+
.workspace()
65+
.containing_ingot(self, Url::parse(BUILTIN_STD_BASE_URL).unwrap());
66+
std.expect("Built-in std ingot failed to initialize")
67+
}
68+
}

crates/hir-analysis/src/ty/ty_def.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'db> TyId<'db> {
184184

185185
let ty_ingot = self.ingot(db);
186186
match ingot.kind(db) {
187-
IngotKind::Core => ty_ingot.is_none() || ty_ingot == Some(ingot),
187+
IngotKind::Core | IngotKind::Std => ty_ingot.is_none() || ty_ingot == Some(ingot),
188188
_ => ty_ingot == Some(ingot),
189189
}
190190
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use std::evm::ops::{sload, sstore}
2+
3+
fn increment(slot: u256) {
4+
let x = sload(slot)
5+
sstore(slot, value: x + 1)
6+
}
7+
8+
fn f() {
9+
increment(slot: 0)
10+
}

crates/hir-analysis/test_files/imports/std_import.snap

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
source: crates/hir-analysis/tests/import.rs
3-
assertion_line: 36
43
expression: res
54
input_file: test_files/imports/std_import.fe
65
---
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use core::option::Option::{self, Some, None}
2+
use core::result::Result::{self, Ok, Err}
3+
use core::functional::{Fn, Functor, Applicative, Monad}
4+
5+
struct AddOne {}
6+
impl Fn<i32, i32> for AddOne {
7+
fn call(self, _ value: i32) -> i32 {
8+
value + 1
9+
}
10+
}
11+
12+
struct ToPositive {}
13+
impl Fn<i32, Option<i32>> for ToPositive {
14+
fn call(self, _ value: i32) -> Option<i32> {
15+
if value > 0 {
16+
Some(value)
17+
} else {
18+
None
19+
}
20+
}
21+
}
22+
23+
struct ToEvenResult {}
24+
impl Fn<i32, Result<(), i32>> for ToEvenResult {
25+
fn call(self, _ value: i32) -> Result<(), i32> {
26+
if value % 2 == 0 {
27+
Ok(value)
28+
} else {
29+
Err(())
30+
}
31+
}
32+
}
33+
34+
fn option_monad_chain(start: Option<i32>) -> Option<i32> {
35+
let mapped = start.map(AddOne{})
36+
mapped.and_then(ToPositive{})
37+
}
38+
39+
fn result_monad_chain(start: Result<(), i32>) -> Result<(), i32> {
40+
let functor_mapped = start.map(AddOne{})
41+
42+
let func: Result<(), AddOne> = Ok(AddOne{})
43+
let value: Result<(), i32> = functor_mapped
44+
let applied = func.ap(value)
45+
46+
applied.bind(ToEvenResult{})
47+
}
48+
49+
trait Logger {
50+
fn log(mut self)
51+
}
52+
53+
struct ConsoleLogger {}
54+
impl Logger for ConsoleLogger {
55+
fn log(mut self) {}
56+
}
57+
58+
pub fn log_and_chain(x: i32) -> Result<(), Option<i32>>
59+
uses (mut logger: Logger)
60+
{
61+
logger.log()
62+
63+
let opt = Some(x)
64+
let opt_chain = option_monad_chain(start: opt)
65+
66+
let base = Ok(x)
67+
let res_chain = result_monad_chain(start: base)
68+
69+
match res_chain {
70+
Ok(_) => Ok(opt_chain)
71+
Err(e) => Err(e)
72+
}
73+
}
74+
75+
pub fn with_logger<R, L: Logger, F: Fn<(), R>>(logger: L, _ func: F) -> R {
76+
with (Logger = logger) {
77+
func.call(())
78+
}
79+
}
80+
81+
pub fn log_once()
82+
uses (mut logger: Logger)
83+
{
84+
logger.log()
85+
}
86+
87+
struct RunWithLogger {}
88+
impl Fn<(), Result<(), Option<i32>>> for RunWithLogger {
89+
fn call(self, _ unit: ()) -> Result<(), Option<i32>> {
90+
with (Logger = ConsoleLogger {}) {
91+
log_once()
92+
log_and_chain(x: 10)
93+
}
94+
}
95+
}
96+
97+
pub fn use_with_logger() {
98+
let logger = ConsoleLogger {}
99+
let result: Result<(), Option<i32>> = with_logger(logger, RunWithLogger{})
100+
let _ = result
101+
}

0 commit comments

Comments
 (0)