Skip to content

Commit b023a13

Browse files
committed
Better error reporting for "using" related errors
1 parent 39a131a commit b023a13

File tree

8 files changed

+48
-22
lines changed

8 files changed

+48
-22
lines changed

include/yoyo/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Yoyo
2323
std::unique_ptr<Statement> parseInterfaceDeclaration(Token identifier);
2424
std::unique_ptr<Statement> parseUnionDeclaration(Token identifier);
2525
std::unique_ptr<Statement> parseMacroDeclaration(Token identifier);
26-
std::unique_ptr<Statement> parseUsingDeclaration();
26+
std::unique_ptr<Statement> parseUsingDeclaration(Token);
2727
std::unordered_map<std::string, std::unique_ptr<Expression>> parseObjectLiteral();
2828
std::unique_ptr<Statement> parseDeclaration();
2929
std::unique_ptr<Statement> parseReturnStatement(Token);

src/yoyo/constexpr_eval.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ namespace Yoyo
2020
ModuleBase* module = irgen->module;
2121
std::string hash = irgen->block_hash;
2222
Type tp{ .name = nexpr->text };
23-
irgen->apply_using(tp, module, hash);
23+
if (auto err = irgen->apply_using(tp, module, hash)) {
24+
err->span = SourceSpan{ nexpr->beg, nexpr->end };
25+
irgen->error(*err);
26+
}
2427
auto [blk, dets] = module->findConst(hash, nexpr->text);
2528
if (!dets)
2629
{

src/yoyo/error.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,7 @@ namespace Yoyo
7777
std::string Error::to_string(const SourceView& view, bool enable_color) const
7878
{
7979
std::vector<std::string> lines;
80-
size_t begin = std::max(size_t(1), span.begin.line - 1);
81-
size_t end = std::min(view.lines.size() + 1, span.end.line + 2);
82-
for (auto line : std::views::iota(begin, end))
83-
{
80+
auto render_line = [this, &view, enable_color, &lines](size_t line) {
8481
std::string line_body(view.lines[line - 1]);
8582
//apply color for the portion of text that is in error
8683
if (enable_color && span.end.line >= line && span.begin.line <= line)
@@ -94,6 +91,24 @@ namespace Yoyo
9491
}
9592
lines.emplace_back(std::format("{: >4} │ {}\n", line, line_body));
9693
lines.emplace_back(markers_for(" ", enable_color, line, markers, view));
94+
};
95+
size_t begin = std::max(size_t(1), span.begin.line - 1);
96+
size_t end = std::min(view.lines.size() + 1, span.end.line + 2);
97+
std::vector<size_t> rendered_lines;
98+
for (auto line : std::views::iota(begin, end))
99+
{
100+
rendered_lines.push_back(line);
101+
render_line(line);
102+
}
103+
104+
for (auto& marker : markers) {
105+
if (auto it = std::ranges::find(rendered_lines, marker.first.begin.line); it != rendered_lines.end())
106+
continue;
107+
lines.emplace_back("\n");
108+
for (auto line : std::views::iota(marker.first.begin.line, marker.first.end.line + 1)) {
109+
rendered_lines.push_back(line);
110+
render_line(line);
111+
}
97112
}
98113
auto result = std::format("{}{}:{}:{} error: {}{}\n",
99114
enable_color ? "\033[1;31m" : "",

src/yoyo/expression_type_checker.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,10 @@ namespace Yoyo
420420
ModuleBase* module = irgen->module;
421421
std::string hash = irgen->block_hash;
422422
Type tp{ .name = expr->text };
423-
irgen->apply_using(tp, module, hash);
423+
if (auto err = irgen->apply_using(tp, module, hash)) {
424+
err->span = { expr->beg, expr->end };
425+
irgen->error(*err);
426+
}
424427
if(auto [name_prefix, fn] = module->findFunction(hash, expr->text); fn)
425428
{
426429
irgen->saturateSignature(fn->sig, irgen->module);

src/yoyo/ir_gen.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ namespace Yoyo
398398
if (auto hs = this_md->hashOf(this_hsh, tp.name); hs && *hs == this_hsh && contains(stat, tp.name)) {
399399
//ambiguous
400400
if (contributing_stat) {
401-
Error err(SourceSpan{}, "The name " + tp.name + " is ambiguous in this context");
401+
Error err(SourceSpan{}, "The name \"" + tp.name + "\" is ambiguous in this context");
402402
err.markers.emplace_back(SourceSpan{ contributing_stat->beg, contributing_stat->end }, "Can be accessed from here");
403403
err.markers.emplace_back(SourceSpan{ stat->beg, stat->end }, "Can also be accessed from here");
404404
return err;
@@ -409,10 +409,10 @@ namespace Yoyo
409409
}
410410
}
411411
// remove this if ambiguity is resolved be how deep the declaration is
412-
if (contributing_stat) break;
412+
//if (contributing_stat) break;
413413
}
414414
if (exists && contributing_stat) {
415-
Error err(SourceSpan{}, "The name " + tp.name + " exists in this context but is imported");
415+
Error err(SourceSpan{}, "The name \"" + tp.name + "\" exists in this context but is imported");
416416
err.markers.emplace_back(SourceSpan{ contributing_stat->beg, contributing_stat->end }, "Import happens here");
417417
return err;
418418
}

src/yoyo/parser.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ namespace Yoyo
122122
auto iden = Get();
123123
if(!iden) return nullptr;
124124
if(iden->type == TokenType::Operator) return parseOperatorOverload(iden.value());
125-
if (iden->type == TokenType::Using) return parseUsingDeclaration();
125+
if (iden->type == TokenType::Using) return parseUsingDeclaration(iden.value());
126126
if(iden->type != TokenType::Identifier) error("Expected Identifier", iden);
127127
Get();//discard the ':'
128128
auto look_ahead = Peek();
@@ -416,7 +416,7 @@ namespace Yoyo
416416
}
417417
std::unique_ptr<Statement> Parser::parseMacroDeclaration(Token identifier)
418418
{
419-
if (!discard(TokenType::Macro)) error("Expected 'union'", Peek());
419+
if (!discard(TokenType::Macro)) error("Expected 'macro'", Peek());
420420
// only single param macros for now
421421
if (!discard(TokenType::LParen)) error("Expected '('", Peek());
422422
auto iden = Get();
@@ -441,7 +441,7 @@ namespace Yoyo
441441
auto end = decl->body->end;
442442
return Statement::attachSLAndParent(std::move(decl), identifier.loc, end, parent);
443443
}
444-
std::unique_ptr<Statement> Parser::parseUsingDeclaration()
444+
std::unique_ptr<Statement> Parser::parseUsingDeclaration(Token using_tok)
445445
{
446446
// modify the behaviour of the type parser to allow for ::{...} and ::*
447447
in_using_stat = true;
@@ -450,7 +450,9 @@ namespace Yoyo
450450
if (!tp) return nullptr;
451451
if (!discard(TokenType::SemiColon)) { error("Expected ';'", Peek()); return nullptr; }
452452
if (tp->name == "__star__") {
453-
return std::make_unique<UsingStatement>(UsingStatement::UsingAll{ .block = tp->block_hash });
453+
return Statement::attachSLAndParent(
454+
std::make_unique<UsingStatement>(UsingStatement::UsingAll{ .block = tp->block_hash }),
455+
using_tok.loc, discardLocation);
454456
}
455457
else if (tp->name == "__multi__") {
456458
//should have just used std::move tbh
@@ -459,17 +461,17 @@ namespace Yoyo
459461
std::ranges::transform(tp->subtypes, std::back_inserter(entities), [](const Type& t) { return t.name; });
460462
return entities;
461463
};
462-
return std::make_unique<UsingStatement>(UsingStatement::UsingMultiple{
464+
return Statement::attachSLAndParent(std::make_unique<UsingStatement>(UsingStatement::UsingMultiple{
463465
.block = tp->block_hash,
464466
.entities = make_entities()
465-
});
467+
}), using_tok.loc, discardLocation);
466468
}
467469
if (!tp->subtypes.empty()) { error("Cannot instantiate generics here", Peek()); }
468470

469-
return std::make_unique<UsingStatement>(UsingStatement::UsingSingle{
471+
return Statement::attachSLAndParent(std::make_unique<UsingStatement>(UsingStatement::UsingSingle{
470472
.block = tp->block_hash,
471473
.entity = tp->name
472-
});
474+
}), using_tok.loc, discardLocation);
473475
}
474476
Attribute parseAttribute(Parser& p)
475477
{

src/yoyo/type.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,12 @@ namespace Yoyo
835835
std::string FunctionSignature::pretty_name(const std::string& block_hash) const
836836
{
837837
std::string final_str = "fn(";
838-
if (parameters.size() >= 1) final_str.append(parameters[0].type.pretty_name(block_hash));
839-
for (auto& param : std::ranges::subrange(parameters.begin() + 1, parameters.end()))
840-
{
841-
final_str.append(", " + param.type.pretty_name(block_hash));
838+
if (parameters.size() >= 1) {
839+
final_str.append(parameters[0].type.pretty_name(block_hash));
840+
for (auto& param : std::ranges::subrange(parameters.begin() + 1, parameters.end()))
841+
{
842+
final_str.append(", " + param.type.pretty_name(block_hash));
843+
}
842844
}
843845
final_str.append(")");
844846
return final_str;

tests/ir_gen_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ Module2: struct = {
269269
}
270270
Module3: struct = {
271271
Type: struct = { to_str: fn(&this) -> str = return "Module 3 type"; }
272+
print: fn = return;
272273
}
273274
using test::print;
274275
main: fn = {

0 commit comments

Comments
 (0)