public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Get rid of get_locus_slow
@ 2021-08-26  0:09 Mark Wielaard
  2021-08-26  2:31 ` The Other
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Wielaard @ 2021-08-26  0:09 UTC (permalink / raw)
  To: gcc-rust; +Cc: Mark Wielaard

In various places there was the following hack:

  /* HACK: slow way of getting location from base expression through
     virtual methods. */
  virtual Location get_locus_slow () const { return Location (); }

The problem with get_locus_slow () is that if a subclass didn't
override it then there was no real location. get_locus_slow was
missing for Module, ExternCrate, UseDeclaration, Function, TypeAlias,
StructStruct, TupleStruct, Enum, Union, ConstantItem, StaticItem,
Trait, ImplBlock, ExternBlock, EmptyStmt, ExprStmtWithoutBlock and
ExprStmtWithBlock. All do have a get_locus () function.

Simply replace the get_locus_slow virtual method with a real virtual
Location get_locus () const = 0 method so we know if something
really doesn't have a location. This was only the case for
MacroRulesDefinition.
---

https://code.wildebeest.org/git/user/mjw/gccrs/commit/?h=no-get-locus-slow

 gcc/rust/ast/rust-ast.h                       |  27 +-
 gcc/rust/ast/rust-expr.h                      |  39 +--
 gcc/rust/ast/rust-item.h                      |  10 -
 gcc/rust/ast/rust-macro.h                     |   3 +-
 gcc/rust/ast/rust-path.h                      |   4 -
 gcc/rust/ast/rust-pattern.h                   |  10 -
 gcc/rust/ast/rust-stmt.h                      |   6 -
 gcc/rust/ast/rust-type.h                      |  15 -
 gcc/rust/backend/rust-compile-expr.h          |   4 +-
 gcc/rust/backend/rust-compile.cc              |   4 +-
 gcc/rust/expand/rust-macro-expand.cc          | 299 +++++++++---------
 gcc/rust/hir/rust-ast-lower-expr.h            |   5 +-
 gcc/rust/hir/rust-ast-lower-item.h            |   2 +-
 .../hir/rust-ast-lower-struct-field-expr.h    |   3 +-
 gcc/rust/hir/rust-ast-lower-type.h            |   8 +-
 gcc/rust/hir/rust-ast-lower.cc                |   4 +-
 gcc/rust/hir/tree/rust-hir-expr.h             |  31 +-
 gcc/rust/hir/tree/rust-hir-item.h             |   2 -
 gcc/rust/hir/tree/rust-hir-path.h             |   2 -
 gcc/rust/hir/tree/rust-hir-stmt.h             |   2 -
 gcc/rust/hir/tree/rust-hir-type.h             |   2 -
 gcc/rust/hir/tree/rust-hir.h                  |  17 +-
 gcc/rust/lint/rust-lint-marklive.cc           |   4 +-
 gcc/rust/parse/rust-parse-impl.h              |  88 +++---
 gcc/rust/resolve/rust-ast-resolve-item.h      |  12 +-
 gcc/rust/resolve/rust-ast-resolve-type.h      |   8 +-
 gcc/rust/resolve/rust-ast-verify-assignee.h   |   2 +-
 gcc/rust/typecheck/rust-hir-const-fold.h      |   4 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.h |  19 +-
 gcc/rust/typecheck/rust-hir-type-check-type.h |   2 +-
 gcc/rust/typecheck/rust-hir-type-check.cc     |  11 +-
 gcc/rust/typecheck/rust-tyty.cc               |  14 +-
 gcc/rust/util/rust-hir-map.cc                 |   4 +-
 33 files changed, 256 insertions(+), 411 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index e376488de8c..2b34b201970 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -816,9 +816,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
@@ -885,9 +883,7 @@ public:
 
   virtual ~Expr () {}
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   // HACK: strictly not needed, but faster than full downcast clone
   virtual bool is_expr_without_block () const = 0;
@@ -967,7 +963,6 @@ public:
   std::string as_string () const override { return ident; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   Identifier get_ident () const { return ident; }
 
@@ -1026,9 +1021,7 @@ public:
   virtual void mark_for_strip () {}
   virtual bool is_marked_for_strip () const { return false; }
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   virtual NodeId get_node_id () const { return node_id; }
 
@@ -1071,7 +1064,7 @@ public:
   virtual void mark_for_strip () {}
   virtual bool is_marked_for_strip () const { return false; }
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () const { return node_id; }
 
@@ -1128,7 +1121,7 @@ public:
 
   NodeId get_node_id () const { return node_id; }
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
 protected:
   // Clone function implementation as pure virtual method
@@ -1187,8 +1180,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   std::string get_lifetime_name () const { return lifetime_name; }
 
 protected:
@@ -1217,7 +1208,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () { return node_id; }
 
@@ -1272,8 +1263,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -1342,7 +1331,7 @@ public:
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 };
 
 // Abstract base class for items used in a trait impl
@@ -1519,8 +1508,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override { return get_locus (); }
-
 protected:
   MacroInvocationSemi *clone_macro_invocation_semi_impl () const
   {
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 4bb35570676..644b3cc60db 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -66,7 +66,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   Literal get_literal () const { return literal; }
 
@@ -244,7 +243,6 @@ protected:
 
 public:
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   // Invalid if expr is null, so base stripping on that.
   void mark_for_strip () override { main_or_left_expr = nullptr; }
@@ -896,7 +894,6 @@ public:
   GroupedExpr &operator= (GroupedExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1140,7 +1137,6 @@ public:
   ArrayExpr &operator= (ArrayExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1224,7 +1220,6 @@ public:
   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1338,7 +1333,6 @@ public:
    * comma, i.e. (0,) rather than (0) */
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1423,7 +1417,6 @@ public:
   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1513,7 +1506,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1600,7 +1592,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () const { return node_id; }
 
@@ -1629,7 +1621,6 @@ public:
   std::string as_string () const override { return field_name; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1704,7 +1695,6 @@ public:
   std::string get_field_name () const { return field_name; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1735,7 +1725,6 @@ public:
   TupleIndex get_index () const { return index; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1914,7 +1903,6 @@ public:
   StructExprTuple &operator= (StructExprTuple &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1951,7 +1939,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2022,7 +2009,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
 protected:
   // Clone function implementation as pure virtual method
@@ -2045,7 +2032,6 @@ public:
   std::string as_string () const override { return field_name; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2114,7 +2100,6 @@ public:
   void accept_vis (ASTVisitor &vis) override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2145,7 +2130,6 @@ public:
   void accept_vis (ASTVisitor &vis) override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2200,7 +2184,6 @@ public:
   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2264,7 +2247,6 @@ public:
   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2303,7 +2285,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2382,7 +2363,6 @@ public:
   bool has_params () const { return !params.empty (); }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2492,7 +2472,6 @@ public:
   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2595,7 +2574,6 @@ public:
   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2734,7 +2712,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   // TODO: this mutable getter seems really dodgy. Think up better way.
   const std::vector<ClosureParam> &get_params () const { return params; }
@@ -2899,7 +2876,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3076,7 +3052,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3166,7 +3141,6 @@ public:
   BreakExpr &operator= (BreakExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3211,7 +3185,6 @@ protected:
 
 public:
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   // should never be called - error if called
   void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
@@ -3658,7 +3631,6 @@ public:
   ReturnExpr &operator= (ReturnExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3741,7 +3713,6 @@ public:
   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3863,7 +3834,6 @@ public:
   LoopLabel &get_loop_label () { return loop_label; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   // Invalid if loop block is null, so base stripping on that.
   void mark_for_strip () override { loop_block = nullptr; }
@@ -4188,7 +4158,6 @@ public:
    * better approach? or does it not parse correctly and have downsides? */
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -4431,7 +4400,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5050,7 +5018,6 @@ public:
   MatchExpr &operator= (MatchExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5137,7 +5104,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5219,7 +5185,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index b996e173d6c..ba1df80b2ca 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -132,8 +132,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   void accept_vis (ASTVisitor &vis) override;
 
   // TODO: is this better? Or is a "vis_block" better?
@@ -891,8 +889,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override { return get_locus (); }
-
 protected:
   /* Use covariance to implement clone function as returning this object
    * rather than base */
@@ -1538,8 +1534,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override { return get_locus (); }
-
   void accept_vis (ASTVisitor &vis) override;
 
   // Invalid if block is null, so base stripping on that.
@@ -1762,8 +1756,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const final { return get_locus (); };
-
   // Invalid if name is empty, so base stripping on that.
   void mark_for_strip () override { struct_name = ""; }
   bool is_marked_for_strip () const override { return struct_name.empty (); }
@@ -2594,8 +2586,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override { return get_locus (); }
-
   void accept_vis (ASTVisitor &vis) override;
 
   // Invalid if type or expression are null, so base stripping on that.
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 51220e47003..620451b768f 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -345,6 +345,8 @@ public:
   std::vector<MacroRule> &get_macro_rules () { return rules; }
   const std::vector<MacroRule> &get_macro_rules () const { return rules; }
 
+  Location get_locus () const { return locus; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -374,7 +376,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 74ea79528af..be4b127c396 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -358,7 +358,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -741,7 +740,6 @@ public:
   TraitBound *to_trait_bound (bool in_parens) const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -886,7 +884,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1024,7 +1021,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 };
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 049aaf00448..46f2b1551d2 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -52,7 +52,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -135,7 +134,6 @@ public:
   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -171,7 +169,6 @@ public:
   WildcardPattern (Location locus) : locus (locus) {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -348,7 +345,6 @@ public:
   RangePattern &operator= (RangePattern &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -413,7 +409,6 @@ public:
   ReferencePattern &operator= (ReferencePattern &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -806,7 +801,6 @@ public:
   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
 
   Location get_locus () const { return path.get_locus (); }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1028,7 +1022,6 @@ public:
   TupleStructPattern &operator= (TupleStructPattern &&other) = default;
 
   Location get_locus () const { return path.get_locus (); }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1281,7 +1274,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1337,7 +1329,6 @@ public:
   GroupedPattern &operator= (GroupedPattern &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1395,7 +1386,6 @@ public:
   SlicePattern &operator= (SlicePattern &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 61854a07cef..43162964a61 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -38,8 +38,6 @@ public:
 
   EmptyStmt (Location locus) : locus (locus) {}
 
-  Location get_locus_slow () const final override { return get_locus (); }
-
   Location get_locus () const { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
@@ -137,8 +135,6 @@ public:
   LetStmt (LetStmt &&other) = default;
   LetStmt &operator= (LetStmt &&other) = default;
 
-  Location get_locus_slow () const final override { return get_locus (); }
-
   Location get_locus () const { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
@@ -188,8 +184,6 @@ class ExprStmt : public Stmt
   Location locus;
 
 public:
-  Location get_locus_slow () const final override { return get_locus (); }
-
   Location get_locus () const { return locus; }
 
 protected:
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index b658a532b98..c87ed9bc038 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -70,8 +70,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   void accept_vis (ASTVisitor &vis) override;
 
   // TODO: this mutable getter seems kinda dodgy
@@ -145,7 +143,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -215,7 +212,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -284,7 +280,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -318,7 +313,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -364,7 +358,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -420,7 +413,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -461,7 +453,6 @@ public:
   std::string as_string () const override { return "! (never type)"; }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 };
@@ -514,7 +505,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -582,7 +572,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -644,7 +633,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -705,7 +693,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -746,7 +733,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 };
@@ -924,7 +910,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 80cdc5eaeb4..ac33ccd247d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -611,7 +611,7 @@ public:
     if (!ctx->get_tyctx ()->lookup_type (
 	  expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
       {
-	rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		       "unresolved type for receiver");
 	return;
       }
@@ -772,7 +772,7 @@ public:
 
 	Bvariable *loop_result_holder = ctx->peek_loop_context ();
 	Bexpression *result_reference = ctx->get_backend ()->var_expression (
-	  loop_result_holder, expr.get_expr ()->get_locus_slow ());
+	  loop_result_holder, expr.get_expr ()->get_locus ());
 
 	Bstatement *assignment = ctx->get_backend ()->assignment_statement (
 	  fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index baaccf06c10..0a65b155e1d 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -352,7 +352,7 @@ CompileBlock::visit (HIR::BlockExpr &expr)
 	    {
 	      Bexpression *result_reference
 		= ctx->get_backend ()->var_expression (
-		  result, expr.get_final_expr ()->get_locus_slow ());
+		  result, expr.get_final_expr ()->get_locus ());
 
 	      Bstatement *assignment
 		= ctx->get_backend ()->assignment_statement (fnctx.fndecl,
@@ -490,7 +490,7 @@ HIRCompileBase::compile_function_body (
 
 	      auto ret = ctx->get_backend ()->return_statement (
 		fndecl, retstmts,
-		function_body->get_final_expr ()->get_locus_slow ());
+		function_body->get_final_expr ()->get_locus ());
 	      ctx->add_statement (ret);
 	    }
 	  else
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4998dc8441f..407992d828f 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -49,7 +49,7 @@ public:
 	auto &type = field.get_field_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// if nothing else happens, increment
@@ -75,7 +75,7 @@ public:
 	auto &type = field.get_field_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// if nothing else happens, increment
@@ -101,13 +101,13 @@ public:
 	auto &pattern = param.get_pattern ();
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment
@@ -124,7 +124,7 @@ public:
       {
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -134,7 +134,7 @@ public:
 	auto &type = binding.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -144,8 +144,7 @@ public:
     auto &type = path_type.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     if (path_type.has_as_clause ())
       {
@@ -174,7 +173,7 @@ public:
 	auto &pattern = param.get_pattern ();
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 
 	if (param.has_type_given ())
@@ -182,7 +181,7 @@ public:
 	    auto &type = param.get_type ();
 	    type->accept_vis (*this);
 	    if (type->is_marked_for_strip ())
-	      rust_error_at (type->get_locus_slow (),
+	      rust_error_at (type->get_locus (),
 			     "cannot strip type in this position");
 	  }
 
@@ -198,7 +197,7 @@ public:
 	auto &type = self_param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
     /* TODO: maybe check for invariants being violated - e.g. both type and
@@ -227,7 +226,7 @@ public:
 	auto &return_type = decl.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -255,7 +254,7 @@ public:
 	auto &return_type = decl.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -363,7 +362,7 @@ public:
       {
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -372,7 +371,7 @@ public:
 	auto &return_type = type_path_function.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -447,7 +446,7 @@ public:
     auto &borrowed_expr = expr.get_borrowed_expr ();
     borrowed_expr->accept_vis (*this);
     if (borrowed_expr->is_marked_for_strip ())
-      rust_error_at (borrowed_expr->get_locus_slow (),
+      rust_error_at (borrowed_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -467,7 +466,7 @@ public:
     auto &dereferenced_expr = expr.get_dereferenced_expr ();
     dereferenced_expr->accept_vis (*this);
     if (dereferenced_expr->is_marked_for_strip ())
-      rust_error_at (dereferenced_expr->get_locus_slow (),
+      rust_error_at (dereferenced_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -487,7 +486,7 @@ public:
     auto &propagating_expr = expr.get_propagating_expr ();
     propagating_expr->accept_vis (*this);
     if (propagating_expr->is_marked_for_strip ())
-      rust_error_at (propagating_expr->get_locus_slow (),
+      rust_error_at (propagating_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -507,7 +506,7 @@ public:
     auto &negated_expr = expr.get_negated_expr ();
     negated_expr->accept_vis (*this);
     if (negated_expr->is_marked_for_strip ())
-      rust_error_at (negated_expr->get_locus_slow (),
+      rust_error_at (negated_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -525,12 +524,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -548,12 +547,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -571,12 +570,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -592,7 +591,7 @@ public:
 
     // ensure that they are not marked for strip
     if (casted_expr->is_marked_for_strip ())
-      rust_error_at (casted_expr->get_locus_slow (),
+      rust_error_at (casted_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed before cast exprs");
 
@@ -600,8 +599,7 @@ public:
     auto &type = expr.get_type_to_cast_to ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::AssignmentExpr &expr) override
   {
@@ -617,12 +615,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -640,12 +638,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -674,7 +672,7 @@ public:
     auto &inner_expr = expr.get_expr_in_parens ();
     inner_expr->accept_vis (*this);
     if (inner_expr->is_marked_for_strip ())
-      rust_error_at (inner_expr->get_locus_slow (),
+      rust_error_at (inner_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -695,14 +693,14 @@ public:
     auto &copied_expr = elems.get_elem_to_copy ();
     copied_expr->accept_vis (*this);
     if (copied_expr->is_marked_for_strip ())
-      rust_error_at (copied_expr->get_locus_slow (),
+      rust_error_at (copied_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
     auto &copy_count = elems.get_num_copies ();
     copy_count->accept_vis (*this);
     if (copy_count->is_marked_for_strip ())
-      rust_error_at (copy_count->get_locus_slow (),
+      rust_error_at (copy_count->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -748,14 +746,14 @@ public:
     auto &array_expr = expr.get_array_expr ();
     array_expr->accept_vis (*this);
     if (array_expr->is_marked_for_strip ())
-      rust_error_at (array_expr->get_locus_slow (),
+      rust_error_at (array_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
     auto &index_expr = expr.get_index_expr ();
     index_expr->accept_vis (*this);
     if (index_expr->is_marked_for_strip ())
-      rust_error_at (index_expr->get_locus_slow (),
+      rust_error_at (index_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -801,7 +799,7 @@ public:
     auto &tuple_expr = expr.get_tuple_expr ();
     tuple_expr->accept_vis (*this);
     if (tuple_expr->is_marked_for_strip ())
-      rust_error_at (tuple_expr->get_locus_slow (),
+      rust_error_at (tuple_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -842,7 +840,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -853,7 +851,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -900,7 +898,7 @@ public:
 	auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
 	base_struct_expr->accept_vis (*this);
 	if (base_struct_expr->is_marked_for_strip ())
-	  rust_error_at (base_struct_expr->get_locus_slow (),
+	  rust_error_at (base_struct_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -937,7 +935,7 @@ public:
     auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
     base_struct_expr->accept_vis (*this);
     if (base_struct_expr->is_marked_for_strip ())
-      rust_error_at (base_struct_expr->get_locus_slow (),
+      rust_error_at (base_struct_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -999,7 +997,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1010,7 +1008,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1093,7 +1091,7 @@ public:
     auto &function = expr.get_function_expr ();
     function->accept_vis (*this);
     if (function->is_marked_for_strip ())
-      rust_error_at (function->get_locus_slow (),
+      rust_error_at (function->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1117,7 +1115,7 @@ public:
     auto &receiver = expr.get_receiver_expr ();
     receiver->accept_vis (*this);
     if (receiver->is_marked_for_strip ())
-      rust_error_at (receiver->get_locus_slow (),
+      rust_error_at (receiver->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1145,7 +1143,7 @@ public:
     auto &receiver = expr.get_receiver_expr ();
     receiver->accept_vis (*this);
     if (receiver->is_marked_for_strip ())
-      rust_error_at (receiver->get_locus_slow (),
+      rust_error_at (receiver->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1167,7 +1165,7 @@ public:
     auto &definition_expr = expr.get_definition_expr ();
     definition_expr->accept_vis (*this);
     if (definition_expr->is_marked_for_strip ())
-      rust_error_at (definition_expr->get_locus_slow (),
+      rust_error_at (definition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1222,14 +1220,13 @@ public:
     auto &type = expr.get_return_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     // can't strip expression itself, but can strip sub-expressions
     auto &definition_block = expr.get_definition_block ();
     definition_block->accept_vis (*this);
     if (definition_block->is_marked_for_strip ())
-      rust_error_at (definition_block->get_locus_slow (),
+      rust_error_at (definition_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1263,7 +1260,7 @@ public:
 	break_expr->accept_vis (*this);
 
 	if (break_expr->is_marked_for_strip ())
-	  rust_error_at (break_expr->get_locus_slow (),
+	  rust_error_at (break_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -1282,12 +1279,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_from_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_from_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before range exprs");
     if (expr.get_to_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_to_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1303,7 +1300,7 @@ public:
     from_expr->accept_vis (*this);
 
     if (from_expr->is_marked_for_strip ())
-      rust_error_at (from_expr->get_locus_slow (),
+      rust_error_at (from_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed before range exprs");
   }
@@ -1319,7 +1316,7 @@ public:
     to_expr->accept_vis (*this);
 
     if (to_expr->is_marked_for_strip ())
-      rust_error_at (to_expr->get_locus_slow (),
+      rust_error_at (to_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1341,12 +1338,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_from_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_from_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before range exprs");
     if (expr.get_to_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_to_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1362,7 +1359,7 @@ public:
     to_expr->accept_vis (*this);
 
     if (to_expr->is_marked_for_strip ())
-      rust_error_at (to_expr->get_locus_slow (),
+      rust_error_at (to_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1386,7 +1383,7 @@ public:
 	returned_expr->accept_vis (*this);
 
 	if (returned_expr->is_marked_for_strip ())
-	  rust_error_at (returned_expr->get_locus_slow (),
+	  rust_error_at (returned_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -1410,7 +1407,7 @@ public:
     auto &block_expr = expr.get_block_expr ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1428,7 +1425,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1446,7 +1443,7 @@ public:
     auto &predicate_expr = expr.get_predicate_expr ();
     predicate_expr->accept_vis (*this);
     if (predicate_expr->is_marked_for_strip ())
-      rust_error_at (predicate_expr->get_locus_slow (),
+      rust_error_at (predicate_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1454,7 +1451,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1472,7 +1469,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1480,7 +1477,7 @@ public:
     auto &scrutinee_expr = expr.get_scrutinee_expr ();
     scrutinee_expr->accept_vis (*this);
     if (scrutinee_expr->is_marked_for_strip ())
-      rust_error_at (scrutinee_expr->get_locus_slow (),
+      rust_error_at (scrutinee_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1488,7 +1485,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1506,14 +1503,14 @@ public:
     auto &pattern = expr.get_pattern ();
     pattern->accept_vis (*this);
     if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus_slow (),
+      rust_error_at (pattern->get_locus (),
 		     "cannot strip pattern in this position");
 
     // can't strip scrutinee expr itself, but can strip sub-expressions
     auto &iterator_expr = expr.get_iterator_expr ();
     iterator_expr->accept_vis (*this);
     if (iterator_expr->is_marked_for_strip ())
-      rust_error_at (iterator_expr->get_locus_slow (),
+      rust_error_at (iterator_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1521,7 +1518,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1542,7 +1539,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1550,7 +1547,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1568,7 +1565,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1576,7 +1573,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1584,7 +1581,7 @@ public:
     auto &else_block = expr.get_else_block ();
     else_block->accept_vis (*this);
     if (else_block->is_marked_for_strip ())
-      rust_error_at (else_block->get_locus_slow (),
+      rust_error_at (else_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1602,7 +1599,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1610,7 +1607,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1618,7 +1615,7 @@ public:
     auto &conseq_if_expr = expr.get_conseq_if_expr ();
     conseq_if_expr->accept_vis (*this);
     if (conseq_if_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_expr->get_locus_slow (),
+      rust_error_at (conseq_if_expr->get_locus (),
 		     "cannot strip consequent if expression in this "
 		     "position - outer attributes not allowed");
   }
@@ -1636,7 +1633,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1644,7 +1641,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1652,7 +1649,7 @@ public:
     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
     conseq_if_let_expr->accept_vis (*this);
     if (conseq_if_let_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_let_expr->get_locus_slow (),
+      rust_error_at (conseq_if_let_expr->get_locus (),
 		     "cannot strip consequent if let expression in this "
 		     "position - outer attributes not "
 		     "allowed");
@@ -1671,7 +1668,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1679,7 +1676,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1687,7 +1684,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1705,7 +1702,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1713,7 +1710,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1721,7 +1718,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1729,7 +1726,7 @@ public:
     auto &else_block = expr.get_else_block ();
     else_block->accept_vis (*this);
     if (else_block->is_marked_for_strip ())
-      rust_error_at (else_block->get_locus_slow (),
+      rust_error_at (else_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1747,7 +1744,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1755,7 +1752,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1763,7 +1760,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1771,7 +1768,7 @@ public:
     auto &conseq_if_expr = expr.get_conseq_if_expr ();
     conseq_if_expr->accept_vis (*this);
     if (conseq_if_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_expr->get_locus_slow (),
+      rust_error_at (conseq_if_expr->get_locus (),
 		     "cannot strip consequent if expression in this "
 		     "position - outer attributes not allowed");
   }
@@ -1789,7 +1786,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1797,7 +1794,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1805,7 +1802,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1813,7 +1810,7 @@ public:
     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
     conseq_if_let_expr->accept_vis (*this);
     if (conseq_if_let_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_let_expr->get_locus_slow (),
+      rust_error_at (conseq_if_let_expr->get_locus (),
 		     "cannot strip consequent if let expression in this "
 		     "position - outer attributes not "
 		     "allowed");
@@ -1840,7 +1837,7 @@ public:
     auto &scrutinee_expr = expr.get_scrutinee_expr ();
     scrutinee_expr->accept_vis (*this);
     if (scrutinee_expr->is_marked_for_strip ())
-      rust_error_at (scrutinee_expr->get_locus_slow (),
+      rust_error_at (scrutinee_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1864,7 +1861,7 @@ public:
 	  {
 	    pattern->accept_vis (*this);
 	    if (pattern->is_marked_for_strip ())
-	      rust_error_at (pattern->get_locus_slow (),
+	      rust_error_at (pattern->get_locus (),
 			     "cannot strip pattern in this position");
 	  }
 
@@ -1877,7 +1874,7 @@ public:
 	    auto &guard_expr = match_arm.get_guard_expr ();
 	    guard_expr->accept_vis (*this);
 	    if (guard_expr->is_marked_for_strip ())
-	      rust_error_at (guard_expr->get_locus_slow (),
+	      rust_error_at (guard_expr->get_locus (),
 			     "cannot strip expression in this position - outer "
 			     "attributes not allowed");
 	  }
@@ -1886,7 +1883,7 @@ public:
 	auto &case_expr = match_case.get_expr ();
 	case_expr->accept_vis (*this);
 	if (case_expr->is_marked_for_strip ())
-	  rust_error_at (case_expr->get_locus_slow (),
+	  rust_error_at (case_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
 
@@ -1909,7 +1906,7 @@ public:
     auto &awaited_expr = expr.get_awaited_expr ();
     awaited_expr->accept_vis (*this);
     if (awaited_expr->is_marked_for_strip ())
-      rust_error_at (awaited_expr->get_locus_slow (),
+      rust_error_at (awaited_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1927,7 +1924,7 @@ public:
     auto &block_expr = expr.get_block_expr ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1948,7 +1945,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -1963,8 +1960,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     // don't strip directly, only components of bounds
     for (auto &bound : item.get_type_param_bounds ())
@@ -1998,7 +1994,7 @@ public:
 	auto &return_type = method.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2011,7 +2007,7 @@ public:
     auto &block_expr = method.get_definition ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2099,7 +2095,7 @@ public:
 	auto &return_type = function.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2112,7 +2108,7 @@ public:
     auto &block_expr = function.get_definition ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2136,8 +2132,7 @@ public:
     auto &type = type_alias.get_type_aliased ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::StructStruct &struct_item) override
   {
@@ -2235,7 +2230,7 @@ public:
     auto &expr = item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2295,8 +2290,7 @@ public:
     auto &type = const_item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2304,7 +2298,7 @@ public:
     auto &expr = const_item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2322,8 +2316,7 @@ public:
     auto &type = static_item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2331,7 +2324,7 @@ public:
     auto &expr = static_item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2355,7 +2348,7 @@ public:
 	auto &block = item.get_definition ();
 	block->accept_vis (*this);
 	if (block->is_marked_for_strip ())
-	  rust_error_at (block->get_locus_slow (),
+	  rust_error_at (block->get_locus (),
 			 "cannot strip block expression in this "
 			 "position - outer attributes not allowed");
       }
@@ -2380,7 +2373,7 @@ public:
 	auto &block = item.get_definition ();
 	block->accept_vis (*this);
 	if (block->is_marked_for_strip ())
-	  rust_error_at (block->get_locus_slow (),
+	  rust_error_at (block->get_locus (),
 			 "cannot strip block expression in this "
 			 "position - outer attributes not allowed");
       }
@@ -2399,8 +2392,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2410,7 +2402,7 @@ public:
 	auto &expr = item.get_expr ();
 	expr->accept_vis (*this);
 	if (expr->is_marked_for_strip ())
-	  rust_error_at (expr->get_locus_slow (),
+	  rust_error_at (expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -2492,8 +2484,7 @@ public:
     auto &type = impl.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     if (impl.has_where_clause ())
       expand_where_clause (impl.get_where_clause ());
@@ -2526,8 +2517,7 @@ public:
     auto &type = impl.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     auto &trait_path = impl.get_trait_path ();
     visit (trait_path);
@@ -2554,8 +2544,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::ExternalFunctionItem &item) override
   {
@@ -2589,7 +2578,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment if nothing else happens
@@ -2607,7 +2596,7 @@ public:
 	auto &return_type = item.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2686,7 +2675,7 @@ public:
     auto &sub_pattern = pattern.get_pattern_to_bind ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::WildcardPattern &) override
@@ -2724,7 +2713,7 @@ public:
     auto &sub_pattern = pattern.get_referenced_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldTuplePat &field) override
@@ -2741,7 +2730,7 @@ public:
     auto &sub_pattern = field.get_index_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldIdentPat &field) override
@@ -2758,7 +2747,7 @@ public:
     auto &sub_pattern = field.get_ident_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldIdent &field) override
@@ -2805,7 +2794,7 @@ public:
 	pattern->accept_vis (*this);
 
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2818,7 +2807,7 @@ public:
 	lower_pattern->accept_vis (*this);
 
 	if (lower_pattern->is_marked_for_strip ())
-	  rust_error_at (lower_pattern->get_locus_slow (),
+	  rust_error_at (lower_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2827,7 +2816,7 @@ public:
 	upper_pattern->accept_vis (*this);
 
 	if (upper_pattern->is_marked_for_strip ())
-	  rust_error_at (upper_pattern->get_locus_slow (),
+	  rust_error_at (upper_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2851,7 +2840,7 @@ public:
 	pattern->accept_vis (*this);
 
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2864,7 +2853,7 @@ public:
 	lower_pattern->accept_vis (*this);
 
 	if (lower_pattern->is_marked_for_strip ())
-	  rust_error_at (lower_pattern->get_locus_slow (),
+	  rust_error_at (lower_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2873,7 +2862,7 @@ public:
 	upper_pattern->accept_vis (*this);
 
 	if (upper_pattern->is_marked_for_strip ())
-	  rust_error_at (upper_pattern->get_locus_slow (),
+	  rust_error_at (upper_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2891,7 +2880,7 @@ public:
     pattern_in_parens->accept_vis (*this);
 
     if (pattern_in_parens->is_marked_for_strip ())
-      rust_error_at (pattern_in_parens->get_locus_slow (),
+      rust_error_at (pattern_in_parens->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::SlicePattern &pattern) override
@@ -2902,7 +2891,7 @@ public:
 	item->accept_vis (*this);
 
 	if (item->is_marked_for_strip ())
-	  rust_error_at (item->get_locus_slow (),
+	  rust_error_at (item->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2926,7 +2915,7 @@ public:
     auto &pattern = stmt.get_pattern ();
     pattern->accept_vis (*this);
     if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus_slow (),
+      rust_error_at (pattern->get_locus (),
 		     "cannot strip pattern in this position");
 
     // similar for type
@@ -2935,7 +2924,7 @@ public:
 	auto &type = stmt.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2947,7 +2936,7 @@ public:
 	auto &init_expr = stmt.get_init_expr ();
 	init_expr->accept_vis (*this);
 	if (init_expr->is_marked_for_strip ())
-	  rust_error_at (init_expr->get_locus_slow (),
+	  rust_error_at (init_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -3016,7 +3005,7 @@ public:
     auto &inner_type = type.get_type_in_parens ();
     inner_type->accept_vis (*this);
     if (inner_type->is_marked_for_strip ())
-      rust_error_at (inner_type->get_locus_slow (),
+      rust_error_at (inner_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ImplTraitTypeOneBound &type) override
@@ -3037,7 +3026,7 @@ public:
       {
 	elem_type->accept_vis (*this);
 	if (elem_type->is_marked_for_strip ())
-	  rust_error_at (elem_type->get_locus_slow (),
+	  rust_error_at (elem_type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -3051,7 +3040,7 @@ public:
     auto &pointed_type = type.get_type_pointed_to ();
     pointed_type->accept_vis (*this);
     if (pointed_type->is_marked_for_strip ())
-      rust_error_at (pointed_type->get_locus_slow (),
+      rust_error_at (pointed_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ReferenceType &type) override
@@ -3060,7 +3049,7 @@ public:
     auto &referenced_type = type.get_type_referenced ();
     referenced_type->accept_vis (*this);
     if (referenced_type->is_marked_for_strip ())
-      rust_error_at (referenced_type->get_locus_slow (),
+      rust_error_at (referenced_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ArrayType &type) override
@@ -3069,14 +3058,14 @@ public:
     auto &base_type = type.get_elem_type ();
     base_type->accept_vis (*this);
     if (base_type->is_marked_for_strip ())
-      rust_error_at (base_type->get_locus_slow (),
+      rust_error_at (base_type->get_locus (),
 		     "cannot strip type in this position");
 
     // same for expression
     auto &size_expr = type.get_size_expr ();
     size_expr->accept_vis (*this);
     if (size_expr->is_marked_for_strip ())
-      rust_error_at (size_expr->get_locus_slow (),
+      rust_error_at (size_expr->get_locus (),
 		     "cannot strip expression in this position");
   }
   void visit (AST::SliceType &type) override
@@ -3085,7 +3074,7 @@ public:
     auto &elem_type = type.get_elem_type ();
     elem_type->accept_vis (*this);
     if (elem_type->is_marked_for_strip ())
-      rust_error_at (elem_type->get_locus_slow (),
+      rust_error_at (elem_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::InferredType &) override
@@ -3113,7 +3102,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment if nothing else happens
@@ -3128,7 +3117,7 @@ public:
 	auto &return_type = type.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 3415567c86b..ff4c181d0e2 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -81,7 +81,7 @@ public:
     expr->accept_vis (resolver);
     if (resolver.translated == nullptr)
       {
-	rust_fatal_error (expr->get_locus_slow (), "Failed to lower expr: [%s]",
+	rust_fatal_error (expr->get_locus (), "Failed to lower expr: [%s]",
 			  expr->as_string ().c_str ());
 	return nullptr;
       }
@@ -91,8 +91,7 @@ public:
       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      expr->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), expr->get_locus ());
 
     if (terminated != nullptr)
       *terminated = resolver.terminated;
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index c7f874d1dc9..7efcffaf05b 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -47,7 +47,7 @@ public:
     // this is useful for debugging
     // if (resolver.translated == nullptr)
     //   {
-    //     rust_fatal_error (item->get_locus_slow (), "failed to lower: %s",
+    //     rust_fatal_error (item->get_locus (), "failed to lower: %s",
     //     		  item->as_string ().c_str ());
     //     return nullptr;
     //   }
diff --git a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
index 3b313a78476..e6322dbb514 100644
--- a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
@@ -41,8 +41,7 @@ public:
       compiler.translated->get_mappings ().get_hirid (), compiler.translated);
     compiler.mappings->insert_location (
       compiler.translated->get_mappings ().get_crate_num (),
-      compiler.translated->get_mappings ().get_hirid (),
-      field->get_locus_slow ());
+      compiler.translated->get_mappings ().get_hirid (), field->get_locus ());
 
     return compiler.translated;
   }
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 9b5ec0a4df7..c16025d137b 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -106,8 +106,7 @@ public:
     rust_assert (resolver.translated != nullptr);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      type->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), type->get_locus ());
 
     return resolver.translated;
   }
@@ -282,8 +281,7 @@ public:
     rust_assert (resolver.translated != nullptr);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      param->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), param->get_locus ());
     resolver.mappings->insert_hir_generic_param (
       resolver.translated->get_mappings ().get_crate_num (),
       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
@@ -356,7 +354,7 @@ public:
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
       resolver.translated->get_mappings ().get_hirid (),
-      resolver.translated->get_locus_slow ());
+      resolver.translated->get_locus ());
 
     return resolver.translated;
   }
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index e693799d4b5..d5138fd64ac 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -66,7 +66,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
   bool block_did_terminate = false;
   expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool {
     if (block_did_terminate)
-      rust_warning_at (s->get_locus_slow (), 0, "unreachable statement");
+      rust_warning_at (s->get_locus (), 0, "unreachable statement");
 
     bool terminated = false;
     auto translated_stmt = ASTLoweringStmt::translate (s, &terminated);
@@ -78,7 +78,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
   if (expr.has_tail_expr () && block_did_terminate)
     {
       // warning unreachable tail expressions
-      rust_warning_at (expr.get_tail_expr ()->get_locus_slow (), 0,
+      rust_warning_at (expr.get_tail_expr ()->get_locus (), 0,
 		       "unreachable expression");
     }
 
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 8d815c5adc6..233e015110c 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -91,7 +91,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -164,7 +163,6 @@ protected:
 
 public:
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
 };
@@ -711,7 +709,6 @@ public:
   GroupedExpr &operator= (GroupedExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -916,7 +913,6 @@ public:
   ArrayExpr &operator= (ArrayExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -982,7 +978,6 @@ public:
   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1061,7 +1056,6 @@ public:
    * comma, i.e. (0,) rather than (0) */
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1145,7 +1139,6 @@ public:
   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1212,7 +1205,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1641,7 +1633,6 @@ public:
   StructExprTuple &operator= (StructExprTuple &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1677,7 +1668,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1895,7 +1885,6 @@ public:
   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1965,7 +1954,6 @@ public:
   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2006,7 +1994,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2083,7 +2070,6 @@ public:
   bool has_params () const { return !params.empty (); }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2173,7 +2159,6 @@ public:
   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2258,7 +2243,6 @@ public:
   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2362,7 +2346,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 };
 
 // Represents a non-type-specified closure expression HIR node
@@ -2498,7 +2481,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2518,7 +2500,7 @@ public:
     if (statements.size () == 0)
       return get_locus ();
 
-    return statements[statements.size () - 1]->get_locus_slow ();
+    return statements[statements.size () - 1]->get_locus ();
   }
 
   std::unique_ptr<Expr> &get_final_expr () { return expr; }
@@ -2633,7 +2615,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2713,7 +2694,6 @@ public:
   BreakExpr &operator= (BreakExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2747,7 +2727,6 @@ protected:
 
 public:
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 };
 
 // Range from (inclusive) and to (exclusive) expression HIR node object
@@ -3090,7 +3069,6 @@ public:
   ReturnExpr &operator= (ReturnExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3152,7 +3130,6 @@ public:
   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3251,7 +3228,6 @@ public:
   bool has_loop_label () const { return !loop_label.is_error (); }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
 
@@ -3541,7 +3517,6 @@ public:
    * better approach? or does it not parse correctly and have downsides? */
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3766,7 +3741,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4342,7 +4316,6 @@ public:
   MatchExpr &operator= (MatchExpr &&other) = default;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4397,7 +4370,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4451,7 +4423,6 @@ public:
   std::string as_string () const override;
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 7a05f02067b..90b6820e64d 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -106,8 +106,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   void accept_vis (HIRVisitor &vis) override;
 
   Identifier get_type_representation () const { return type_representation; }
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index a8bbbb62ef6..9f60b8fb7df 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -316,7 +316,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -792,7 +791,6 @@ public:
   {}
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index 584b0e358cd..eef6834f99a 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -109,8 +109,6 @@ public:
   LetStmt (LetStmt &&other) = default;
   LetStmt &operator= (LetStmt &&other) = default;
 
-  Location get_locus_slow () const override { return get_locus (); }
-
   Location get_locus () const { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index 8d75d0285d3..5b578d915a2 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -63,8 +63,6 @@ public:
     return mappings;
   }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   BoundType get_bound_type () const final override { return TRAITBOUND; }
 
   TypePath &get_path () { return type_path; }
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index b8acf1a6e40..b285d352b59 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -100,9 +100,7 @@ public:
 
   virtual void accept_vis (HIRVisitor &vis) = 0;
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   virtual bool is_unit_check_needed () const { return false; }
 
@@ -194,9 +192,7 @@ public:
 
   virtual ~Expr () {}
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   // HACK: strictly not needed, but faster than full downcast clone
   virtual bool is_expr_without_block () const = 0;
@@ -285,7 +281,6 @@ public:
   }
 
   Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -426,7 +421,7 @@ public:
 
   virtual Analysis::NodeMapping get_mappings () const = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   virtual BoundType get_bound_type () const = 0;
 
@@ -483,8 +478,6 @@ public:
     return mappings;
   }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   BoundType get_bound_type () const final override { return LIFETIME; }
 
 protected:
@@ -522,7 +515,7 @@ public:
 
   virtual void accept_vis (HIRVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
@@ -611,8 +604,6 @@ public:
 
   Location get_locus () const { return locus; }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
index 87fa3ef2f3e..f383d48377e 100644
--- a/gcc/rust/lint/rust-lint-marklive.cc
+++ b/gcc/rust/lint/rust-lint-marklive.cc
@@ -211,7 +211,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
   if (!tyctx->lookup_type (
 	expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		     "unresolved type for receiver");
     }
   bool ok = receiver->get_kind () == TyTy::TypeKind::ADT;
@@ -223,7 +223,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
   adt->get_field (expr.get_field_name (), &index);
   if (index >= adt->num_fields ())
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		     "cannot access struct %s by index: %ld",
 		     adt->get_name ().c_str (), index);
       return;
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index fa6d409c6dc..8ee9e42f944 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -11431,7 +11431,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_with_block (
     return ExprOrStmt (std::move (expr));
 
   // internal block expr must either have semicolons followed, or evaluate to ()
-  auto locus = expr->get_locus_slow ();
+  auto locus = expr->get_locus ();
   std::unique_ptr<AST::ExprStmtWithBlock> stmt (
     new AST::ExprStmtWithBlock (std::move (expr), locus,
 				tok->get_id () == SEMICOLON));
@@ -12823,7 +12823,7 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
     {
       // FIXME: allow for outer attributes to be applied
       case QUESTION_MARK: {
-	Location left_locus = left->get_locus_slow ();
+	Location left_locus = left->get_locus ();
 	// error propagation expression - unary postfix
 	return std::unique_ptr<AST::ErrorPropagationExpr> (
 	  new AST::ErrorPropagationExpr (std::move (left),
@@ -13185,7 +13185,7 @@ Parser<ManagedTokenSource>::parse_arithmetic_or_logical_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13206,7 +13206,7 @@ Parser<ManagedTokenSource>::parse_binary_plus_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13227,7 +13227,7 @@ Parser<ManagedTokenSource>::parse_binary_minus_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13249,7 +13249,7 @@ Parser<ManagedTokenSource>::parse_binary_mult_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13271,7 +13271,7 @@ Parser<ManagedTokenSource>::parse_binary_div_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13293,7 +13293,7 @@ Parser<ManagedTokenSource>::parse_binary_mod_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13316,7 +13316,7 @@ Parser<ManagedTokenSource>::parse_bitwise_and_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13339,7 +13339,7 @@ Parser<ManagedTokenSource>::parse_bitwise_or_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13362,7 +13362,7 @@ Parser<ManagedTokenSource>::parse_bitwise_xor_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13384,7 +13384,7 @@ Parser<ManagedTokenSource>::parse_left_shift_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13406,7 +13406,7 @@ Parser<ManagedTokenSource>::parse_right_shift_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13458,7 +13458,7 @@ Parser<ManagedTokenSource>::parse_comparison_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right), expr_type,
@@ -13479,7 +13479,7 @@ Parser<ManagedTokenSource>::parse_binary_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13500,7 +13500,7 @@ Parser<ManagedTokenSource>::parse_binary_not_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13521,7 +13521,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_than_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13542,7 +13542,7 @@ Parser<ManagedTokenSource>::parse_binary_less_than_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13563,7 +13563,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13584,7 +13584,7 @@ Parser<ManagedTokenSource>::parse_binary_less_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13605,7 +13605,7 @@ Parser<ManagedTokenSource>::parse_lazy_or_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::LazyBooleanExpr> (
     new AST::LazyBooleanExpr (std::move (left), std::move (right),
@@ -13626,7 +13626,7 @@ Parser<ManagedTokenSource>::parse_lazy_and_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::LazyBooleanExpr> (
     new AST::LazyBooleanExpr (std::move (left), std::move (right),
@@ -13648,7 +13648,7 @@ Parser<ManagedTokenSource>::parse_type_cast_expr (
   // FIXME: how do I get precedence put in here?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = expr_to_cast->get_locus_slow ();
+  Location locus = expr_to_cast->get_locus ();
 
   return std::unique_ptr<AST::TypeCastExpr> (
     new AST::TypeCastExpr (std::move (expr_to_cast), std::move (type), locus));
@@ -13669,7 +13669,7 @@ Parser<ManagedTokenSource>::parse_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::AssignmentExpr> (
     new AST::AssignmentExpr (std::move (left), std::move (right), locus));
@@ -13728,7 +13728,7 @@ Parser<ManagedTokenSource>::parse_compound_assignment_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13750,7 +13750,7 @@ Parser<ManagedTokenSource>::parse_plus_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13772,7 +13772,7 @@ Parser<ManagedTokenSource>::parse_minus_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13795,7 +13795,7 @@ Parser<ManagedTokenSource>::parse_mult_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13818,7 +13818,7 @@ Parser<ManagedTokenSource>::parse_div_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13841,7 +13841,7 @@ Parser<ManagedTokenSource>::parse_mod_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13864,7 +13864,7 @@ Parser<ManagedTokenSource>::parse_and_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13887,7 +13887,7 @@ Parser<ManagedTokenSource>::parse_or_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13910,7 +13910,7 @@ Parser<ManagedTokenSource>::parse_xor_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13933,7 +13933,7 @@ Parser<ManagedTokenSource>::parse_left_shift_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13956,7 +13956,7 @@ Parser<ManagedTokenSource>::parse_right_shift_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13985,7 +13985,7 @@ Parser<ManagedTokenSource>::parse_await_expr (
     }
 
   // TODO: check inside async block in semantic analysis
-  Location locus = expr_to_await->get_locus_slow ();
+  Location locus = expr_to_await->get_locus ();
 
   return std::unique_ptr<AST::AwaitExpr> (
     new AST::AwaitExpr (std::move (expr_to_await), std::move (outer_attrs),
@@ -14008,7 +14008,7 @@ Parser<ManagedTokenSource>::parse_led_range_exclusive_expr (
   std::unique_ptr<AST::Expr> right
     = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
 
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   if (right == nullptr)
     {
@@ -14066,7 +14066,7 @@ Parser<ManagedTokenSource>::parse_range_inclusive_expr (
   // FIXME: make non-associative
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::RangeFromToInclExpr> (
     new AST::RangeFromToInclExpr (std::move (left), std::move (right), locus));
@@ -14114,7 +14114,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr (
     }
   int index_int = atoi (index.c_str ());
 
-  Location locus = tuple_expr->get_locus_slow ();
+  Location locus = tuple_expr->get_locus ();
 
   return std::unique_ptr<AST::TupleIndexExpr> (
     new AST::TupleIndexExpr (std::move (tuple_expr), index_int,
@@ -14145,7 +14145,7 @@ Parser<ManagedTokenSource>::parse_index_expr (
     }
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = array_expr->get_locus_slow ();
+  Location locus = array_expr->get_locus ();
 
   return std::unique_ptr<AST::ArrayIndexExpr> (
     new AST::ArrayIndexExpr (std::move (array_expr), std::move (index_expr),
@@ -14167,7 +14167,7 @@ Parser<ManagedTokenSource>::parse_field_access_expr (
 
   Identifier ident = ident_tok->get_str ();
 
-  Location locus = struct_expr->get_locus_slow ();
+  Location locus = struct_expr->get_locus ();
 
   // TODO: check types. actually, do so during semantic analysis
   return std::unique_ptr<AST::FieldAccessExpr> (
@@ -14230,7 +14230,7 @@ Parser<ManagedTokenSource>::parse_method_call_expr (
     }
 
   // TODO: check types. actually do so in semantic analysis pass.
-  Location locus = receiver_expr->get_locus_slow ();
+  Location locus = receiver_expr->get_locus ();
 
   return std::unique_ptr<AST::MethodCallExpr> (
     new AST::MethodCallExpr (std::move (receiver_expr), std::move (segment),
@@ -14277,7 +14277,7 @@ Parser<ManagedTokenSource>::parse_function_call_expr (
     }
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = function_expr->get_locus_slow ();
+  Location locus = function_expr->get_locus ();
 
   return std::unique_ptr<AST::CallExpr> (
     new AST::CallExpr (std::move (function_expr), std::move (params),
@@ -14772,7 +14772,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr_float (
   // get int from string
   int index = atoi (index_str.c_str ());
 
-  Location locus = tuple_expr->get_locus_slow ();
+  Location locus = tuple_expr->get_locus ();
 
   return std::unique_ptr<AST::TupleIndexExpr> (
     new AST::TupleIndexExpr (std::move (tuple_expr), index,
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index bc05e93069c..d3c053b609f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -400,9 +400,9 @@ public:
     auto Self
       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
 
-    resolver->get_type_scope ().insert (
-      Self, impl_block.get_type ()->get_node_id (),
-      impl_block.get_type ()->get_locus_slow ());
+    resolver->get_type_scope ().insert (Self,
+					impl_block.get_type ()->get_node_id (),
+					impl_block.get_type ()->get_locus ());
 
     for (auto &impl_item : impl_block.get_impl_items ())
       {
@@ -519,9 +519,9 @@ public:
     auto Self
       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
 
-    resolver->get_type_scope ().insert (
-      Self, impl_block.get_type ()->get_node_id (),
-      impl_block.get_type ()->get_locus_slow ());
+    resolver->get_type_scope ().insert (Self,
+					impl_block.get_type ()->get_node_id (),
+					impl_block.get_type ()->get_locus ());
 
     for (auto &impl_item : impl_block.get_impl_items ())
       {
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index b8affe68c41..97c031199b3 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -211,7 +211,7 @@ public:
     // https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_resolve/src/lib.rs#L1722
     if (!resolver->get_type_scope ().lookup (canonical_path, &resolved_node))
       {
-	rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s",
+	rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
 		       canonical_path.get ().c_str ());
 	return UNKNOWN_NODEID;
       }
@@ -231,7 +231,7 @@ public:
     ResolveType resolver (parent, canonicalize_type_with_generics);
     type->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (type->get_locus_slow (), "unresolved type");
+      rust_error_at (type->get_locus (), "unresolved type");
 
     return resolver.resolved_node;
   };
@@ -311,7 +311,7 @@ public:
     ResolveTypeBound resolver (parent, canonicalize_type_with_generics);
     type->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (type->get_locus_slow (), "unresolved type bound");
+      rust_error_at (type->get_locus (), "unresolved type bound");
 
     return resolver.resolved_node;
   };
@@ -346,7 +346,7 @@ public:
     ResolveGenericParam resolver (parent);
     param->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (param->get_locus_slow (), "unresolved generic parameter");
+      rust_error_at (param->get_locus (), "unresolved generic parameter");
 
     return resolver.resolved_node;
   };
diff --git a/gcc/rust/resolve/rust-ast-verify-assignee.h b/gcc/rust/resolve/rust-ast-verify-assignee.h
index aed01196f81..9da3883220d 100644
--- a/gcc/rust/resolve/rust-ast-verify-assignee.h
+++ b/gcc/rust/resolve/rust-ast-verify-assignee.h
@@ -35,7 +35,7 @@ public:
     VerifyAsignee checker (parent);
     assignee->accept_vis (checker);
     if (!checker.ok)
-      rust_error_at (assignee->get_locus_slow (),
+      rust_error_at (assignee->get_locus (),
 		     "invalid left-hand side of assignment");
     return checker.ok;
   }
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
index 9e0450e8882..1bff7ef13b7 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold.h
@@ -211,7 +211,7 @@ public:
     item.accept_vis (folder);
     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
       {
-	rust_error_at (item.get_locus_slow (), "non const value");
+	rust_error_at (item.get_locus (), "non const value");
 	return nullptr;
       }
 
@@ -240,7 +240,7 @@ public:
     expr->accept_vis (folder);
     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
       {
-	rust_error_at (expr->get_locus_slow (), "non const value");
+	rust_error_at (expr->get_locus (), "non const value");
 	return nullptr;
       }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index a95a4e91c78..274451606cb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -49,8 +49,7 @@ public:
 
     if (resolver.infered == nullptr)
       {
-	rust_error_at (expr->get_locus_slow (),
-		       "failed to type resolve expression");
+	rust_error_at (expr->get_locus (), "failed to type resolve expression");
 	return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
       }
 
@@ -67,7 +66,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get (), inside_loop);
     if (resolved == nullptr)
       {
-	rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_tuple_expr ()->get_locus (),
 		       "failed to resolve TupleIndexExpr receiver");
 	return;
       }
@@ -76,7 +75,7 @@ public:
 			 || resolved->get_kind () == TyTy::TypeKind::TUPLE;
     if (!is_valid_type)
       {
-	rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_tuple_expr ()->get_locus (),
 		       "Expected Tuple or ADT got: %s",
 		       resolved->as_string ().c_str ());
 	return;
@@ -203,7 +202,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_receiver ().get (), false);
     if (receiver_tyty == nullptr)
       {
-	rust_error_at (expr.get_receiver ()->get_locus_slow (),
+	rust_error_at (expr.get_receiver ()->get_locus (),
 		       "failed to resolve receiver in MethodCallExpr");
 	return;
       }
@@ -771,7 +770,7 @@ public:
       = size_ty->unify (TypeCheckExpr::Resolve (expr.get_index_expr (), false));
     if (resolved_index_expr == nullptr)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "Type Resolver failure in Index for ArrayIndexExpr");
 	return;
       }
@@ -782,13 +781,13 @@ public:
     expr.get_array_expr ()->accept_vis (*this);
     if (infered == nullptr)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "failed to resolve array reference expression");
 	return;
       }
     else if (infered->get_kind () != TyTy::TypeKind::ARRAY)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "expected an ArrayType got [%s]",
 		       infered->as_string ().c_str ());
 	infered = nullptr;
@@ -936,7 +935,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_loop_block ().get (), true);
     if (!block_expr->is_unit ())
       {
-	rust_error_at (expr.get_loop_block ()->get_locus_slow (),
+	rust_error_at (expr.get_loop_block ()->get_locus (),
 		       "expected %<()%> got %s",
 		       block_expr->as_string ().c_str ());
 	return;
@@ -965,7 +964,7 @@ public:
 
     if (!block_expr->is_unit ())
       {
-	rust_error_at (expr.get_loop_block ()->get_locus_slow (),
+	rust_error_at (expr.get_loop_block ()->get_locus (),
 		       "expected %<()%> got %s",
 		       block_expr->as_string ().c_str ());
 	return;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index fff86beaa27..0cc1cfb3d40 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -257,7 +257,7 @@ public:
 
     if (resolver.resolved == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to setup generic parameter");
 	return nullptr;
       }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 4b66fdbd6e6..7f0e0ffdb30 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -97,7 +97,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
     auto resolved = TypeCheckStmt::Resolve (s, inside_loop);
     if (resolved == nullptr)
       {
-	rust_error_at (s->get_locus_slow (), "failure to resolve type");
+	rust_error_at (s->get_locus (), "failure to resolve type");
 	return false;
       }
 
@@ -145,9 +145,8 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
 	= (TyTy::ADTType *) struct_path_resolved->unify (base_resolved);
       if (struct_def == nullptr)
 	{
-	  rust_fatal_error (
-	    struct_expr.struct_base->base_struct->get_locus_slow (),
-	    "incompatible types for base struct reference");
+	  rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
+			    "incompatible types for base struct reference");
 	  return;
 	}
     }
@@ -229,11 +228,11 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
 	      HIR::Expr *field_value = new HIR::FieldAccessExpr (
 		mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
 		std::move (outer_attribs),
-		struct_expr.struct_base->base_struct->get_locus_slow ());
+		struct_expr.struct_base->base_struct->get_locus ());
 
 	      implicit_field = new HIR::StructExprFieldIdentifierValue (
 		mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
-		struct_expr.struct_base->base_struct->get_locus_slow ());
+		struct_expr.struct_base->base_struct->get_locus ());
 
 	      size_t field_index;
 	      bool ok = struct_path_resolved->get_field (missing, &field_index);
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 56fdafd7919..e449b55f41e 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2207,7 +2207,7 @@ TypeCheckCallExpr::visit (ADTType &type)
     BaseType *arg = Resolver::TypeCheckExpr::Resolve (p, false);
     if (arg == nullptr)
       {
-	rust_error_at (p->get_locus_slow (), "failed to resolve argument type");
+	rust_error_at (p->get_locus (), "failed to resolve argument type");
 	return false;
       }
 
@@ -2262,7 +2262,7 @@ TypeCheckCallExpr::visit (FnType &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2276,7 +2276,7 @@ TypeCheckCallExpr::visit (FnType &type)
 	resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
 	if (resolved_argument_type == nullptr)
 	  {
-	    rust_error_at (param->get_locus_slow (),
+	    rust_error_at (param->get_locus (),
 			   "Type Resolution failure on parameter");
 	    return false;
 	  }
@@ -2327,7 +2327,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2335,7 +2335,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
     auto resolved_argument_type = fnparam->unify (argument_expr_tyty);
     if (resolved_argument_type == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "Type Resolution failure on parameter");
 	return false;
       }
@@ -2378,7 +2378,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2386,7 +2386,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
     auto resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
     if (resolved_argument_type == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "Type Resolution failure on parameter");
 	return false;
       }
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index d544042b344..deade08db37 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -380,7 +380,7 @@ Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
 {
   hirExprMappings[crateNum][id] = expr;
   nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
-  insert_location (crateNum, id, expr->get_locus_slow ());
+  insert_location (crateNum, id, expr->get_locus ());
 }
 
 HIR::Expr *
@@ -430,7 +430,7 @@ Mappings::insert_hir_generic_param (CrateNum crateNum, HirId id,
 
   hirGenericParamMappings[crateNum][id] = param;
   nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
-  insert_location (crateNum, id, param->get_locus_slow ());
+  insert_location (crateNum, id, param->get_locus ());
 }
 
 HIR::GenericParam *
-- 
2.32.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Get rid of get_locus_slow
  2021-08-26  0:09 [PATCH] Get rid of get_locus_slow Mark Wielaard
@ 2021-08-26  2:31 ` The Other
  2021-08-26 19:19   ` Mark Wielaard
  0 siblings, 1 reply; 4+ messages in thread
From: The Other @ 2021-08-26  2:31 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: gcc-rust

The original point of the distinction between get_locus_slow() and get_locus() was to avoid the overhead of virtual function calls whenever possible, but still have a way to access locations from abstract base classes like Expr. 

As such, I’d at least make the overridden calls ‘final override’ in the hope that the compiler can optimise out the virtual call. 

> On 26 Aug 2021, at 8:10 am, Mark Wielaard <mark@klomp.org> wrote:
> In various places there was the following hack:
> 
>  /* HACK: slow way of getting location from base expression through
>     virtual methods. */
>  virtual Location get_locus_slow () const { return Location (); }
> 
> The problem with get_locus_slow () is that if a subclass didn't
> override it then there was no real location. get_locus_slow was
> missing for Module, ExternCrate, UseDeclaration, Function, TypeAlias,
> StructStruct, TupleStruct, Enum, Union, ConstantItem, StaticItem,
> Trait, ImplBlock, ExternBlock, EmptyStmt, ExprStmtWithoutBlock and
> ExprStmtWithBlock. All do have a get_locus () function.
> 
> Simply replace the get_locus_slow virtual method with a real virtual
> Location get_locus () const = 0 method so we know if something
> really doesn't have a location. This was only the case for
> MacroRulesDefinition.
> ---
> 
> https://code.wildebeest.org/git/user/mjw/gccrs/commit/?h=no-get-locus-slow
> 
> gcc/rust/ast/rust-ast.h                       |  27 +-
> gcc/rust/ast/rust-expr.h                      |  39 +--
> gcc/rust/ast/rust-item.h                      |  10 -
> gcc/rust/ast/rust-macro.h                     |   3 +-
> gcc/rust/ast/rust-path.h                      |   4 -
> gcc/rust/ast/rust-pattern.h                   |  10 -
> gcc/rust/ast/rust-stmt.h                      |   6 -
> gcc/rust/ast/rust-type.h                      |  15 -
> gcc/rust/backend/rust-compile-expr.h          |   4 +-
> gcc/rust/backend/rust-compile.cc              |   4 +-
> gcc/rust/expand/rust-macro-expand.cc          | 299 +++++++++---------
> gcc/rust/hir/rust-ast-lower-expr.h            |   5 +-
> gcc/rust/hir/rust-ast-lower-item.h            |   2 +-
> .../hir/rust-ast-lower-struct-field-expr.h    |   3 +-
> gcc/rust/hir/rust-ast-lower-type.h            |   8 +-
> gcc/rust/hir/rust-ast-lower.cc                |   4 +-
> gcc/rust/hir/tree/rust-hir-expr.h             |  31 +-
> gcc/rust/hir/tree/rust-hir-item.h             |   2 -
> gcc/rust/hir/tree/rust-hir-path.h             |   2 -
> gcc/rust/hir/tree/rust-hir-stmt.h             |   2 -
> gcc/rust/hir/tree/rust-hir-type.h             |   2 -
> gcc/rust/hir/tree/rust-hir.h                  |  17 +-
> gcc/rust/lint/rust-lint-marklive.cc           |   4 +-
> gcc/rust/parse/rust-parse-impl.h              |  88 +++---
> gcc/rust/resolve/rust-ast-resolve-item.h      |  12 +-
> gcc/rust/resolve/rust-ast-resolve-type.h      |   8 +-
> gcc/rust/resolve/rust-ast-verify-assignee.h   |   2 +-
> gcc/rust/typecheck/rust-hir-const-fold.h      |   4 +-
> gcc/rust/typecheck/rust-hir-type-check-expr.h |  19 +-
> gcc/rust/typecheck/rust-hir-type-check-type.h |   2 +-
> gcc/rust/typecheck/rust-hir-type-check.cc     |  11 +-
> gcc/rust/typecheck/rust-tyty.cc               |  14 +-
> gcc/rust/util/rust-hir-map.cc                 |   4 +-
> 33 files changed, 256 insertions(+), 411 deletions(-)
> 
> diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
> index e376488de8c..2b34b201970 100644
> --- a/gcc/rust/ast/rust-ast.h
> +++ b/gcc/rust/ast/rust-ast.h
> @@ -816,9 +816,7 @@ public:
> 
>   virtual void accept_vis (ASTVisitor &vis) = 0;
> 
> -  /* HACK: slow way of getting location from base expression through virtual
> -   * methods. */
> -  virtual Location get_locus_slow () const { return Location (); }
> +  virtual Location get_locus () const = 0;
> 
>   virtual void mark_for_strip () = 0;
>   virtual bool is_marked_for_strip () const = 0;
> @@ -885,9 +883,7 @@ public:
> 
>   virtual ~Expr () {}
> 
> -  /* HACK: slow way of getting location from base expression through virtual
> -   * methods. */
> -  virtual Location get_locus_slow () const { return Location (); }
> +  virtual Location get_locus () const = 0;
> 
>   // HACK: strictly not needed, but faster than full downcast clone
>   virtual bool is_expr_without_block () const = 0;
> @@ -967,7 +963,6 @@ public:
>   std::string as_string () const override { return ident; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   Identifier get_ident () const { return ident; }
> 
> @@ -1026,9 +1021,7 @@ public:
>   virtual void mark_for_strip () {}
>   virtual bool is_marked_for_strip () const { return false; }
> 
> -  /* HACK: slow way of getting location from base expression through virtual
> -   * methods. */
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   virtual NodeId get_node_id () const { return node_id; }
> 
> @@ -1071,7 +1064,7 @@ public:
>   virtual void mark_for_strip () {}
>   virtual bool is_marked_for_strip () const { return false; }
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   NodeId get_node_id () const { return node_id; }
> 
> @@ -1128,7 +1121,7 @@ public:
> 
>   NodeId get_node_id () const { return node_id; }
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
> protected:
>   // Clone function implementation as pure virtual method
> @@ -1187,8 +1180,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   std::string get_lifetime_name () const { return lifetime_name; }
> 
> protected:
> @@ -1217,7 +1208,7 @@ public:
> 
>   virtual void accept_vis (ASTVisitor &vis) = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   NodeId get_node_id () { return node_id; }
> 
> @@ -1272,8 +1263,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
> protected:
>   /* Use covariance to implement clone function as returning this object rather
>    * than base */
> @@ -1342,7 +1331,7 @@ public:
>   virtual void mark_for_strip () = 0;
>   virtual bool is_marked_for_strip () const = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> };
> 
> // Abstract base class for items used in a trait impl
> @@ -1519,8 +1508,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override { return get_locus (); }
> -
> protected:
>   MacroInvocationSemi *clone_macro_invocation_semi_impl () const
>   {
> diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
> index 4bb35570676..644b3cc60db 100644
> --- a/gcc/rust/ast/rust-expr.h
> +++ b/gcc/rust/ast/rust-expr.h
> @@ -66,7 +66,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   Literal get_literal () const { return literal; }
> 
> @@ -244,7 +243,6 @@ protected:
> 
> public:
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   // Invalid if expr is null, so base stripping on that.
>   void mark_for_strip () override { main_or_left_expr = nullptr; }
> @@ -896,7 +894,6 @@ public:
>   GroupedExpr &operator= (GroupedExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1140,7 +1137,6 @@ public:
>   ArrayExpr &operator= (ArrayExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1224,7 +1220,6 @@ public:
>   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1338,7 +1333,6 @@ public:
>    * comma, i.e. (0,) rather than (0) */
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1423,7 +1417,6 @@ public:
>   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1513,7 +1506,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1600,7 +1592,7 @@ public:
> 
>   virtual void accept_vis (ASTVisitor &vis) = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   NodeId get_node_id () const { return node_id; }
> 
> @@ -1629,7 +1621,6 @@ public:
>   std::string as_string () const override { return field_name; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1704,7 +1695,6 @@ public:
>   std::string get_field_name () const { return field_name; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
> protected:
>   /* Use covariance to implement clone function as returning this object rather
> @@ -1735,7 +1725,6 @@ public:
>   TupleIndex get_index () const { return index; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
> protected:
>   /* Use covariance to implement clone function as returning this object rather
> @@ -1914,7 +1903,6 @@ public:
>   StructExprTuple &operator= (StructExprTuple &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1951,7 +1939,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2022,7 +2009,7 @@ public:
> 
>   virtual void accept_vis (ASTVisitor &vis) = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
> protected:
>   // Clone function implementation as pure virtual method
> @@ -2045,7 +2032,6 @@ public:
>   std::string as_string () const override { return field_name; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
> protected:
>   /* Use covariance to implement clone function as returning this object rather
> @@ -2114,7 +2100,6 @@ public:
>   void accept_vis (ASTVisitor &vis) override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
> protected:
>   /* Use covariance to implement clone function as returning this object rather
> @@ -2145,7 +2130,6 @@ public:
>   void accept_vis (ASTVisitor &vis) override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
> protected:
>   /* Use covariance to implement clone function as returning this object rather
> @@ -2200,7 +2184,6 @@ public:
>   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2264,7 +2247,6 @@ public:
>   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2303,7 +2285,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2382,7 +2363,6 @@ public:
>   bool has_params () const { return !params.empty (); }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2492,7 +2472,6 @@ public:
>   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2595,7 +2574,6 @@ public:
>   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -2734,7 +2712,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   // TODO: this mutable getter seems really dodgy. Think up better way.
>   const std::vector<ClosureParam> &get_params () const { return params; }
> @@ -2899,7 +2876,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -3076,7 +3052,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -3166,7 +3141,6 @@ public:
>   BreakExpr &operator= (BreakExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -3211,7 +3185,6 @@ protected:
> 
> public:
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   // should never be called - error if called
>   void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
> @@ -3658,7 +3631,6 @@ public:
>   ReturnExpr &operator= (ReturnExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -3741,7 +3713,6 @@ public:
>   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -3863,7 +3834,6 @@ public:
>   LoopLabel &get_loop_label () { return loop_label; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   // Invalid if loop block is null, so base stripping on that.
>   void mark_for_strip () override { loop_block = nullptr; }
> @@ -4188,7 +4158,6 @@ public:
>    * better approach? or does it not parse correctly and have downsides? */
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -4431,7 +4400,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -5050,7 +5018,6 @@ public:
>   MatchExpr &operator= (MatchExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -5137,7 +5104,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -5219,7 +5185,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
> index b996e173d6c..ba1df80b2ca 100644
> --- a/gcc/rust/ast/rust-item.h
> +++ b/gcc/rust/ast/rust-item.h
> @@ -132,8 +132,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   void accept_vis (ASTVisitor &vis) override;
> 
>   // TODO: is this better? Or is a "vis_block" better?
> @@ -891,8 +889,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override { return get_locus (); }
> -
> protected:
>   /* Use covariance to implement clone function as returning this object
>    * rather than base */
> @@ -1538,8 +1534,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override { return get_locus (); }
> -
>   void accept_vis (ASTVisitor &vis) override;
> 
>   // Invalid if block is null, so base stripping on that.
> @@ -1762,8 +1756,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const final { return get_locus (); };
> -
>   // Invalid if name is empty, so base stripping on that.
>   void mark_for_strip () override { struct_name = ""; }
>   bool is_marked_for_strip () const override { return struct_name.empty (); }
> @@ -2594,8 +2586,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override { return get_locus (); }
> -
>   void accept_vis (ASTVisitor &vis) override;
> 
>   // Invalid if type or expression are null, so base stripping on that.
> diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
> index 51220e47003..620451b768f 100644
> --- a/gcc/rust/ast/rust-macro.h
> +++ b/gcc/rust/ast/rust-macro.h
> @@ -345,6 +345,8 @@ public:
>   std::vector<MacroRule> &get_macro_rules () { return rules; }
>   const std::vector<MacroRule> &get_macro_rules () const { return rules; }
> 
> +  Location get_locus () const { return locus; }
> +
> protected:
>   /* Use covariance to implement clone function as returning this object rather
>    * than base */
> @@ -374,7 +376,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
> index 74ea79528af..be4b127c396 100644
> --- a/gcc/rust/ast/rust-path.h
> +++ b/gcc/rust/ast/rust-path.h
> @@ -358,7 +358,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -741,7 +740,6 @@ public:
>   TraitBound *to_trait_bound (bool in_parens) const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -886,7 +884,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1024,7 +1021,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> };
> } // namespace AST
> } // namespace Rust
> diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
> index 049aaf00448..46f2b1551d2 100644
> --- a/gcc/rust/ast/rust-pattern.h
> +++ b/gcc/rust/ast/rust-pattern.h
> @@ -52,7 +52,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -135,7 +134,6 @@ public:
>   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -171,7 +169,6 @@ public:
>   WildcardPattern (Location locus) : locus (locus) {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -348,7 +345,6 @@ public:
>   RangePattern &operator= (RangePattern &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -413,7 +409,6 @@ public:
>   ReferencePattern &operator= (ReferencePattern &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -806,7 +801,6 @@ public:
>   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
> 
>   Location get_locus () const { return path.get_locus (); }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1028,7 +1022,6 @@ public:
>   TupleStructPattern &operator= (TupleStructPattern &&other) = default;
> 
>   Location get_locus () const { return path.get_locus (); }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1281,7 +1274,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1337,7 +1329,6 @@ public:
>   GroupedPattern &operator= (GroupedPattern &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -1395,7 +1386,6 @@ public:
>   SlicePattern &operator= (SlicePattern &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
> index 61854a07cef..43162964a61 100644
> --- a/gcc/rust/ast/rust-stmt.h
> +++ b/gcc/rust/ast/rust-stmt.h
> @@ -38,8 +38,6 @@ public:
> 
>   EmptyStmt (Location locus) : locus (locus) {}
> 
> -  Location get_locus_slow () const final override { return get_locus (); }
> -
>   Location get_locus () const { return locus; }
> 
>   void accept_vis (ASTVisitor &vis) override;
> @@ -137,8 +135,6 @@ public:
>   LetStmt (LetStmt &&other) = default;
>   LetStmt &operator= (LetStmt &&other) = default;
> 
> -  Location get_locus_slow () const final override { return get_locus (); }
> -
>   Location get_locus () const { return locus; }
> 
>   void accept_vis (ASTVisitor &vis) override;
> @@ -188,8 +184,6 @@ class ExprStmt : public Stmt
>   Location locus;
> 
> public:
> -  Location get_locus_slow () const final override { return get_locus (); }
> -
>   Location get_locus () const { return locus; }
> 
> protected:
> diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
> index b658a532b98..c87ed9bc038 100644
> --- a/gcc/rust/ast/rust-type.h
> +++ b/gcc/rust/ast/rust-type.h
> @@ -70,8 +70,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   void accept_vis (ASTVisitor &vis) override;
> 
>   // TODO: this mutable getter seems kinda dodgy
> @@ -145,7 +143,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -215,7 +212,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -284,7 +280,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -318,7 +313,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -364,7 +358,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -420,7 +413,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -461,7 +453,6 @@ public:
>   std::string as_string () const override { return "! (never type)"; }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> };
> @@ -514,7 +505,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -582,7 +572,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -644,7 +633,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -705,7 +693,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> @@ -746,7 +733,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> };
> @@ -924,7 +910,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const final override { return get_locus (); }
> 
>   void accept_vis (ASTVisitor &vis) override;
> 
> diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
> index 80cdc5eaeb4..ac33ccd247d 100644
> --- a/gcc/rust/backend/rust-compile-expr.h
> +++ b/gcc/rust/backend/rust-compile-expr.h
> @@ -611,7 +611,7 @@ public:
>     if (!ctx->get_tyctx ()->lookup_type (
>      expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
>       {
> -    rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_receiver_expr ()->get_locus (),
>               "unresolved type for receiver");
>    return;
>       }
> @@ -772,7 +772,7 @@ public:
> 
>    Bvariable *loop_result_holder = ctx->peek_loop_context ();
>    Bexpression *result_reference = ctx->get_backend ()->var_expression (
> -      loop_result_holder, expr.get_expr ()->get_locus_slow ());
> +      loop_result_holder, expr.get_expr ()->get_locus ());
> 
>    Bstatement *assignment = ctx->get_backend ()->assignment_statement (
>      fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
> diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
> index baaccf06c10..0a65b155e1d 100644
> --- a/gcc/rust/backend/rust-compile.cc
> +++ b/gcc/rust/backend/rust-compile.cc
> @@ -352,7 +352,7 @@ CompileBlock::visit (HIR::BlockExpr &expr)
>        {
>          Bexpression *result_reference
>        = ctx->get_backend ()->var_expression (
> -          result, expr.get_final_expr ()->get_locus_slow ());
> +          result, expr.get_final_expr ()->get_locus ());
> 
>          Bstatement *assignment
>        = ctx->get_backend ()->assignment_statement (fnctx.fndecl,
> @@ -490,7 +490,7 @@ HIRCompileBase::compile_function_body (
> 
>          auto ret = ctx->get_backend ()->return_statement (
>        fndecl, retstmts,
> -        function_body->get_final_expr ()->get_locus_slow ());
> +        function_body->get_final_expr ()->get_locus ());
>          ctx->add_statement (ret);
>        }
>      else
> diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
> index 4998dc8441f..407992d828f 100644
> --- a/gcc/rust/expand/rust-macro-expand.cc
> +++ b/gcc/rust/expand/rust-macro-expand.cc
> @@ -49,7 +49,7 @@ public:
>    auto &type = field.get_field_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
> 
>    // if nothing else happens, increment
> @@ -75,7 +75,7 @@ public:
>    auto &type = field.get_field_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
> 
>    // if nothing else happens, increment
> @@ -101,13 +101,13 @@ public:
>    auto &pattern = param.get_pattern ();
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
> 
>    auto &type = param.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
> 
>    // increment
> @@ -124,7 +124,7 @@ public:
>       {
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -134,7 +134,7 @@ public:
>    auto &type = binding.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
>   }
> @@ -144,8 +144,7 @@ public:
>     auto &type = path_type.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     if (path_type.has_as_clause ())
>       {
> @@ -174,7 +173,7 @@ public:
>    auto &pattern = param.get_pattern ();
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
> 
>    if (param.has_type_given ())
> @@ -182,7 +181,7 @@ public:
>        auto &type = param.get_type ();
>        type->accept_vis (*this);
>        if (type->is_marked_for_strip ())
> -          rust_error_at (type->get_locus_slow (),
> +          rust_error_at (type->get_locus (),
>                 "cannot strip type in this position");
>      }
> 
> @@ -198,7 +197,7 @@ public:
>    auto &type = self_param.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
>     /* TODO: maybe check for invariants being violated - e.g. both type and
> @@ -227,7 +226,7 @@ public:
>    auto &return_type = decl.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -255,7 +254,7 @@ public:
>    auto &return_type = decl.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -363,7 +362,7 @@ public:
>       {
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -372,7 +371,7 @@ public:
>    auto &return_type = type_path_function.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
>   }
> @@ -447,7 +446,7 @@ public:
>     auto &borrowed_expr = expr.get_borrowed_expr ();
>     borrowed_expr->accept_vis (*this);
>     if (borrowed_expr->is_marked_for_strip ())
> -      rust_error_at (borrowed_expr->get_locus_slow (),
> +      rust_error_at (borrowed_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -467,7 +466,7 @@ public:
>     auto &dereferenced_expr = expr.get_dereferenced_expr ();
>     dereferenced_expr->accept_vis (*this);
>     if (dereferenced_expr->is_marked_for_strip ())
> -      rust_error_at (dereferenced_expr->get_locus_slow (),
> +      rust_error_at (dereferenced_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -487,7 +486,7 @@ public:
>     auto &propagating_expr = expr.get_propagating_expr ();
>     propagating_expr->accept_vis (*this);
>     if (propagating_expr->is_marked_for_strip ())
> -      rust_error_at (propagating_expr->get_locus_slow (),
> +      rust_error_at (propagating_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -507,7 +506,7 @@ public:
>     auto &negated_expr = expr.get_negated_expr ();
>     negated_expr->accept_vis (*this);
>     if (negated_expr->is_marked_for_strip ())
> -      rust_error_at (negated_expr->get_locus_slow (),
> +      rust_error_at (negated_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -525,12 +524,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_left_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_left_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before binary op exprs");
>     if (expr.get_right_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_right_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -548,12 +547,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_left_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_left_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before binary op exprs");
>     if (expr.get_right_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_right_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -571,12 +570,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_left_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_left_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before binary op exprs");
>     if (expr.get_right_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_right_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -592,7 +591,7 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (casted_expr->is_marked_for_strip ())
> -      rust_error_at (casted_expr->get_locus_slow (),
> +      rust_error_at (casted_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed before cast exprs");
> 
> @@ -600,8 +599,7 @@ public:
>     auto &type = expr.get_type_to_cast_to ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
>   }
>   void visit (AST::AssignmentExpr &expr) override
>   {
> @@ -617,12 +615,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_left_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_left_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before binary op exprs");
>     if (expr.get_right_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_right_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -640,12 +638,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_left_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_left_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before binary op exprs");
>     if (expr.get_right_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_right_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -674,7 +672,7 @@ public:
>     auto &inner_expr = expr.get_expr_in_parens ();
>     inner_expr->accept_vis (*this);
>     if (inner_expr->is_marked_for_strip ())
> -      rust_error_at (inner_expr->get_locus_slow (),
> +      rust_error_at (inner_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -695,14 +693,14 @@ public:
>     auto &copied_expr = elems.get_elem_to_copy ();
>     copied_expr->accept_vis (*this);
>     if (copied_expr->is_marked_for_strip ())
> -      rust_error_at (copied_expr->get_locus_slow (),
> +      rust_error_at (copied_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
>     auto &copy_count = elems.get_num_copies ();
>     copy_count->accept_vis (*this);
>     if (copy_count->is_marked_for_strip ())
> -      rust_error_at (copy_count->get_locus_slow (),
> +      rust_error_at (copy_count->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -748,14 +746,14 @@ public:
>     auto &array_expr = expr.get_array_expr ();
>     array_expr->accept_vis (*this);
>     if (array_expr->is_marked_for_strip ())
> -      rust_error_at (array_expr->get_locus_slow (),
> +      rust_error_at (array_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
>     auto &index_expr = expr.get_index_expr ();
>     index_expr->accept_vis (*this);
>     if (index_expr->is_marked_for_strip ())
> -      rust_error_at (index_expr->get_locus_slow (),
> +      rust_error_at (index_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -801,7 +799,7 @@ public:
>     auto &tuple_expr = expr.get_tuple_expr ();
>     tuple_expr->accept_vis (*this);
>     if (tuple_expr->is_marked_for_strip ())
> -      rust_error_at (tuple_expr->get_locus_slow (),
> +      rust_error_at (tuple_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -842,7 +840,7 @@ public:
>     auto &value = field.get_value ();
>     value->accept_vis (*this);
>     if (value->is_marked_for_strip ())
> -      rust_error_at (value->get_locus_slow (),
> +      rust_error_at (value->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -853,7 +851,7 @@ public:
>     auto &value = field.get_value ();
>     value->accept_vis (*this);
>     if (value->is_marked_for_strip ())
> -      rust_error_at (value->get_locus_slow (),
> +      rust_error_at (value->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -900,7 +898,7 @@ public:
>    auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
>    base_struct_expr->accept_vis (*this);
>    if (base_struct_expr->is_marked_for_strip ())
> -      rust_error_at (base_struct_expr->get_locus_slow (),
> +      rust_error_at (base_struct_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>       }
> @@ -937,7 +935,7 @@ public:
>     auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
>     base_struct_expr->accept_vis (*this);
>     if (base_struct_expr->is_marked_for_strip ())
> -      rust_error_at (base_struct_expr->get_locus_slow (),
> +      rust_error_at (base_struct_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -999,7 +997,7 @@ public:
>     auto &value = field.get_value ();
>     value->accept_vis (*this);
>     if (value->is_marked_for_strip ())
> -      rust_error_at (value->get_locus_slow (),
> +      rust_error_at (value->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1010,7 +1008,7 @@ public:
>     auto &value = field.get_value ();
>     value->accept_vis (*this);
>     if (value->is_marked_for_strip ())
> -      rust_error_at (value->get_locus_slow (),
> +      rust_error_at (value->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1093,7 +1091,7 @@ public:
>     auto &function = expr.get_function_expr ();
>     function->accept_vis (*this);
>     if (function->is_marked_for_strip ())
> -      rust_error_at (function->get_locus_slow (),
> +      rust_error_at (function->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1117,7 +1115,7 @@ public:
>     auto &receiver = expr.get_receiver_expr ();
>     receiver->accept_vis (*this);
>     if (receiver->is_marked_for_strip ())
> -      rust_error_at (receiver->get_locus_slow (),
> +      rust_error_at (receiver->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1145,7 +1143,7 @@ public:
>     auto &receiver = expr.get_receiver_expr ();
>     receiver->accept_vis (*this);
>     if (receiver->is_marked_for_strip ())
> -      rust_error_at (receiver->get_locus_slow (),
> +      rust_error_at (receiver->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1167,7 +1165,7 @@ public:
>     auto &definition_expr = expr.get_definition_expr ();
>     definition_expr->accept_vis (*this);
>     if (definition_expr->is_marked_for_strip ())
> -      rust_error_at (definition_expr->get_locus_slow (),
> +      rust_error_at (definition_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1222,14 +1220,13 @@ public:
>     auto &type = expr.get_return_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     // can't strip expression itself, but can strip sub-expressions
>     auto &definition_block = expr.get_definition_block ();
>     definition_block->accept_vis (*this);
>     if (definition_block->is_marked_for_strip ())
> -      rust_error_at (definition_block->get_locus_slow (),
> +      rust_error_at (definition_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1263,7 +1260,7 @@ public:
>    break_expr->accept_vis (*this);
> 
>    if (break_expr->is_marked_for_strip ())
> -      rust_error_at (break_expr->get_locus_slow (),
> +      rust_error_at (break_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>       }
> @@ -1282,12 +1279,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_from_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_from_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before range exprs");
>     if (expr.get_to_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_to_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1303,7 +1300,7 @@ public:
>     from_expr->accept_vis (*this);
> 
>     if (from_expr->is_marked_for_strip ())
> -      rust_error_at (from_expr->get_locus_slow (),
> +      rust_error_at (from_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed before range exprs");
>   }
> @@ -1319,7 +1316,7 @@ public:
>     to_expr->accept_vis (*this);
> 
>     if (to_expr->is_marked_for_strip ())
> -      rust_error_at (to_expr->get_locus_slow (),
> +      rust_error_at (to_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1341,12 +1338,12 @@ public:
> 
>     // ensure that they are not marked for strip
>     if (expr.get_from_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_from_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes are never allowed "
>             "before range exprs");
>     if (expr.get_to_expr ()->is_marked_for_strip ())
> -      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_to_expr ()->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1362,7 +1359,7 @@ public:
>     to_expr->accept_vis (*this);
> 
>     if (to_expr->is_marked_for_strip ())
> -      rust_error_at (to_expr->get_locus_slow (),
> +      rust_error_at (to_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1386,7 +1383,7 @@ public:
>    returned_expr->accept_vis (*this);
> 
>    if (returned_expr->is_marked_for_strip ())
> -      rust_error_at (returned_expr->get_locus_slow (),
> +      rust_error_at (returned_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>       }
> @@ -1410,7 +1407,7 @@ public:
>     auto &block_expr = expr.get_block_expr ();
>     block_expr->accept_vis (*this);
>     if (block_expr->is_marked_for_strip ())
> -      rust_error_at (block_expr->get_locus_slow (),
> +      rust_error_at (block_expr->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1428,7 +1425,7 @@ public:
>     auto &loop_block = expr.get_loop_block ();
>     loop_block->accept_vis (*this);
>     if (loop_block->is_marked_for_strip ())
> -      rust_error_at (loop_block->get_locus_slow (),
> +      rust_error_at (loop_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1446,7 +1443,7 @@ public:
>     auto &predicate_expr = expr.get_predicate_expr ();
>     predicate_expr->accept_vis (*this);
>     if (predicate_expr->is_marked_for_strip ())
> -      rust_error_at (predicate_expr->get_locus_slow (),
> +      rust_error_at (predicate_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1454,7 +1451,7 @@ public:
>     auto &loop_block = expr.get_loop_block ();
>     loop_block->accept_vis (*this);
>     if (loop_block->is_marked_for_strip ())
> -      rust_error_at (loop_block->get_locus_slow (),
> +      rust_error_at (loop_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1472,7 +1469,7 @@ public:
>       {
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>       }
> 
> @@ -1480,7 +1477,7 @@ public:
>     auto &scrutinee_expr = expr.get_scrutinee_expr ();
>     scrutinee_expr->accept_vis (*this);
>     if (scrutinee_expr->is_marked_for_strip ())
> -      rust_error_at (scrutinee_expr->get_locus_slow (),
> +      rust_error_at (scrutinee_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1488,7 +1485,7 @@ public:
>     auto &loop_block = expr.get_loop_block ();
>     loop_block->accept_vis (*this);
>     if (loop_block->is_marked_for_strip ())
> -      rust_error_at (loop_block->get_locus_slow (),
> +      rust_error_at (loop_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1506,14 +1503,14 @@ public:
>     auto &pattern = expr.get_pattern ();
>     pattern->accept_vis (*this);
>     if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
> 
>     // can't strip scrutinee expr itself, but can strip sub-expressions
>     auto &iterator_expr = expr.get_iterator_expr ();
>     iterator_expr->accept_vis (*this);
>     if (iterator_expr->is_marked_for_strip ())
> -      rust_error_at (iterator_expr->get_locus_slow (),
> +      rust_error_at (iterator_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1521,7 +1518,7 @@ public:
>     auto &loop_block = expr.get_loop_block ();
>     loop_block->accept_vis (*this);
>     if (loop_block->is_marked_for_strip ())
> -      rust_error_at (loop_block->get_locus_slow (),
> +      rust_error_at (loop_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1542,7 +1539,7 @@ public:
>     auto &condition_expr = expr.get_condition_expr ();
>     condition_expr->accept_vis (*this);
>     if (condition_expr->is_marked_for_strip ())
> -      rust_error_at (condition_expr->get_locus_slow (),
> +      rust_error_at (condition_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1550,7 +1547,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1568,7 +1565,7 @@ public:
>     auto &condition_expr = expr.get_condition_expr ();
>     condition_expr->accept_vis (*this);
>     if (condition_expr->is_marked_for_strip ())
> -      rust_error_at (condition_expr->get_locus_slow (),
> +      rust_error_at (condition_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1576,7 +1573,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1584,7 +1581,7 @@ public:
>     auto &else_block = expr.get_else_block ();
>     else_block->accept_vis (*this);
>     if (else_block->is_marked_for_strip ())
> -      rust_error_at (else_block->get_locus_slow (),
> +      rust_error_at (else_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1602,7 +1599,7 @@ public:
>     auto &condition_expr = expr.get_condition_expr ();
>     condition_expr->accept_vis (*this);
>     if (condition_expr->is_marked_for_strip ())
> -      rust_error_at (condition_expr->get_locus_slow (),
> +      rust_error_at (condition_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1610,7 +1607,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1618,7 +1615,7 @@ public:
>     auto &conseq_if_expr = expr.get_conseq_if_expr ();
>     conseq_if_expr->accept_vis (*this);
>     if (conseq_if_expr->is_marked_for_strip ())
> -      rust_error_at (conseq_if_expr->get_locus_slow (),
> +      rust_error_at (conseq_if_expr->get_locus (),
>             "cannot strip consequent if expression in this "
>             "position - outer attributes not allowed");
>   }
> @@ -1636,7 +1633,7 @@ public:
>     auto &condition_expr = expr.get_condition_expr ();
>     condition_expr->accept_vis (*this);
>     if (condition_expr->is_marked_for_strip ())
> -      rust_error_at (condition_expr->get_locus_slow (),
> +      rust_error_at (condition_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1644,7 +1641,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1652,7 +1649,7 @@ public:
>     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
>     conseq_if_let_expr->accept_vis (*this);
>     if (conseq_if_let_expr->is_marked_for_strip ())
> -      rust_error_at (conseq_if_let_expr->get_locus_slow (),
> +      rust_error_at (conseq_if_let_expr->get_locus (),
>             "cannot strip consequent if let expression in this "
>             "position - outer attributes not "
>             "allowed");
> @@ -1671,7 +1668,7 @@ public:
>       {
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>       }
> 
> @@ -1679,7 +1676,7 @@ public:
>     auto &value_expr = expr.get_value_expr ();
>     value_expr->accept_vis (*this);
>     if (value_expr->is_marked_for_strip ())
> -      rust_error_at (value_expr->get_locus_slow (),
> +      rust_error_at (value_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1687,7 +1684,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1705,7 +1702,7 @@ public:
>       {
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>       }
> 
> @@ -1713,7 +1710,7 @@ public:
>     auto &value_expr = expr.get_value_expr ();
>     value_expr->accept_vis (*this);
>     if (value_expr->is_marked_for_strip ())
> -      rust_error_at (value_expr->get_locus_slow (),
> +      rust_error_at (value_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1721,7 +1718,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1729,7 +1726,7 @@ public:
>     auto &else_block = expr.get_else_block ();
>     else_block->accept_vis (*this);
>     if (else_block->is_marked_for_strip ())
> -      rust_error_at (else_block->get_locus_slow (),
> +      rust_error_at (else_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1747,7 +1744,7 @@ public:
>       {
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>       }
> 
> @@ -1755,7 +1752,7 @@ public:
>     auto &value_expr = expr.get_value_expr ();
>     value_expr->accept_vis (*this);
>     if (value_expr->is_marked_for_strip ())
> -      rust_error_at (value_expr->get_locus_slow (),
> +      rust_error_at (value_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1763,7 +1760,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1771,7 +1768,7 @@ public:
>     auto &conseq_if_expr = expr.get_conseq_if_expr ();
>     conseq_if_expr->accept_vis (*this);
>     if (conseq_if_expr->is_marked_for_strip ())
> -      rust_error_at (conseq_if_expr->get_locus_slow (),
> +      rust_error_at (conseq_if_expr->get_locus (),
>             "cannot strip consequent if expression in this "
>             "position - outer attributes not allowed");
>   }
> @@ -1789,7 +1786,7 @@ public:
>       {
>    pattern->accept_vis (*this);
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>       }
> 
> @@ -1797,7 +1794,7 @@ public:
>     auto &value_expr = expr.get_value_expr ();
>     value_expr->accept_vis (*this);
>     if (value_expr->is_marked_for_strip ())
> -      rust_error_at (value_expr->get_locus_slow (),
> +      rust_error_at (value_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1805,7 +1802,7 @@ public:
>     auto &if_block = expr.get_if_block ();
>     if_block->accept_vis (*this);
>     if (if_block->is_marked_for_strip ())
> -      rust_error_at (if_block->get_locus_slow (),
> +      rust_error_at (if_block->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1813,7 +1810,7 @@ public:
>     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
>     conseq_if_let_expr->accept_vis (*this);
>     if (conseq_if_let_expr->is_marked_for_strip ())
> -      rust_error_at (conseq_if_let_expr->get_locus_slow (),
> +      rust_error_at (conseq_if_let_expr->get_locus (),
>             "cannot strip consequent if let expression in this "
>             "position - outer attributes not "
>             "allowed");
> @@ -1840,7 +1837,7 @@ public:
>     auto &scrutinee_expr = expr.get_scrutinee_expr ();
>     scrutinee_expr->accept_vis (*this);
>     if (scrutinee_expr->is_marked_for_strip ())
> -      rust_error_at (scrutinee_expr->get_locus_slow (),
> +      rust_error_at (scrutinee_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1864,7 +1861,7 @@ public:
>      {
>        pattern->accept_vis (*this);
>        if (pattern->is_marked_for_strip ())
> -          rust_error_at (pattern->get_locus_slow (),
> +          rust_error_at (pattern->get_locus (),
>                 "cannot strip pattern in this position");
>      }
> 
> @@ -1877,7 +1874,7 @@ public:
>        auto &guard_expr = match_arm.get_guard_expr ();
>        guard_expr->accept_vis (*this);
>        if (guard_expr->is_marked_for_strip ())
> -          rust_error_at (guard_expr->get_locus_slow (),
> +          rust_error_at (guard_expr->get_locus (),
>                 "cannot strip expression in this position - outer "
>                 "attributes not allowed");
>      }
> @@ -1886,7 +1883,7 @@ public:
>    auto &case_expr = match_case.get_expr ();
>    case_expr->accept_vis (*this);
>    if (case_expr->is_marked_for_strip ())
> -      rust_error_at (case_expr->get_locus_slow (),
> +      rust_error_at (case_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
> 
> @@ -1909,7 +1906,7 @@ public:
>     auto &awaited_expr = expr.get_awaited_expr ();
>     awaited_expr->accept_vis (*this);
>     if (awaited_expr->is_marked_for_strip ())
> -      rust_error_at (awaited_expr->get_locus_slow (),
> +      rust_error_at (awaited_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1927,7 +1924,7 @@ public:
>     auto &block_expr = expr.get_block_expr ();
>     block_expr->accept_vis (*this);
>     if (block_expr->is_marked_for_strip ())
> -      rust_error_at (block_expr->get_locus_slow (),
> +      rust_error_at (block_expr->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -1948,7 +1945,7 @@ public:
>    auto &type = param.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
>   }
> @@ -1963,8 +1960,7 @@ public:
>     auto &type = item.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     // don't strip directly, only components of bounds
>     for (auto &bound : item.get_type_param_bounds ())
> @@ -1998,7 +1994,7 @@ public:
>    auto &return_type = method.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -2011,7 +2007,7 @@ public:
>     auto &block_expr = method.get_definition ();
>     block_expr->accept_vis (*this);
>     if (block_expr->is_marked_for_strip ())
> -      rust_error_at (block_expr->get_locus_slow (),
> +      rust_error_at (block_expr->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -2099,7 +2095,7 @@ public:
>    auto &return_type = function.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -2112,7 +2108,7 @@ public:
>     auto &block_expr = function.get_definition ();
>     block_expr->accept_vis (*this);
>     if (block_expr->is_marked_for_strip ())
> -      rust_error_at (block_expr->get_locus_slow (),
> +      rust_error_at (block_expr->get_locus (),
>             "cannot strip block expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -2136,8 +2132,7 @@ public:
>     auto &type = type_alias.get_type_aliased ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
>   }
>   void visit (AST::StructStruct &struct_item) override
>   {
> @@ -2235,7 +2230,7 @@ public:
>     auto &expr = item.get_expr ();
>     expr->accept_vis (*this);
>     if (expr->is_marked_for_strip ())
> -      rust_error_at (expr->get_locus_slow (),
> +      rust_error_at (expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -2295,8 +2290,7 @@ public:
>     auto &type = const_item.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     /* strip any internal sub-expressions - expression itself isn't
>      * allowed to have external attributes in this position so can't be
> @@ -2304,7 +2298,7 @@ public:
>     auto &expr = const_item.get_expr ();
>     expr->accept_vis (*this);
>     if (expr->is_marked_for_strip ())
> -      rust_error_at (expr->get_locus_slow (),
> +      rust_error_at (expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -2322,8 +2316,7 @@ public:
>     auto &type = static_item.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     /* strip any internal sub-expressions - expression itself isn't
>      * allowed to have external attributes in this position so can't be
> @@ -2331,7 +2324,7 @@ public:
>     auto &expr = static_item.get_expr ();
>     expr->accept_vis (*this);
>     if (expr->is_marked_for_strip ())
> -      rust_error_at (expr->get_locus_slow (),
> +      rust_error_at (expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>   }
> @@ -2355,7 +2348,7 @@ public:
>    auto &block = item.get_definition ();
>    block->accept_vis (*this);
>    if (block->is_marked_for_strip ())
> -      rust_error_at (block->get_locus_slow (),
> +      rust_error_at (block->get_locus (),
>             "cannot strip block expression in this "
>             "position - outer attributes not allowed");
>       }
> @@ -2380,7 +2373,7 @@ public:
>    auto &block = item.get_definition ();
>    block->accept_vis (*this);
>    if (block->is_marked_for_strip ())
> -      rust_error_at (block->get_locus_slow (),
> +      rust_error_at (block->get_locus (),
>             "cannot strip block expression in this "
>             "position - outer attributes not allowed");
>       }
> @@ -2399,8 +2392,7 @@ public:
>     auto &type = item.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     /* strip any internal sub-expressions - expression itself isn't
>      * allowed to have external attributes in this position so can't be
> @@ -2410,7 +2402,7 @@ public:
>    auto &expr = item.get_expr ();
>    expr->accept_vis (*this);
>    if (expr->is_marked_for_strip ())
> -      rust_error_at (expr->get_locus_slow (),
> +      rust_error_at (expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>       }
> @@ -2492,8 +2484,7 @@ public:
>     auto &type = impl.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     if (impl.has_where_clause ())
>       expand_where_clause (impl.get_where_clause ());
> @@ -2526,8 +2517,7 @@ public:
>     auto &type = impl.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
> 
>     auto &trait_path = impl.get_trait_path ();
>     visit (trait_path);
> @@ -2554,8 +2544,7 @@ public:
>     auto &type = item.get_type ();
>     type->accept_vis (*this);
>     if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> -             "cannot strip type in this position");
> +      rust_error_at (type->get_locus (), "cannot strip type in this position");
>   }
>   void visit (AST::ExternalFunctionItem &item) override
>   {
> @@ -2589,7 +2578,7 @@ public:
>    auto &type = param.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
> 
>    // increment if nothing else happens
> @@ -2607,7 +2596,7 @@ public:
>    auto &return_type = item.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -2686,7 +2675,7 @@ public:
>     auto &sub_pattern = pattern.get_pattern_to_bind ();
>     sub_pattern->accept_vis (*this);
>     if (sub_pattern->is_marked_for_strip ())
> -      rust_error_at (sub_pattern->get_locus_slow (),
> +      rust_error_at (sub_pattern->get_locus (),
>             "cannot strip pattern in this position");
>   }
>   void visit (AST::WildcardPattern &) override
> @@ -2724,7 +2713,7 @@ public:
>     auto &sub_pattern = pattern.get_referenced_pattern ();
>     sub_pattern->accept_vis (*this);
>     if (sub_pattern->is_marked_for_strip ())
> -      rust_error_at (sub_pattern->get_locus_slow (),
> +      rust_error_at (sub_pattern->get_locus (),
>             "cannot strip pattern in this position");
>   }
>   void visit (AST::StructPatternFieldTuplePat &field) override
> @@ -2741,7 +2730,7 @@ public:
>     auto &sub_pattern = field.get_index_pattern ();
>     sub_pattern->accept_vis (*this);
>     if (sub_pattern->is_marked_for_strip ())
> -      rust_error_at (sub_pattern->get_locus_slow (),
> +      rust_error_at (sub_pattern->get_locus (),
>             "cannot strip pattern in this position");
>   }
>   void visit (AST::StructPatternFieldIdentPat &field) override
> @@ -2758,7 +2747,7 @@ public:
>     auto &sub_pattern = field.get_ident_pattern ();
>     sub_pattern->accept_vis (*this);
>     if (sub_pattern->is_marked_for_strip ())
> -      rust_error_at (sub_pattern->get_locus_slow (),
> +      rust_error_at (sub_pattern->get_locus (),
>             "cannot strip pattern in this position");
>   }
>   void visit (AST::StructPatternFieldIdent &field) override
> @@ -2805,7 +2794,7 @@ public:
>    pattern->accept_vis (*this);
> 
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2818,7 +2807,7 @@ public:
>    lower_pattern->accept_vis (*this);
> 
>    if (lower_pattern->is_marked_for_strip ())
> -      rust_error_at (lower_pattern->get_locus_slow (),
> +      rust_error_at (lower_pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2827,7 +2816,7 @@ public:
>    upper_pattern->accept_vis (*this);
> 
>    if (upper_pattern->is_marked_for_strip ())
> -      rust_error_at (upper_pattern->get_locus_slow (),
> +      rust_error_at (upper_pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2851,7 +2840,7 @@ public:
>    pattern->accept_vis (*this);
> 
>    if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2864,7 +2853,7 @@ public:
>    lower_pattern->accept_vis (*this);
> 
>    if (lower_pattern->is_marked_for_strip ())
> -      rust_error_at (lower_pattern->get_locus_slow (),
> +      rust_error_at (lower_pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2873,7 +2862,7 @@ public:
>    upper_pattern->accept_vis (*this);
> 
>    if (upper_pattern->is_marked_for_strip ())
> -      rust_error_at (upper_pattern->get_locus_slow (),
> +      rust_error_at (upper_pattern->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2891,7 +2880,7 @@ public:
>     pattern_in_parens->accept_vis (*this);
> 
>     if (pattern_in_parens->is_marked_for_strip ())
> -      rust_error_at (pattern_in_parens->get_locus_slow (),
> +      rust_error_at (pattern_in_parens->get_locus (),
>             "cannot strip pattern in this position");
>   }
>   void visit (AST::SlicePattern &pattern) override
> @@ -2902,7 +2891,7 @@ public:
>    item->accept_vis (*this);
> 
>    if (item->is_marked_for_strip ())
> -      rust_error_at (item->get_locus_slow (),
> +      rust_error_at (item->get_locus (),
>             "cannot strip pattern in this position");
>    // TODO: quit stripping now? or keep going?
>       }
> @@ -2926,7 +2915,7 @@ public:
>     auto &pattern = stmt.get_pattern ();
>     pattern->accept_vis (*this);
>     if (pattern->is_marked_for_strip ())
> -      rust_error_at (pattern->get_locus_slow (),
> +      rust_error_at (pattern->get_locus (),
>             "cannot strip pattern in this position");
> 
>     // similar for type
> @@ -2935,7 +2924,7 @@ public:
>    auto &type = stmt.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> @@ -2947,7 +2936,7 @@ public:
>    auto &init_expr = stmt.get_init_expr ();
>    init_expr->accept_vis (*this);
>    if (init_expr->is_marked_for_strip ())
> -      rust_error_at (init_expr->get_locus_slow (),
> +      rust_error_at (init_expr->get_locus (),
>             "cannot strip expression in this position - outer "
>             "attributes not allowed");
>       }
> @@ -3016,7 +3005,7 @@ public:
>     auto &inner_type = type.get_type_in_parens ();
>     inner_type->accept_vis (*this);
>     if (inner_type->is_marked_for_strip ())
> -      rust_error_at (inner_type->get_locus_slow (),
> +      rust_error_at (inner_type->get_locus (),
>             "cannot strip type in this position");
>   }
>   void visit (AST::ImplTraitTypeOneBound &type) override
> @@ -3037,7 +3026,7 @@ public:
>       {
>    elem_type->accept_vis (*this);
>    if (elem_type->is_marked_for_strip ())
> -      rust_error_at (elem_type->get_locus_slow (),
> +      rust_error_at (elem_type->get_locus (),
>             "cannot strip type in this position");
>       }
>   }
> @@ -3051,7 +3040,7 @@ public:
>     auto &pointed_type = type.get_type_pointed_to ();
>     pointed_type->accept_vis (*this);
>     if (pointed_type->is_marked_for_strip ())
> -      rust_error_at (pointed_type->get_locus_slow (),
> +      rust_error_at (pointed_type->get_locus (),
>             "cannot strip type in this position");
>   }
>   void visit (AST::ReferenceType &type) override
> @@ -3060,7 +3049,7 @@ public:
>     auto &referenced_type = type.get_type_referenced ();
>     referenced_type->accept_vis (*this);
>     if (referenced_type->is_marked_for_strip ())
> -      rust_error_at (referenced_type->get_locus_slow (),
> +      rust_error_at (referenced_type->get_locus (),
>             "cannot strip type in this position");
>   }
>   void visit (AST::ArrayType &type) override
> @@ -3069,14 +3058,14 @@ public:
>     auto &base_type = type.get_elem_type ();
>     base_type->accept_vis (*this);
>     if (base_type->is_marked_for_strip ())
> -      rust_error_at (base_type->get_locus_slow (),
> +      rust_error_at (base_type->get_locus (),
>             "cannot strip type in this position");
> 
>     // same for expression
>     auto &size_expr = type.get_size_expr ();
>     size_expr->accept_vis (*this);
>     if (size_expr->is_marked_for_strip ())
> -      rust_error_at (size_expr->get_locus_slow (),
> +      rust_error_at (size_expr->get_locus (),
>             "cannot strip expression in this position");
>   }
>   void visit (AST::SliceType &type) override
> @@ -3085,7 +3074,7 @@ public:
>     auto &elem_type = type.get_elem_type ();
>     elem_type->accept_vis (*this);
>     if (elem_type->is_marked_for_strip ())
> -      rust_error_at (elem_type->get_locus_slow (),
> +      rust_error_at (elem_type->get_locus (),
>             "cannot strip type in this position");
>   }
>   void visit (AST::InferredType &) override
> @@ -3113,7 +3102,7 @@ public:
>    auto &type = param.get_type ();
>    type->accept_vis (*this);
>    if (type->is_marked_for_strip ())
> -      rust_error_at (type->get_locus_slow (),
> +      rust_error_at (type->get_locus (),
>             "cannot strip type in this position");
> 
>    // increment if nothing else happens
> @@ -3128,7 +3117,7 @@ public:
>    auto &return_type = type.get_return_type ();
>    return_type->accept_vis (*this);
>    if (return_type->is_marked_for_strip ())
> -      rust_error_at (return_type->get_locus_slow (),
> +      rust_error_at (return_type->get_locus (),
>             "cannot strip type in this position");
>       }
> 
> diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
> index 3415567c86b..ff4c181d0e2 100644
> --- a/gcc/rust/hir/rust-ast-lower-expr.h
> +++ b/gcc/rust/hir/rust-ast-lower-expr.h
> @@ -81,7 +81,7 @@ public:
>     expr->accept_vis (resolver);
>     if (resolver.translated == nullptr)
>       {
> -    rust_fatal_error (expr->get_locus_slow (), "Failed to lower expr: [%s]",
> +    rust_fatal_error (expr->get_locus (), "Failed to lower expr: [%s]",
>              expr->as_string ().c_str ());
>    return nullptr;
>       }
> @@ -91,8 +91,7 @@ public:
>       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
>     resolver.mappings->insert_location (
>       resolver.translated->get_mappings ().get_crate_num (),
> -      resolver.translated->get_mappings ().get_hirid (),
> -      expr->get_locus_slow ());
> +      resolver.translated->get_mappings ().get_hirid (), expr->get_locus ());
> 
>     if (terminated != nullptr)
>       *terminated = resolver.terminated;
> diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
> index c7f874d1dc9..7efcffaf05b 100644
> --- a/gcc/rust/hir/rust-ast-lower-item.h
> +++ b/gcc/rust/hir/rust-ast-lower-item.h
> @@ -47,7 +47,7 @@ public:
>     // this is useful for debugging
>     // if (resolver.translated == nullptr)
>     //   {
> -    //     rust_fatal_error (item->get_locus_slow (), "failed to lower: %s",
> +    //     rust_fatal_error (item->get_locus (), "failed to lower: %s",
>     //               item->as_string ().c_str ());
>     //     return nullptr;
>     //   }
> diff --git a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
> index 3b313a78476..e6322dbb514 100644
> --- a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
> +++ b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
> @@ -41,8 +41,7 @@ public:
>       compiler.translated->get_mappings ().get_hirid (), compiler.translated);
>     compiler.mappings->insert_location (
>       compiler.translated->get_mappings ().get_crate_num (),
> -      compiler.translated->get_mappings ().get_hirid (),
> -      field->get_locus_slow ());
> +      compiler.translated->get_mappings ().get_hirid (), field->get_locus ());
> 
>     return compiler.translated;
>   }
> diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
> index 9b5ec0a4df7..c16025d137b 100644
> --- a/gcc/rust/hir/rust-ast-lower-type.h
> +++ b/gcc/rust/hir/rust-ast-lower-type.h
> @@ -106,8 +106,7 @@ public:
>     rust_assert (resolver.translated != nullptr);
>     resolver.mappings->insert_location (
>       resolver.translated->get_mappings ().get_crate_num (),
> -      resolver.translated->get_mappings ().get_hirid (),
> -      type->get_locus_slow ());
> +      resolver.translated->get_mappings ().get_hirid (), type->get_locus ());
> 
>     return resolver.translated;
>   }
> @@ -282,8 +281,7 @@ public:
>     rust_assert (resolver.translated != nullptr);
>     resolver.mappings->insert_location (
>       resolver.translated->get_mappings ().get_crate_num (),
> -      resolver.translated->get_mappings ().get_hirid (),
> -      param->get_locus_slow ());
> +      resolver.translated->get_mappings ().get_hirid (), param->get_locus ());
>     resolver.mappings->insert_hir_generic_param (
>       resolver.translated->get_mappings ().get_crate_num (),
>       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
> @@ -356,7 +354,7 @@ public:
>     resolver.mappings->insert_location (
>       resolver.translated->get_mappings ().get_crate_num (),
>       resolver.translated->get_mappings ().get_hirid (),
> -      resolver.translated->get_locus_slow ());
> +      resolver.translated->get_locus ());
> 
>     return resolver.translated;
>   }
> diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
> index e693799d4b5..d5138fd64ac 100644
> --- a/gcc/rust/hir/rust-ast-lower.cc
> +++ b/gcc/rust/hir/rust-ast-lower.cc
> @@ -66,7 +66,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
>   bool block_did_terminate = false;
>   expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool {
>     if (block_did_terminate)
> -      rust_warning_at (s->get_locus_slow (), 0, "unreachable statement");
> +      rust_warning_at (s->get_locus (), 0, "unreachable statement");
> 
>     bool terminated = false;
>     auto translated_stmt = ASTLoweringStmt::translate (s, &terminated);
> @@ -78,7 +78,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
>   if (expr.has_tail_expr () && block_did_terminate)
>     {
>       // warning unreachable tail expressions
> -      rust_warning_at (expr.get_tail_expr ()->get_locus_slow (), 0,
> +      rust_warning_at (expr.get_tail_expr ()->get_locus (), 0,
>               "unreachable expression");
>     }
> 
> diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
> index 8d815c5adc6..233e015110c 100644
> --- a/gcc/rust/hir/tree/rust-hir-expr.h
> +++ b/gcc/rust/hir/tree/rust-hir-expr.h
> @@ -91,7 +91,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -164,7 +163,6 @@ protected:
> 
> public:
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
> };
> @@ -711,7 +709,6 @@ public:
>   GroupedExpr &operator= (GroupedExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -916,7 +913,6 @@ public:
>   ArrayExpr &operator= (ArrayExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -982,7 +978,6 @@ public:
>   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1061,7 +1056,6 @@ public:
>    * comma, i.e. (0,) rather than (0) */
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1145,7 +1139,6 @@ public:
>   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1212,7 +1205,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1641,7 +1633,6 @@ public:
>   StructExprTuple &operator= (StructExprTuple &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1677,7 +1668,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1895,7 +1885,6 @@ public:
>   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -1965,7 +1954,6 @@ public:
>   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2006,7 +1994,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2083,7 +2070,6 @@ public:
>   bool has_params () const { return !params.empty (); }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2173,7 +2159,6 @@ public:
>   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2258,7 +2243,6 @@ public:
>   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2362,7 +2346,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> };
> 
> // Represents a non-type-specified closure expression HIR node
> @@ -2498,7 +2481,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2518,7 +2500,7 @@ public:
>     if (statements.size () == 0)
>       return get_locus ();
> 
> -    return statements[statements.size () - 1]->get_locus_slow ();
> +    return statements[statements.size () - 1]->get_locus ();
>   }
> 
>   std::unique_ptr<Expr> &get_final_expr () { return expr; }
> @@ -2633,7 +2615,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2713,7 +2694,6 @@ public:
>   BreakExpr &operator= (BreakExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -2747,7 +2727,6 @@ protected:
> 
> public:
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> };
> 
> // Range from (inclusive) and to (exclusive) expression HIR node object
> @@ -3090,7 +3069,6 @@ public:
>   ReturnExpr &operator= (ReturnExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -3152,7 +3130,6 @@ public:
>   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -3251,7 +3228,6 @@ public:
>   bool has_loop_label () const { return !loop_label.is_error (); }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
> 
> @@ -3541,7 +3517,6 @@ public:
>    * better approach? or does it not parse correctly and have downsides? */
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -3766,7 +3741,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -4342,7 +4316,6 @@ public:
>   MatchExpr &operator= (MatchExpr &&other) = default;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -4397,7 +4370,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -4451,7 +4423,6 @@ public:
>   std::string as_string () const override;
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
> index 7a05f02067b..90b6820e64d 100644
> --- a/gcc/rust/hir/tree/rust-hir-item.h
> +++ b/gcc/rust/hir/tree/rust-hir-item.h
> @@ -106,8 +106,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   void accept_vis (HIRVisitor &vis) override;
> 
>   Identifier get_type_representation () const { return type_representation; }
> diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
> index a8bbbb62ef6..9f60b8fb7df 100644
> --- a/gcc/rust/hir/tree/rust-hir-path.h
> +++ b/gcc/rust/hir/tree/rust-hir-path.h
> @@ -316,7 +316,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -792,7 +791,6 @@ public:
>   {}
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
> index 584b0e358cd..eef6834f99a 100644
> --- a/gcc/rust/hir/tree/rust-hir-stmt.h
> +++ b/gcc/rust/hir/tree/rust-hir-stmt.h
> @@ -109,8 +109,6 @@ public:
>   LetStmt (LetStmt &&other) = default;
>   LetStmt &operator= (LetStmt &&other) = default;
> 
> -  Location get_locus_slow () const override { return get_locus (); }
> -
>   Location get_locus () const { return locus; }
> 
>   void accept_vis (HIRVisitor &vis) override;
> diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
> index 8d75d0285d3..5b578d915a2 100644
> --- a/gcc/rust/hir/tree/rust-hir-type.h
> +++ b/gcc/rust/hir/tree/rust-hir-type.h
> @@ -63,8 +63,6 @@ public:
>     return mappings;
>   }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   BoundType get_bound_type () const final override { return TRAITBOUND; }
> 
>   TypePath &get_path () { return type_path; }
> diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
> index b8acf1a6e40..b285d352b59 100644
> --- a/gcc/rust/hir/tree/rust-hir.h
> +++ b/gcc/rust/hir/tree/rust-hir.h
> @@ -100,9 +100,7 @@ public:
> 
>   virtual void accept_vis (HIRVisitor &vis) = 0;
> 
> -  /* HACK: slow way of getting location from base expression through virtual
> -   * methods. */
> -  virtual Location get_locus_slow () const { return Location (); }
> +  virtual Location get_locus () const = 0;
> 
>   virtual bool is_unit_check_needed () const { return false; }
> 
> @@ -194,9 +192,7 @@ public:
> 
>   virtual ~Expr () {}
> 
> -  /* HACK: slow way of getting location from base expression through virtual
> -   * methods. */
> -  virtual Location get_locus_slow () const { return Location (); }
> +  virtual Location get_locus () const = 0;
> 
>   // HACK: strictly not needed, but faster than full downcast clone
>   virtual bool is_expr_without_block () const = 0;
> @@ -285,7 +281,6 @@ public:
>   }
> 
>   Location get_locus () const { return locus; }
> -  Location get_locus_slow () const override { return get_locus (); }
> 
>   void accept_vis (HIRVisitor &vis) override;
> 
> @@ -426,7 +421,7 @@ public:
> 
>   virtual Analysis::NodeMapping get_mappings () const = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   virtual BoundType get_bound_type () const = 0;
> 
> @@ -483,8 +478,6 @@ public:
>     return mappings;
>   }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
>   BoundType get_bound_type () const final override { return LIFETIME; }
> 
> protected:
> @@ -522,7 +515,7 @@ public:
> 
>   virtual void accept_vis (HIRVisitor &vis) = 0;
> 
> -  virtual Location get_locus_slow () const = 0;
> +  virtual Location get_locus () const = 0;
> 
>   Analysis::NodeMapping get_mappings () const { return mappings; }
> 
> @@ -611,8 +604,6 @@ public:
> 
>   Location get_locus () const { return locus; }
> 
> -  Location get_locus_slow () const override final { return get_locus (); }
> -
> protected:
>   /* Use covariance to implement clone function as returning this object rather
>    * than base */
> diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
> index 87fa3ef2f3e..f383d48377e 100644
> --- a/gcc/rust/lint/rust-lint-marklive.cc
> +++ b/gcc/rust/lint/rust-lint-marklive.cc
> @@ -211,7 +211,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
>   if (!tyctx->lookup_type (
>    expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
>     {
> -      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_receiver_expr ()->get_locus (),
>             "unresolved type for receiver");
>     }
>   bool ok = receiver->get_kind () == TyTy::TypeKind::ADT;
> @@ -223,7 +223,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
>   adt->get_field (expr.get_field_name (), &index);
>   if (index >= adt->num_fields ())
>     {
> -      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
> +      rust_error_at (expr.get_receiver_expr ()->get_locus (),
>             "cannot access struct %s by index: %ld",
>             adt->get_name ().c_str (), index);
>       return;
> diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
> index fa6d409c6dc..8ee9e42f944 100644
> --- a/gcc/rust/parse/rust-parse-impl.h
> +++ b/gcc/rust/parse/rust-parse-impl.h
> @@ -11431,7 +11431,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_with_block (
>     return ExprOrStmt (std::move (expr));
> 
>   // internal block expr must either have semicolons followed, or evaluate to ()
> -  auto locus = expr->get_locus_slow ();
> +  auto locus = expr->get_locus ();
>   std::unique_ptr<AST::ExprStmtWithBlock> stmt (
>     new AST::ExprStmtWithBlock (std::move (expr), locus,
>                tok->get_id () == SEMICOLON));
> @@ -12823,7 +12823,7 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
>     {
>       // FIXME: allow for outer attributes to be applied
>       case QUESTION_MARK: {
> -    Location left_locus = left->get_locus_slow ();
> +    Location left_locus = left->get_locus ();
>    // error propagation expression - unary postfix
>    return std::unique_ptr<AST::ErrorPropagationExpr> (
>      new AST::ErrorPropagationExpr (std::move (left),
> @@ -13185,7 +13185,7 @@ Parser<ManagedTokenSource>::parse_arithmetic_or_logical_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13206,7 +13206,7 @@ Parser<ManagedTokenSource>::parse_binary_plus_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13227,7 +13227,7 @@ Parser<ManagedTokenSource>::parse_binary_minus_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13249,7 +13249,7 @@ Parser<ManagedTokenSource>::parse_binary_mult_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13271,7 +13271,7 @@ Parser<ManagedTokenSource>::parse_binary_div_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13293,7 +13293,7 @@ Parser<ManagedTokenSource>::parse_binary_mod_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13316,7 +13316,7 @@ Parser<ManagedTokenSource>::parse_bitwise_and_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13339,7 +13339,7 @@ Parser<ManagedTokenSource>::parse_bitwise_or_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13362,7 +13362,7 @@ Parser<ManagedTokenSource>::parse_bitwise_xor_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13384,7 +13384,7 @@ Parser<ManagedTokenSource>::parse_left_shift_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13406,7 +13406,7 @@ Parser<ManagedTokenSource>::parse_right_shift_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
>     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
> @@ -13458,7 +13458,7 @@ Parser<ManagedTokenSource>::parse_comparison_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right), expr_type,
> @@ -13479,7 +13479,7 @@ Parser<ManagedTokenSource>::parse_binary_equal_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13500,7 +13500,7 @@ Parser<ManagedTokenSource>::parse_binary_not_equal_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13521,7 +13521,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_than_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13542,7 +13542,7 @@ Parser<ManagedTokenSource>::parse_binary_less_than_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13563,7 +13563,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_equal_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13584,7 +13584,7 @@ Parser<ManagedTokenSource>::parse_binary_less_equal_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::ComparisonExpr> (
>     new AST::ComparisonExpr (std::move (left), std::move (right),
> @@ -13605,7 +13605,7 @@ Parser<ManagedTokenSource>::parse_lazy_or_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::LazyBooleanExpr> (
>     new AST::LazyBooleanExpr (std::move (left), std::move (right),
> @@ -13626,7 +13626,7 @@ Parser<ManagedTokenSource>::parse_lazy_and_expr (
>     return nullptr;
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::LazyBooleanExpr> (
>     new AST::LazyBooleanExpr (std::move (left), std::move (right),
> @@ -13648,7 +13648,7 @@ Parser<ManagedTokenSource>::parse_type_cast_expr (
>   // FIXME: how do I get precedence put in here?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = expr_to_cast->get_locus_slow ();
> +  Location locus = expr_to_cast->get_locus ();
> 
>   return std::unique_ptr<AST::TypeCastExpr> (
>     new AST::TypeCastExpr (std::move (expr_to_cast), std::move (type), locus));
> @@ -13669,7 +13669,7 @@ Parser<ManagedTokenSource>::parse_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::AssignmentExpr> (
>     new AST::AssignmentExpr (std::move (left), std::move (right), locus));
> @@ -13728,7 +13728,7 @@ Parser<ManagedTokenSource>::parse_compound_assignment_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13750,7 +13750,7 @@ Parser<ManagedTokenSource>::parse_plus_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13772,7 +13772,7 @@ Parser<ManagedTokenSource>::parse_minus_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13795,7 +13795,7 @@ Parser<ManagedTokenSource>::parse_mult_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13818,7 +13818,7 @@ Parser<ManagedTokenSource>::parse_div_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13841,7 +13841,7 @@ Parser<ManagedTokenSource>::parse_mod_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13864,7 +13864,7 @@ Parser<ManagedTokenSource>::parse_and_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13887,7 +13887,7 @@ Parser<ManagedTokenSource>::parse_or_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13910,7 +13910,7 @@ Parser<ManagedTokenSource>::parse_xor_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13933,7 +13933,7 @@ Parser<ManagedTokenSource>::parse_left_shift_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13956,7 +13956,7 @@ Parser<ManagedTokenSource>::parse_right_shift_assig_expr (
>   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::CompoundAssignmentExpr> (
>     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
> @@ -13985,7 +13985,7 @@ Parser<ManagedTokenSource>::parse_await_expr (
>     }
> 
>   // TODO: check inside async block in semantic analysis
> -  Location locus = expr_to_await->get_locus_slow ();
> +  Location locus = expr_to_await->get_locus ();
> 
>   return std::unique_ptr<AST::AwaitExpr> (
>     new AST::AwaitExpr (std::move (expr_to_await), std::move (outer_attrs),
> @@ -14008,7 +14008,7 @@ Parser<ManagedTokenSource>::parse_led_range_exclusive_expr (
>   std::unique_ptr<AST::Expr> right
>     = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
> 
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   if (right == nullptr)
>     {
> @@ -14066,7 +14066,7 @@ Parser<ManagedTokenSource>::parse_range_inclusive_expr (
>   // FIXME: make non-associative
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = left->get_locus_slow ();
> +  Location locus = left->get_locus ();
> 
>   return std::unique_ptr<AST::RangeFromToInclExpr> (
>     new AST::RangeFromToInclExpr (std::move (left), std::move (right), locus));
> @@ -14114,7 +14114,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr (
>     }
>   int index_int = atoi (index.c_str ());
> 
> -  Location locus = tuple_expr->get_locus_slow ();
> +  Location locus = tuple_expr->get_locus ();
> 
>   return std::unique_ptr<AST::TupleIndexExpr> (
>     new AST::TupleIndexExpr (std::move (tuple_expr), index_int,
> @@ -14145,7 +14145,7 @@ Parser<ManagedTokenSource>::parse_index_expr (
>     }
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = array_expr->get_locus_slow ();
> +  Location locus = array_expr->get_locus ();
> 
>   return std::unique_ptr<AST::ArrayIndexExpr> (
>     new AST::ArrayIndexExpr (std::move (array_expr), std::move (index_expr),
> @@ -14167,7 +14167,7 @@ Parser<ManagedTokenSource>::parse_field_access_expr (
> 
>   Identifier ident = ident_tok->get_str ();
> 
> -  Location locus = struct_expr->get_locus_slow ();
> +  Location locus = struct_expr->get_locus ();
> 
>   // TODO: check types. actually, do so during semantic analysis
>   return std::unique_ptr<AST::FieldAccessExpr> (
> @@ -14230,7 +14230,7 @@ Parser<ManagedTokenSource>::parse_method_call_expr (
>     }
> 
>   // TODO: check types. actually do so in semantic analysis pass.
> -  Location locus = receiver_expr->get_locus_slow ();
> +  Location locus = receiver_expr->get_locus ();
> 
>   return std::unique_ptr<AST::MethodCallExpr> (
>     new AST::MethodCallExpr (std::move (receiver_expr), std::move (segment),
> @@ -14277,7 +14277,7 @@ Parser<ManagedTokenSource>::parse_function_call_expr (
>     }
> 
>   // TODO: check types. actually, do so during semantic analysis
> -  Location locus = function_expr->get_locus_slow ();
> +  Location locus = function_expr->get_locus ();
> 
>   return std::unique_ptr<AST::CallExpr> (
>     new AST::CallExpr (std::move (function_expr), std::move (params),
> @@ -14772,7 +14772,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr_float (
>   // get int from string
>   int index = atoi (index_str.c_str ());
> 
> -  Location locus = tuple_expr->get_locus_slow ();
> +  Location locus = tuple_expr->get_locus ();
> 
>   return std::unique_ptr<AST::TupleIndexExpr> (
>     new AST::TupleIndexExpr (std::move (tuple_expr), index,
> diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
> index bc05e93069c..d3c053b609f 100644
> --- a/gcc/rust/resolve/rust-ast-resolve-item.h
> +++ b/gcc/rust/resolve/rust-ast-resolve-item.h
> @@ -400,9 +400,9 @@ public:
>     auto Self
>       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
> 
> -    resolver->get_type_scope ().insert (
> -      Self, impl_block.get_type ()->get_node_id (),
> -      impl_block.get_type ()->get_locus_slow ());
> +    resolver->get_type_scope ().insert (Self,
> +                    impl_block.get_type ()->get_node_id (),
> +                    impl_block.get_type ()->get_locus ());
> 
>     for (auto &impl_item : impl_block.get_impl_items ())
>       {
> @@ -519,9 +519,9 @@ public:
>     auto Self
>       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
> 
> -    resolver->get_type_scope ().insert (
> -      Self, impl_block.get_type ()->get_node_id (),
> -      impl_block.get_type ()->get_locus_slow ());
> +    resolver->get_type_scope ().insert (Self,
> +                    impl_block.get_type ()->get_node_id (),
> +                    impl_block.get_type ()->get_locus ());
> 
>     for (auto &impl_item : impl_block.get_impl_items ())
>       {
> diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
> index b8affe68c41..97c031199b3 100644
> --- a/gcc/rust/resolve/rust-ast-resolve-type.h
> +++ b/gcc/rust/resolve/rust-ast-resolve-type.h
> @@ -211,7 +211,7 @@ public:
>     // https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_resolve/src/lib.rs#L1722
>     if (!resolver->get_type_scope ().lookup (canonical_path, &resolved_node))
>       {
> -    rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s",
> +    rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
>               canonical_path.get ().c_str ());
>    return UNKNOWN_NODEID;
>       }
> @@ -231,7 +231,7 @@ public:
>     ResolveType resolver (parent, canonicalize_type_with_generics);
>     type->accept_vis (resolver);
>     if (!resolver.ok)
> -      rust_error_at (type->get_locus_slow (), "unresolved type");
> +      rust_error_at (type->get_locus (), "unresolved type");
> 
>     return resolver.resolved_node;
>   };
> @@ -311,7 +311,7 @@ public:
>     ResolveTypeBound resolver (parent, canonicalize_type_with_generics);
>     type->accept_vis (resolver);
>     if (!resolver.ok)
> -      rust_error_at (type->get_locus_slow (), "unresolved type bound");
> +      rust_error_at (type->get_locus (), "unresolved type bound");
> 
>     return resolver.resolved_node;
>   };
> @@ -346,7 +346,7 @@ public:
>     ResolveGenericParam resolver (parent);
>     param->accept_vis (resolver);
>     if (!resolver.ok)
> -      rust_error_at (param->get_locus_slow (), "unresolved generic parameter");
> +      rust_error_at (param->get_locus (), "unresolved generic parameter");
> 
>     return resolver.resolved_node;
>   };
> diff --git a/gcc/rust/resolve/rust-ast-verify-assignee.h b/gcc/rust/resolve/rust-ast-verify-assignee.h
> index aed01196f81..9da3883220d 100644
> --- a/gcc/rust/resolve/rust-ast-verify-assignee.h
> +++ b/gcc/rust/resolve/rust-ast-verify-assignee.h
> @@ -35,7 +35,7 @@ public:
>     VerifyAsignee checker (parent);
>     assignee->accept_vis (checker);
>     if (!checker.ok)
> -      rust_error_at (assignee->get_locus_slow (),
> +      rust_error_at (assignee->get_locus (),
>             "invalid left-hand side of assignment");
>     return checker.ok;
>   }
> diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
> index 9e0450e8882..1bff7ef13b7 100644
> --- a/gcc/rust/typecheck/rust-hir-const-fold.h
> +++ b/gcc/rust/typecheck/rust-hir-const-fold.h
> @@ -211,7 +211,7 @@ public:
>     item.accept_vis (folder);
>     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
>       {
> -    rust_error_at (item.get_locus_slow (), "non const value");
> +    rust_error_at (item.get_locus (), "non const value");
>    return nullptr;
>       }
> 
> @@ -240,7 +240,7 @@ public:
>     expr->accept_vis (folder);
>     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
>       {
> -    rust_error_at (expr->get_locus_slow (), "non const value");
> +    rust_error_at (expr->get_locus (), "non const value");
>    return nullptr;
>       }
> 
> diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
> index a95a4e91c78..274451606cb 100644
> --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
> +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
> @@ -49,8 +49,7 @@ public:
> 
>     if (resolver.infered == nullptr)
>       {
> -    rust_error_at (expr->get_locus_slow (),
> -               "failed to type resolve expression");
> +    rust_error_at (expr->get_locus (), "failed to type resolve expression");
>    return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
>       }
> 
> @@ -67,7 +66,7 @@ public:
>       = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get (), inside_loop);
>     if (resolved == nullptr)
>       {
> -    rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_tuple_expr ()->get_locus (),
>               "failed to resolve TupleIndexExpr receiver");
>    return;
>       }
> @@ -76,7 +75,7 @@ public:
>             || resolved->get_kind () == TyTy::TypeKind::TUPLE;
>     if (!is_valid_type)
>       {
> -    rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_tuple_expr ()->get_locus (),
>               "Expected Tuple or ADT got: %s",
>               resolved->as_string ().c_str ());
>    return;
> @@ -203,7 +202,7 @@ public:
>       = TypeCheckExpr::Resolve (expr.get_receiver ().get (), false);
>     if (receiver_tyty == nullptr)
>       {
> -    rust_error_at (expr.get_receiver ()->get_locus_slow (),
> +    rust_error_at (expr.get_receiver ()->get_locus (),
>               "failed to resolve receiver in MethodCallExpr");
>    return;
>       }
> @@ -771,7 +770,7 @@ public:
>       = size_ty->unify (TypeCheckExpr::Resolve (expr.get_index_expr (), false));
>     if (resolved_index_expr == nullptr)
>       {
> -    rust_error_at (expr.get_index_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_index_expr ()->get_locus (),
>               "Type Resolver failure in Index for ArrayIndexExpr");
>    return;
>       }
> @@ -782,13 +781,13 @@ public:
>     expr.get_array_expr ()->accept_vis (*this);
>     if (infered == nullptr)
>       {
> -    rust_error_at (expr.get_index_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_index_expr ()->get_locus (),
>               "failed to resolve array reference expression");
>    return;
>       }
>     else if (infered->get_kind () != TyTy::TypeKind::ARRAY)
>       {
> -    rust_error_at (expr.get_index_expr ()->get_locus_slow (),
> +    rust_error_at (expr.get_index_expr ()->get_locus (),
>               "expected an ArrayType got [%s]",
>               infered->as_string ().c_str ());
>    infered = nullptr;
> @@ -936,7 +935,7 @@ public:
>       = TypeCheckExpr::Resolve (expr.get_loop_block ().get (), true);
>     if (!block_expr->is_unit ())
>       {
> -    rust_error_at (expr.get_loop_block ()->get_locus_slow (),
> +    rust_error_at (expr.get_loop_block ()->get_locus (),
>               "expected %<()%> got %s",
>               block_expr->as_string ().c_str ());
>    return;
> @@ -965,7 +964,7 @@ public:
> 
>     if (!block_expr->is_unit ())
>       {
> -    rust_error_at (expr.get_loop_block ()->get_locus_slow (),
> +    rust_error_at (expr.get_loop_block ()->get_locus (),
>               "expected %<()%> got %s",
>               block_expr->as_string ().c_str ());
>    return;
> diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
> index fff86beaa27..0cc1cfb3d40 100644
> --- a/gcc/rust/typecheck/rust-hir-type-check-type.h
> +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
> @@ -257,7 +257,7 @@ public:
> 
>     if (resolver.resolved == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "failed to setup generic parameter");
>    return nullptr;
>       }
> diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
> index 4b66fdbd6e6..7f0e0ffdb30 100644
> --- a/gcc/rust/typecheck/rust-hir-type-check.cc
> +++ b/gcc/rust/typecheck/rust-hir-type-check.cc
> @@ -97,7 +97,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
>     auto resolved = TypeCheckStmt::Resolve (s, inside_loop);
>     if (resolved == nullptr)
>       {
> -    rust_error_at (s->get_locus_slow (), "failure to resolve type");
> +    rust_error_at (s->get_locus (), "failure to resolve type");
>    return false;
>       }
> 
> @@ -145,9 +145,8 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
>    = (TyTy::ADTType *) struct_path_resolved->unify (base_resolved);
>       if (struct_def == nullptr)
>    {
> -      rust_fatal_error (
> -        struct_expr.struct_base->base_struct->get_locus_slow (),
> -        "incompatible types for base struct reference");
> +      rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
> +                "incompatible types for base struct reference");
>      return;
>    }
>     }
> @@ -229,11 +228,11 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
>          HIR::Expr *field_value = new HIR::FieldAccessExpr (
>        mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
>        std::move (outer_attribs),
> -        struct_expr.struct_base->base_struct->get_locus_slow ());
> +        struct_expr.struct_base->base_struct->get_locus ());
> 
>          implicit_field = new HIR::StructExprFieldIdentifierValue (
>        mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
> -        struct_expr.struct_base->base_struct->get_locus_slow ());
> +        struct_expr.struct_base->base_struct->get_locus ());
> 
>          size_t field_index;
>          bool ok = struct_path_resolved->get_field (missing, &field_index);
> diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
> index 56fdafd7919..e449b55f41e 100644
> --- a/gcc/rust/typecheck/rust-tyty.cc
> +++ b/gcc/rust/typecheck/rust-tyty.cc
> @@ -2207,7 +2207,7 @@ TypeCheckCallExpr::visit (ADTType &type)
>     BaseType *arg = Resolver::TypeCheckExpr::Resolve (p, false);
>     if (arg == nullptr)
>       {
> -    rust_error_at (p->get_locus_slow (), "failed to resolve argument type");
> +    rust_error_at (p->get_locus (), "failed to resolve argument type");
>    return false;
>       }
> 
> @@ -2262,7 +2262,7 @@ TypeCheckCallExpr::visit (FnType &type)
>     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
>     if (argument_expr_tyty == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "failed to resolve type for argument expr in CallExpr");
>    return false;
>       }
> @@ -2276,7 +2276,7 @@ TypeCheckCallExpr::visit (FnType &type)
>    resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
>    if (resolved_argument_type == nullptr)
>      {
> -        rust_error_at (param->get_locus_slow (),
> +        rust_error_at (param->get_locus (),
>               "Type Resolution failure on parameter");
>        return false;
>      }
> @@ -2327,7 +2327,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
>     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
>     if (argument_expr_tyty == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "failed to resolve type for argument expr in CallExpr");
>    return false;
>       }
> @@ -2335,7 +2335,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
>     auto resolved_argument_type = fnparam->unify (argument_expr_tyty);
>     if (resolved_argument_type == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "Type Resolution failure on parameter");
>    return false;
>       }
> @@ -2378,7 +2378,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
>     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
>     if (argument_expr_tyty == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "failed to resolve type for argument expr in CallExpr");
>    return false;
>       }
> @@ -2386,7 +2386,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
>     auto resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
>     if (resolved_argument_type == nullptr)
>       {
> -    rust_error_at (param->get_locus_slow (),
> +    rust_error_at (param->get_locus (),
>               "Type Resolution failure on parameter");
>    return false;
>       }
> diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
> index d544042b344..deade08db37 100644
> --- a/gcc/rust/util/rust-hir-map.cc
> +++ b/gcc/rust/util/rust-hir-map.cc
> @@ -380,7 +380,7 @@ Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
> {
>   hirExprMappings[crateNum][id] = expr;
>   nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
> -  insert_location (crateNum, id, expr->get_locus_slow ());
> +  insert_location (crateNum, id, expr->get_locus ());
> }
> 
> HIR::Expr *
> @@ -430,7 +430,7 @@ Mappings::insert_hir_generic_param (CrateNum crateNum, HirId id,
> 
>   hirGenericParamMappings[crateNum][id] = param;
>   nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
> -  insert_location (crateNum, id, param->get_locus_slow ());
> +  insert_location (crateNum, id, param->get_locus ());
> }
> 
> HIR::GenericParam *
> -- 
> 2.32.0
> 
> -- 
> Gcc-rust mailing list
> Gcc-rust@gcc.gnu.org
> https://gcc.gnu.org/mailman/listinfo/gcc-rust

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Get rid of get_locus_slow
  2021-08-26  2:31 ` The Other
