Skip to content

Commit 164b3c3

Browse files
authored
Merge pull request #386 from Pivot-Studio/feat/check_before_compile-2
feature: support check command
2 parents ca7280a + 38514a6 commit 164b3c3

File tree

22 files changed

+305
-166
lines changed

22 files changed

+305
-166
lines changed

Cargo.lock

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ derivative = "2.2"
4545
console = "0.15"
4646
anstyle = "1.0"
4747
regex = "1.9"
48-
ena = "0.2"
48+
ena = "0.14"
4949

5050
[target.'cfg(target_arch = "wasm32")'.dependencies]
5151
wasm-bindgen = "0.2"

src/ast/compiler.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::node::program::ASSET_PATH;
44
#[cfg(feature = "llvm")]
55
use crate::ast::jit_config::IS_JIT;
66
use crate::{
7-
ast::{accumulators::ModBuffer, diag::ensure_no_error, node::program::Program},
7+
ast::{accumulators::ModBuffer, node::program::Program},
88
lsp::mem_docs::{FileCompileInput, MemDocsInput},
99
nomparser::parse,
1010
utils::read_config::search_config_file,
@@ -77,6 +77,7 @@ pub fn compile(db: &dyn Db, docs: MemDocsInput, out: String, op: Options) {
7777
}
7878

7979
let ctx = Context::create();
80+
// ensure_no_error(db, docs);
8081
let (llvmmod, files) = process_llvm_ir(db, docs, &ctx, op);
8182

8283
pl_link(llvmmod, files, out.clone(), op);
@@ -162,7 +163,6 @@ pub fn process_llvm_ir<'a>(
162163
op: Options,
163164
) -> (Module<'a>, Vec<PathBuf>) {
164165
let mods = compile_dry::accumulated::<ModBuffer>(db, docs);
165-
ensure_no_error(db, docs);
166166

167167
let total_steps = 3;
168168
let pb = ProgressBar::hidden();

src/ast/compiler/progress.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use lazy_static::lazy_static;
88

99
lazy_static! {
1010
pub static ref COMPILE_PROGRESS: ProgressBar = ProgressBar::hidden();
11+
pub static ref CHECK_PROGRESS: ProgressBar = ProgressBar::hidden();
1112
}
1213

1314
pub(crate) static LOOKING_GLASS: Emoji<'_, '_> = Emoji("🔍 ", ":-)");

src/ast/ctx.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use crate::utils::read_config::Config;
3535
use crate::Db;
3636

3737
use crate::ast::node::function::generator::GeneratorCtxData;
38+
use ena::unify::InPlace;
3839
use ena::unify::UnificationTable;
3940
use indexmap::IndexMap;
4041

@@ -180,7 +181,7 @@ pub struct Ctx<'a> {
180181
as_root: bool,
181182

182183
macro_expand_depth: Arc<RefCell<u64>>,
183-
pub unify_table: Arc<RefCell<UnificationTable<TyVariable>>>,
184+
pub unify_table: Arc<RefCell<UnificationTable<InPlace<TyVariable>>>>,
184185
pub disable_diag: bool,
185186

186187
pub macro_vars: FxHashMap<String, MacroReplaceNode>,

src/ast/ctx/generic.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,17 @@ impl<'a> Ctx<'a> {
102102
if lg.curpltype.is_some() {
103103
return self.eq(lg.curpltype.as_ref().unwrap().clone(), r);
104104
}
105+
// set the real type of generic type to the type of the right
105106
lg.set_type(r.clone());
107+
// in this case, we need to check if the right type
108+
// satisfies the trait constraints of the generic type
109+
// so we don't return here
106110
}
107111
if let PLType::Generic(lg) = &*l.borrow() {
108112
if lg.trait_impl.is_some() {
109113
if let PLType::Generic(r) = &*r.borrow() {
114+
// in case checking equality of two generic types,
115+
// we need to check if the trait impls of them are equal
110116
if let Some(reason) = self.diff_trait_impl(lg, r) {
111117
return EqRes {
112118
eq: false,
@@ -123,6 +129,8 @@ impl<'a> Ctx<'a> {
123129
.iter()
124130
.any(|lt| !self.eq(lt.clone(), r.clone()).eq)
125131
{
132+
// try to pass normal type as generic type, check if it contains
133+
// all the trait expected by the generic type
126134
return EqRes {
127135
eq: false,
128136
need_up_cast: false,

src/ast/ctx/lsp.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ impl Ctx<'_> {
9494
if self.need_highlight.borrow().ne(&0) || self.in_macro {
9595
return;
9696
}
97+
if range.start.line > 200 {
98+
eprintln!();
99+
}
97100
self.get_root_ctx()
98101
.plmod
99102
.semantic_tokens_builder

src/ast/ctx/references.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ impl<'a> Ctx<'a> {
7777
return;
7878
}
7979
let root = self.get_root_ctx();
80+
if root.get_file() != self.get_file() {
81+
return;
82+
}
83+
if range.start.line == 1 && range.start.column == 12 && root.get_file().contains("iter.pi")
84+
{
85+
eprintln!(
86+
"{}:{}:{}",
87+
root.get_file(),
88+
range.start.line,
89+
range.start.column
90+
);
91+
}
8092
root.plmod
8193
.glob_refs
8294
.borrow_mut()

src/ast/diag.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,14 +516,14 @@ pub(crate) fn ensure_no_error(db: &dyn Db, docs: MemDocsInput) {
516516
if errs_num == 1 {
517517
log::error!(
518518
"{}",
519-
format!("compile failed: there is {} error", errs_num).bright_red()
519+
format!("check failed: there is {} error", errs_num).bright_red()
520520
);
521521
println!("{}", dot::ERROR);
522522
exit(1);
523523
}
524524
log::error!(
525525
"{}",
526-
format!("compile failed: there are {} errors", errs_num).bright_red()
526+
format!("check failed: there are {} errors", errs_num).bright_red()
527527
);
528528
println!("{}", dot::TOOMANYERROR);
529529
exit(1);

src/ast/node/function.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ impl Node for FuncCallNode {
214214
_ => return Err(ctx.add_diag(self.range.new_err(ErrorCode::FUNCTION_NOT_FOUND))),
215215
};
216216

217+
if let Some(p) = &self.generic_params {
218+
p.emit_highlight(ctx);
219+
}
217220
generic_tp_apply(&fnvalue, self, ctx, builder)?;
218221
let mut skip = 0;
219222
let mut para_values = vec![];
@@ -299,6 +302,7 @@ impl Node for FuncCallNode {
299302
res
300303
}
301304
}
305+
302306
/// # generic_tp_apply
303307
///
304308
/// This method will apply generic parameter types to a generic custom type.
@@ -308,13 +312,24 @@ pub fn generic_tp_apply<'a, 'b, T: Generic + CustomType, N: GenericInferenceAble
308312
ctx: &'b mut Ctx<'a>,
309313
builder: &'b BuilderEnum<'a, '_>,
310314
) -> Result<(), PLDiag> {
311-
// disable highlight
312-
*ctx.need_highlight.borrow_mut() += 1;
313315
let generic_size = tp.get_generic_size();
314316
let generic_params = node.get_generic_params();
317+
// disable highlight
318+
*ctx.need_highlight.borrow_mut() += 1;
315319
let range = node.range();
316-
let mut generic_types = preprocess_generics(generic_params, generic_size, range, ctx, builder)?;
317-
320+
let re = preprocess_generics(
321+
generic_params,
322+
generic_size,
323+
tp.get_user_generic_size(),
324+
range,
325+
ctx,
326+
builder,
327+
);
328+
if let Err(diag) = re {
329+
*ctx.need_highlight.borrow_mut() -= 1;
330+
return Err(diag);
331+
}
332+
let mut generic_types = re.unwrap();
318333
let re = ctx.run_in_type_mod(tp, |ctx, t| {
319334
ctx.protect_generic_context(t.get_generic_map(), |ctx| {
320335
for (i, (_, pltype)) in t.get_generic_map().iter().enumerate() {
@@ -329,7 +344,7 @@ pub fn generic_tp_apply<'a, 'b, T: Generic + CustomType, N: GenericInferenceAble
329344
.unwrap_or_default()
330345
.get(i)
331346
.map(|v| {
332-
let ty = ctx.unify_table.borrow_mut().probe(*v);
347+
let ty = ctx.unify_table.borrow_mut().probe_value(*v);
333348
ty.get_type(ctx, builder, &mut ctx.unify_table.clone().borrow_mut())
334349
});
335350
if let Some(ty) = ty {
@@ -355,6 +370,14 @@ pub fn generic_tp_apply<'a, 'b, T: Generic + CustomType, N: GenericInferenceAble
355370
format_label!("parameter `{}` defined in `{}`", g.0, t.get_name()),
356371
);
357372
return Err(diag.add_to_ctx(ctx));
373+
} else if i < t.get_user_generic_size() {
374+
ctx.set_if_refs_tp(
375+
generic_types[i].as_ref().unwrap().clone(),
376+
generic_params
377+
.as_ref()
378+
.and_then(|v| v.generics[i].as_ref().map(|v| v.range()))
379+
.unwrap_or_default(),
380+
);
358381
}
359382
}
360383
Ok(())
@@ -370,14 +393,15 @@ pub fn generic_tp_apply<'a, 'b, T: Generic + CustomType, N: GenericInferenceAble
370393
fn preprocess_generics<'a, 'b>(
371394
generic_params: &Option<Box<GenericParamNode>>,
372395
generic_size: usize,
396+
usr_generic_size: usize,
373397
range: Range,
374398
ctx: &'b mut Ctx<'a>,
375399
builder: &'b BuilderEnum<'a, '_>,
376400
) -> Result<Vec<Option<Arc<RefCell<PLType>>>>, PLDiag> {
377401
let generic_params = if let Some(generic_params) = generic_params {
378402
generic_params.emit_highlight(ctx);
379403
let generic_params_range = generic_params.range;
380-
if generic_params.generics.len() != generic_size {
404+
if generic_params.generics.len() != usr_generic_size {
381405
return Err(
382406
ctx.add_diag(generic_params_range.new_err(ErrorCode::GENERIC_PARAM_LEN_MISMATCH))
383407
);
@@ -389,7 +413,10 @@ fn preprocess_generics<'a, 'b>(
389413
range,
390414
})
391415
};
392-
let generic_types = generic_params.get_generic_types(ctx, builder)?;
416+
let mut generic_types = generic_params.get_generic_types(ctx, builder)?;
417+
if generic_types.len() != generic_size {
418+
generic_types.resize(generic_size, None);
419+
}
393420
Ok(generic_types)
394421
}
395422

@@ -1034,7 +1061,7 @@ impl Node for ClosureNode {
10341061
typenode.emit_highlight(ctx);
10351062
typenode.get_type(ctx, builder, true)?
10361063
} else if let Some(id) = v.id {
1037-
let vv = ctx.unify_table.borrow_mut().probe(id);
1064+
let vv = ctx.unify_table.borrow_mut().probe_value(id);
10381065
let tp = vv.get_type(ctx, builder, &mut ctx.unify_table.clone().borrow_mut());
10391066
if *tp.borrow() == PLType::Unknown {
10401067
v.range()
@@ -1078,7 +1105,7 @@ impl Node for ClosureNode {
10781105
ret.emit_highlight(ctx);
10791106
ret.get_type(ctx, builder, true)?
10801107
} else if let Some(ty) = self.ret_id {
1081-
let v = ctx.unify_table.borrow_mut().probe(ty);
1108+
let v = ctx.unify_table.borrow_mut().probe_value(ty);
10821109
let tp = v.get_type(ctx, builder, &mut ctx.unify_table.clone().borrow_mut());
10831110
tp
10841111
} else if let Some(exp_ty) = &ctx.expect_ty {

0 commit comments

Comments
 (0)