Skip to content

Commit 668ba1e

Browse files
authored
Merge pull request #101 from matt-cornell/destructor-bugs
Fix some issues involving affine types
2 parents 30847c0 + 6cc521a commit 668ba1e

File tree

5 files changed

+81
-89
lines changed

5 files changed

+81
-89
lines changed

cobalt-ast/src/ast/funcs.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum ParamType {
1313
Constant,
1414
}
1515
pub type Parameter<'src> = (
16+
SourceSpan,
1617
Cow<'src, str>,
1718
ParamType,
1819
BoxedAST<'src>,
@@ -59,7 +60,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
5960
+ self
6061
.params
6162
.iter()
62-
.map(|(_, _, ty, def)| ty.nodes() + def.as_ref().map_or(0, |x| x.nodes()))
63+
.map(|(_, _, _, ty, def)| ty.nodes() + def.as_ref().map_or(0, |x| x.nodes()))
6364
.sum::<usize>()
6465
+ 1
6566
}
@@ -80,7 +81,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
8081
let params = self
8182
.params
8283
.iter()
83-
.map(|(_, pt, ty, _)| {
84+
.map(|(_, _, pt, ty, _)| {
8485
(
8586
{
8687
let mut val = ops::impl_convert(
@@ -338,7 +339,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
338339
.params
339340
.iter()
340341
.zip(cloned)
341-
.filter_map(|((_, _, _, d), (t, _))| {
342+
.filter_map(|((_,_, _, _, d), (t, _))| {
342343
d.as_ref().map(|a| {
343344
let old_const = ctx.is_const.replace(true);
344345
let val = a.codegen(ctx).0;
@@ -434,7 +435,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
434435
.params
435436
.iter()
436437
.zip(cloned)
437-
.filter_map(|((_, _, _, d), (t, _))| {
438+
.filter_map(|((_, _, _, _, d), (t, _))| {
438439
d.as_ref().map(|a| {
439440
let old_const = ctx.is_const.replace(true);
440441
let val = a.codegen(ctx).0;
@@ -474,7 +475,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
474475
.params
475476
.iter()
476477
.zip(cloned)
477-
.filter_map(|((_, _, _, d), (t, _))| {
478+
.filter_map(|((_, _, _, _, d), (t, _))| {
478479
d.as_ref().map(|a| {
479480
let old_const = ctx.is_const.replace(true);
480481
let val = a.codegen(ctx).0;
@@ -543,7 +544,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
543544
let mut params = self
544545
.params
545546
.iter()
546-
.map(|(_, pt, ty, _)| {
547+
.map(|(_, _, pt, ty, _)| {
547548
(
548549
{
549550
let mut val = ops::impl_convert(
@@ -901,7 +902,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
901902
))
902903
{
903904
errs.push(CobaltError::InvalidSelfParam {
904-
loc: self.params[0].2.loc(),
905+
loc: self.params[0].3.loc(),
905906
self_t: s,
906907
param: Some(params[0].0.to_string()),
907908
});
@@ -960,7 +961,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
960961
))
961962
{
962963
errs.push(CobaltError::InvalidSelfParam {
963-
loc: self.params[0].2.loc(),
964+
loc: self.params[0].3.loc(),
964965
self_t: s,
965966
param: Some(params[0].0.to_string()),
966967
});
@@ -1068,7 +1069,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
10681069
gv.set_linkage(Private)
10691070
}
10701071
let cloned = params.clone(); // Rust doesn't like me using params in the following closure
1071-
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, d), (t, _))| d.as_ref().map(|a| {
1072+
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, _, d), (t, _))| d.as_ref().map(|a| {
10721073
let old_const = ctx.is_const.replace(true);
10731074
let val = a.codegen_errs(ctx, &mut errs);
10741075
let val = ops::impl_convert(a.loc(), (val, None), (t.clone(), None), ctx);
@@ -1096,12 +1097,14 @@ impl<'src> AST<'src> for FnDefAST<'src> {
10961097
Type::Reference(Box::new(fty.clone()))
10971098
), VariableData::with_vis(self.loc, vs)))).clone();
10981099
if is_extern.is_none() {
1100+
let entry = ctx.context.append_basic_block(f, "entry");
1101+
ctx.builder.position_at_end(entry);
10991102
let old_scope = ctx.push_scope(&self.name);
11001103
ctx.map_vars(|v| Box::new(VarMap::new(Some(v))));
11011104
ctx.lex_scope.incr();
11021105
{
11031106
let mut n = 0;
1104-
for ((name, pt), (ty, is_const)) in self.params.iter().map(|x| (&x.0, x.1)).zip(params.iter()) {
1107+
for ((loc, name, pt), (ty, is_const)) in self.params.iter().map(|x| (x.0, &x.1, x.2)).zip(params.iter()) {
11051108
if name.is_empty() {
11061109
if !is_const {
11071110
n += 1;
@@ -1119,7 +1122,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
11191122
val.data_type = Type::Mut(Box::new(val.data_type));
11201123
}
11211124
val.name = Some((name.clone(), ctx.lex_scope.get()));
1122-
ctx.with_vars(|v| v.insert(&DottedName::local((name.clone(), unreachable_span())), Symbol(val, VariableData::default()))).map_or((), |_| ());
1125+
let _ = ctx.with_vars(|v| v.insert(&DottedName::local((name.clone(), unreachable_span())), Symbol(val, VariableData {loc: Some(loc), ..VariableData::default()})));
11231126
n += 1;
11241127
}
11251128
else {
@@ -1131,8 +1134,6 @@ impl<'src> AST<'src> for FnDefAST<'src> {
11311134
}
11321135
}
11331136
}
1134-
let entry = ctx.context.append_basic_block(f, "entry");
1135-
ctx.builder.position_at_end(entry);
11361137
ctx.to_drop.borrow_mut().push(Vec::new());
11371138
let body = self.body.codegen_errs(ctx, &mut errs);
11381139
ctx.to_drop.borrow_mut().pop().unwrap().into_iter().for_each(|v| v.ins_dtor(ctx));
@@ -1183,7 +1184,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
11831184
}
11841185
else {
11851186
let cloned = params.clone(); // Rust doesn't like me using params in the following closure
1186-
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, d), (t, _))| d.as_ref().map(|a| {
1187+
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, _, d), (t, _))| d.as_ref().map(|a| {
11871188
let old_const = ctx.is_const.replace(true);
11881189
let val = a.codegen_errs(ctx, &mut errs);
11891190
let val = ops::impl_convert(a.loc(), (val, None), (t.clone(), None), ctx);
@@ -1231,7 +1232,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
12311232
gv.set_linkage(Private)
12321233
}
12331234
let cloned = params.clone(); // Rust doesn't like me using params in the following closure
1234-
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, d), (t, _))| d.as_ref().map(|a| {
1235+
let defaults = self.params.iter().zip(cloned).filter_map(|((_,_, _, _, d), (t, _))| d.as_ref().map(|a| {
12351236
let old_const = ctx.is_const.replace(true);
12361237
let val = a.codegen_errs(ctx, &mut errs);
12371238
let val = ops::impl_convert(a.loc(), (val, None), (t.clone(), None), ctx);
@@ -1259,12 +1260,14 @@ impl<'src> AST<'src> for FnDefAST<'src> {
12591260
Type::Reference(Box::new(fty.clone()))
12601261
), VariableData::with_vis(self.loc, vs)))).clone();
12611262
if is_extern.is_none() {
1263+
let entry = ctx.context.append_basic_block(f, "entry");
1264+
ctx.builder.position_at_end(entry);
12621265
let old_scope = ctx.push_scope(&self.name);
12631266
ctx.map_vars(|v| Box::new(VarMap::new(Some(v))));
12641267
ctx.lex_scope.incr();
12651268
{
12661269
let mut n = 0;
1267-
for ((name, pt), (ty, is_const)) in self.params.iter().map(|x| (&x.0, x.1)).zip(params.iter()) {
1270+
for ((loc, name, pt), (ty, is_const)) in self.params.iter().map(|x| (x.0, &x.1, x.2)).zip(params.iter()) {
12681271
if name.is_empty() {
12691272
if !is_const {
12701273
n += 1;
@@ -1282,7 +1285,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
12821285
val.data_type = Type::Mut(Box::new(val.data_type));
12831286
}
12841287
val.name = Some((name.clone(), ctx.lex_scope.get()));
1285-
ctx.with_vars(|v| v.insert(&DottedName::local((name.clone(), unreachable_span())), Symbol(val, VariableData::default()))).map_or((), |_| ());
1288+
let _ = ctx.with_vars(|v| v.insert(&DottedName::local((name.clone(), unreachable_span())), Symbol(val, VariableData {loc: Some(loc), ..VariableData::default()})));
12861289
n += 1;
12871290
}
12881291
else {
@@ -1294,8 +1297,6 @@ impl<'src> AST<'src> for FnDefAST<'src> {
12941297
}
12951298
}
12961299
}
1297-
let entry = ctx.context.append_basic_block(f, "entry");
1298-
ctx.builder.position_at_end(entry);
12991300
ctx.to_drop.borrow_mut().push(Vec::new());
13001301
self.body.codegen_errs(ctx, &mut errs);
13011302
ctx.to_drop.borrow_mut().pop().unwrap().into_iter().for_each(|v| v.ins_dtor(ctx));
@@ -1346,7 +1347,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
13461347
}
13471348
else {
13481349
let cloned = params.clone(); // Rust doesn't like me using params in the following closure
1349-
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, d), (t, _))| d.as_ref().map(|a| {
1350+
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, _, d), (t, _))| d.as_ref().map(|a| {
13501351
let old_const = ctx.is_const.replace(true);
13511352
let val = a.codegen_errs(ctx, &mut errs);
13521353
let val = ops::impl_convert(a.loc(), (val, None), (t.clone(), None), ctx);
@@ -1377,7 +1378,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
13771378
}
13781379
else {
13791380
let cloned = params.clone(); // Rust doesn't like me using params in the following closure
1380-
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, d), (t, _))| d.as_ref().map(|a| {
1381+
let defaults = self.params.iter().zip(cloned).filter_map(|((_, _, _, _, d), (t, _))| d.as_ref().map(|a| {
13811382
let old_const = ctx.is_const.replace(true);
13821383
let val = a.codegen_errs(ctx, &mut errs);
13831384
let val = ops::impl_convert(a.loc(), (val, None), (t.clone(), None), ctx);
@@ -1465,7 +1466,7 @@ impl<'src> AST<'src> for FnDefAST<'src> {
14651466
pre.pop();
14661467
writeln!(f, "{pre}├── parameters:")?;
14671468
pre.push(false);
1468-
for (n, (param, param_ty, ty, default)) in self.params.iter().enumerate() {
1469+
for (n, (_, param, param_ty, ty, default)) in self.params.iter().enumerate() {
14691470
writeln!(
14701471
f,
14711472
"{pre}{}{}{}",

cobalt-ast/src/ast/groups.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl<'src> AST<'src> for BlockAST<'src> {
2121
ctx: &CompCtx<'src, 'ctx>,
2222
) -> (Value<'src, 'ctx>, Vec<CobaltError<'src>>) {
2323
ctx.map_vars(|v| Box::new(VarMap::new(Some(v))));
24-
// ctx.lex_scope.incr();
24+
ctx.lex_scope.incr();
2525
let mut out = Value::null();
2626
let mut errs = vec![];
2727
let start = cfg::Location::current(ctx);
@@ -65,9 +65,10 @@ impl<'src> AST<'src> for BlockAST<'src> {
6565
}));
6666
}
6767
}
68-
// let mut b = ctx.moves.borrow_mut();
69-
// b.0.retain(|v| v.name.1 < ctx.lex_scope.get());
70-
// b.1.retain(|v| v.name.1 < ctx.lex_scope.get());
68+
let mut b = ctx.moves.borrow_mut();
69+
b.0.retain(|v| v.name.1 < ctx.lex_scope.get());
70+
b.1.retain(|v| v.name.1 < ctx.lex_scope.get());
71+
ctx.lex_scope.decr();
7172
ctx.map_vars(|v| v.parent.unwrap());
7273
(out, errs)
7374
}

cobalt-ast/src/cfg.rs

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ impl<'a, 'src, 'ctx> Cfg<'a, 'src, 'ctx> {
870870
inst: Option<Location<'ctx>>,
871871
ctx: &CompCtx<'src, 'ctx>,
872872
) -> IntValue<'ctx> {
873+
let allow_eq = inst.is_none();
873874
let inst = inst.unwrap_or(self.last);
874875
let mut blk = None;
875876

@@ -913,7 +914,7 @@ impl<'a, 'src, 'ctx> Cfg<'a, 'src, 'ctx> {
913914
.moves
914915
.iter()
915916
.rev() // 1
916-
.filter(|e| for_both!(e, e => (**e).name.0 == name && (**e).inst <= inst)) // 2
917+
.filter(|e| for_both!(e, e => (**e).name.0 == name && ((allow_eq && (**e).inst == inst) || (**e).inst < inst))) // 2
917918
.find_map(|e| match e {
918919
// 3
919920
Either::Left(u) => ((**u).is_move && (**u).real).then_some(true_),
@@ -925,7 +926,18 @@ impl<'a, 'src, 'ctx> Cfg<'a, 'src, 'ctx> {
925926
let mut seen = HashSet::new();
926927
while let Some(idx) = queue.pop() {
927928
let block = &self.blocks[idx];
928-
match block.output.get() {
929+
match if block.block == inst.block() {
930+
block.moves
931+
.iter()
932+
.rev()
933+
.filter(|e| for_both!(e, e => (**e).name.0 == name && ((allow_eq && (**e).inst == inst) || (**e).inst < inst)))
934+
.find_map(|e| match e {
935+
Either::Left(u) => ((**u).is_move && (**u).real).then_some(true),
936+
Either::Right(s) => (**s).real.then_some(false),
937+
})
938+
} else {
939+
block.output.get()
940+
} {
929941
None => {
930942
let len = queue.len();
931943
queue.extend(
@@ -970,29 +982,29 @@ impl<'a, 'src, 'ctx> Cfg<'a, 'src, 'ctx> {
970982
.unwrap()
971983
.get_parent()
972984
.unwrap();
985+
let mut reposition = true;
973986
self.blocks
974987
.iter()
975988
.flat_map(|b| &b.moves)
976989
.filter_map(|e| e.as_ref().right())
990+
.filter(|s| unsafe { (***s).name.1 } == ctx.lex_scope.get())
977991
.for_each(|m| unsafe {
978992
let m = &**m;
979-
match m.inst {
980-
Location::Block(b) => {
981-
if let Some(i) = b.get_first_instruction() {
982-
ctx.builder.position_before(&i)
983-
} else {
984-
ctx.builder.position_at_end(b)
985-
}
986-
}
987-
Location::Inst(i, _) => ctx.builder.position_before(&i),
988-
Location::AfterInst(i) => {
989-
if let Some(i) = i.get_next_instruction() {
990-
ctx.builder.position_before(&i)
991-
} else {
992-
ctx.builder.position_at_end(i.get_parent().unwrap())
993-
}
994-
}
995-
}
993+
let i = if let Location::Inst(i, 0) = m.inst {
994+
i
995+
} else {
996+
unreachable!("store locations should only be Location::Inst(_, 0)")
997+
};
998+
assert_eq!(
999+
i.get_next_instruction()
1000+
.map(|i| (i.get_opcode(), i.get_num_operands())),
1001+
Some((inkwell::values::InstructionOpcode::Br, 1))
1002+
);
1003+
let next = i.get_next_instruction().unwrap();
1004+
let next_block = next.get_operand(0).unwrap().unwrap_right();
1005+
reposition = false;
1006+
ctx.builder
1007+
.position_before(&i.get_next_instruction().unwrap());
9961008
let c = self.is_moved(&m.name.0, Some(m.name.1), Some(m.inst), ctx);
9971009
match c.get_zero_extended_constant() {
9981010
Some(0) => {
@@ -1005,33 +1017,16 @@ impl<'a, 'src, 'ctx> Cfg<'a, 'src, 'ctx> {
10051017
let db = ctx
10061018
.context
10071019
.append_basic_block(f, &format!("dtor.{}.{}", m.name.0, m.name.1));
1008-
let mb = ctx.context.append_basic_block(f, "merge");
1009-
ctx.builder.build_conditional_branch(c, mb, db);
1020+
ctx.builder.build_conditional_branch(c, next_block, db);
1021+
next.erase_from_basic_block();
10101022
ctx.builder.position_at_end(db);
10111023
ctx.lookup(&m.name.0, false).unwrap().0.ins_dtor(ctx);
1012-
ctx.builder.build_unconditional_branch(mb);
1013-
ctx.builder.position_at_end(mb);
1024+
ctx.builder.build_unconditional_branch(next_block);
1025+
ctx.builder.position_at_end(next_block);
10141026
}
10151027
}
10161028
});
10171029
if at_end {
1018-
match self.last {
1019-
Location::Block(b) => {
1020-
if let Some(i) = b.get_first_instruction() {
1021-
ctx.builder.position_before(&i)
1022-
} else {
1023-
ctx.builder.position_at_end(b)
1024-
}
1025-
}
1026-
Location::Inst(i, _) => ctx.builder.position_before(&i),
1027-
Location::AfterInst(i) => {
1028-
if let Some(i) = i.get_next_instruction() {
1029-
ctx.builder.position_before(&i)
1030-
} else {
1031-
ctx.builder.position_at_end(i.get_parent().unwrap())
1032-
}
1033-
}
1034-
}
10351030
ctx.with_vars(|v| {
10361031
v.symbols.iter().for_each(|(n, v)| {
10371032
let scope =

0 commit comments

Comments
 (0)