@ 2021-08-26 19:19   ` Mark Wielaard
  2021-08-26 19:25     ` [PATCHv2] " Mark Wielaard
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Wielaard @ 2021-08-26 19:19 UTC (permalink / raw)
  To: The Other; +Cc: gcc-rust

On Thu, Aug 26, 2021 at 10:31:06AM +0800, The Other wrote:

> The original point of the distinction between get_locus_slow() and
> get_locus() was to avoid the overhead of virtual function calls
> whenever possible, but still have a way to access locations from
> abstract base classes like Expr.

If only we had Traits :)

> As such, I’d at least make the overridden calls ‘final override’ in
> the hope that the compiler can optimise out the virtual call.

Yes, makes sense. I'll sent an updated patch.

Thanks,

Mark


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCHv2] Get rid of get_locus_slow
  2021-08-26 19:19   ` Mark Wielaard
@ 2021-08-26 19:25     ` Mark Wielaard
  0 siblings, 0 replies; 4+ messages in thread
From: Mark Wielaard @ 2021-08-26 19:25 UTC (permalink / raw)
  To: gcc-rust; +Cc: Mark Wielaard

In various places there was the following hack:

  /* HACK: slow way of getting location from base expression through
     virtual methods. */
  virtual Location get_locus_slow () const { return Location (); }

