aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/backend/rust-mangle.cc16
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc69
-rw-r--r--gcc/rust/expand/rust-macro-builtins.h3
-rw-r--r--gcc/rust/typecheck/rust-autoderef.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h25
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h5
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc5
-rw-r--r--gcc/rust/typecheck/rust-tyty-cmp.h26
-rw-r--r--gcc/rust/util/rust-hir-map.cc1
-rw-r--r--gcc/rust/util/rust-mapping-common.h9
-rw-r--r--gcc/testsuite/rust/compile/builtin_macro_concat.rs15
-rw-r--r--gcc/testsuite/rust/compile/generics7.rs2
-rw-r--r--gcc/testsuite/rust/compile/generics8.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-1075.rs42
-rw-r--r--gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs23
15 files changed, 202 insertions, 43 deletions
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
index eaf7814..82f643a 100644
--- a/gcc/rust/backend/rust-mangle.cc
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -11,6 +11,9 @@ static const std::string kMangledSubstBegin = "$LT$";
static const std::string kMangledSubstEnd = "$GT$";
static const std::string kMangledSpace = "$u20$";
static const std::string kMangledRef = "$RF$";
+static const std::string kMangledPtr = "$BP$";
+static const std::string kMangledLeftSqParen = "$u5b$"; // [
+static const std::string kMangledRightSqParen = "$u5d$"; // ]
static const std::string kQualPathBegin = "_" + kMangledSubstBegin;
namespace Rust {
@@ -29,8 +32,15 @@ legacy_mangle_name (const std::string &name)
// <example::Bar as example::A>::fooA:
// _ZN43_$LT$example..Bar$u20$as$u20$example..A$GT$4fooA17hfc615fa76c7db7a0E:
//
+ // core::ptr::const_ptr::<impl *const T>::cast:
+ // _ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$4cast17hb79f4617226f1d55E:
+ //
+ // core::ptr::const_ptr::<impl *const [T]>::as_ptr:
+ // _ZN4core3ptr9const_ptr43_$LT$impl$u20$$BP$const$u20$$u5b$T$u5d$$GT$6as_ptr17he16e0dcd9473b04fE:
+ //
// example::Foo<T>::new:
// _ZN7example12Foo$LT$T$GT$3new17h9a2aacb7fd783515E:
+
std::string buffer;
for (size_t i = 0; i < name.size (); i++)
{
@@ -47,6 +57,12 @@ legacy_mangle_name (const std::string &name)
m = kMangledSubstBegin;
else if (c == '>')
m = kMangledSubstEnd;
+ else if (c == '*')
+ m = kMangledPtr;
+ else if (c == '[')
+ m = kMangledLeftSqParen;
+ else if (c == ']')
+ m = kMangledRightSqParen;
else if (c == ':')
{
rust_assert (i + 1 < name.size ());
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 3cd6e43..85520ec 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -34,17 +34,12 @@ make_string (Location locus, std::string value)
PrimitiveCoreType::CORETYPE_STR, {}, locus));
}
-/* Parse a single string literal from the given delimited token tree,
- and return the LiteralExpr for it. Allow for an optional trailing comma,
- but otherwise enforce that these are the only tokens. */
+/* Match the end token of a macro given the start delimiter of the macro */
-std::unique_ptr<AST::LiteralExpr>
-parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree,
- Location invoc_locus)
+static inline TokenId
+macro_end_token (AST::DelimTokenTree &invoc_token_tree,
+ Parser<MacroInvocLexer> &parser)
{
- MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
- Parser<MacroInvocLexer> parser (std::move (lex));
-
auto last_token_id = TokenId::RIGHT_CURLY;
switch (invoc_token_tree.get_delim_type ())
{
@@ -63,6 +58,22 @@ parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree,
break;
}
+ return last_token_id;
+}
+
+/* Parse a single string literal from the given delimited token tree,
+ and return the LiteralExpr for it. Allow for an optional trailing comma,
+ but otherwise enforce that these are the only tokens. */
+
+std::unique_ptr<AST::LiteralExpr>
+parse_single_string_literal (AST::DelimTokenTree &invoc_token_tree,
+ Location invoc_locus)
+{
+ MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
+ Parser<MacroInvocLexer> parser (std::move (lex));
+
+ auto last_token_id = macro_end_token (invoc_token_tree, parser);
+
std::unique_ptr<AST::LiteralExpr> lit_expr = nullptr;
if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
@@ -252,4 +263,44 @@ MacroBuiltin::compile_error (Location invoc_locus, AST::MacroInvocData &invoc)
return AST::ASTFragment::create_error ();
}
+/* Expand builtin macro concat!(), which joins all the literal parameters
+ into a string with no delimiter. */
+
+AST::ASTFragment
+MacroBuiltin::concat (Location invoc_locus, AST::MacroInvocData &invoc)
+{
+ auto invoc_token_tree = invoc.get_delim_tok_tree ();
+ MacroInvocLexer lex (invoc_token_tree.to_token_stream ());
+ Parser<MacroInvocLexer> parser (std::move (lex));
+ auto str = std::string ();
+ bool has_error = false;
+
+ auto last_token_id = macro_end_token (invoc_token_tree, parser);
+
+ /* NOTE: concat! could accept no argument, so we don't have any checks here */
+ while (parser.peek_current_token ()->get_id () != last_token_id)
+ {
+ auto lit_expr = parser.parse_literal_expr ();
+ if (lit_expr)
+ {
+ str += lit_expr->as_string ();
+ }
+ else
+ {
+ rust_error_at (parser.peek_current_token ()->get_locus (),
+ "argument must be a constant literal");
+ has_error = true;
+ }
+ parser.maybe_skip_token (COMMA);
+ }
+
+ parser.skip_token (last_token_id);
+
+ if (has_error)
+ return AST::ASTFragment::create_error ();
+
+ auto node = AST::SingleASTNode (make_string (invoc_locus, str));
+ return AST::ASTFragment ({node});
+}
+
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index b119466..a581af4 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -80,6 +80,9 @@ public:
static AST::ASTFragment compile_error (Location invoc_locus,
AST::MacroInvocData &invoc);
+
+ static AST::ASTFragment concat (Location invoc_locus,
+ AST::MacroInvocData &invoc);
};
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-autoderef.cc b/gcc/rust/typecheck/rust-autoderef.cc
index 67c1908..986ff46 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -116,7 +116,7 @@ Adjuster::try_unsize_type (const TyTy::BaseType *ty)
TyTy::TyVar (slice_elem->get_ref ()));
context->insert_implicit_type (slice);
- return Adjustment (Adjustment::AdjustmentType::INDIRECTION, slice);
+ return Adjustment (Adjustment::AdjustmentType::UNSIZE, slice);
}
static bool
diff --git a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
index 2908a4b..9abf872 100644
--- a/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
+++ b/gcc/rust/typecheck/rust-hir-inherent-impl-overlap.h
@@ -123,7 +123,26 @@ public:
continue;
if (query->can_eq (candidate, false))
- possible_collision (it->second, iy->second);
+ {
+ // we might be in the case that we have:
+ //
+ // *const T vs *const [T]
+ //
+ // so lets use an equality check when the
+ // candidates are both generic to be sure we dont emit a false
+ // positive
+
+ bool a = query->is_concrete ();
+ bool b = candidate->is_concrete ();
+ bool both_generic = !a && !b;
+ if (both_generic)
+ {
+ if (!query->is_equal (*candidate))
+ continue;
+ }
+
+ possible_collision (it->second, iy->second);
+ }
}
}
}
@@ -152,8 +171,8 @@ public:
void collision_detected (HIR::ImplItem *query, HIR::ImplItem *dup,
const std::string &name)
{
- RichLocation r (query->get_locus ());
- r.add_range (dup->get_locus ());
+ RichLocation r (dup->get_locus ());
+ r.add_range (query->get_locus ());
rust_error_at (r, "duplicate definitions with name %s", name.c_str ());
}
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index 3c1858c..fda505a 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -284,7 +284,10 @@ protected:
return;
if (!receiver->can_eq (impl_block_ty, false))
- return;
+ {
+ if (!impl_block_ty->can_eq (receiver, false))
+ return;
+ }
// lets visit the impl_item
item->accept_vis (*this);
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index a7ec42c..b34db3b 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -41,7 +41,10 @@ TypeBoundsProbe::scan ()
return true;
if (!receiver->can_eq (impl_type, false))
- return true;
+ {
+ if (!impl_type->can_eq (receiver, false))
+ return true;
+ }
possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
return true;
diff --git a/gcc/rust/typecheck/rust-tyty-cmp.h b/gcc/rust/typecheck/rust-tyty-cmp.h
index afc928da..34c8963 100644
--- a/gcc/rust/typecheck/rust-tyty-cmp.h
+++ b/gcc/rust/typecheck/rust-tyty-cmp.h
@@ -886,8 +886,6 @@ public:
ok = true;
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const ArrayType *base;
@@ -916,8 +914,6 @@ public:
ok = true;
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const SliceType *base;
@@ -939,8 +935,6 @@ public:
ok = type.get_infer_kind () == InferType::InferTypeKind::GENERAL;
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const BoolType *base;
@@ -965,8 +959,6 @@ public:
ok = type.get_int_kind () == base->get_int_kind ();
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const IntType *base;
@@ -991,8 +983,6 @@ public:
ok = type.get_uint_kind () == base->get_uint_kind ();
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const UintType *base;
@@ -1017,8 +1007,6 @@ public:
ok = type.get_float_kind () == base->get_float_kind ();
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const FloatType *base;
@@ -1120,8 +1108,6 @@ public:
ok = true;
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const TupleType *base;
@@ -1143,8 +1129,6 @@ public:
void visit (const USizeType &type) override { ok = true; }
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const USizeType *base;
@@ -1166,8 +1150,6 @@ public:
void visit (const ISizeType &type) override { ok = true; }
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const ISizeType *base;
@@ -1189,8 +1171,6 @@ public:
void visit (const CharType &type) override { ok = true; }
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const CharType *base;
@@ -1365,8 +1345,6 @@ public:
void visit (const StrType &type) override { ok = true; }
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const StrType *base;
@@ -1383,8 +1361,6 @@ public:
void visit (const NeverType &type) override { ok = true; }
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
const NeverType *base;
@@ -1478,8 +1454,6 @@ public:
ok = base->bounds_compatible (type, ref_locus, false);
}
- void visit (const ParamType &type) override { ok = true; }
-
private:
const BaseType *get_base () const override { return base; }
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 47f9175..7bacc4c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -754,6 +754,7 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro)
{"include_bytes", MacroBuiltin::include_bytes},
{"include_str", MacroBuiltin::include_str},
{"compile_error", MacroBuiltin::compile_error},
+ {"concat", MacroBuiltin::concat},
};
auto builtin = builtin_macros.find (macro->get_rule_name ());
diff --git a/gcc/rust/util/rust-mapping-common.h b/gcc/rust/util/rust-mapping-common.h
index 42a4e8e..27faa7f 100644
--- a/gcc/rust/util/rust-mapping-common.h
+++ b/gcc/rust/util/rust-mapping-common.h
@@ -50,6 +50,15 @@ struct DefId
return ((uint64_t) this->crateNum << 32 | this->localDefId)
< ((uint64_t) other.crateNum << 32 | other.localDefId);
}
+
+ std::string as_string () const
+ {
+ std::string buf;
+ buf += std::to_string (crateNum);
+ buf += " "; // or anything else
+ buf += std::to_string (localDefId);
+ return buf;
+ }
};
#define UNKNOWN_CREATENUM ((uint32_t) (0))
diff --git a/gcc/testsuite/rust/compile/builtin_macro_concat.rs b/gcc/testsuite/rust/compile/builtin_macro_concat.rs
new file mode 100644
index 0000000..1fcd65f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/builtin_macro_concat.rs
@@ -0,0 +1,15 @@
+macro_rules! concat {
+ () => {{}};
+}
+
+fn main () {
+ let not_literal = "identifier";
+ concat! ();
+ concat! (,); // { dg-error "argument must be a constant literal" }
+ concat! (not_literal); // { dg-error "argument must be a constant literal" }
+ concat! ("message");
+ concat! ("message",);
+ concat! ("message",1, true, false, 1.0, 10usize, 2000u64);
+ concat! ("message",1, true, false, 1.0, 10usize, 2000u64,);
+ concat! ("m", not_literal); // { dg-error "argument must be a constant literal" }
+}
diff --git a/gcc/testsuite/rust/compile/generics7.rs b/gcc/testsuite/rust/compile/generics7.rs
index 78b6149..2a41632 100644
--- a/gcc/testsuite/rust/compile/generics7.rs
+++ b/gcc/testsuite/rust/compile/generics7.rs
@@ -15,7 +15,7 @@ impl Foo<char> {
}
impl<T> Foo<T> {
- fn bar(self) -> T { // { dg-error "duplicate definitions with name bar" }
+ fn bar(self) -> T {
self.a
}
}
diff --git a/gcc/testsuite/rust/compile/generics8.rs b/gcc/testsuite/rust/compile/generics8.rs
index 70bad1a..ceefc5d 100644
--- a/gcc/testsuite/rust/compile/generics8.rs
+++ b/gcc/testsuite/rust/compile/generics8.rs
@@ -1,7 +1,7 @@
struct Foo<A, B>(A, B);
impl<T> Foo<i32, T> {
- fn test(a: T) -> T { // { dg-error "duplicate definitions with name test" }
+ fn test(a: T) -> T {
a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/issue-1075.rs b/gcc/testsuite/rust/compile/torture/issue-1075.rs
new file mode 100644
index 0000000..3bd6321
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-1075.rs
@@ -0,0 +1,42 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+ pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+ data: *const T,
+ len: usize,
+}
+
+union Repr<T> {
+ rust: *const [T],
+ rust_mut: *mut [T],
+ raw: FatPtr<T>,
+}
+
+impl<T> *const [T] {
+ pub const fn len(self) -> usize {
+ // SAFETY: this is safe because `*const [T]` and `FatPtr<T>` have the same layout.
+ // Only `std` can make this guarantee.
+ let a = unsafe { Repr { rust: self }.raw };
+ a.len
+ }
+
+ pub const fn as_ptr(self) -> *const T {
+ self as *const T
+ }
+}
+
+impl<T> *const T {
+ pub const unsafe fn offset(self, count: isize) -> *const T {
+ unsafe { offset(self, count) }
+ }
+
+ pub const unsafe fn add(self, count: usize) -> Self {
+ unsafe { self.offset(count as isize) }
+ }
+
+ pub const fn as_ptr(self) -> *const T {
+ self as *const T
+ }
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs
new file mode 100644
index 0000000..ca40585
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs
@@ -0,0 +1,23 @@
+// { dg-output "\ntest10btrue2.15\ntest10bfalse2.151\n" }
+macro_rules! concat {
+ () => {{}};
+}
+
+extern "C" {
+ fn printf(fmt: *const i8, ...);
+}
+
+fn print(s: &str) {
+ printf("%s\n" as *const str as *const i8, s as *const str as *const i8);
+}
+
+fn main() -> i32 {
+ let a = concat!();
+ let b = concat!("test", 10, 'b', true, 2.15);
+ let c = concat!("test", 10, 'b', false, 2.15, 1u64);
+ print(a);
+ print(b);
+ print(c);
+
+ 0
+}