Skip to content

Commit

Permalink
Merge #374
Browse files Browse the repository at this point in the history
374: Add basic wrapper over gcc rich_location r=philberty a=philberty

Adding rich location will improve our error message diagnostics, this is
an initial building block to keep a wrapper over the GCC stuff we call.

Addresses: #97 
Fixes: #327 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
  • Loading branch information
bors[bot] and philberty committed Apr 17, 2021
2 parents f958d17 + 5b8de2b commit 498758a
Show file tree
Hide file tree
Showing 28 changed files with 216 additions and 83 deletions.
15 changes: 9 additions & 6 deletions gcc/rust/resolve/rust-ast-resolve-implitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ class ResolveToplevelImplItem : public ResolverBase
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (constant.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (constant.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
Expand All @@ -59,8 +60,9 @@ class ResolveToplevelImplItem : public ResolverBase
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (function.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (function.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
Expand All @@ -74,8 +76,9 @@ class ResolveToplevelImplItem : public ResolverBase
resolver->get_name_scope ().insert (
path, method.get_node_id (), method.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (method.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (method.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (method.get_node_id (),
Definition{method.get_node_id (),
Expand Down
30 changes: 18 additions & 12 deletions gcc/rust/resolve/rust-ast-resolve-toplevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ class ResolveTopLevel : public ResolverBase
CanonicalPath (alias.get_new_type_name ()), alias.get_node_id (),
alias.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (alias.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (alias.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
}

Expand All @@ -56,8 +57,9 @@ class ResolveTopLevel : public ResolverBase
CanonicalPath (struct_decl.get_identifier ()), struct_decl.get_node_id (),
struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (struct_decl.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (struct_decl.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
}

Expand All @@ -67,8 +69,9 @@ class ResolveTopLevel : public ResolverBase
CanonicalPath (struct_decl.get_identifier ()), struct_decl.get_node_id (),
struct_decl.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (struct_decl.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (struct_decl.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
}

Expand All @@ -78,8 +81,9 @@ class ResolveTopLevel : public ResolverBase
CanonicalPath (var.get_identifier ()), var.get_node_id (),
var.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (var.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (var.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (var.get_node_id (),
Definition{var.get_node_id (),
Expand All @@ -94,8 +98,9 @@ class ResolveTopLevel : public ResolverBase
resolver->get_name_scope ().insert (
path, constant.get_node_id (), constant.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (constant.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (constant.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
Expand All @@ -109,8 +114,9 @@ class ResolveTopLevel : public ResolverBase
resolver->get_name_scope ().insert (
path, function.get_node_id (), function.get_locus (), false,
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
rust_error_at (function.get_locus (), "redefined multiple times");
rust_error_at (locus, "was defined here");
RichLocation r (function.get_locus ());
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
Expand Down
11 changes: 11 additions & 0 deletions gcc/rust/rust-diagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ rust_inform (const Location location, const char *fmt, ...)
va_end (ap);
}

// Rich Locations
void
rust_error_at (const RichLocation location, const char *fmt, ...)
{
va_list ap;

va_start (ap, fmt);
rust_be_error_at (location, expand_message (fmt, ap));
va_end (ap);
}

// rust_debug uses normal printf formatting, not GCC diagnostic formatting.

void
Expand Down
8 changes: 8 additions & 0 deletions gcc/rust/rust-diagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
// All other format specifiers are as defined by 'sprintf'. The final resulting
// message is then sent to the back end via rust_be_error_at/rust_be_warning_at.

// simple location
extern void
rust_error_at (const Location, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);
Expand All @@ -61,6 +62,11 @@ extern void
rust_inform (const Location, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);

// rich locations
extern void
rust_error_at (const RichLocation, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);

// These interfaces provide a way for the front end to ask for
// the open/close quote characters it should use when formatting
// diagnostics (warnings, errors).
Expand All @@ -78,6 +84,8 @@ rust_close_quote ();
extern void
rust_be_error_at (const Location, const std::string &errmsg);
extern void
rust_be_error_at (const RichLocation, const std::string &errmsg);
extern void
rust_be_warning_at (const Location, int opt, const std::string &warningmsg);
extern void
rust_be_fatal_error (const Location, const std::string &errmsg);
Expand Down
7 changes: 7 additions & 0 deletions gcc/rust/rust-gcc-diagnostics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ rust_be_inform (const Location location, const std::string &infomsg)
inform (gcc_loc, "%s", infomsg.c_str ());
}

void
rust_be_error_at (const RichLocation location, const std::string &errmsg)
{
rich_location gcc_loc = location.get ();
error_at (&gcc_loc, "%s", errmsg.c_str ());
}

void
rust_be_get_quotechars (const char **open_qu, const char **close_qu)
{
Expand Down
43 changes: 43 additions & 0 deletions gcc/rust/rust-linemap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,46 @@ rust_get_linemap ()
{
return new Gcc_linemap;
}

RichLocation::RichLocation (Location root)
: gcc_rich_loc (line_table, root.gcc_location ())
{
/*rich_location (line_maps *set, location_t loc,
const range_label *label = NULL);*/
}

RichLocation::~RichLocation () {}

void
RichLocation::add_range (Location loc)
{
gcc_rich_loc.add_range (loc.gcc_location ());
}

void
RichLocation::add_fixit_insert_before (const std::string &new_parent)
{
gcc_rich_loc.add_fixit_insert_before (new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_before (Location where,
const std::string &new_parent)
{
gcc_rich_loc.add_fixit_insert_before (where.gcc_location (),
new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_after (const std::string &new_parent)
{
gcc_rich_loc.add_fixit_insert_after (new_parent.c_str ());
}

void
RichLocation::add_fixit_insert_after (Location where,
const std::string &new_parent)
{
gcc_rich_loc.add_fixit_insert_after (where.gcc_location (),
new_parent.c_str ());
}
22 changes: 22 additions & 0 deletions gcc/rust/rust-location.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,26 @@ operator- (Location lhs, location_t rhs)
return lhs;
}

class RichLocation
{
public:
RichLocation (Location root);
~RichLocation ();

void add_range (Location loc);

void add_fixit_insert_before (const std::string &new_parent);

void add_fixit_insert_before (Location where, const std::string &new_parent);

void add_fixit_insert_after (const std::string &new_parent);

void add_fixit_insert_after (Location where, const std::string &new_parent);

rich_location get () const { return gcc_rich_loc; }

private:
rich_location gcc_rich_loc;
};

#endif // !defined(RUST_LOCATION_H)
14 changes: 5 additions & 9 deletions gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,17 @@ class OverlappingImplItemPass : public TypeCheckBase
void collision_detected (HIR::InherentImplItem *query,
HIR::InherentImplItem *dup, const std::string &name)
{
Location qlocus;
Location qlocus; // query
bool ok = GetLocusFromImplItem::Resolve (query, qlocus);
rust_assert (ok);

Location dlocus;
Location dlocus; // dup
ok = GetLocusFromImplItem::Resolve (dup, dlocus);
rust_assert (ok);

// this needs GCC Rich locations see
// https://github.com/Rust-GCC/gccrs/issues/97
rust_error_at (qlocus, "duplicate definitions with name %s", name.c_str ());
rust_error_at (dlocus, "duplicate def associated with");
RichLocation r (qlocus);
r.add_range (dlocus);
rust_error_at (r, "duplicate definitions with name %s", name.c_str ());
}

private:
Expand All @@ -209,9 +208,6 @@ class OverlappingImplItemPass : public TypeCheckBase
std::map<TyTy::BaseType *,
std::set<std::pair<HIR::InherentImplItem *, std::string> > >
impl_mappings;

std::map<TyTy::BaseType *, std::set<TyTy::BaseType *> >
possible_colliding_impls;
};

} // namespace Resolver
Expand Down
19 changes: 11 additions & 8 deletions gcc/rust/typecheck/rust-hir-path-probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,31 +129,34 @@ class ReportMultipleCandidateError : private TypeCheckBase
static void Report (std::vector<PathProbeCandidate> &candidates,
const HIR::PathIdentSegment &query, Location query_locus)
{
rust_error_at (query_locus, "multiple applicable items in scope for: %s",
query.as_string ().c_str ());

ReportMultipleCandidateError visitor;
RichLocation r (query_locus);
ReportMultipleCandidateError visitor (r);
for (auto &c : candidates)
c.impl_item->accept_vis (visitor);

rust_error_at (r, "multiple applicable items in scope for: %s",
query.as_string ().c_str ());
}

void visit (HIR::ConstantItem &constant) override
{
rust_error_at (constant.get_locus (), "possible candidate");
r.add_range (constant.get_locus ());
}

void visit (HIR::Function &function) override
{
rust_error_at (function.get_locus (), "possible candidate");
r.add_range (function.get_locus ());
}

void visit (HIR::Method &method) override
{
rust_error_at (method.get_locus (), "possible candidate");
r.add_range (method.get_locus ());
}

private:
ReportMultipleCandidateError () : TypeCheckBase () {}
ReportMultipleCandidateError (RichLocation &r) : TypeCheckBase (), r (r) {}

RichLocation &r;
};

} // namespace Resolver
Expand Down
6 changes: 1 addition & 5 deletions gcc/rust/typecheck/rust-hir-type-check-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,7 @@ class TypeCheckExpr : public TypeCheckBase

auto result = lhs->unify (rhs);
if (result->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (expr.get_locus (),
"type resolution failure in AssignmentExpr");
return;
}
return;

// in the case of declare first for an ADT Type:
//
Expand Down
6 changes: 1 addition & 5 deletions gcc/rust/typecheck/rust-hir-type-check-stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,7 @@ class TypeCheckStmt : public TypeCheckBase
{
auto unified_ty = specified_ty->unify (init_expr_ty);
if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_fatal_error (stmt.get_locus (),
"failure in setting up let stmt type");
return;
}
return;

context->insert_type (stmt.get_mappings (), unified_ty);
}
Expand Down

0 comments on commit 498758a

Please sign in to comment.