The problem with get_locus_slow () is that if a subclass didn't
override it then there was no real location. get_locus_slow was
missing for Module, ExternCrate, UseDeclaration, Function, TypeAlias,
StructStruct, TupleStruct, Enum, Union, ConstantItem, StaticItem,
Trait, ImplBlock, ExternBlock, EmptyStmt, ExprStmtWithoutBlock and
ExprStmtWithBlock. All do have a get_locus () function.

Simply replace the get_locus_slow virtual method with a real virtual
Location get_locus () const = 0 method so we know if something
really doesn't have a location. This was only the case for
MacroRulesDefinition.
---

https://code.wildebeest.org/git/user/mjw/gccrs/commit/?h=no-get-locus-slow

Changes in v2:

  - all replaced get_locus_slow -> get_locus methods are now marked
    with final override

 gcc/rust/ast/rust-ast.h                       |  35 +-
 gcc/rust/ast/rust-expr.h                      | 109 +++----
 gcc/rust/ast/rust-item.h                      |  42 +--
 gcc/rust/ast/rust-macro.h                     |   5 +-
 gcc/rust/ast/rust-path.h                      |  12 +-
 gcc/rust/ast/rust-pattern.h                   |  26 +-
 gcc/rust/ast/rust-stmt.h                      |  12 +-
 gcc/rust/ast/rust-type.h                      |  43 +--
 gcc/rust/backend/rust-compile-expr.h          |   4 +-
 gcc/rust/backend/rust-compile.cc              |   4 +-
 gcc/rust/expand/rust-macro-expand.cc          | 299 +++++++++---------
 gcc/rust/hir/rust-ast-lower-expr.h            |   5 +-
 gcc/rust/hir/rust-ast-lower-item.h            |   2 +-
 .../hir/rust-ast-lower-struct-field-expr.h    |   3 +-
 gcc/rust/hir/rust-ast-lower-type.h            |   8 +-
 gcc/rust/hir/rust-ast-lower.cc                |   4 +-
 gcc/rust/hir/tree/rust-hir-expr.h             |  89 ++----
 gcc/rust/hir/tree/rust-hir-item.h             |  30 +-
 gcc/rust/hir/tree/rust-hir-path.h             |   6 +-
 gcc/rust/hir/tree/rust-hir-stmt.h             |   8 +-
 gcc/rust/hir/tree/rust-hir-type.h             |   4 +-
 gcc/rust/hir/tree/rust-hir.h                  |  23 +-
 gcc/rust/lint/rust-lint-marklive.cc           |   4 +-
 gcc/rust/parse/rust-parse-impl.h              |  88 +++---
 gcc/rust/resolve/rust-ast-resolve-item.h      |  12 +-
 gcc/rust/resolve/rust-ast-resolve-type.h      |   8 +-
 gcc/rust/resolve/rust-ast-verify-assignee.h   |   2 +-
 gcc/rust/typecheck/rust-hir-const-fold.h      |   4 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.h |  19 +-
 gcc/rust/typecheck/rust-hir-type-check-type.h |   2 +-
 gcc/rust/typecheck/rust-hir-type-check.cc     |  11 +-
 gcc/rust/typecheck/rust-tyty.cc               |  14 +-
 gcc/rust/util/rust-hir-map.cc                 |   4 +-
 33 files changed, 393 insertions(+), 548 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index e376488de8c..2bfaeb1d364 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -816,9 +816,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
