aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config.gcc24
-rw-r--r--gcc/config/dragonfly-rust.cc40
-rw-r--r--gcc/config/freebsd-rust.cc40
-rw-r--r--gcc/config/fuchsia-rust.cc40
-rw-r--r--gcc/config/linux-rust.cc57
-rw-r--r--gcc/config/netbsd-rust.cc40
-rw-r--r--gcc/config/openbsd-rust.cc40
-rw-r--r--gcc/config/sol2-rust.cc40
-rw-r--r--gcc/config/t-dragonfly4
-rw-r--r--gcc/config/t-freebsd4
-rw-r--r--gcc/config/t-fuchsia21
-rw-r--r--gcc/config/t-linux4
-rw-r--r--gcc/config/t-netbsd4
-rw-r--r--gcc/config/t-openbsd5
-rw-r--r--gcc/config/t-sol25
-rw-r--r--gcc/config/t-vxworks4
-rw-r--r--gcc/config/t-winnt4
-rw-r--r--gcc/config/vxworks-rust.cc40
-rw-r--r--gcc/config/winnt-rust.cc40
-rw-r--r--gcc/rust/ast/rust-ast-dump.cc230
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc6
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h30
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h14
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h6
-rw-r--r--gcc/rust/hir/tree/rust-hir.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc65
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h29
-rw-r--r--gcc/rust/util/rust-hir-map.cc24
-rw-r--r--gcc/rust/util/rust-hir-map.h3
-rw-r--r--gcc/testsuite/rust/compile/issue-1589.rs5
31 files changed, 805 insertions, 77 deletions
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4cd81c8..7a2daa9 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -790,6 +790,8 @@ case ${target} in
d_target_objs="${d_target_objs} dragonfly-d.o"
tmake_file="${tmake_file} t-dragonfly"
target_has_targetdm=yes
+ rust_target_objs="${rust_target_objs} dragonfly-rust.o"
+ target_has_targetrustm=yes
;;
*-*-freebsd*)
# This is the generic ELF configuration of FreeBSD. Later
@@ -841,9 +843,14 @@ case ${target} in
d_target_objs="${d_target_objs} freebsd-d.o"
tmake_file="${tmake_file} t-freebsd"
target_has_targetdm=yes
+ rust_target_objs="${rust_target_objs} freebsd-rust.o"
+ target_has_targetrustm=yes
;;
*-*-fuchsia*)
native_system_header_dir=/include
+ tmake_file="t-fuchsia"
+ rust_target_objs="${rust_target_objs} fuchsia-rust.o"
+ target_has_targetrustm=yes
;;
*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi)
extra_options="$extra_options gnu-user.opt"
@@ -912,6 +919,12 @@ case ${target} in
gcc_cv_initfini_array=yes
;;
esac
+ case $target in
+ *linux*)
+ rust_target_objs="${rust_target_objs} linux-rust.o"
+ target_has_targetrustm=yes
+ ;;
+ esac
;;
*-*-netbsd*)
tm_p_file="${tm_p_file} netbsd-protos.h"
@@ -932,6 +945,8 @@ case ${target} in
default_gnu_indirect_function=yes
;;
esac
+ rust_target_objs="${rust_target_objs} netbsd-rust.o"
+ target_has_targetrustm=yes
;;
*-*-openbsd*)
tmake_file="t-openbsd"
@@ -947,6 +962,8 @@ case ${target} in
esac
d_target_objs="${d_target_objs} openbsd-d.o"
target_has_targetdm=yes
+ rust_target_objs="${rust_target_objs} openbsd-rust.o"
+ target_has_targetrustm=yes
;;
*-*-phoenix*)
gas=yes
@@ -1011,6 +1028,8 @@ case ${target} in
;;
esac
target_has_targetdm=yes
+ rust_target_objs="${rust_target_objs} sol2-rust.o"
+ target_has_targetrustm=yes
;;
*-*-*vms*)
extra_options="${extra_options} vms/vms.opt"
@@ -1043,6 +1062,9 @@ case ${target} in
extra_headers="${extra_headers} ../vxworks/vxworks-predef.h"
target_has_targetcm="yes"
+ rust_target_objs="${rust_target_objs} vxworks-rust.o"
+ target_has_targetrustm=yes
+
# This private header exposes a consistent interface for checks on
# the VxWorks version our runtime header files need to perform, based on
# what the system headers adverstise:
@@ -2100,6 +2122,8 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
d_target_objs="${d_target_objs} winnt-d.o"
target_has_targetcm="yes"
target_has_targetdm="yes"
+ rust_target_objs="${rust_target_objs} winnt-rust.o"
+ target_has_targetrustm="yes"
case ${target} in
x86_64-*-* | *-w64-*)
need_64bit_isa=yes
diff --git a/gcc/config/dragonfly-rust.cc b/gcc/config/dragonfly-rust.cc
new file mode 100644
index 0000000..ce501d1
--- /dev/null
+++ b/gcc/config/dragonfly-rust.cc
@@ -0,0 +1,40 @@
+/* DragonFly support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for DragonFly targets. */
+
+static void
+dragonfly_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "dragonfly");
+ rust_add_target_info ("target_vendor", "unknown");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO dragonfly_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/freebsd-rust.cc b/gcc/config/freebsd-rust.cc
new file mode 100644
index 0000000..1dbf2ed
--- /dev/null
+++ b/gcc/config/freebsd-rust.cc
@@ -0,0 +1,40 @@
+/* FreeBSD support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for FreeBSD targets. */
+
+static void
+freebsd_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "freebsd");
+ rust_add_target_info ("target_vendor", "unknown");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO freebsd_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/fuchsia-rust.cc b/gcc/config/fuchsia-rust.cc
new file mode 100644
index 0000000..8626250
--- /dev/null
+++ b/gcc/config/fuchsia-rust.cc
@@ -0,0 +1,40 @@
+/* Fuchsia support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for Fuchsia targets. */
+
+static void
+fushsia_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "fushsia");
+ rust_add_target_info ("target_vendor", "unknown");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO fushsia_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/linux-rust.cc b/gcc/config/linux-rust.cc
new file mode 100644
index 0000000..3eaa918
--- /dev/null
+++ b/gcc/config/linux-rust.cc
@@ -0,0 +1,57 @@
+/* Linux support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* `-mandroid' is not available as an command-line option. */
+#ifndef TARGET_ANDROID
+#define TARGET_ANDROID 0
+#endif
+
+/* Implement TARGET_RUST_OS_INFO for Linux targets. */
+
+static void
+linux_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_vendor", "unknown");
+
+ if (TARGET_ANDROID)
+ rust_add_target_info ("target_os", "android");
+ else
+ rust_add_target_info ("target_os", "linux");
+
+ if (OPTION_GLIBC)
+ rust_add_target_info ("target_env", "gnu");
+ else if (OPTION_MUSL)
+ rust_add_target_info ("target_env", "musl");
+ else if (OPTION_UCLIBC)
+ rust_add_target_info ("target_env", "uclibc");
+ else
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO linux_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/netbsd-rust.cc b/gcc/config/netbsd-rust.cc
new file mode 100644
index 0000000..9395466
--- /dev/null
+++ b/gcc/config/netbsd-rust.cc
@@ -0,0 +1,40 @@
+/* NetBSD support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for NetBSD targets. */
+
+static void
+netbsd_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "netbsd");
+ rust_add_target_info ("target_vendor", "unknown");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO netbsd_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/openbsd-rust.cc b/gcc/config/openbsd-rust.cc
new file mode 100644
index 0000000..c4721ea
--- /dev/null
+++ b/gcc/config/openbsd-rust.cc
@@ -0,0 +1,40 @@
+/* OpenBSD support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for OpenBSD targets. */
+
+static void
+openbsd_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "openbsd");
+ rust_add_target_info ("target_vendor", "unknown");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO openbsd_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/sol2-rust.cc b/gcc/config/sol2-rust.cc
new file mode 100644
index 0000000..e36bd45
--- /dev/null
+++ b/gcc/config/sol2-rust.cc
@@ -0,0 +1,40 @@
+/* Solaris support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for Solaris targets. */
+
+static void
+solaris_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "solaris");
+ rust_add_target_info ("target_vendor", "sun");
+ rust_add_target_info ("target_env", "");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO solaris_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/t-dragonfly b/gcc/config/t-dragonfly
index a282579..1eee293 100644
--- a/gcc/config/t-dragonfly
+++ b/gcc/config/t-dragonfly
@@ -19,3 +19,7 @@
dragonfly-d.o: $(srcdir)/config/dragonfly-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+dragonfly-rust.o: $(srcdir)/config/dragonfly-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-freebsd b/gcc/config/t-freebsd
index 37049f7..dd5dfdd 100644
--- a/gcc/config/t-freebsd
+++ b/gcc/config/t-freebsd
@@ -19,3 +19,7 @@
freebsd-d.o: $(srcdir)/config/freebsd-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+freebsd-rust.o: $(srcdir)/config/freebsd-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-fuchsia b/gcc/config/t-fuchsia
new file mode 100644
index 0000000..55c884b
--- /dev/null
+++ b/gcc/config/t-fuchsia
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+fuchsia-rust.o: $(srcdir)/config/fuchsia-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index d9bc9b8..8404e14 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -19,3 +19,7 @@
linux.o: $(srcdir)/config/linux.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+linux-rust.o: $(srcdir)/config/linux-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-netbsd b/gcc/config/t-netbsd
index 77f850f..b9546da 100644
--- a/gcc/config/t-netbsd
+++ b/gcc/config/t-netbsd
@@ -23,3 +23,7 @@ netbsd.o: $(srcdir)/config/netbsd.cc
netbsd-d.o: $(srcdir)/config/netbsd-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+netbsd-rust.o: $(srcdir)/config/netbsd-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-openbsd b/gcc/config/t-openbsd
index 69643f5..3b625d6 100644
--- a/gcc/config/t-openbsd
+++ b/gcc/config/t-openbsd
@@ -5,3 +5,8 @@ USER_H = $(EXTRA_HEADERS)
openbsd-d.o: $(srcdir)/config/openbsd-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+# OpenBSD-specific Rust support.
+openbsd-rust.o: $(srcdir)/config/openbsd-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
index 8732e2e..e207534 100644
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -31,6 +31,11 @@ sol2-d.o: $(srcdir)/config/sol2-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+# Solaris-specific Rust support.
+sol2-rust.o: $(srcdir)/config/sol2-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
# Corresponding stub routines.
sol2-stubs.o: $(srcdir)/config/sol2-stubs.cc
$(COMPILE) $<
diff --git a/gcc/config/t-vxworks b/gcc/config/t-vxworks
index 40c6cc4..7fb2adf 100644
--- a/gcc/config/t-vxworks
+++ b/gcc/config/t-vxworks
@@ -24,6 +24,10 @@ vxworks-c.o: $(srcdir)/config/vxworks-c.cc
$(COMPILE) $<
$(POSTCOMPILE)
+vxworks-rust.o: $(srcdir)/config/vxworks-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
# We leverage $sysroot to find target system headers only, distributed
# in a VxWorks (a)typical fashion with a different set of headers for
# rtp vs kernel mode. We setup SYSROOT_HEADERS_SUFFIX_SPEC to handle
diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt
index c44e9bf..3c7c953 100644
--- a/gcc/config/t-winnt
+++ b/gcc/config/t-winnt
@@ -20,3 +20,7 @@ winnt-c.o: config/winnt-c.cc $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(C_TARGET_H) $(C_TARGET_DEF_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$< $(OUTPUT_OPTION)
+
+winnt-rust.o: $(srcdir)/config/winnt-rust.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/config/vxworks-rust.cc b/gcc/config/vxworks-rust.cc
new file mode 100644
index 0000000..76d618c
--- /dev/null
+++ b/gcc/config/vxworks-rust.cc
@@ -0,0 +1,40 @@
+/* VxWorks support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for VxWorks targets. */
+
+static void
+vxworks_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "unix");
+ rust_add_target_info ("target_os", "vxworks");
+ rust_add_target_info ("target_vendor", "wrs");
+ rust_add_target_info ("target_env", "gnu");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO vxworks_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/winnt-rust.cc b/gcc/config/winnt-rust.cc
new file mode 100644
index 0000000..190584d
--- /dev/null
+++ b/gcc/config/winnt-rust.cc
@@ -0,0 +1,40 @@
+/* Windows support needed only by Rust front-end.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_OS_INFO for Windows targets. */
+
+static void
+winnt_rust_target_os_info (void)
+{
+ rust_add_target_info ("target_family", "windows");
+ rust_add_target_info ("target_os", "windows");
+ rust_add_target_info ("target_vendor", "pc");
+ rust_add_target_info ("target_env", "gnu");
+}
+
+#undef TARGET_RUST_OS_INFO
+#define TARGET_RUST_OS_INFO winnt_rust_target_os_info
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/rust/ast/rust-ast-dump.cc b/gcc/rust/ast/rust-ast-dump.cc
index a37f94b..4817962 100644
--- a/gcc/rust/ast/rust-ast-dump.cc
+++ b/gcc/rust/ast/rust-ast-dump.cc
@@ -275,19 +275,44 @@ Dump::visit (MetaItemPathLit &meta_item)
void
Dump::visit (BorrowExpr &expr)
-{}
+{
+ stream << '&';
+ if (expr.get_is_double_borrow ())
+ stream << '&';
+ if (expr.get_is_mut ())
+ stream << "mut ";
+
+ expr.get_borrowed_expr ()->accept_vis (*this);
+}
void
Dump::visit (DereferenceExpr &expr)
-{}
+{
+ stream << '*';
+ expr.get_dereferenced_expr ()->accept_vis (*this);
+}
void
Dump::visit (ErrorPropagationExpr &expr)
-{}
+{
+ expr.get_propagating_expr ()->accept_vis (*this);
+ stream << '?';
+}
void
Dump::visit (NegationExpr &expr)
-{}
+{
+ switch (expr.get_expr_type ())
+ {
+ case NegationOperator::NEGATE:
+ stream << '-';
+ break;
+ case NegationOperator::NOT:
+ stream << '!';
+ break;
+ }
+ expr.get_negated_expr ()->accept_vis (*this);
+}
void
Dump::visit (ArithmeticOrLogicalExpr &expr)
@@ -343,15 +368,65 @@ Dump::visit (ArithmeticOrLogicalExpr &expr)
void
Dump::visit (ComparisonExpr &expr)
-{}
+{
+ auto op = "";
+ switch (expr.get_expr_type ())
+ {
+ case ComparisonOperator::EQUAL:
+ op = "==";
+ break;
+ case ComparisonOperator::NOT_EQUAL:
+ op = "!=";
+ break;
+
+ case ComparisonOperator::GREATER_THAN:
+ op = ">";
+ break;
+
+ case ComparisonOperator::LESS_THAN:
+ op = "<";
+ break;
+
+ case ComparisonOperator::GREATER_OR_EQUAL:
+ op = ">=";
+ break;
+
+ case ComparisonOperator::LESS_OR_EQUAL:
+ op = "<=";
+ break;
+ }
+
+ expr.get_left_expr ()->accept_vis (*this);
+ stream << " " << op << " ";
+ expr.get_right_expr ()->accept_vis (*this);
+}
void
Dump::visit (LazyBooleanExpr &expr)
-{}
+{
+ auto op = "";
+ switch (expr.get_expr_type ())
+ {
+ case LazyBooleanOperator::LOGICAL_AND:
+ op = "&&";
+ break;
+ case LazyBooleanOperator::LOGICAL_OR:
+ op = "||";
+ break;
+ }
+
+ expr.get_left_expr ()->accept_vis (*this);
+ stream << " " << op << " ";
+ expr.get_right_expr ()->accept_vis (*this);
+}
void
Dump::visit (TypeCastExpr &expr)
-{}
+{
+ expr.get_casted_expr ()->accept_vis (*this);
+ stream << " as ";
+ expr.get_type_to_cast_to ()->accept_vis (*this);
+}
void
Dump::visit (AssignmentExpr &expr)
@@ -415,23 +490,51 @@ Dump::visit (CompoundAssignmentExpr &expr)
void
Dump::visit (GroupedExpr &expr)
-{}
+{
+ stream << '(';
+ expr.get_expr_in_parens ()->accept_vis (*this);
+ stream << ')';
+}
void
Dump::visit (ArrayElemsValues &elems)
-{}
+{
+ auto &vals = elems.get_values ();
+ if (vals.size () >= 1)
+ {
+ vals[0]->accept_vis (*this);
+ for (size_t i = 1; i < vals.size (); i++)
+ {
+ stream << ", ";
+ vals[i]->accept_vis (*this);
+ }
+ }
+}
void
Dump::visit (ArrayElemsCopied &elems)
-{}
+{
+ elems.get_elem_to_copy ()->accept_vis (*this);
+ stream << "; ";
+ elems.get_num_copies ()->accept_vis (*this);
+}
void
Dump::visit (ArrayExpr &expr)
-{}
+{
+ stream << '[';
+ expr.get_array_elems ()->accept_vis (*this);
+ stream << ']';
+}
void
Dump::visit (ArrayIndexExpr &expr)
-{}
+{
+ expr.get_array_expr ()->accept_vis (*this);
+ stream << '[';
+ expr.get_index_expr ()->accept_vis (*this);
+ stream << ']';
+}
void
Dump::visit (TupleExpr &expr)
@@ -514,11 +617,11 @@ Dump::visit (BlockExpr &expr)
{
stream << indentation;
expr.get_tail_expr ()->accept_vis (*this);
- stream << " /* tail expr */";
+ stream << " /* tail expr */\n";
}
indentation.decrement ();
- stream << "\n" << indentation << "}\n";
+ stream << indentation << "}\n";
}
void
@@ -535,27 +638,46 @@ Dump::visit (BreakExpr &expr)
void
Dump::visit (RangeFromToExpr &expr)
-{}
+{
+ expr.get_from_expr ()->accept_vis (*this);
+ stream << "..";
+ expr.get_to_expr ()->accept_vis (*this);
+}
void
Dump::visit (RangeFromExpr &expr)
-{}
+{
+ expr.get_from_expr ()->accept_vis (*this);
+ stream << "..";
+}
void
Dump::visit (RangeToExpr &expr)
-{}
+{
+ stream << "..";
+ expr.get_to_expr ()->accept_vis (*this);
+}
void
Dump::visit (RangeFullExpr &expr)
-{}
+{
+ stream << "..";
+}
void
Dump::visit (RangeFromToInclExpr &expr)
-{}
+{
+ expr.get_from_expr ()->accept_vis (*this);
+ stream << "..=";
+ expr.get_to_expr ()->accept_vis (*this);
+}
void
Dump::visit (RangeToInclExpr &expr)
-{}
+{
+ stream << "..=";
+ expr.get_to_expr ()->accept_vis (*this);
+}
void
Dump::visit (ReturnExpr &expr)
@@ -586,6 +708,7 @@ Dump::visit (IfExpr &expr)
{
stream << "if ";
expr.vis_if_condition (*this);
+ stream << " ";
expr.vis_if_block (*this);
}
@@ -594,6 +717,7 @@ Dump::visit (IfExprConseqElse &expr)
{
stream << "if ";
expr.vis_if_condition (*this);
+ stream << " ";
expr.vis_if_block (*this);
stream << indentation << "else ";
expr.vis_else_block (*this);
@@ -604,8 +728,10 @@ Dump::visit (IfExprConseqIf &expr)
{
stream << "if ";
expr.vis_if_condition (*this);
+ stream << " ";
expr.vis_if_block (*this);
- stream << indentation << "else if ";
+ stream << indentation << "else ";
+ // The "if" part of the "else if" is printed by the next visitor
expr.vis_conseq_if_expr (*this);
}
@@ -699,7 +825,46 @@ Dump::visit (Method &method)
void
Dump::visit (Module &module)
-{}
+{
+ // Syntax:
+ // mod IDENTIFIER ;
+ // | mod IDENTIFIER {
+ // InnerAttribute*
+ // Item*
+ // }
+
+ emit_visibility (module.get_visibility ());
+ stream << "mod " << module.get_name ();
+
+ if (module.get_kind () == Module::UNLOADED)
+ {
+ stream << ";\n";
+ }
+ else /* Module::LOADED */
+ {
+ stream << " {\n";
+
+ indentation.increment ();
+
+ for (auto &item : module.get_inner_attrs ())
+ {
+ stream << indentation;
+ emit_attrib (item);
+ stream << '\n';
+ }
+
+ for (auto &item : module.get_items ())
+ {
+ stream << indentation;
+ item->accept_vis (*this);
+ stream << '\n';
+ }
+
+ indentation.decrement ();
+
+ stream << indentation << "}\n";
+ }
+}
void
Dump::visit (ExternCrate &crate)
@@ -725,8 +890,8 @@ void
Dump::visit (Function &function)
{
emit_visibility (function.get_visibility ());
- stream << "fn " << function.get_function_name ();
+ stream << "fn " << function.get_function_name ();
if (function.has_generics ())
emit_generic_params (function.get_generic_params ());
@@ -762,7 +927,24 @@ Dump::visit (Function &function)
void
Dump::visit (TypeAlias &type_alias)
-{}
+{
+ // Syntax:
+ // Visibility? type IDENTIFIER GenericParams? WhereClause? = Type;
+
+ // Note: Associated types are handled by `AST::TraitItemType`.
+
+ if (type_alias.has_visibility ())
+ emit_visibility (type_alias.get_visibility ());
+ stream << "type " << type_alias.get_new_type_name ();
+ if (type_alias.has_generics ())
+ emit_generic_params (type_alias.get_generic_params ());
+ if (type_alias.has_where_clause ())
+ {
+ } // FIXME: WhereClause
+ stream << " = ";
+ type_alias.get_type_aliased ()->accept_vis (*this);
+ stream << ";\n";
+}
void
Dump::visit (StructStruct &struct_item)
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index a674617..d52d108 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -824,7 +824,7 @@ ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
}
void
-ASTLoweringBase::handle_outer_attributes (const HIR::Item &item)
+ASTLoweringBase::handle_outer_attributes (const ItemWrapper &item)
{
for (const auto &attr : item.get_outer_attrs ())
{
@@ -855,7 +855,7 @@ ASTLoweringBase::handle_outer_attributes (const HIR::Item &item)
}
void
-ASTLoweringBase::handle_doc_item_attribute (const HIR::Item &item,
+ASTLoweringBase::handle_doc_item_attribute (const ItemWrapper &item,
const AST::Attribute &attr)
{
auto simple_doc_comment = attr.has_attr_input ()
@@ -878,7 +878,7 @@ ASTLoweringBase::handle_doc_item_attribute (const HIR::Item &item,
}
void
-ASTLoweringBase::handle_lang_item_attribute (const HIR::Item &item,
+ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
const AST::Attribute &attr)
{
auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index 68c57e0..5479e63 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -29,6 +29,30 @@
namespace Rust {
namespace HIR {
+// proxy class so we can do attribute checking on items and trait items
+class ItemWrapper
+{
+public:
+ ItemWrapper (const HIR::Item &item)
+ : mappings (item.get_mappings ()), locus (item.get_locus ()),
+ outer_attrs (item.get_outer_attrs ())
+ {}
+
+ ItemWrapper (const HIR::TraitItem &item)
+ : mappings (item.get_mappings ()), locus (item.get_trait_locus ()),
+ outer_attrs (item.get_outer_attrs ())
+ {}
+
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+ Location get_locus () const { return locus; }
+ const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
+
+private:
+ const Analysis::NodeMapping &mappings;
+ Location locus;
+ const AST::AttrVec &outer_attrs;
+};
+
// base class to allow derivatives to overload as needed
class ASTLoweringBase : public AST::ASTVisitor
{
@@ -264,12 +288,12 @@ protected:
HIR::FunctionQualifiers
lower_qualifiers (const AST::FunctionQualifiers &qualifiers);
- void handle_outer_attributes (const HIR::Item &item);
+ void handle_outer_attributes (const ItemWrapper &item);
- void handle_lang_item_attribute (const HIR::Item &item,
+ void handle_lang_item_attribute (const ItemWrapper &item,
const AST::Attribute &attr);
- void handle_doc_item_attribute (const HIR::Item &item,
+ void handle_doc_item_attribute (const ItemWrapper &item,
const AST::Attribute &attr);
bool is_known_attribute (const std::string &attribute_path) const;
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index d5ca475..4f3e813 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -305,16 +305,14 @@ public:
if (resolver.translated != nullptr)
{
- // FIXME
+ auto id = resolver.translated->get_mappings ().get_hirid ();
+ auto defid = resolver.translated->get_mappings ().get_defid ();
+ auto locus = resolver.translated->get_trait_locus ();
- // auto id = resolver.translated->get_mappings ().get_hirid ();
- // auto defid = resolver.translated->get_mappings ().get_defid ();
- // auto locus = resolver.translated->get_locus ();
-
- // resolver.handle_outer_attributes (*resolver.translated);
+ resolver.handle_outer_attributes (*resolver.translated);
resolver.mappings->insert_hir_trait_item (resolver.translated);
- // resolver.mappings->insert_location (id, locus);
- // resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
+ resolver.mappings->insert_location (id, locus);
+ resolver.mappings->insert_defid_mapping (defid, resolver.translated);
}
return resolver.translated;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 394b04f..d84e41e 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -2394,6 +2394,8 @@ public:
return outer_attrs;
}
+ Location get_trait_locus () const override { return get_locus (); }
+
protected:
// Clone function implementation as (not pure) virtual method
TraitItemFunc *clone_trait_item_impl () const override
@@ -2480,6 +2482,8 @@ public:
return outer_attrs;
}
+ Location get_trait_locus () const override { return get_locus (); }
+
protected:
// Clone function implementation as (not pure) virtual method
TraitItemConst *clone_trait_item_impl () const override
@@ -2567,6 +2571,8 @@ public:
return outer_attrs;
}
+ Location get_trait_locus () const override { return get_locus (); }
+
protected:
// Clone function implementation as (not pure) virtual method
TraitItemType *clone_trait_item_impl () const override
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 927ac06..26bf302 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -796,7 +796,9 @@ public:
virtual const std::string trait_identifier () const = 0;
- const Analysis::NodeMapping get_mappings () const { return mappings; }
+ const Analysis::NodeMapping &get_mappings () const { return mappings; }
+
+ virtual Location get_trait_locus () const = 0;
virtual TraitItemKind get_item_kind () const = 0;
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 146fe26..6bd3cc1 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -91,33 +91,42 @@ TraitResolver::Lookup (HIR::TypePath &path)
return resolver.lookup_path (path);
}
-TraitResolver::TraitResolver ()
- : TypeCheckBase (), resolved_trait_reference (nullptr)
-{}
+TraitResolver::TraitResolver () : TypeCheckBase () {}
-TraitReference *
-TraitResolver::resolve_path (HIR::TypePath &path)
+bool
+TraitResolver::resolve_path_to_trait (const HIR::TypePath &path,
+ HIR::Trait **resolved) const
{
NodeId ref;
if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
&ref))
{
rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
- return &TraitReference::error_node ();
+ return false;
}
HirId hir_node = UNKNOWN_HIRID;
if (!mappings->lookup_node_to_hir (ref, &hir_node))
{
rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
- return &TraitReference::error_node ();
+ return false;
}
HIR::Item *resolved_item = mappings->lookup_hir_item (hir_node);
-
rust_assert (resolved_item != nullptr);
- resolved_item->accept_vis (*this);
- rust_assert (resolved_trait_reference != nullptr);
+ rust_assert (resolved_item->get_item_kind () == HIR::Item::ItemKind::Trait);
+ *resolved = static_cast<HIR::Trait *> (resolved_item);
+
+ return true;
+}
+
+TraitReference *
+TraitResolver::resolve_path (HIR::TypePath &path)
+{
+ HIR::Trait *resolved_trait_reference;
+ bool ok = resolve_path_to_trait (path, &resolved_trait_reference);
+ if (!ok)
+ return &TraitReference::error_node ();
return resolve_trait (resolved_trait_reference);
}
@@ -132,6 +141,14 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
return tref;
}
+ DefId trait_id = trait_reference->get_mappings ().get_defid ();
+ if (context->trait_query_in_progress (trait_id))
+ {
+ rust_error_at (trait_reference->get_locus (), "trait cycle detected");
+ return &TraitReference::error_node ();
+ }
+
+ TraitQueryGuard guard (trait_id);
TyTy::BaseType *self = nullptr;
std::vector<TyTy::SubstitutionParamMapping> substitutions;
for (auto &generic_param : trait_reference->get_generic_params ())
@@ -192,8 +209,10 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
HIR::TraitBound *b
= static_cast<HIR::TraitBound *> (bound.get ());
- // FIXME this might be recursive we need a check for that
auto predicate = get_predicate_from_bound (b->get_path ());
+ if (predicate.is_error ())
+ return &TraitReference::error_node ();
+
specified_bounds.push_back (predicate);
super_traits.push_back (predicate.get ());
}
@@ -237,26 +256,10 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
TraitReference *
TraitResolver::lookup_path (HIR::TypePath &path)
{
- NodeId ref;
- if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
- &ref))
- {
- rust_error_at (path.get_locus (), "Failed to resolve path to node-id");
- return &TraitReference::error_node ();
- }
-
- HirId hir_node = UNKNOWN_HIRID;
- if (!mappings->lookup_node_to_hir (ref, &hir_node))
- {
- rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
- return &TraitReference::error_node ();
- }
-
- HIR::Item *resolved_item = mappings->lookup_hir_item (hir_node);
-
- rust_assert (resolved_item != nullptr);
- resolved_item->accept_vis (*this);
- rust_assert (resolved_trait_reference != nullptr);
+ HIR::Trait *resolved_trait_reference;
+ bool ok = resolve_path_to_trait (path, &resolved_trait_reference);
+ if (!ok)
+ return &TraitReference::error_node ();
TraitReference *tref = &TraitReference::error_node ();
if (context->lookup_trait_reference (
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index c4aaf42..468f429 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -55,10 +55,8 @@ private:
std::vector<TyTy::SubstitutionParamMapping> substitutions;
};
-class TraitResolver : public TypeCheckBase, private HIR::HIRFullVisitorBase
+class TraitResolver : public TypeCheckBase
{
- using HIR::HIRFullVisitorBase::visit;
-
public:
static TraitReference *Resolve (HIR::TypePath &path);
@@ -75,10 +73,8 @@ private:
TraitReference *lookup_path (HIR::TypePath &path);
- HIR::Trait *resolved_trait_reference;
-
-public:
- void visit (HIR::Trait &trait) override { resolved_trait_reference = &trait; }
+ bool resolve_path_to_trait (const HIR::TypePath &path,
+ HIR::Trait **resolved) const;
};
} // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index f85585b..de3467b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -381,6 +381,19 @@ public:
return querys_in_progress.find (id) != querys_in_progress.end ();
}
+ void insert_trait_query (DefId id) { trait_queries_in_progress.insert (id); }
+
+ void trait_query_completed (DefId id)
+ {
+ trait_queries_in_progress.erase (id);
+ }
+
+ bool trait_query_in_progress (DefId id) const
+ {
+ return trait_queries_in_progress.find (id)
+ != trait_queries_in_progress.end ();
+ }
+
private:
TypeCheckContext ();
@@ -418,6 +431,7 @@ private:
// query context lookups
std::set<HirId> querys_in_progress;
+ std::set<DefId> trait_queries_in_progress;
};
class TypeResolution
@@ -426,6 +440,21 @@ public:
static void Resolve (HIR::Crate &crate);
};
+class TraitQueryGuard
+{
+public:
+ TraitQueryGuard (DefId id) : id (id), ctx (*TypeCheckContext::get ())
+ {
+ ctx.insert_trait_query (id);
+ }
+
+ ~TraitQueryGuard () { ctx.trait_query_completed (id); }
+
+private:
+ DefId id;
+ TypeCheckContext &ctx;
+};
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 53c5b5a..cb540cd 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -316,6 +316,7 @@ Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
rust_assert (lookup_defid (id) == nullptr);
rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
+ rust_assert (lookup_trait_item_defid (id) == nullptr);
defIdMappings[id] = item;
insert_local_defid_mapping (crate_num, local_def_id, item);
@@ -332,6 +333,29 @@ Mappings::lookup_defid (DefId id)
}
void
+Mappings::insert_defid_mapping (DefId id, HIR::TraitItem *item)
+{
+ CrateNum crate_num = id.crateNum;
+ LocalDefId local_def_id = id.localDefId;
+
+ rust_assert (lookup_defid (id) == nullptr);
+ rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
+ rust_assert (lookup_trait_item_defid (id) == nullptr);
+
+ defIdTraitItemMappings[id] = item;
+}
+
+HIR::TraitItem *
+Mappings::lookup_trait_item_defid (DefId id)
+{
+ auto it = defIdTraitItemMappings.find (id);
+ if (it == defIdTraitItemMappings.end ())
+ return nullptr;
+
+ return it->second;
+}
+
+void
Mappings::insert_hir_item (HIR::Item *item)
{
auto id = item->get_mappings ().get_hirid ();
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 5913a02..4c7e562 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -104,6 +104,8 @@ public:
void insert_defid_mapping (DefId id, HIR::Item *item);
HIR::Item *lookup_defid (DefId id);
+ void insert_defid_mapping (DefId id, HIR::TraitItem *item);
+ HIR::TraitItem *lookup_trait_item_defid (DefId id);
void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
HIR::Item *item);
@@ -307,6 +309,7 @@ private:
std::map<CrateNum, AST::Crate *> ast_crate_mappings;
std::map<CrateNum, HIR::Crate *> hir_crate_mappings;
std::map<DefId, HIR::Item *> defIdMappings;
+ std::map<DefId, HIR::TraitItem *> defIdTraitItemMappings;
std::map<CrateNum, std::map<LocalDefId, HIR::Item *>> localDefIdMappings;
std::map<HirId, HIR::Module *> hirModuleMappings;
diff --git a/gcc/testsuite/rust/compile/issue-1589.rs b/gcc/testsuite/rust/compile/issue-1589.rs
new file mode 100644
index 0000000..79a5866
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1589.rs
@@ -0,0 +1,5 @@
+pub trait A: B {}
+// { dg-error "trait cycle detected" "" { target *-*-* } .-1 }
+
+pub trait B: A {}
+// { dg-error "trait cycle detected" "" { target *-*-* } .-1 }