@@ -885,9 +883,7 @@ public:
 
   virtual ~Expr () {}
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   // HACK: strictly not needed, but faster than full downcast clone
   virtual bool is_expr_without_block () const = 0;
@@ -966,8 +962,7 @@ public:
 
   std::string as_string () const override { return ident; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   Identifier get_ident () const { return ident; }
 
@@ -1026,9 +1021,7 @@ public:
   virtual void mark_for_strip () {}
   virtual bool is_marked_for_strip () const { return false; }
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   virtual NodeId get_node_id () const { return node_id; }
 
@@ -1071,7 +1064,7 @@ public:
   virtual void mark_for_strip () {}
   virtual bool is_marked_for_strip () const { return false; }
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () const { return node_id; }
 
@@ -1128,7 +1121,7 @@ public:
 
   NodeId get_node_id () const { return node_id; }
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
 protected:
   // Clone function implementation as pure virtual method
@@ -1185,9 +1178,7 @@ public:
 
   LifetimeType get_lifetime_type () { return lifetime_type; }
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   std::string get_lifetime_name () const { return lifetime_name; }
 
@@ -1217,7 +1208,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () { return node_id; }
 
@@ -1270,9 +1261,7 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1342,7 +1331,7 @@ public:
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 };
 
 // Abstract base class for items used in a trait impl
@@ -1517,9 +1506,7 @@ public:
   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
   std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   MacroInvocationSemi *clone_macro_invocation_semi_impl () const
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 4bb35570676..88e45fef330 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -65,8 +65,7 @@ public:
     return std::unique_ptr<LiteralExpr> (clone_literal_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   Literal get_literal () const { return literal; }
 
@@ -243,8 +242,7 @@ protected:
   OperatorExpr &operator= (OperatorExpr &&other) = default;
 
 public:
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   // Invalid if expr is null, so base stripping on that.
   void mark_for_strip () override { main_or_left_expr = nullptr; }
@@ -895,8 +893,7 @@ public:
   GroupedExpr (GroupedExpr &&other) = default;
   GroupedExpr &operator= (GroupedExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1139,8 +1136,7 @@ public:
   ArrayExpr (ArrayExpr &&other) = default;
   ArrayExpr &operator= (ArrayExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1223,8 +1219,7 @@ public:
   ArrayIndexExpr (ArrayIndexExpr &&other) = default;
   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1337,8 +1332,7 @@ public:
   /* Note: syntactically, can disambiguate single-element tuple from parens with
    * comma, i.e. (0,) rather than (0) */
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1422,8 +1416,7 @@ public:
   TupleIndexExpr (TupleIndexExpr &&other) = default;
   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1512,8 +1505,7 @@ public:
       inner_attrs (std::move (inner_attribs)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1600,7 +1592,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   NodeId get_node_id () const { return node_id; }
 
@@ -1628,8 +1620,7 @@ public:
 
   std::string as_string () const override { return field_name; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1703,8 +1694,7 @@ public:
 
   std::string get_field_name () const { return field_name; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1734,8 +1724,7 @@ public:
 
   TupleIndex get_index () const { return index; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -1913,8 +1902,7 @@ public:
   StructExprTuple (StructExprTuple &&other) = default;
   StructExprTuple &operator= (StructExprTuple &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1950,8 +1938,7 @@ public:
       locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2022,7 +2009,7 @@ public:
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
 protected:
   // Clone function implementation as pure virtual method
@@ -2044,8 +2031,7 @@ public:
 
   std::string as_string () const override { return field_name; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2113,8 +2099,7 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2144,8 +2129,7 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2199,8 +2183,7 @@ public:
   EnumExprStruct (EnumExprStruct &&other) = default;
   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2263,8 +2246,7 @@ public:
   EnumExprTuple (EnumExprTuple &&other) = default;
   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2302,8 +2284,7 @@ public:
       locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2381,8 +2362,7 @@ public:
   // Returns whether function call has parameters.
   bool has_params () const { return !params.empty (); }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2491,8 +2471,7 @@ public:
   MethodCallExpr (MethodCallExpr &&other) = default;
   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2594,8 +2573,7 @@ public:
   FieldAccessExpr (FieldAccessExpr &&other) = default;
   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2733,8 +2711,7 @@ protected:
 public:
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   // TODO: this mutable getter seems really dodgy. Think up better way.
   const std::vector<ClosureParam> &get_params () const { return params; }
@@ -2898,8 +2875,7 @@ public:
     return std::unique_ptr<BlockExpr> (clone_block_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3075,8 +3051,7 @@ public:
       locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3165,8 +3140,7 @@ public:
   BreakExpr (BreakExpr &&other) = default;
   BreakExpr &operator= (BreakExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3210,8 +3184,7 @@ protected:
   RangeExpr (Location locus) : locus (locus) {}
 
 public:
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   // should never be called - error if called
   void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
@@ -3657,8 +3630,7 @@ public:
   ReturnExpr (ReturnExpr &&other) = default;
   ReturnExpr &operator= (ReturnExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3740,8 +3712,7 @@ public:
   UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3862,8 +3833,7 @@ public:
 
   LoopLabel &get_loop_label () { return loop_label; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   // Invalid if loop block is null, so base stripping on that.
   void mark_for_strip () override { loop_block = nullptr; }
@@ -4187,8 +4157,7 @@ public:
    * vector of else ifs - i.e. not like a switch statement. TODO - is this a
    * better approach? or does it not parse correctly and have downsides? */
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -4430,8 +4399,7 @@ public:
     return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5049,8 +5017,7 @@ public:
   MatchExpr (MatchExpr &&other) = default;
   MatchExpr &operator= (MatchExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5136,8 +5103,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -5218,8 +5184,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index b996e173d6c..dcfc3d1d6b4 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -130,9 +130,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -889,9 +887,7 @@ public:
 
   NodeId get_node_id () const { return node_id; }
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object
@@ -1080,7 +1076,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   // Invalid if name is empty, so base stripping on that.
   void mark_for_strip () override { module_name = ""; }
@@ -1127,7 +1123,7 @@ public:
       as_clause_name (std::move (as_clause_name)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1399,7 +1395,7 @@ public:
   UseDeclaration (UseDeclaration &&other) = default;
   UseDeclaration &operator= (UseDeclaration &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1536,9 +1532,7 @@ public:
   Function (Function &&other) = default;
   Function &operator= (Function &&other) = default;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1687,7 +1681,7 @@ public:
   TypeAlias (TypeAlias &&other) = default;
   TypeAlias &operator= (TypeAlias &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1760,9 +1754,7 @@ public:
   // Returns whether struct has a where clause.
   bool has_where_clause () const { return !where_clause.is_empty (); }
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const final { return get_locus (); };
+  Location get_locus () const override final { return locus; }
 
   // Invalid if name is empty, so base stripping on that.
   void mark_for_strip () override { struct_name = ""; }
@@ -2378,7 +2370,7 @@ public:
   Enum (Enum &&other) = default;
   Enum &operator= (Enum &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2482,7 +2474,7 @@ public:
   Union (Union &&other) = default;
   Union &operator= (Union &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2592,9 +2584,7 @@ public:
    * as identifier) constant. */
   bool is_unnamed () const { return identifier == "_"; }
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -2706,7 +2696,7 @@ public:
   StaticItem (StaticItem &&other) = default;
   StaticItem &operator= (StaticItem &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3497,7 +3487,7 @@ public:
   Trait (Trait &&other) = default;
   Trait &operator= (Trait &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -3585,7 +3575,7 @@ public:
   // Returns whether impl has inner attributes.
   bool has_inner_attrs () const { return !inner_attrs.empty (); }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   // Invalid if trait type is null, so base stripping on that.
   void mark_for_strip () override { trait_type = nullptr; }
@@ -3861,7 +3851,7 @@ public:
 
   virtual std::string as_string () const;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   virtual void accept_vis (ASTVisitor &vis) = 0;
 
@@ -4350,7 +4340,7 @@ public:
   ExternBlock (ExternBlock &&other) = default;
   ExternBlock &operator= (ExternBlock &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 51220e47003..0fb16d61fe2 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -345,6 +345,8 @@ public:
   std::vector<MacroRule> &get_macro_rules () { return rules; }
   const std::vector<MacroRule> &get_macro_rules () const { return rules; }
 
+  Location get_locus () const override final { return locus; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
@@ -373,8 +375,7 @@ public:
       invoc_data (std::move (invoc_data)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 74ea79528af..c042a8f1ff1 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -357,8 +357,7 @@ public:
     return convert_to_simple_path (has_opening_scope_resolution);
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -740,8 +739,7 @@ public:
   // Creates a trait bound with a clone of this type path as its only element.
   TraitBound *to_trait_bound (bool in_parens) const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -885,8 +883,7 @@ public:
 				      {}, Location ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1023,8 +1020,7 @@ public:
     return segments;
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 };
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 049aaf00448..7fd1fa50aa4 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -51,8 +51,7 @@ public:
       has_minus (has_minus), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -134,8 +133,7 @@ public:
   IdentifierPattern (IdentifierPattern &&other) = default;
   IdentifierPattern &operator= (IdentifierPattern &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -170,8 +168,7 @@ public:
 
   WildcardPattern (Location locus) : locus (locus) {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -347,8 +344,7 @@ public:
   RangePattern (RangePattern &&other) = default;
   RangePattern &operator= (RangePattern &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -412,8 +408,7 @@ public:
   ReferencePattern (ReferencePattern &&other) = default;
   ReferencePattern &operator= (ReferencePattern &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -806,7 +801,6 @@ public:
   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
 
   Location get_locus () const { return path.get_locus (); }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1028,7 +1022,6 @@ public:
   TupleStructPattern &operator= (TupleStructPattern &&other) = default;
 
   Location get_locus () const { return path.get_locus (); }
-  Location get_locus_slow () const final override { return get_locus (); }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1280,8 +1273,7 @@ public:
     return *this;
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1336,8 +1328,7 @@ public:
   GroupedPattern (GroupedPattern &&other) = default;
   GroupedPattern &operator= (GroupedPattern &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -1394,8 +1385,7 @@ public:
   SlicePattern (SlicePattern &&other) = default;
   SlicePattern &operator= (SlicePattern &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 61854a07cef..4f7399ef6ab 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -38,9 +38,7 @@ public:
 
   EmptyStmt (Location locus) : locus (locus) {}
 
-  Location get_locus_slow () const final override { return get_locus (); }
-
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -137,9 +135,7 @@ public:
   LetStmt (LetStmt &&other) = default;
   LetStmt &operator= (LetStmt &&other) = default;
 
-  Location get_locus_slow () const final override { return get_locus (); }
-
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -188,9 +184,7 @@ class ExprStmt : public Stmt
   Location locus;
 
 public:
-  Location get_locus_slow () const final override { return get_locus (); }
-
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
 protected:
   ExprStmt (Location locus) : locus (locus) {}
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index b658a532b98..fd695649d7b 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -68,9 +68,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -144,8 +142,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -214,8 +211,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -283,8 +279,7 @@ public:
     return type_in_parens->to_trait_bound (true);
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -317,8 +312,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -363,8 +357,7 @@ public:
     return new TraitBound (trait_bound);
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -419,8 +412,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -460,8 +452,7 @@ public:
 
   std::string as_string () const override { return "! (never type)"; }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 };
@@ -513,8 +504,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -581,8 +571,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -643,8 +632,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -704,8 +692,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
@@ -745,8 +732,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 };
@@ -923,8 +909,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const final override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (ASTVisitor &vis) override;
 
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 80cdc5eaeb4..ac33ccd247d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -611,7 +611,7 @@ public:
     if (!ctx->get_tyctx ()->lookup_type (
 	  expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
       {
-	rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		       "unresolved type for receiver");
 	return;
       }
@@ -772,7 +772,7 @@ public:
 
 	Bvariable *loop_result_holder = ctx->peek_loop_context ();
 	Bexpression *result_reference = ctx->get_backend ()->var_expression (
-	  loop_result_holder, expr.get_expr ()->get_locus_slow ());
+	  loop_result_holder, expr.get_expr ()->get_locus ());
 
 	Bstatement *assignment = ctx->get_backend ()->assignment_statement (
 	  fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index baaccf06c10..0a65b155e1d 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -352,7 +352,7 @@ CompileBlock::visit (HIR::BlockExpr &expr)
 	    {
 	      Bexpression *result_reference
 		= ctx->get_backend ()->var_expression (
-		  result, expr.get_final_expr ()->get_locus_slow ());
+		  result, expr.get_final_expr ()->get_locus ());
 
 	      Bstatement *assignment
 		= ctx->get_backend ()->assignment_statement (fnctx.fndecl,
@@ -490,7 +490,7 @@ HIRCompileBase::compile_function_body (
 
 	      auto ret = ctx->get_backend ()->return_statement (
 		fndecl, retstmts,
-		function_body->get_final_expr ()->get_locus_slow ());
+		function_body->get_final_expr ()->get_locus ());
 	      ctx->add_statement (ret);
 	    }
 	  else
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 4998dc8441f..407992d828f 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -49,7 +49,7 @@ public:
 	auto &type = field.get_field_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// if nothing else happens, increment
@@ -75,7 +75,7 @@ public:
 	auto &type = field.get_field_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// if nothing else happens, increment
@@ -101,13 +101,13 @@ public:
 	auto &pattern = param.get_pattern ();
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment
@@ -124,7 +124,7 @@ public:
       {
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -134,7 +134,7 @@ public:
 	auto &type = binding.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -144,8 +144,7 @@ public:
     auto &type = path_type.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     if (path_type.has_as_clause ())
       {
@@ -174,7 +173,7 @@ public:
 	auto &pattern = param.get_pattern ();
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 
 	if (param.has_type_given ())
@@ -182,7 +181,7 @@ public:
 	    auto &type = param.get_type ();
 	    type->accept_vis (*this);
 	    if (type->is_marked_for_strip ())
-	      rust_error_at (type->get_locus_slow (),
+	      rust_error_at (type->get_locus (),
 			     "cannot strip type in this position");
 	  }
 
@@ -198,7 +197,7 @@ public:
 	auto &type = self_param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
     /* TODO: maybe check for invariants being violated - e.g. both type and
@@ -227,7 +226,7 @@ public:
 	auto &return_type = decl.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -255,7 +254,7 @@ public:
 	auto &return_type = decl.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -363,7 +362,7 @@ public:
       {
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -372,7 +371,7 @@ public:
 	auto &return_type = type_path_function.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -447,7 +446,7 @@ public:
     auto &borrowed_expr = expr.get_borrowed_expr ();
     borrowed_expr->accept_vis (*this);
     if (borrowed_expr->is_marked_for_strip ())
-      rust_error_at (borrowed_expr->get_locus_slow (),
+      rust_error_at (borrowed_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -467,7 +466,7 @@ public:
     auto &dereferenced_expr = expr.get_dereferenced_expr ();
     dereferenced_expr->accept_vis (*this);
     if (dereferenced_expr->is_marked_for_strip ())
-      rust_error_at (dereferenced_expr->get_locus_slow (),
+      rust_error_at (dereferenced_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -487,7 +486,7 @@ public:
     auto &propagating_expr = expr.get_propagating_expr ();
     propagating_expr->accept_vis (*this);
     if (propagating_expr->is_marked_for_strip ())
-      rust_error_at (propagating_expr->get_locus_slow (),
+      rust_error_at (propagating_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -507,7 +506,7 @@ public:
     auto &negated_expr = expr.get_negated_expr ();
     negated_expr->accept_vis (*this);
     if (negated_expr->is_marked_for_strip ())
-      rust_error_at (negated_expr->get_locus_slow (),
+      rust_error_at (negated_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -525,12 +524,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -548,12 +547,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -571,12 +570,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -592,7 +591,7 @@ public:
 
     // ensure that they are not marked for strip
     if (casted_expr->is_marked_for_strip ())
-      rust_error_at (casted_expr->get_locus_slow (),
+      rust_error_at (casted_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed before cast exprs");
 
@@ -600,8 +599,7 @@ public:
     auto &type = expr.get_type_to_cast_to ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::AssignmentExpr &expr) override
   {
@@ -617,12 +615,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -640,12 +638,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_left_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_left_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_left_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before binary op exprs");
     if (expr.get_right_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_right_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_right_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -674,7 +672,7 @@ public:
     auto &inner_expr = expr.get_expr_in_parens ();
     inner_expr->accept_vis (*this);
     if (inner_expr->is_marked_for_strip ())
-      rust_error_at (inner_expr->get_locus_slow (),
+      rust_error_at (inner_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -695,14 +693,14 @@ public:
     auto &copied_expr = elems.get_elem_to_copy ();
     copied_expr->accept_vis (*this);
     if (copied_expr->is_marked_for_strip ())
-      rust_error_at (copied_expr->get_locus_slow (),
+      rust_error_at (copied_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
     auto &copy_count = elems.get_num_copies ();
     copy_count->accept_vis (*this);
     if (copy_count->is_marked_for_strip ())
-      rust_error_at (copy_count->get_locus_slow (),
+      rust_error_at (copy_count->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -748,14 +746,14 @@ public:
     auto &array_expr = expr.get_array_expr ();
     array_expr->accept_vis (*this);
     if (array_expr->is_marked_for_strip ())
-      rust_error_at (array_expr->get_locus_slow (),
+      rust_error_at (array_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
     auto &index_expr = expr.get_index_expr ();
     index_expr->accept_vis (*this);
     if (index_expr->is_marked_for_strip ())
-      rust_error_at (index_expr->get_locus_slow (),
+      rust_error_at (index_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -801,7 +799,7 @@ public:
     auto &tuple_expr = expr.get_tuple_expr ();
     tuple_expr->accept_vis (*this);
     if (tuple_expr->is_marked_for_strip ())
-      rust_error_at (tuple_expr->get_locus_slow (),
+      rust_error_at (tuple_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -842,7 +840,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -853,7 +851,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -900,7 +898,7 @@ public:
 	auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
 	base_struct_expr->accept_vis (*this);
 	if (base_struct_expr->is_marked_for_strip ())
-	  rust_error_at (base_struct_expr->get_locus_slow (),
+	  rust_error_at (base_struct_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -937,7 +935,7 @@ public:
     auto &base_struct_expr = expr.get_struct_base ().get_base_struct ();
     base_struct_expr->accept_vis (*this);
     if (base_struct_expr->is_marked_for_strip ())
-      rust_error_at (base_struct_expr->get_locus_slow (),
+      rust_error_at (base_struct_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -999,7 +997,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1010,7 +1008,7 @@ public:
     auto &value = field.get_value ();
     value->accept_vis (*this);
     if (value->is_marked_for_strip ())
-      rust_error_at (value->get_locus_slow (),
+      rust_error_at (value->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1093,7 +1091,7 @@ public:
     auto &function = expr.get_function_expr ();
     function->accept_vis (*this);
     if (function->is_marked_for_strip ())
-      rust_error_at (function->get_locus_slow (),
+      rust_error_at (function->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1117,7 +1115,7 @@ public:
     auto &receiver = expr.get_receiver_expr ();
     receiver->accept_vis (*this);
     if (receiver->is_marked_for_strip ())
-      rust_error_at (receiver->get_locus_slow (),
+      rust_error_at (receiver->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1145,7 +1143,7 @@ public:
     auto &receiver = expr.get_receiver_expr ();
     receiver->accept_vis (*this);
     if (receiver->is_marked_for_strip ())
-      rust_error_at (receiver->get_locus_slow (),
+      rust_error_at (receiver->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1167,7 +1165,7 @@ public:
     auto &definition_expr = expr.get_definition_expr ();
     definition_expr->accept_vis (*this);
     if (definition_expr->is_marked_for_strip ())
-      rust_error_at (definition_expr->get_locus_slow (),
+      rust_error_at (definition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1222,14 +1220,13 @@ public:
     auto &type = expr.get_return_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     // can't strip expression itself, but can strip sub-expressions
     auto &definition_block = expr.get_definition_block ();
     definition_block->accept_vis (*this);
     if (definition_block->is_marked_for_strip ())
-      rust_error_at (definition_block->get_locus_slow (),
+      rust_error_at (definition_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1263,7 +1260,7 @@ public:
 	break_expr->accept_vis (*this);
 
 	if (break_expr->is_marked_for_strip ())
-	  rust_error_at (break_expr->get_locus_slow (),
+	  rust_error_at (break_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -1282,12 +1279,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_from_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_from_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before range exprs");
     if (expr.get_to_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_to_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1303,7 +1300,7 @@ public:
     from_expr->accept_vis (*this);
 
     if (from_expr->is_marked_for_strip ())
-      rust_error_at (from_expr->get_locus_slow (),
+      rust_error_at (from_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed before range exprs");
   }
@@ -1319,7 +1316,7 @@ public:
     to_expr->accept_vis (*this);
 
     if (to_expr->is_marked_for_strip ())
-      rust_error_at (to_expr->get_locus_slow (),
+      rust_error_at (to_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1341,12 +1338,12 @@ public:
 
     // ensure that they are not marked for strip
     if (expr.get_from_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_from_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_from_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes are never allowed "
 		     "before range exprs");
     if (expr.get_to_expr ()->is_marked_for_strip ())
-      rust_error_at (expr.get_to_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_to_expr ()->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1362,7 +1359,7 @@ public:
     to_expr->accept_vis (*this);
 
     if (to_expr->is_marked_for_strip ())
-      rust_error_at (to_expr->get_locus_slow (),
+      rust_error_at (to_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1386,7 +1383,7 @@ public:
 	returned_expr->accept_vis (*this);
 
 	if (returned_expr->is_marked_for_strip ())
-	  rust_error_at (returned_expr->get_locus_slow (),
+	  rust_error_at (returned_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -1410,7 +1407,7 @@ public:
     auto &block_expr = expr.get_block_expr ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1428,7 +1425,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1446,7 +1443,7 @@ public:
     auto &predicate_expr = expr.get_predicate_expr ();
     predicate_expr->accept_vis (*this);
     if (predicate_expr->is_marked_for_strip ())
-      rust_error_at (predicate_expr->get_locus_slow (),
+      rust_error_at (predicate_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1454,7 +1451,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1472,7 +1469,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1480,7 +1477,7 @@ public:
     auto &scrutinee_expr = expr.get_scrutinee_expr ();
     scrutinee_expr->accept_vis (*this);
     if (scrutinee_expr->is_marked_for_strip ())
-      rust_error_at (scrutinee_expr->get_locus_slow (),
+      rust_error_at (scrutinee_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1488,7 +1485,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1506,14 +1503,14 @@ public:
     auto &pattern = expr.get_pattern ();
     pattern->accept_vis (*this);
     if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus_slow (),
+      rust_error_at (pattern->get_locus (),
 		     "cannot strip pattern in this position");
 
     // can't strip scrutinee expr itself, but can strip sub-expressions
     auto &iterator_expr = expr.get_iterator_expr ();
     iterator_expr->accept_vis (*this);
     if (iterator_expr->is_marked_for_strip ())
-      rust_error_at (iterator_expr->get_locus_slow (),
+      rust_error_at (iterator_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1521,7 +1518,7 @@ public:
     auto &loop_block = expr.get_loop_block ();
     loop_block->accept_vis (*this);
     if (loop_block->is_marked_for_strip ())
-      rust_error_at (loop_block->get_locus_slow (),
+      rust_error_at (loop_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1542,7 +1539,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1550,7 +1547,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1568,7 +1565,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1576,7 +1573,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1584,7 +1581,7 @@ public:
     auto &else_block = expr.get_else_block ();
     else_block->accept_vis (*this);
     if (else_block->is_marked_for_strip ())
-      rust_error_at (else_block->get_locus_slow (),
+      rust_error_at (else_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1602,7 +1599,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1610,7 +1607,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1618,7 +1615,7 @@ public:
     auto &conseq_if_expr = expr.get_conseq_if_expr ();
     conseq_if_expr->accept_vis (*this);
     if (conseq_if_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_expr->get_locus_slow (),
+      rust_error_at (conseq_if_expr->get_locus (),
 		     "cannot strip consequent if expression in this "
 		     "position - outer attributes not allowed");
   }
@@ -1636,7 +1633,7 @@ public:
     auto &condition_expr = expr.get_condition_expr ();
     condition_expr->accept_vis (*this);
     if (condition_expr->is_marked_for_strip ())
-      rust_error_at (condition_expr->get_locus_slow (),
+      rust_error_at (condition_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1644,7 +1641,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1652,7 +1649,7 @@ public:
     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
     conseq_if_let_expr->accept_vis (*this);
     if (conseq_if_let_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_let_expr->get_locus_slow (),
+      rust_error_at (conseq_if_let_expr->get_locus (),
 		     "cannot strip consequent if let expression in this "
 		     "position - outer attributes not "
 		     "allowed");
@@ -1671,7 +1668,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1679,7 +1676,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1687,7 +1684,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1705,7 +1702,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1713,7 +1710,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1721,7 +1718,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1729,7 +1726,7 @@ public:
     auto &else_block = expr.get_else_block ();
     else_block->accept_vis (*this);
     if (else_block->is_marked_for_strip ())
-      rust_error_at (else_block->get_locus_slow (),
+      rust_error_at (else_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1747,7 +1744,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1755,7 +1752,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1763,7 +1760,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1771,7 +1768,7 @@ public:
     auto &conseq_if_expr = expr.get_conseq_if_expr ();
     conseq_if_expr->accept_vis (*this);
     if (conseq_if_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_expr->get_locus_slow (),
+      rust_error_at (conseq_if_expr->get_locus (),
 		     "cannot strip consequent if expression in this "
 		     "position - outer attributes not allowed");
   }
@@ -1789,7 +1786,7 @@ public:
       {
 	pattern->accept_vis (*this);
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
       }
 
@@ -1797,7 +1794,7 @@ public:
     auto &value_expr = expr.get_value_expr ();
     value_expr->accept_vis (*this);
     if (value_expr->is_marked_for_strip ())
-      rust_error_at (value_expr->get_locus_slow (),
+      rust_error_at (value_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1805,7 +1802,7 @@ public:
     auto &if_block = expr.get_if_block ();
     if_block->accept_vis (*this);
     if (if_block->is_marked_for_strip ())
-      rust_error_at (if_block->get_locus_slow (),
+      rust_error_at (if_block->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1813,7 +1810,7 @@ public:
     auto &conseq_if_let_expr = expr.get_conseq_if_let_expr ();
     conseq_if_let_expr->accept_vis (*this);
     if (conseq_if_let_expr->is_marked_for_strip ())
-      rust_error_at (conseq_if_let_expr->get_locus_slow (),
+      rust_error_at (conseq_if_let_expr->get_locus (),
 		     "cannot strip consequent if let expression in this "
 		     "position - outer attributes not "
 		     "allowed");
@@ -1840,7 +1837,7 @@ public:
     auto &scrutinee_expr = expr.get_scrutinee_expr ();
     scrutinee_expr->accept_vis (*this);
     if (scrutinee_expr->is_marked_for_strip ())
-      rust_error_at (scrutinee_expr->get_locus_slow (),
+      rust_error_at (scrutinee_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
 
@@ -1864,7 +1861,7 @@ public:
 	  {
 	    pattern->accept_vis (*this);
 	    if (pattern->is_marked_for_strip ())
-	      rust_error_at (pattern->get_locus_slow (),
+	      rust_error_at (pattern->get_locus (),
 			     "cannot strip pattern in this position");
 	  }
 
@@ -1877,7 +1874,7 @@ public:
 	    auto &guard_expr = match_arm.get_guard_expr ();
 	    guard_expr->accept_vis (*this);
 	    if (guard_expr->is_marked_for_strip ())
-	      rust_error_at (guard_expr->get_locus_slow (),
+	      rust_error_at (guard_expr->get_locus (),
 			     "cannot strip expression in this position - outer "
 			     "attributes not allowed");
 	  }
@@ -1886,7 +1883,7 @@ public:
 	auto &case_expr = match_case.get_expr ();
 	case_expr->accept_vis (*this);
 	if (case_expr->is_marked_for_strip ())
-	  rust_error_at (case_expr->get_locus_slow (),
+	  rust_error_at (case_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
 
@@ -1909,7 +1906,7 @@ public:
     auto &awaited_expr = expr.get_awaited_expr ();
     awaited_expr->accept_vis (*this);
     if (awaited_expr->is_marked_for_strip ())
-      rust_error_at (awaited_expr->get_locus_slow (),
+      rust_error_at (awaited_expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1927,7 +1924,7 @@ public:
     auto &block_expr = expr.get_block_expr ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -1948,7 +1945,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -1963,8 +1960,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     // don't strip directly, only components of bounds
     for (auto &bound : item.get_type_param_bounds ())
@@ -1998,7 +1994,7 @@ public:
 	auto &return_type = method.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2011,7 +2007,7 @@ public:
     auto &block_expr = method.get_definition ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2099,7 +2095,7 @@ public:
 	auto &return_type = function.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2112,7 +2108,7 @@ public:
     auto &block_expr = function.get_definition ();
     block_expr->accept_vis (*this);
     if (block_expr->is_marked_for_strip ())
-      rust_error_at (block_expr->get_locus_slow (),
+      rust_error_at (block_expr->get_locus (),
 		     "cannot strip block expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2136,8 +2132,7 @@ public:
     auto &type = type_alias.get_type_aliased ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::StructStruct &struct_item) override
   {
@@ -2235,7 +2230,7 @@ public:
     auto &expr = item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2295,8 +2290,7 @@ public:
     auto &type = const_item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2304,7 +2298,7 @@ public:
     auto &expr = const_item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2322,8 +2316,7 @@ public:
     auto &type = static_item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2331,7 +2324,7 @@ public:
     auto &expr = static_item.get_expr ();
     expr->accept_vis (*this);
     if (expr->is_marked_for_strip ())
-      rust_error_at (expr->get_locus_slow (),
+      rust_error_at (expr->get_locus (),
 		     "cannot strip expression in this position - outer "
 		     "attributes not allowed");
   }
@@ -2355,7 +2348,7 @@ public:
 	auto &block = item.get_definition ();
 	block->accept_vis (*this);
 	if (block->is_marked_for_strip ())
-	  rust_error_at (block->get_locus_slow (),
+	  rust_error_at (block->get_locus (),
 			 "cannot strip block expression in this "
 			 "position - outer attributes not allowed");
       }
@@ -2380,7 +2373,7 @@ public:
 	auto &block = item.get_definition ();
 	block->accept_vis (*this);
 	if (block->is_marked_for_strip ())
-	  rust_error_at (block->get_locus_slow (),
+	  rust_error_at (block->get_locus (),
 			 "cannot strip block expression in this "
 			 "position - outer attributes not allowed");
       }
@@ -2399,8 +2392,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     /* strip any internal sub-expressions - expression itself isn't
      * allowed to have external attributes in this position so can't be
@@ -2410,7 +2402,7 @@ public:
 	auto &expr = item.get_expr ();
 	expr->accept_vis (*this);
 	if (expr->is_marked_for_strip ())
-	  rust_error_at (expr->get_locus_slow (),
+	  rust_error_at (expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -2492,8 +2484,7 @@ public:
     auto &type = impl.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     if (impl.has_where_clause ())
       expand_where_clause (impl.get_where_clause ());
@@ -2526,8 +2517,7 @@ public:
     auto &type = impl.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
 
     auto &trait_path = impl.get_trait_path ();
     visit (trait_path);
@@ -2554,8 +2544,7 @@ public:
     auto &type = item.get_type ();
     type->accept_vis (*this);
     if (type->is_marked_for_strip ())
-      rust_error_at (type->get_locus_slow (),
-		     "cannot strip type in this position");
+      rust_error_at (type->get_locus (), "cannot strip type in this position");
   }
   void visit (AST::ExternalFunctionItem &item) override
   {
@@ -2589,7 +2578,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment if nothing else happens
@@ -2607,7 +2596,7 @@ public:
 	auto &return_type = item.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2686,7 +2675,7 @@ public:
     auto &sub_pattern = pattern.get_pattern_to_bind ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::WildcardPattern &) override
@@ -2724,7 +2713,7 @@ public:
     auto &sub_pattern = pattern.get_referenced_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldTuplePat &field) override
@@ -2741,7 +2730,7 @@ public:
     auto &sub_pattern = field.get_index_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldIdentPat &field) override
@@ -2758,7 +2747,7 @@ public:
     auto &sub_pattern = field.get_ident_pattern ();
     sub_pattern->accept_vis (*this);
     if (sub_pattern->is_marked_for_strip ())
-      rust_error_at (sub_pattern->get_locus_slow (),
+      rust_error_at (sub_pattern->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::StructPatternFieldIdent &field) override
@@ -2805,7 +2794,7 @@ public:
 	pattern->accept_vis (*this);
 
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2818,7 +2807,7 @@ public:
 	lower_pattern->accept_vis (*this);
 
 	if (lower_pattern->is_marked_for_strip ())
-	  rust_error_at (lower_pattern->get_locus_slow (),
+	  rust_error_at (lower_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2827,7 +2816,7 @@ public:
 	upper_pattern->accept_vis (*this);
 
 	if (upper_pattern->is_marked_for_strip ())
-	  rust_error_at (upper_pattern->get_locus_slow (),
+	  rust_error_at (upper_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2851,7 +2840,7 @@ public:
 	pattern->accept_vis (*this);
 
 	if (pattern->is_marked_for_strip ())
-	  rust_error_at (pattern->get_locus_slow (),
+	  rust_error_at (pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2864,7 +2853,7 @@ public:
 	lower_pattern->accept_vis (*this);
 
 	if (lower_pattern->is_marked_for_strip ())
-	  rust_error_at (lower_pattern->get_locus_slow (),
+	  rust_error_at (lower_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2873,7 +2862,7 @@ public:
 	upper_pattern->accept_vis (*this);
 
 	if (upper_pattern->is_marked_for_strip ())
-	  rust_error_at (upper_pattern->get_locus_slow (),
+	  rust_error_at (upper_pattern->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2891,7 +2880,7 @@ public:
     pattern_in_parens->accept_vis (*this);
 
     if (pattern_in_parens->is_marked_for_strip ())
-      rust_error_at (pattern_in_parens->get_locus_slow (),
+      rust_error_at (pattern_in_parens->get_locus (),
 		     "cannot strip pattern in this position");
   }
   void visit (AST::SlicePattern &pattern) override
@@ -2902,7 +2891,7 @@ public:
 	item->accept_vis (*this);
 
 	if (item->is_marked_for_strip ())
-	  rust_error_at (item->get_locus_slow (),
+	  rust_error_at (item->get_locus (),
 			 "cannot strip pattern in this position");
 	// TODO: quit stripping now? or keep going?
       }
@@ -2926,7 +2915,7 @@ public:
     auto &pattern = stmt.get_pattern ();
     pattern->accept_vis (*this);
     if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus_slow (),
+      rust_error_at (pattern->get_locus (),
 		     "cannot strip pattern in this position");
 
     // similar for type
@@ -2935,7 +2924,7 @@ public:
 	auto &type = stmt.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
       }
 
@@ -2947,7 +2936,7 @@ public:
 	auto &init_expr = stmt.get_init_expr ();
 	init_expr->accept_vis (*this);
 	if (init_expr->is_marked_for_strip ())
-	  rust_error_at (init_expr->get_locus_slow (),
+	  rust_error_at (init_expr->get_locus (),
 			 "cannot strip expression in this position - outer "
 			 "attributes not allowed");
       }
@@ -3016,7 +3005,7 @@ public:
     auto &inner_type = type.get_type_in_parens ();
     inner_type->accept_vis (*this);
     if (inner_type->is_marked_for_strip ())
-      rust_error_at (inner_type->get_locus_slow (),
+      rust_error_at (inner_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ImplTraitTypeOneBound &type) override
@@ -3037,7 +3026,7 @@ public:
       {
 	elem_type->accept_vis (*this);
 	if (elem_type->is_marked_for_strip ())
-	  rust_error_at (elem_type->get_locus_slow (),
+	  rust_error_at (elem_type->get_locus (),
 			 "cannot strip type in this position");
       }
   }
@@ -3051,7 +3040,7 @@ public:
     auto &pointed_type = type.get_type_pointed_to ();
     pointed_type->accept_vis (*this);
     if (pointed_type->is_marked_for_strip ())
-      rust_error_at (pointed_type->get_locus_slow (),
+      rust_error_at (pointed_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ReferenceType &type) override
@@ -3060,7 +3049,7 @@ public:
     auto &referenced_type = type.get_type_referenced ();
     referenced_type->accept_vis (*this);
     if (referenced_type->is_marked_for_strip ())
-      rust_error_at (referenced_type->get_locus_slow (),
+      rust_error_at (referenced_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::ArrayType &type) override
@@ -3069,14 +3058,14 @@ public:
     auto &base_type = type.get_elem_type ();
     base_type->accept_vis (*this);
     if (base_type->is_marked_for_strip ())
-      rust_error_at (base_type->get_locus_slow (),
+      rust_error_at (base_type->get_locus (),
 		     "cannot strip type in this position");
 
     // same for expression
     auto &size_expr = type.get_size_expr ();
     size_expr->accept_vis (*this);
     if (size_expr->is_marked_for_strip ())
-      rust_error_at (size_expr->get_locus_slow (),
+      rust_error_at (size_expr->get_locus (),
 		     "cannot strip expression in this position");
   }
   void visit (AST::SliceType &type) override
@@ -3085,7 +3074,7 @@ public:
     auto &elem_type = type.get_elem_type ();
     elem_type->accept_vis (*this);
     if (elem_type->is_marked_for_strip ())
-      rust_error_at (elem_type->get_locus_slow (),
+      rust_error_at (elem_type->get_locus (),
 		     "cannot strip type in this position");
   }
   void visit (AST::InferredType &) override
@@ -3113,7 +3102,7 @@ public:
 	auto &type = param.get_type ();
 	type->accept_vis (*this);
 	if (type->is_marked_for_strip ())
-	  rust_error_at (type->get_locus_slow (),
+	  rust_error_at (type->get_locus (),
 			 "cannot strip type in this position");
 
 	// increment if nothing else happens
@@ -3128,7 +3117,7 @@ public:
 	auto &return_type = type.get_return_type ();
 	return_type->accept_vis (*this);
 	if (return_type->is_marked_for_strip ())
-	  rust_error_at (return_type->get_locus_slow (),
+	  rust_error_at (return_type->get_locus (),
 			 "cannot strip type in this position");
       }
 
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 3415567c86b..ff4c181d0e2 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -81,7 +81,7 @@ public:
     expr->accept_vis (resolver);
     if (resolver.translated == nullptr)
       {
-	rust_fatal_error (expr->get_locus_slow (), "Failed to lower expr: [%s]",
+	rust_fatal_error (expr->get_locus (), "Failed to lower expr: [%s]",
 			  expr->as_string ().c_str ());
 	return nullptr;
       }
@@ -91,8 +91,7 @@ public:
       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      expr->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), expr->get_locus ());
 
     if (terminated != nullptr)
       *terminated = resolver.terminated;
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index c7f874d1dc9..7efcffaf05b 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -47,7 +47,7 @@ public:
     // this is useful for debugging
     // if (resolver.translated == nullptr)
     //   {
-    //     rust_fatal_error (item->get_locus_slow (), "failed to lower: %s",
+    //     rust_fatal_error (item->get_locus (), "failed to lower: %s",
     //     		  item->as_string ().c_str ());
     //     return nullptr;
     //   }
diff --git a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
index 3b313a78476..e6322dbb514 100644
--- a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h
@@ -41,8 +41,7 @@ public:
       compiler.translated->get_mappings ().get_hirid (), compiler.translated);
     compiler.mappings->insert_location (
       compiler.translated->get_mappings ().get_crate_num (),
-      compiler.translated->get_mappings ().get_hirid (),
-      field->get_locus_slow ());
+      compiler.translated->get_mappings ().get_hirid (), field->get_locus ());
 
     return compiler.translated;
   }
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 9b5ec0a4df7..c16025d137b 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -106,8 +106,7 @@ public:
     rust_assert (resolver.translated != nullptr);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      type->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), type->get_locus ());
 
     return resolver.translated;
   }
@@ -282,8 +281,7 @@ public:
     rust_assert (resolver.translated != nullptr);
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
-      resolver.translated->get_mappings ().get_hirid (),
-      param->get_locus_slow ());
+      resolver.translated->get_mappings ().get_hirid (), param->get_locus ());
     resolver.mappings->insert_hir_generic_param (
       resolver.translated->get_mappings ().get_crate_num (),
       resolver.translated->get_mappings ().get_hirid (), resolver.translated);
@@ -356,7 +354,7 @@ public:
     resolver.mappings->insert_location (
       resolver.translated->get_mappings ().get_crate_num (),
       resolver.translated->get_mappings ().get_hirid (),
-      resolver.translated->get_locus_slow ());
+      resolver.translated->get_locus ());
 
     return resolver.translated;
   }
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index e693799d4b5..d5138fd64ac 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -66,7 +66,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
   bool block_did_terminate = false;
   expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool {
     if (block_did_terminate)
-      rust_warning_at (s->get_locus_slow (), 0, "unreachable statement");
+      rust_warning_at (s->get_locus (), 0, "unreachable statement");
 
     bool terminated = false;
     auto translated_stmt = ASTLoweringStmt::translate (s, &terminated);
@@ -78,7 +78,7 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
   if (expr.has_tail_expr () && block_did_terminate)
     {
       // warning unreachable tail expressions
-      rust_warning_at (expr.get_tail_expr ()->get_locus_slow (), 0,
+      rust_warning_at (expr.get_tail_expr ()->get_locus (), 0,
 		       "unreachable expression");
     }
 
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 8d815c5adc6..bb15d4f9901 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -90,8 +90,7 @@ public:
     return std::unique_ptr<LiteralExpr> (clone_literal_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -163,8 +162,7 @@ protected:
   OperatorExpr &operator= (OperatorExpr &&other) = default;
 
 public:
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   std::unique_ptr<Expr> &get_expr () { return main_or_left_expr; }
 };
@@ -710,8 +708,7 @@ public:
   GroupedExpr (GroupedExpr &&other) = default;
   GroupedExpr &operator= (GroupedExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -915,8 +912,7 @@ public:
   ArrayExpr (ArrayExpr &&other) = default;
   ArrayExpr &operator= (ArrayExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -981,8 +977,7 @@ public:
   ArrayIndexExpr (ArrayIndexExpr &&other) = default;
   ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1060,8 +1055,7 @@ public:
   /* Note: syntactically, can disambiguate single-element tuple from parens with
    * comma, i.e. (0,) rather than (0) */
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1144,8 +1138,7 @@ public:
   TupleIndexExpr (TupleIndexExpr &&other) = default;
   TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1211,8 +1204,7 @@ public:
       inner_attrs (std::move (inner_attribs)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1640,8 +1632,7 @@ public:
   StructExprTuple (StructExprTuple &&other) = default;
   StructExprTuple &operator= (StructExprTuple &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1676,8 +1667,7 @@ public:
       locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1894,8 +1884,7 @@ public:
   EnumExprStruct (EnumExprStruct &&other) = default;
   EnumExprStruct &operator= (EnumExprStruct &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1964,8 +1953,7 @@ public:
   EnumExprTuple (EnumExprTuple &&other) = default;
   EnumExprTuple &operator= (EnumExprTuple &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2005,8 +1993,7 @@ public:
       locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2082,8 +2069,7 @@ public:
   // Returns whether function call has parameters.
   bool has_params () const { return !params.empty (); }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2172,8 +2158,7 @@ public:
   MethodCallExpr (MethodCallExpr &&other) = default;
   MethodCallExpr &operator= (MethodCallExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2257,8 +2242,7 @@ public:
   FieldAccessExpr (FieldAccessExpr &&other) = default;
   FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2361,8 +2345,7 @@ protected:
 public:
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 };
 
 // Represents a non-type-specified closure expression HIR node
@@ -2497,8 +2480,7 @@ public:
     return std::unique_ptr<BlockExpr> (clone_block_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2518,7 +2500,7 @@ public:
     if (statements.size () == 0)
       return get_locus ();
 
-    return statements[statements.size () - 1]->get_locus_slow ();
+    return statements[statements.size () - 1]->get_locus ();
   }
 
   std::unique_ptr<Expr> &get_final_expr () { return expr; }
@@ -2632,8 +2614,7 @@ public:
       label (std::move (label)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2712,8 +2693,7 @@ public:
   BreakExpr (BreakExpr &&other) = default;
   BreakExpr &operator= (BreakExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2746,8 +2726,7 @@ protected:
   {}
 
 public:
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 };
 
 // Range from (inclusive) and to (exclusive) expression HIR node object
@@ -3089,8 +3068,7 @@ public:
   ReturnExpr (ReturnExpr &&other) = default;
   ReturnExpr &operator= (ReturnExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3151,8 +3129,7 @@ public:
   UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
   UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3250,8 +3227,7 @@ protected:
 public:
   bool has_loop_label () const { return !loop_label.is_error (); }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   std::unique_ptr<HIR::BlockExpr> &get_loop_block () { return loop_block; };
 
@@ -3540,8 +3516,7 @@ public:
    * vector of else ifs - i.e. not like a switch statement. TODO - is this a
    * better approach? or does it not parse correctly and have downsides? */
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -3765,8 +3740,7 @@ public:
     return std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ());
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4341,8 +4315,7 @@ public:
   MatchExpr (MatchExpr &&other) = default;
   MatchExpr &operator= (MatchExpr &&other) = default;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4396,8 +4369,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -4450,8 +4422,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 7a05f02067b..99fc91de117 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -104,9 +104,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -704,7 +702,7 @@ public:
    * the module. */
   void add_crate_name (std::vector<std::string> &names) const override;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object
@@ -754,7 +752,7 @@ public:
       as_clause_name (std::move (as_clause_name)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1019,7 +1017,7 @@ public:
   UseDeclaration (UseDeclaration &&other) = default;
   UseDeclaration &operator= (UseDeclaration &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1126,7 +1124,7 @@ public:
   Function (Function &&other) = default;
   Function &operator= (Function &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   Location get_impl_locus () const final { return get_locus (); }
 
@@ -1268,7 +1266,7 @@ public:
   TypeAlias (TypeAlias &&other) = default;
   TypeAlias &operator= (TypeAlias &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   Location get_impl_locus () const final { return get_locus (); }
 
@@ -1340,7 +1338,7 @@ public:
   // Returns whether struct has a where clause.
   bool has_where_clause () const { return !where_clause.is_empty (); }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
   {
@@ -1863,7 +1861,7 @@ public:
   Enum (Enum &&other) = default;
   Enum &operator= (Enum &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -1953,7 +1951,7 @@ public:
 
   Identifier get_identifier () const { return union_name; }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2017,7 +2015,7 @@ public:
   // as identifier) constant.
   bool is_unnamed () const { return identifier == std::string ("_"); }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   Location get_impl_locus () const final { return get_locus (); }
 
@@ -2095,7 +2093,7 @@ public:
   StaticItem (StaticItem &&other) = default;
   StaticItem &operator= (StaticItem &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2534,7 +2532,7 @@ public:
   Trait (Trait &&other) = default;
   Trait &operator= (Trait &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -2642,7 +2640,7 @@ public:
   // Returns whether impl has inner attributes.
   bool has_inner_attrs () const { return !inner_attrs.empty (); }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   std::unique_ptr<Type> &get_type () { return impl_type; };
 
@@ -2998,7 +2996,7 @@ public:
   ExternBlock (ExternBlock &&other) = default;
   ExternBlock &operator= (ExternBlock &&other) = default;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index a8bbbb62ef6..0e3c430edb7 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -315,8 +315,7 @@ public:
     return convert_to_simple_path (has_opening_scope_resolution);
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -791,8 +790,7 @@ public:
       path_type (std::move (qual_path_type)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index 584b0e358cd..b049ea9bd8d 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -37,7 +37,7 @@ public:
     : Stmt (std::move (mappings)), locus (locus)
   {}
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -109,9 +109,7 @@ public:
   LetStmt (LetStmt &&other) = default;
   LetStmt &operator= (LetStmt &&other) = default;
 
-  Location get_locus_slow () const override { return get_locus (); }
-
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -136,7 +134,7 @@ class ExprStmt : public Stmt
   Location locus;
 
 public:
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
 protected:
   ExprStmt (Analysis::NodeMapping mappings, Location locus)
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index 8d75d0285d3..cf33b9dfaee 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -54,7 +54,7 @@ public:
 
   std::string as_string () const override;
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -63,8 +63,6 @@ public:
     return mappings;
   }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   BoundType get_bound_type () const final override { return TRAITBOUND; }
 
   TypePath &get_path () { return type_path; }
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index b8acf1a6e40..b994d063452 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -100,9 +100,7 @@ public:
 
   virtual void accept_vis (HIRVisitor &vis) = 0;
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   virtual bool is_unit_check_needed () const { return false; }
 
@@ -194,9 +192,7 @@ public:
 
   virtual ~Expr () {}
 
-  /* HACK: slow way of getting location from base expression through virtual
-   * methods. */
-  virtual Location get_locus_slow () const { return Location (); }
+  virtual Location get_locus () const = 0;
 
   // HACK: strictly not needed, but faster than full downcast clone
   virtual bool is_expr_without_block () const = 0;
@@ -284,8 +280,7 @@ public:
     return "( " + ident + " (" + get_mappings ().as_string () + "))";
   }
 
-  Location get_locus () const { return locus; }
-  Location get_locus_slow () const override { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
   void accept_vis (HIRVisitor &vis) override;
 
@@ -426,7 +421,7 @@ public:
 
   virtual Analysis::NodeMapping get_mappings () const = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   virtual BoundType get_bound_type () const = 0;
 
@@ -476,15 +471,13 @@ public:
     return lifetime_type;
   }
 
-  Location get_locus () const { return locus; }
+  Location get_locus () const override final { return locus; }
 
   Analysis::NodeMapping get_mappings () const override final
   {
     return mappings;
   }
 
-  Location get_locus_slow () const override final { return get_locus (); }
-
   BoundType get_bound_type () const final override { return LIFETIME; }
 
 protected:
@@ -522,7 +515,7 @@ public:
 
   virtual void accept_vis (HIRVisitor &vis) = 0;
 
-  virtual Location get_locus_slow () const = 0;
+  virtual Location get_locus () const = 0;
 
   Analysis::NodeMapping get_mappings () const { return mappings; }
 
@@ -609,9 +602,7 @@ public:
 
   void accept_vis (HIRVisitor &vis) override;
 
-  Location get_locus () const { return locus; }
-
-  Location get_locus_slow () const override final { return get_locus (); }
+  Location get_locus () const override final { return locus; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
index 87fa3ef2f3e..f383d48377e 100644
--- a/gcc/rust/lint/rust-lint-marklive.cc
+++ b/gcc/rust/lint/rust-lint-marklive.cc
@@ -211,7 +211,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
   if (!tyctx->lookup_type (
 	expr.get_receiver_expr ()->get_mappings ().get_hirid (), &receiver))
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		     "unresolved type for receiver");
     }
   bool ok = receiver->get_kind () == TyTy::TypeKind::ADT;
@@ -223,7 +223,7 @@ MarkLive::visit (HIR::FieldAccessExpr &expr)
   adt->get_field (expr.get_field_name (), &index);
   if (index >= adt->num_fields ())
     {
-      rust_error_at (expr.get_receiver_expr ()->get_locus_slow (),
+      rust_error_at (expr.get_receiver_expr ()->get_locus (),
 		     "cannot access struct %s by index: %ld",
 		     adt->get_name ().c_str (), index);
       return;
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index fa6d409c6dc..8ee9e42f944 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -11431,7 +11431,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_with_block (
     return ExprOrStmt (std::move (expr));
 
   // internal block expr must either have semicolons followed, or evaluate to ()
-  auto locus = expr->get_locus_slow ();
+  auto locus = expr->get_locus ();
   std::unique_ptr<AST::ExprStmtWithBlock> stmt (
     new AST::ExprStmtWithBlock (std::move (expr), locus,
 				tok->get_id () == SEMICOLON));
@@ -12823,7 +12823,7 @@ Parser<ManagedTokenSource>::left_denotation (const_TokenPtr tok,
     {
       // FIXME: allow for outer attributes to be applied
       case QUESTION_MARK: {
-	Location left_locus = left->get_locus_slow ();
+	Location left_locus = left->get_locus ();
 	// error propagation expression - unary postfix
 	return std::unique_ptr<AST::ErrorPropagationExpr> (
 	  new AST::ErrorPropagationExpr (std::move (left),
@@ -13185,7 +13185,7 @@ Parser<ManagedTokenSource>::parse_arithmetic_or_logical_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13206,7 +13206,7 @@ Parser<ManagedTokenSource>::parse_binary_plus_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13227,7 +13227,7 @@ Parser<ManagedTokenSource>::parse_binary_minus_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13249,7 +13249,7 @@ Parser<ManagedTokenSource>::parse_binary_mult_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13271,7 +13271,7 @@ Parser<ManagedTokenSource>::parse_binary_div_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13293,7 +13293,7 @@ Parser<ManagedTokenSource>::parse_binary_mod_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13316,7 +13316,7 @@ Parser<ManagedTokenSource>::parse_bitwise_and_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13339,7 +13339,7 @@ Parser<ManagedTokenSource>::parse_bitwise_or_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13362,7 +13362,7 @@ Parser<ManagedTokenSource>::parse_bitwise_xor_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13384,7 +13384,7 @@ Parser<ManagedTokenSource>::parse_left_shift_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13406,7 +13406,7 @@ Parser<ManagedTokenSource>::parse_right_shift_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ArithmeticOrLogicalExpr> (
     new AST::ArithmeticOrLogicalExpr (std::move (left), std::move (right),
@@ -13458,7 +13458,7 @@ Parser<ManagedTokenSource>::parse_comparison_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right), expr_type,
@@ -13479,7 +13479,7 @@ Parser<ManagedTokenSource>::parse_binary_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13500,7 +13500,7 @@ Parser<ManagedTokenSource>::parse_binary_not_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13521,7 +13521,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_than_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13542,7 +13542,7 @@ Parser<ManagedTokenSource>::parse_binary_less_than_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13563,7 +13563,7 @@ Parser<ManagedTokenSource>::parse_binary_greater_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13584,7 +13584,7 @@ Parser<ManagedTokenSource>::parse_binary_less_equal_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::ComparisonExpr> (
     new AST::ComparisonExpr (std::move (left), std::move (right),
@@ -13605,7 +13605,7 @@ Parser<ManagedTokenSource>::parse_lazy_or_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::LazyBooleanExpr> (
     new AST::LazyBooleanExpr (std::move (left), std::move (right),
@@ -13626,7 +13626,7 @@ Parser<ManagedTokenSource>::parse_lazy_and_expr (
     return nullptr;
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::LazyBooleanExpr> (
     new AST::LazyBooleanExpr (std::move (left), std::move (right),
@@ -13648,7 +13648,7 @@ Parser<ManagedTokenSource>::parse_type_cast_expr (
   // FIXME: how do I get precedence put in here?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = expr_to_cast->get_locus_slow ();
+  Location locus = expr_to_cast->get_locus ();
 
   return std::unique_ptr<AST::TypeCastExpr> (
     new AST::TypeCastExpr (std::move (expr_to_cast), std::move (type), locus));
@@ -13669,7 +13669,7 @@ Parser<ManagedTokenSource>::parse_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::AssignmentExpr> (
     new AST::AssignmentExpr (std::move (left), std::move (right), locus));
@@ -13728,7 +13728,7 @@ Parser<ManagedTokenSource>::parse_compound_assignment_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13750,7 +13750,7 @@ Parser<ManagedTokenSource>::parse_plus_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13772,7 +13772,7 @@ Parser<ManagedTokenSource>::parse_minus_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13795,7 +13795,7 @@ Parser<ManagedTokenSource>::parse_mult_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13818,7 +13818,7 @@ Parser<ManagedTokenSource>::parse_div_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13841,7 +13841,7 @@ Parser<ManagedTokenSource>::parse_mod_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13864,7 +13864,7 @@ Parser<ManagedTokenSource>::parse_and_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13887,7 +13887,7 @@ Parser<ManagedTokenSource>::parse_or_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13910,7 +13910,7 @@ Parser<ManagedTokenSource>::parse_xor_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13933,7 +13933,7 @@ Parser<ManagedTokenSource>::parse_left_shift_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13956,7 +13956,7 @@ Parser<ManagedTokenSource>::parse_right_shift_assig_expr (
   // FIXME: ensure right-associativity for this - 'LBP - 1' may do this?
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::CompoundAssignmentExpr> (
     new AST::CompoundAssignmentExpr (std::move (left), std::move (right),
@@ -13985,7 +13985,7 @@ Parser<ManagedTokenSource>::parse_await_expr (
     }
 
   // TODO: check inside async block in semantic analysis
-  Location locus = expr_to_await->get_locus_slow ();
+  Location locus = expr_to_await->get_locus ();
 
   return std::unique_ptr<AST::AwaitExpr> (
     new AST::AwaitExpr (std::move (expr_to_await), std::move (outer_attrs),
@@ -14008,7 +14008,7 @@ Parser<ManagedTokenSource>::parse_led_range_exclusive_expr (
   std::unique_ptr<AST::Expr> right
     = parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
 
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   if (right == nullptr)
     {
@@ -14066,7 +14066,7 @@ Parser<ManagedTokenSource>::parse_range_inclusive_expr (
   // FIXME: make non-associative
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = left->get_locus_slow ();
+  Location locus = left->get_locus ();
 
   return std::unique_ptr<AST::RangeFromToInclExpr> (
     new AST::RangeFromToInclExpr (std::move (left), std::move (right), locus));
@@ -14114,7 +14114,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr (
     }
   int index_int = atoi (index.c_str ());
 
-  Location locus = tuple_expr->get_locus_slow ();
+  Location locus = tuple_expr->get_locus ();
 
   return std::unique_ptr<AST::TupleIndexExpr> (
     new AST::TupleIndexExpr (std::move (tuple_expr), index_int,
@@ -14145,7 +14145,7 @@ Parser<ManagedTokenSource>::parse_index_expr (
     }
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = array_expr->get_locus_slow ();
+  Location locus = array_expr->get_locus ();
 
   return std::unique_ptr<AST::ArrayIndexExpr> (
     new AST::ArrayIndexExpr (std::move (array_expr), std::move (index_expr),
@@ -14167,7 +14167,7 @@ Parser<ManagedTokenSource>::parse_field_access_expr (
 
   Identifier ident = ident_tok->get_str ();
 
-  Location locus = struct_expr->get_locus_slow ();
+  Location locus = struct_expr->get_locus ();
 
   // TODO: check types. actually, do so during semantic analysis
   return std::unique_ptr<AST::FieldAccessExpr> (
@@ -14230,7 +14230,7 @@ Parser<ManagedTokenSource>::parse_method_call_expr (
     }
 
   // TODO: check types. actually do so in semantic analysis pass.
-  Location locus = receiver_expr->get_locus_slow ();
+  Location locus = receiver_expr->get_locus ();
 
   return std::unique_ptr<AST::MethodCallExpr> (
     new AST::MethodCallExpr (std::move (receiver_expr), std::move (segment),
@@ -14277,7 +14277,7 @@ Parser<ManagedTokenSource>::parse_function_call_expr (
     }
 
   // TODO: check types. actually, do so during semantic analysis
-  Location locus = function_expr->get_locus_slow ();
+  Location locus = function_expr->get_locus ();
 
   return std::unique_ptr<AST::CallExpr> (
     new AST::CallExpr (std::move (function_expr), std::move (params),
@@ -14772,7 +14772,7 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr_float (
   // get int from string
   int index = atoi (index_str.c_str ());
 
-  Location locus = tuple_expr->get_locus_slow ();
+  Location locus = tuple_expr->get_locus ();
 
   return std::unique_ptr<AST::TupleIndexExpr> (
     new AST::TupleIndexExpr (std::move (tuple_expr), index,
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index bc05e93069c..d3c053b609f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -400,9 +400,9 @@ public:
     auto Self
       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
 
-    resolver->get_type_scope ().insert (
-      Self, impl_block.get_type ()->get_node_id (),
-      impl_block.get_type ()->get_locus_slow ());
+    resolver->get_type_scope ().insert (Self,
+					impl_block.get_type ()->get_node_id (),
+					impl_block.get_type ()->get_locus ());
 
     for (auto &impl_item : impl_block.get_impl_items ())
       {
@@ -519,9 +519,9 @@ public:
     auto Self
       = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ());
 
-    resolver->get_type_scope ().insert (
-      Self, impl_block.get_type ()->get_node_id (),
-      impl_block.get_type ()->get_locus_slow ());
+    resolver->get_type_scope ().insert (Self,
+					impl_block.get_type ()->get_node_id (),
+					impl_block.get_type ()->get_locus ());
 
     for (auto &impl_item : impl_block.get_impl_items ())
       {
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index b8affe68c41..97c031199b3 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -211,7 +211,7 @@ public:
     // https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_resolve/src/lib.rs#L1722
     if (!resolver->get_type_scope ().lookup (canonical_path, &resolved_node))
       {
-	rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s",
+	rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
 		       canonical_path.get ().c_str ());
 	return UNKNOWN_NODEID;
       }
@@ -231,7 +231,7 @@ public:
     ResolveType resolver (parent, canonicalize_type_with_generics);
     type->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (type->get_locus_slow (), "unresolved type");
+      rust_error_at (type->get_locus (), "unresolved type");
 
     return resolver.resolved_node;
   };
@@ -311,7 +311,7 @@ public:
     ResolveTypeBound resolver (parent, canonicalize_type_with_generics);
     type->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (type->get_locus_slow (), "unresolved type bound");
+      rust_error_at (type->get_locus (), "unresolved type bound");
 
     return resolver.resolved_node;
   };
@@ -346,7 +346,7 @@ public:
     ResolveGenericParam resolver (parent);
     param->accept_vis (resolver);
     if (!resolver.ok)
-      rust_error_at (param->get_locus_slow (), "unresolved generic parameter");
+      rust_error_at (param->get_locus (), "unresolved generic parameter");
 
     return resolver.resolved_node;
   };
diff --git a/gcc/rust/resolve/rust-ast-verify-assignee.h b/gcc/rust/resolve/rust-ast-verify-assignee.h
index aed01196f81..9da3883220d 100644
--- a/gcc/rust/resolve/rust-ast-verify-assignee.h
+++ b/gcc/rust/resolve/rust-ast-verify-assignee.h
@@ -35,7 +35,7 @@ public:
     VerifyAsignee checker (parent);
     assignee->accept_vis (checker);
     if (!checker.ok)
-      rust_error_at (assignee->get_locus_slow (),
+      rust_error_at (assignee->get_locus (),
 		     "invalid left-hand side of assignment");
     return checker.ok;
   }
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
index 9e0450e8882..1bff7ef13b7 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold.h
@@ -211,7 +211,7 @@ public:
     item.accept_vis (folder);
     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
       {
-	rust_error_at (item.get_locus_slow (), "non const value");
+	rust_error_at (item.get_locus (), "non const value");
 	return nullptr;
       }
 
@@ -240,7 +240,7 @@ public:
     expr->accept_vis (folder);
     if (folder.ctx->get_backend ()->is_error_expression (folder.folded))
       {
-	rust_error_at (expr->get_locus_slow (), "non const value");
+	rust_error_at (expr->get_locus (), "non const value");
 	return nullptr;
       }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index a95a4e91c78..274451606cb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -49,8 +49,7 @@ public:
 
     if (resolver.infered == nullptr)
       {
-	rust_error_at (expr->get_locus_slow (),
-		       "failed to type resolve expression");
+	rust_error_at (expr->get_locus (), "failed to type resolve expression");
 	return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
       }
 
@@ -67,7 +66,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_tuple_expr ().get (), inside_loop);
     if (resolved == nullptr)
       {
-	rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_tuple_expr ()->get_locus (),
 		       "failed to resolve TupleIndexExpr receiver");
 	return;
       }
@@ -76,7 +75,7 @@ public:
 			 || resolved->get_kind () == TyTy::TypeKind::TUPLE;
     if (!is_valid_type)
       {
-	rust_error_at (expr.get_tuple_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_tuple_expr ()->get_locus (),
 		       "Expected Tuple or ADT got: %s",
 		       resolved->as_string ().c_str ());
 	return;
@@ -203,7 +202,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_receiver ().get (), false);
     if (receiver_tyty == nullptr)
       {
-	rust_error_at (expr.get_receiver ()->get_locus_slow (),
+	rust_error_at (expr.get_receiver ()->get_locus (),
 		       "failed to resolve receiver in MethodCallExpr");
 	return;
       }
@@ -771,7 +770,7 @@ public:
       = size_ty->unify (TypeCheckExpr::Resolve (expr.get_index_expr (), false));
     if (resolved_index_expr == nullptr)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "Type Resolver failure in Index for ArrayIndexExpr");
 	return;
       }
@@ -782,13 +781,13 @@ public:
     expr.get_array_expr ()->accept_vis (*this);
     if (infered == nullptr)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "failed to resolve array reference expression");
 	return;
       }
     else if (infered->get_kind () != TyTy::TypeKind::ARRAY)
       {
-	rust_error_at (expr.get_index_expr ()->get_locus_slow (),
+	rust_error_at (expr.get_index_expr ()->get_locus (),
 		       "expected an ArrayType got [%s]",
 		       infered->as_string ().c_str ());
 	infered = nullptr;
@@ -936,7 +935,7 @@ public:
       = TypeCheckExpr::Resolve (expr.get_loop_block ().get (), true);
     if (!block_expr->is_unit ())
       {
-	rust_error_at (expr.get_loop_block ()->get_locus_slow (),
+	rust_error_at (expr.get_loop_block ()->get_locus (),
 		       "expected %<()%> got %s",
 		       block_expr->as_string ().c_str ());
 	return;
@@ -965,7 +964,7 @@ public:
 
     if (!block_expr->is_unit ())
       {
-	rust_error_at (expr.get_loop_block ()->get_locus_slow (),
+	rust_error_at (expr.get_loop_block ()->get_locus (),
 		       "expected %<()%> got %s",
 		       block_expr->as_string ().c_str ());
 	return;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index fff86beaa27..0cc1cfb3d40 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -257,7 +257,7 @@ public:
 
     if (resolver.resolved == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to setup generic parameter");
 	return nullptr;
       }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 4b66fdbd6e6..7f0e0ffdb30 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -97,7 +97,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
     auto resolved = TypeCheckStmt::Resolve (s, inside_loop);
     if (resolved == nullptr)
       {
-	rust_error_at (s->get_locus_slow (), "failure to resolve type");
+	rust_error_at (s->get_locus (), "failure to resolve type");
 	return false;
       }
 
@@ -145,9 +145,8 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
 	= (TyTy::ADTType *) struct_path_resolved->unify (base_resolved);
       if (struct_def == nullptr)
 	{
-	  rust_fatal_error (
-	    struct_expr.struct_base->base_struct->get_locus_slow (),
-	    "incompatible types for base struct reference");
+	  rust_fatal_error (struct_expr.struct_base->base_struct->get_locus (),
+			    "incompatible types for base struct reference");
 	  return;
 	}
     }
@@ -229,11 +228,11 @@ TypeCheckStructExpr::visit (HIR::StructExprStructFields &struct_expr)
 	      HIR::Expr *field_value = new HIR::FieldAccessExpr (
 		mapping, std::unique_ptr<HIR::Expr> (receiver), missing,
 		std::move (outer_attribs),
-		struct_expr.struct_base->base_struct->get_locus_slow ());
+		struct_expr.struct_base->base_struct->get_locus ());
 
 	      implicit_field = new HIR::StructExprFieldIdentifierValue (
 		mapping, missing, std::unique_ptr<HIR::Expr> (field_value),
-		struct_expr.struct_base->base_struct->get_locus_slow ());
+		struct_expr.struct_base->base_struct->get_locus ());
 
 	      size_t field_index;
 	      bool ok = struct_path_resolved->get_field (missing, &field_index);
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 56fdafd7919..e449b55f41e 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2207,7 +2207,7 @@ TypeCheckCallExpr::visit (ADTType &type)
     BaseType *arg = Resolver::TypeCheckExpr::Resolve (p, false);
     if (arg == nullptr)
       {
-	rust_error_at (p->get_locus_slow (), "failed to resolve argument type");
+	rust_error_at (p->get_locus (), "failed to resolve argument type");
 	return false;
       }
 
@@ -2262,7 +2262,7 @@ TypeCheckCallExpr::visit (FnType &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2276,7 +2276,7 @@ TypeCheckCallExpr::visit (FnType &type)
 	resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
 	if (resolved_argument_type == nullptr)
 	  {
-	    rust_error_at (param->get_locus_slow (),
+	    rust_error_at (param->get_locus (),
 			   "Type Resolution failure on parameter");
 	    return false;
 	  }
@@ -2327,7 +2327,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2335,7 +2335,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
     auto resolved_argument_type = fnparam->unify (argument_expr_tyty);
     if (resolved_argument_type == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "Type Resolution failure on parameter");
 	return false;
       }
@@ -2378,7 +2378,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
     auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param, false);
     if (argument_expr_tyty == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "failed to resolve type for argument expr in CallExpr");
 	return false;
       }
@@ -2386,7 +2386,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
     auto resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
     if (resolved_argument_type == nullptr)
       {
-	rust_error_at (param->get_locus_slow (),
+	rust_error_at (param->get_locus (),
 		       "Type Resolution failure on parameter");
 	return false;
       }
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index d544042b344..deade08db37 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -380,7 +380,7 @@ Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
 {
   hirExprMappings[crateNum][id] = expr;
   nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
-  insert_location (crateNum, id, expr->get_locus_slow ());
+  insert_location (crateNum, id, expr->get_locus ());
 }
 
 HIR::Expr *
@@ -430,7 +430,7 @@ Mappings::insert_hir_generic_param (CrateNum crateNum, HirId id,
 
   hirGenericParamMappings[crateNum][id] = param;
   nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
-  insert_location (crateNum, id, param->get_locus_slow ());
+  insert_location (crateNum, id, param->get_locus ());
 }
 
 HIR::GenericParam *
-- 
2.32.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-08-26 19:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-26  0:09 [PATCH] Get rid of get_locus_slow Mark Wielaard
2021-08-26  2:31 ` The Other
2021-08-26 19:19   ` Mark Wielaard
2021-08-26 19:25     ` [PATCHv2] " Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).