Rollup merge of #68313 - batrla:master, r=alexcrichton
Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD
Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD and Solaris
See ip(4P) man page:
IP_MULTICAST_TTL Time to live for multicast datagrams. This option
takes an unsigned character as an argument. Its
value is the TTL that IP uses on outgoing multi-
cast datagrams. The default is 1.
IP_MULTICAST_LOOP Loopback for multicast datagrams. Normally multi-
cast datagrams are delivered to members on the
sending host (or sending zone). Setting the
unsigned character argument to 0 causes the oppo-
site behavior, meaning that when multiple zones
are present, the datagrams are delivered to all
zones except the sending zone.
https://docs.oracle.com/cd/E88353_01/html/E37851/ip-4p.html
https://man.openbsd.org/ip.4
diff --git a/.gitmodules b/.gitmodules
index 31db077..62cbbdd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -40,7 +40,7 @@
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
- branch = rustc/9.0-2019-09-19
+ branch = rustc/9.0-2019-12-19
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git
diff --git a/Cargo.lock b/Cargo.lock
index f33d7ff..48bc269 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3092,7 +3092,6 @@
"rustc-rayon-core",
"rustc_apfloat",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_hir",
@@ -3358,7 +3357,6 @@
"log",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_index",
@@ -3375,7 +3373,6 @@
dependencies = [
"log",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_parse",
@@ -3391,7 +3388,6 @@
"fmt_macros",
"log",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_expand",
"rustc_feature",
@@ -3445,7 +3441,6 @@
"rustc_apfloat",
"rustc_codegen_utils",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_fs_util",
"rustc_hir",
@@ -3675,7 +3670,6 @@
"log",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_hir",
@@ -3716,7 +3710,6 @@
"memmap",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_expand",
"rustc_hir",
@@ -3744,7 +3737,6 @@
"rustc",
"rustc_apfloat",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_index",
@@ -3767,7 +3759,6 @@
"rustc",
"rustc_apfloat",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_index",
@@ -3786,7 +3777,6 @@
"bitflags",
"log",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_lexer",
@@ -3804,7 +3794,6 @@
"log",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_hir",
@@ -3820,7 +3809,6 @@
version = "0.0.0"
dependencies = [
"rustc",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_lint",
@@ -3836,7 +3824,6 @@
"log",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_span",
@@ -3854,7 +3841,6 @@
"rustc",
"rustc_ast_lowering",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_expand",
"rustc_feature",
@@ -3890,7 +3876,6 @@
"log",
"num_cpus",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_fs_util",
@@ -3973,7 +3958,6 @@
"log",
"rustc",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_index",
@@ -4493,7 +4477,6 @@
dependencies = [
"log",
"rustc_data_structures",
- "rustc_error_codes",
"rustc_errors",
"rustc_feature",
"rustc_index",
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 16fe87b..1b5ec8b 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -174,28 +174,3 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index 6bbf092..546e73e 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -2,11 +2,24 @@
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ \
+ automake \
+ bison \
+ bzip2 \
+ flex \
+ help2man \
+ libtool-bin \
+ texinfo \
+ unzip \
+ wget \
+ xz-utils \
+ libncurses-dev \
+ gawk \
make \
file \
curl \
ca-certificates \
python2.7 \
+ python3 \
git \
cmake \
sudo \
@@ -35,6 +48,18 @@
apt-get update && \
apt-get install -y --no-install-recommends gcc-arm-embedded
+COPY scripts/rustbuild-setup.sh dist-various-1/build-riscv-toolchain.sh dist-various-1/riscv64-unknown-linux-gnu.config dist-various-1/crosstool-ng.sh /build/
+RUN ./crosstool-ng.sh
+
+# Crosstool-ng will refuse to build as root
+RUN sh ./rustbuild-setup.sh
+USER rustbuild
+
+RUN ./build-riscv-toolchain.sh
+
+USER root
+ENV PATH=/x-tools/riscv64-unknown-linux-gnu/bin:$PATH
+
COPY dist-various-1/build-rumprun.sh /build
RUN ./build-rumprun.sh
@@ -129,6 +154,7 @@
ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf
ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf
ENV TARGETS=$TARGETS,riscv64gc-unknown-none-elf
+ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-gnu
ENV TARGETS=$TARGETS,armebv7r-none-eabi
ENV TARGETS=$TARGETS,armebv7r-none-eabihf
ENV TARGETS=$TARGETS,armv7r-none-eabi
@@ -147,6 +173,9 @@
CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \
+ CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
+ AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
+ CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \
CC_riscv32i_unknown_none_elf=false \
CC_riscv32imc_unknown_none_elf=false \
CC_riscv32imac_unknown_none_elf=false \
diff --git a/src/ci/docker/dist-various-1/build-riscv-toolchain.sh b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh
new file mode 100755
index 0000000..9cb5700
--- /dev/null
+++ b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+set -ex
+
+hide_output() {
+ set +x
+ on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+ trap "$on_err" ERR
+ bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+ PING_LOOP_PID=$!
+ $@ &> /tmp/build.log
+ rm /tmp/build.log
+ trap - ERR
+ kill $PING_LOOP_PID
+ set -x
+}
+
+mkdir -p /tmp/build-riscv
+cp riscv64-unknown-linux-gnu.config /tmp/build-riscv/.config
+cd /tmp/build-riscv
+hide_output ct-ng build
+cd ..
+rm -rf build-riscv
diff --git a/src/ci/docker/dist-various-1/crosstool-ng.sh b/src/ci/docker/dist-various-1/crosstool-ng.sh
new file mode 100755
index 0000000..b01fdd0
--- /dev/null
+++ b/src/ci/docker/dist-various-1/crosstool-ng.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -ex
+
+# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz
+url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz"
+curl -Lf $url | tar xzf -
+cd crosstool-ng-crosstool-ng-1.24.0
+./bootstrap
+./configure --prefix=/usr/local
+make -j$(nproc)
+make install
+cd ..
+rm -rf crosstool-ng-crosstool-ng-1.24.0
diff --git a/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config
new file mode 100644
index 0000000..dd06065
--- /dev/null
+++ b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config
@@ -0,0 +1,908 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# crosstool-NG Configuration
+#
+CT_CONFIGURE_has_static_link=y
+CT_CONFIGURE_has_cxx11=y
+CT_CONFIGURE_has_wget=y
+CT_CONFIGURE_has_curl=y
+CT_CONFIGURE_has_make_3_81_or_newer=y
+CT_CONFIGURE_has_make_4_0_or_newer=y
+CT_CONFIGURE_has_libtool_2_4_or_newer=y
+CT_CONFIGURE_has_libtoolize_2_4_or_newer=y
+CT_CONFIGURE_has_autoconf_2_65_or_newer=y
+CT_CONFIGURE_has_autoreconf_2_65_or_newer=y
+CT_CONFIGURE_has_automake_1_15_or_newer=y
+CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y
+CT_CONFIGURE_has_python_3_4_or_newer=y
+CT_CONFIGURE_has_bison_2_7_or_newer=y
+CT_CONFIGURE_has_python=y
+CT_CONFIGURE_has_dtc=y
+CT_CONFIGURE_has_svn=y
+CT_CONFIGURE_has_git=y
+CT_CONFIGURE_has_md5sum=y
+CT_CONFIGURE_has_sha1sum=y
+CT_CONFIGURE_has_sha256sum=y
+CT_CONFIGURE_has_sha512sum=y
+CT_CONFIGURE_has_install_with_strip_program=y
+CT_CONFIG_VERSION_CURRENT="3"
+CT_CONFIG_VERSION="3"
+CT_MODULES=y
+
+#
+# Paths and misc options
+#
+
+#
+# crosstool-NG behavior
+#
+# CT_OBSOLETE is not set
+CT_EXPERIMENTAL=y
+# CT_ALLOW_BUILD_AS_ROOT is not set
+# CT_DEBUG_CT is not set
+
+#
+# Paths
+#
+CT_LOCAL_TARBALLS_DIR="${HOME}/src"
+CT_SAVE_TARBALLS=y
+# CT_TARBALLS_BUILDROOT_LAYOUT is not set
+CT_WORK_DIR="${CT_TOP_DIR}/.build"
+CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}"
+CT_PREFIX_DIR="/x-tools/${CT_TARGET}"
+CT_RM_RF_PREFIX_DIR=y
+CT_REMOVE_DOCS=y
+CT_INSTALL_LICENSES=y
+CT_PREFIX_DIR_RO=y
+CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
+# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set
+
+#
+# Downloading
+#
+CT_DOWNLOAD_AGENT_WGET=y
+# CT_DOWNLOAD_AGENT_CURL is not set
+# CT_DOWNLOAD_AGENT_NONE is not set
+# CT_FORBID_DOWNLOAD is not set
+# CT_FORCE_DOWNLOAD is not set
+CT_CONNECT_TIMEOUT=10
+CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary"
+# CT_ONLY_DOWNLOAD is not set
+# CT_USE_MIRROR is not set
+CT_VERIFY_DOWNLOAD_DIGEST=y
+CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set
+# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set
+CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512"
+# CT_VERIFY_DOWNLOAD_SIGNATURE is not set
+
+#
+# Extracting
+#
+# CT_FORCE_EXTRACT is not set
+CT_OVERRIDE_CONFIG_GUESS_SUB=y
+# CT_ONLY_EXTRACT is not set
+CT_PATCH_BUNDLED=y
+# CT_PATCH_LOCAL is not set
+# CT_PATCH_BUNDLED_LOCAL is not set
+# CT_PATCH_LOCAL_BUNDLED is not set
+# CT_PATCH_NONE is not set
+CT_PATCH_ORDER="bundled"
+
+#
+# Build behavior
+#
+CT_PARALLEL_JOBS=0
+CT_LOAD=""
+CT_USE_PIPES=y
+CT_EXTRA_CFLAGS_FOR_BUILD=""
+CT_EXTRA_LDFLAGS_FOR_BUILD=""
+CT_EXTRA_CFLAGS_FOR_HOST=""
+CT_EXTRA_LDFLAGS_FOR_HOST=""
+# CT_CONFIG_SHELL_SH is not set
+# CT_CONFIG_SHELL_ASH is not set
+CT_CONFIG_SHELL_BASH=y
+# CT_CONFIG_SHELL_CUSTOM is not set
+CT_CONFIG_SHELL="${bash}"
+
+#
+# Logging
+#
+# CT_LOG_ERROR is not set
+# CT_LOG_WARN is not set
+# CT_LOG_INFO is not set
+# CT_LOG_EXTRA is not set
+CT_LOG_ALL=y
+# CT_LOG_DEBUG is not set
+CT_LOG_LEVEL_MAX="ALL"
+# CT_LOG_SEE_TOOLS_WARN is not set
+CT_LOG_TO_FILE=y
+CT_LOG_FILE_COMPRESS=y
+
+#
+# Target options
+#
+# CT_ARCH_ALPHA is not set
+# CT_ARCH_ARC is not set
+# CT_ARCH_ARM is not set
+# CT_ARCH_AVR is not set
+# CT_ARCH_M68K is not set
+# CT_ARCH_MICROBLAZE is not set
+# CT_ARCH_MIPS is not set
+# CT_ARCH_MOXIE is not set
+# CT_ARCH_MSP430 is not set
+# CT_ARCH_NIOS2 is not set
+# CT_ARCH_POWERPC is not set
+CT_ARCH_RISCV=y
+# CT_ARCH_S390 is not set
+# CT_ARCH_SH is not set
+# CT_ARCH_SPARC is not set
+# CT_ARCH_X86 is not set
+# CT_ARCH_XTENSA is not set
+CT_ARCH="riscv"
+CT_ARCH_CHOICE_KSYM="RISCV"
+CT_ARCH_TUNE=""
+CT_ARCH_RISCV_SHOW=y
+
+#
+# Options for riscv
+#
+CT_ARCH_RISCV_PKG_KSYM=""
+CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA"
+CT_ARCH_SUFFIX=""
+# CT_OMIT_TARGET_VENDOR is not set
+
+#
+# Generic target options
+#
+# CT_MULTILIB is not set
+# CT_DEMULTILIB is not set
+CT_ARCH_SUPPORTS_BOTH_MMU=y
+CT_ARCH_USE_MMU=y
+CT_ARCH_SUPPORTS_32=y
+CT_ARCH_SUPPORTS_64=y
+CT_ARCH_DEFAULT_32=y
+CT_ARCH_BITNESS=64
+# CT_ARCH_32 is not set
+CT_ARCH_64=y
+
+#
+# Target optimisations
+#
+CT_ARCH_SUPPORTS_WITH_ARCH=y
+CT_ARCH_SUPPORTS_WITH_ABI=y
+CT_ARCH_SUPPORTS_WITH_TUNE=y
+CT_ARCH_ARCH="rv64gc"
+CT_ARCH_ABI=""
+CT_TARGET_CFLAGS=""
+CT_TARGET_LDFLAGS=""
+
+#
+# Toolchain options
+#
+
+#
+# General toolchain options
+#
+CT_FORCE_SYSROOT=y
+CT_USE_SYSROOT=y
+CT_SYSROOT_NAME="sysroot"
+CT_SYSROOT_DIR_PREFIX=""
+CT_WANTS_STATIC_LINK=y
+CT_WANTS_STATIC_LINK_CXX=y
+# CT_STATIC_TOOLCHAIN is not set
+CT_SHOW_CT_VERSION=y
+CT_TOOLCHAIN_PKGVERSION=""
+CT_TOOLCHAIN_BUGURL=""
+
+#
+# Tuple completion and aliasing
+#
+CT_TARGET_VENDOR="unknown"
+CT_TARGET_ALIAS_SED_EXPR=""
+CT_TARGET_ALIAS=""
+
+#
+# Toolchain type
+#
+# CT_NATIVE is not set
+CT_CROSS=y
+# CT_CROSS_NATIVE is not set
+# CT_CANADIAN is not set
+CT_TOOLCHAIN_TYPE="cross"
+
+#
+# Build system
+#
+CT_BUILD=""
+CT_BUILD_PREFIX=""
+CT_BUILD_SUFFIX=""
+
+#
+# Misc options
+#
+# CT_TOOLCHAIN_ENABLE_NLS is not set
+
+#
+# Operating System
+#
+CT_KERNEL_SUPPORTS_SHARED_LIBS=y
+# CT_KERNEL_BARE_METAL is not set
+CT_KERNEL_LINUX=y
+CT_KERNEL="linux"
+CT_KERNEL_CHOICE_KSYM="LINUX"
+CT_KERNEL_LINUX_SHOW=y
+
+#
+# Options for linux
+#
+CT_KERNEL_LINUX_PKG_KSYM="LINUX"
+CT_LINUX_DIR_NAME="linux"
+CT_LINUX_PKG_NAME="linux"
+CT_LINUX_SRC_RELEASE=y
+# CT_LINUX_SRC_DEVEL is not set
+# CT_LINUX_SRC_CUSTOM is not set
+CT_LINUX_PATCH_GLOBAL=y
+# CT_LINUX_PATCH_BUNDLED is not set
+# CT_LINUX_PATCH_LOCAL is not set
+# CT_LINUX_PATCH_BUNDLED_LOCAL is not set
+# CT_LINUX_PATCH_LOCAL_BUNDLED is not set
+# CT_LINUX_PATCH_NONE is not set
+CT_LINUX_PATCH_ORDER="global"
+CT_LINUX_V_4_20=y
+# CT_LINUX_V_4_19 is not set
+# CT_LINUX_V_4_18 is not set
+# CT_LINUX_V_4_17 is not set
+# CT_LINUX_V_4_16 is not set
+# CT_LINUX_V_4_15 is not set
+# CT_LINUX_V_4_14 is not set
+# CT_LINUX_V_4_13 is not set
+# CT_LINUX_V_4_12 is not set
+# CT_LINUX_V_4_11 is not set
+# CT_LINUX_V_4_10 is not set
+# CT_LINUX_V_4_9 is not set
+# CT_LINUX_V_4_4 is not set
+# CT_LINUX_V_4_1 is not set
+# CT_LINUX_V_3_16 is not set
+# CT_LINUX_V_3_13 is not set
+# CT_LINUX_V_3_12 is not set
+# CT_LINUX_V_3_10 is not set
+# CT_LINUX_V_3_4 is not set
+# CT_LINUX_V_3_2 is not set
+# CT_LINUX_NO_VERSIONS is not set
+CT_LINUX_VERSION="4.20.8"
+CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})"
+CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign"
+CT_LINUX_later_than_4_8=y
+CT_LINUX_4_8_or_later=y
+CT_LINUX_later_than_3_7=y
+CT_LINUX_3_7_or_later=y
+CT_LINUX_later_than_3_2=y
+CT_LINUX_3_2_or_later=y
+CT_LINUX_REQUIRE_3_2_or_later=y
+CT_KERNEL_LINUX_VERBOSITY_0=y
+# CT_KERNEL_LINUX_VERBOSITY_1 is not set
+# CT_KERNEL_LINUX_VERBOSITY_2 is not set
+CT_KERNEL_LINUX_VERBOSE_LEVEL=0
+CT_KERNEL_LINUX_INSTALL_CHECK=y
+CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS"
+
+#
+# Common kernel options
+#
+CT_SHARED_LIBS=y
+
+#
+# Binary utilities
+#
+CT_ARCH_BINFMT_ELF=y
+CT_BINUTILS_BINUTILS=y
+CT_BINUTILS="binutils"
+CT_BINUTILS_CHOICE_KSYM="BINUTILS"
+CT_BINUTILS_BINUTILS_SHOW=y
+
+#
+# Options for binutils
+#
+CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS"
+CT_BINUTILS_DIR_NAME="binutils"
+CT_BINUTILS_USE_GNU=y
+CT_BINUTILS_USE="BINUTILS"
+CT_BINUTILS_PKG_NAME="binutils"
+CT_BINUTILS_SRC_RELEASE=y
+# CT_BINUTILS_SRC_DEVEL is not set
+# CT_BINUTILS_SRC_CUSTOM is not set
+CT_BINUTILS_PATCH_GLOBAL=y
+# CT_BINUTILS_PATCH_BUNDLED is not set
+# CT_BINUTILS_PATCH_LOCAL is not set
+# CT_BINUTILS_PATCH_BUNDLED_LOCAL is not set
+# CT_BINUTILS_PATCH_LOCAL_BUNDLED is not set
+# CT_BINUTILS_PATCH_NONE is not set
+CT_BINUTILS_PATCH_ORDER="global"
+CT_BINUTILS_V_2_32=y
+# CT_BINUTILS_V_2_31 is not set
+# CT_BINUTILS_V_2_30 is not set
+# CT_BINUTILS_V_2_29 is not set
+# CT_BINUTILS_V_2_28 is not set
+# CT_BINUTILS_V_2_27 is not set
+# CT_BINUTILS_V_2_26 is not set
+# CT_BINUTILS_NO_VERSIONS is not set
+CT_BINUTILS_VERSION="2.32"
+CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)"
+CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig"
+CT_BINUTILS_later_than_2_30=y
+CT_BINUTILS_2_30_or_later=y
+CT_BINUTILS_later_than_2_27=y
+CT_BINUTILS_2_27_or_later=y
+CT_BINUTILS_later_than_2_25=y
+CT_BINUTILS_2_25_or_later=y
+CT_BINUTILS_REQUIRE_2_25_or_later=y
+CT_BINUTILS_later_than_2_23=y
+CT_BINUTILS_2_23_or_later=y
+
+#
+# GNU binutils
+#
+CT_BINUTILS_HAS_HASH_STYLE=y
+CT_BINUTILS_HAS_GOLD=y
+CT_BINUTILS_HAS_PLUGINS=y
+CT_BINUTILS_HAS_PKGVERSION_BUGURL=y
+CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y
+CT_BINUTILS_LINKER_LD=y
+CT_BINUTILS_LINKERS_LIST="ld"
+CT_BINUTILS_LINKER_DEFAULT="bfd"
+# CT_BINUTILS_PLUGINS is not set
+CT_BINUTILS_RELRO=m
+CT_BINUTILS_EXTRA_CONFIG_ARRAY=""
+# CT_BINUTILS_FOR_TARGET is not set
+CT_ALL_BINUTILS_CHOICES="BINUTILS"
+
+#
+# C-library
+#
+CT_LIBC_GLIBC=y
+# CT_LIBC_MUSL is not set
+# CT_LIBC_UCLIBC is not set
+CT_LIBC="glibc"
+CT_LIBC_CHOICE_KSYM="GLIBC"
+CT_THREADS="nptl"
+CT_LIBC_GLIBC_SHOW=y
+
+#
+# Options for glibc
+#
+CT_LIBC_GLIBC_PKG_KSYM="GLIBC"
+CT_GLIBC_DIR_NAME="glibc"
+CT_GLIBC_USE_GNU=y
+CT_GLIBC_USE="GLIBC"
+CT_GLIBC_PKG_NAME="glibc"
+CT_GLIBC_SRC_RELEASE=y
+# CT_GLIBC_SRC_DEVEL is not set
+# CT_GLIBC_SRC_CUSTOM is not set
+CT_GLIBC_PATCH_GLOBAL=y
+# CT_GLIBC_PATCH_BUNDLED is not set
+# CT_GLIBC_PATCH_LOCAL is not set
+# CT_GLIBC_PATCH_BUNDLED_LOCAL is not set
+# CT_GLIBC_PATCH_LOCAL_BUNDLED is not set
+# CT_GLIBC_PATCH_NONE is not set
+CT_GLIBC_PATCH_ORDER="global"
+CT_GLIBC_V_2_29=y
+# CT_GLIBC_NO_VERSIONS is not set
+CT_GLIBC_VERSION="2.29"
+CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)"
+CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_GLIBC_SIGNATURE_FORMAT="packed/.sig"
+CT_GLIBC_2_29_or_later=y
+CT_GLIBC_2_29_or_older=y
+CT_GLIBC_REQUIRE_2_29_or_later=y
+CT_GLIBC_later_than_2_27=y
+CT_GLIBC_2_27_or_later=y
+CT_GLIBC_later_than_2_26=y
+CT_GLIBC_2_26_or_later=y
+CT_GLIBC_later_than_2_25=y
+CT_GLIBC_2_25_or_later=y
+CT_GLIBC_later_than_2_24=y
+CT_GLIBC_2_24_or_later=y
+CT_GLIBC_later_than_2_23=y
+CT_GLIBC_2_23_or_later=y
+CT_GLIBC_later_than_2_20=y
+CT_GLIBC_2_20_or_later=y
+CT_GLIBC_later_than_2_17=y
+CT_GLIBC_2_17_or_later=y
+CT_GLIBC_later_than_2_14=y
+CT_GLIBC_2_14_or_later=y
+CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y
+CT_GLIBC_DEP_BINUTILS=y
+CT_GLIBC_DEP_GCC=y
+CT_GLIBC_DEP_PYTHON=y
+CT_GLIBC_BUILD_SSP=y
+CT_GLIBC_HAS_LIBIDN_ADDON=y
+# CT_GLIBC_USE_LIBIDN_ADDON is not set
+CT_GLIBC_NO_SPARC_V8=y
+CT_GLIBC_HAS_OBSOLETE_RPC=y
+CT_GLIBC_EXTRA_CONFIG_ARRAY=""
+CT_GLIBC_CONFIGPARMS=""
+CT_GLIBC_EXTRA_CFLAGS=""
+CT_GLIBC_ENABLE_OBSOLETE_RPC=y
+# CT_GLIBC_ENABLE_FORTIFIED_BUILD is not set
+# CT_GLIBC_DISABLE_VERSIONING is not set
+CT_GLIBC_OLDEST_ABI=""
+CT_GLIBC_FORCE_UNWIND=y
+# CT_GLIBC_LOCALES is not set
+CT_GLIBC_KERNEL_VERSION_NONE=y
+# CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set
+# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set
+CT_GLIBC_MIN_KERNEL=""
+CT_GLIBC_SSP_DEFAULT=y
+# CT_GLIBC_SSP_NO is not set
+# CT_GLIBC_SSP_YES is not set
+# CT_GLIBC_SSP_ALL is not set
+# CT_GLIBC_SSP_STRONG is not set
+# CT_GLIBC_ENABLE_WERROR is not set
+CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC"
+CT_LIBC_SUPPORT_THREADS_ANY=y
+CT_LIBC_SUPPORT_THREADS_NATIVE=y
+
+#
+# Common C library options
+#
+CT_THREADS_NATIVE=y
+# CT_CREATE_LDSO_CONF is not set
+CT_LIBC_XLDD=y
+
+#
+# C compiler
+#
+CT_CC_CORE_PASSES_NEEDED=y
+CT_CC_CORE_PASS_1_NEEDED=y
+CT_CC_CORE_PASS_2_NEEDED=y
+CT_CC_SUPPORT_CXX=y
+CT_CC_SUPPORT_FORTRAN=y
+CT_CC_SUPPORT_ADA=y
+CT_CC_SUPPORT_OBJC=y
+CT_CC_SUPPORT_OBJCXX=y
+CT_CC_SUPPORT_GOLANG=y
+CT_CC_GCC=y
+CT_CC="gcc"
+CT_CC_CHOICE_KSYM="GCC"
+CT_CC_GCC_SHOW=y
+
+#
+# Options for gcc
+#
+CT_CC_GCC_PKG_KSYM="GCC"
+CT_GCC_DIR_NAME="gcc"
+CT_GCC_USE_GNU=y
+# CT_GCC_USE_LINARO is not set
+CT_GCC_USE="GCC"
+CT_GCC_PKG_NAME="gcc"
+CT_GCC_SRC_RELEASE=y
+# CT_GCC_SRC_DEVEL is not set
+# CT_GCC_SRC_CUSTOM is not set
+CT_GCC_PATCH_GLOBAL=y
+# CT_GCC_PATCH_BUNDLED is not set
+# CT_GCC_PATCH_LOCAL is not set
+# CT_GCC_PATCH_BUNDLED_LOCAL is not set
+# CT_GCC_PATCH_LOCAL_BUNDLED is not set
+# CT_GCC_PATCH_NONE is not set
+CT_GCC_PATCH_ORDER="global"
+CT_GCC_V_8=y
+# CT_GCC_V_7 is not set
+# CT_GCC_NO_VERSIONS is not set
+CT_GCC_VERSION="8.3.0"
+CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})"
+CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GCC_SIGNATURE_FORMAT=""
+CT_GCC_later_than_7=y
+CT_GCC_7_or_later=y
+CT_GCC_REQUIRE_7_or_later=y
+CT_GCC_later_than_6=y
+CT_GCC_6_or_later=y
+CT_GCC_later_than_5=y
+CT_GCC_5_or_later=y
+CT_GCC_REQUIRE_5_or_later=y
+CT_GCC_later_than_4_9=y
+CT_GCC_4_9_or_later=y
+CT_GCC_REQUIRE_4_9_or_later=y
+CT_GCC_later_than_4_8=y
+CT_GCC_4_8_or_later=y
+CT_CC_GCC_HAS_LIBMPX=y
+CT_CC_GCC_ENABLE_CXX_FLAGS=""
+CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_EXTRA_CONFIG_ARRAY=""
+CT_CC_GCC_STATIC_LIBSTDCXX=y
+# CT_CC_GCC_SYSTEM_ZLIB is not set
+CT_CC_GCC_CONFIG_TLS=m
+
+#
+# Optimisation features
+#
+CT_CC_GCC_USE_GRAPHITE=y
+CT_CC_GCC_USE_LTO=y
+
+#
+# Settings for libraries running on target
+#
+CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y
+# CT_CC_GCC_LIBMUDFLAP is not set
+# CT_CC_GCC_LIBGOMP is not set
+# CT_CC_GCC_LIBSSP is not set
+# CT_CC_GCC_LIBQUADMATH is not set
+# CT_CC_GCC_LIBSANITIZER is not set
+
+#
+# Misc. obscure options.
+#
+CT_CC_CXA_ATEXIT=y
+# CT_CC_GCC_DISABLE_PCH is not set
+CT_CC_GCC_SJLJ_EXCEPTIONS=m
+CT_CC_GCC_LDBL_128=m
+# CT_CC_GCC_BUILD_ID is not set
+CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y
+# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set
+# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set
+# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set
+CT_CC_GCC_LNK_HASH_STYLE=""
+CT_CC_GCC_DEC_FLOAT_AUTO=y
+# CT_CC_GCC_DEC_FLOAT_BID is not set
+# CT_CC_GCC_DEC_FLOAT_DPD is not set
+# CT_CC_GCC_DEC_FLOATS_NO is not set
+CT_ALL_CC_CHOICES="GCC"
+
+#
+# Additional supported languages:
+#
+CT_CC_LANG_CXX=y
+# CT_CC_LANG_FORTRAN is not set
+# CT_CC_LANG_ADA is not set
+# CT_CC_LANG_OBJC is not set
+# CT_CC_LANG_OBJCXX is not set
+# CT_CC_LANG_GOLANG is not set
+CT_CC_LANG_OTHERS=""
+
+#
+# Debug facilities
+#
+# CT_DEBUG_DUMA is not set
+CT_DEBUG_GDB=y
+CT_DEBUG_GDB_PKG_KSYM="GDB"
+CT_GDB_DIR_NAME="gdb"
+CT_GDB_USE_GNU=y
+CT_GDB_USE="GDB"
+CT_GDB_PKG_NAME="gdb"
+CT_GDB_SRC_RELEASE=y
+# CT_GDB_SRC_DEVEL is not set
+# CT_GDB_SRC_CUSTOM is not set
+CT_GDB_PATCH_GLOBAL=y
+# CT_GDB_PATCH_BUNDLED is not set
+# CT_GDB_PATCH_LOCAL is not set
+# CT_GDB_PATCH_BUNDLED_LOCAL is not set
+# CT_GDB_PATCH_LOCAL_BUNDLED is not set
+# CT_GDB_PATCH_NONE is not set
+CT_GDB_PATCH_ORDER="global"
+CT_GDB_V_8_2=y
+# CT_GDB_V_8_1 is not set
+# CT_GDB_V_8_0 is not set
+# CT_GDB_NO_VERSIONS is not set
+CT_GDB_VERSION="8.2.1"
+CT_GDB_MIRRORS="$(CT_Mirrors GNU gdb) $(CT_Mirrors sourceware gdb/releases)"
+CT_GDB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GDB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GDB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_GDB_SIGNATURE_FORMAT=""
+CT_GDB_later_than_8_0=y
+CT_GDB_8_0_or_later=y
+CT_GDB_REQUIRE_8_0_or_later=y
+CT_GDB_later_than_7_12=y
+CT_GDB_7_12_or_later=y
+CT_GDB_later_than_7_2=y
+CT_GDB_7_2_or_later=y
+CT_GDB_later_than_7_0=y
+CT_GDB_7_0_or_later=y
+CT_GDB_CROSS=y
+# CT_GDB_CROSS_STATIC is not set
+# CT_GDB_CROSS_SIM is not set
+# CT_GDB_CROSS_PYTHON is not set
+CT_GDB_CROSS_EXTRA_CONFIG_ARRAY=""
+# CT_GDB_NATIVE is not set
+# CT_GDB_GDBSERVER is not set
+CT_GDB_HAS_PKGVERSION_BUGURL=y
+CT_GDB_HAS_PYTHON=y
+CT_GDB_INSTALL_GDBINIT=y
+CT_GDB_HAS_IPA_LIB=y
+# CT_DEBUG_LTRACE is not set
+# CT_DEBUG_STRACE is not set
+CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE"
+
+#
+# Companion libraries
+#
+# CT_COMPLIBS_CHECK is not set
+# CT_COMP_LIBS_CLOOG is not set
+CT_COMP_LIBS_EXPAT=y
+CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT"
+CT_EXPAT_DIR_NAME="expat"
+CT_EXPAT_PKG_NAME="expat"
+CT_EXPAT_SRC_RELEASE=y
+# CT_EXPAT_SRC_DEVEL is not set
+# CT_EXPAT_SRC_CUSTOM is not set
+CT_EXPAT_PATCH_GLOBAL=y
+# CT_EXPAT_PATCH_BUNDLED is not set
+# CT_EXPAT_PATCH_LOCAL is not set
+# CT_EXPAT_PATCH_BUNDLED_LOCAL is not set
+# CT_EXPAT_PATCH_LOCAL_BUNDLED is not set
+# CT_EXPAT_PATCH_NONE is not set
+CT_EXPAT_PATCH_ORDER="global"
+CT_EXPAT_V_2_2=y
+# CT_EXPAT_NO_VERSIONS is not set
+CT_EXPAT_VERSION="2.2.6"
+CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}"
+CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2"
+CT_EXPAT_SIGNATURE_FORMAT=""
+CT_COMP_LIBS_GETTEXT=y
+CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT"
+CT_GETTEXT_DIR_NAME="gettext"
+CT_GETTEXT_PKG_NAME="gettext"
+CT_GETTEXT_SRC_RELEASE=y
+# CT_GETTEXT_SRC_DEVEL is not set
+# CT_GETTEXT_SRC_CUSTOM is not set
+CT_GETTEXT_PATCH_GLOBAL=y
+# CT_GETTEXT_PATCH_BUNDLED is not set
+# CT_GETTEXT_PATCH_LOCAL is not set
+# CT_GETTEXT_PATCH_BUNDLED_LOCAL is not set
+# CT_GETTEXT_PATCH_LOCAL_BUNDLED is not set
+# CT_GETTEXT_PATCH_NONE is not set
+CT_GETTEXT_PATCH_ORDER="global"
+CT_GETTEXT_V_0_19_8_1=y
+# CT_GETTEXT_NO_VERSIONS is not set
+CT_GETTEXT_VERSION="0.19.8.1"
+CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)"
+CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz"
+CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_GMP=y
+CT_COMP_LIBS_GMP_PKG_KSYM="GMP"
+CT_GMP_DIR_NAME="gmp"
+CT_GMP_PKG_NAME="gmp"
+CT_GMP_SRC_RELEASE=y
+# CT_GMP_SRC_DEVEL is not set
+# CT_GMP_SRC_CUSTOM is not set
+CT_GMP_PATCH_GLOBAL=y
+# CT_GMP_PATCH_BUNDLED is not set
+# CT_GMP_PATCH_LOCAL is not set
+# CT_GMP_PATCH_BUNDLED_LOCAL is not set
+# CT_GMP_PATCH_LOCAL_BUNDLED is not set
+# CT_GMP_PATCH_NONE is not set
+CT_GMP_PATCH_ORDER="global"
+CT_GMP_V_6_1=y
+# CT_GMP_NO_VERSIONS is not set
+CT_GMP_VERSION="6.1.2"
+CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)"
+CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2"
+CT_GMP_SIGNATURE_FORMAT="packed/.sig"
+CT_GMP_later_than_5_1_0=y
+CT_GMP_5_1_0_or_later=y
+CT_GMP_later_than_5_0_0=y
+CT_GMP_5_0_0_or_later=y
+CT_GMP_REQUIRE_5_0_0_or_later=y
+CT_COMP_LIBS_ISL=y
+CT_COMP_LIBS_ISL_PKG_KSYM="ISL"
+CT_ISL_DIR_NAME="isl"
+CT_ISL_PKG_NAME="isl"
+CT_ISL_SRC_RELEASE=y
+# CT_ISL_SRC_DEVEL is not set
+# CT_ISL_SRC_CUSTOM is not set
+CT_ISL_PATCH_GLOBAL=y
+# CT_ISL_PATCH_BUNDLED is not set
+# CT_ISL_PATCH_LOCAL is not set
+# CT_ISL_PATCH_BUNDLED_LOCAL is not set
+# CT_ISL_PATCH_LOCAL_BUNDLED is not set
+# CT_ISL_PATCH_NONE is not set
+CT_ISL_PATCH_ORDER="global"
+CT_ISL_V_0_20=y
+# CT_ISL_V_0_19 is not set
+# CT_ISL_V_0_18 is not set
+# CT_ISL_V_0_17 is not set
+# CT_ISL_V_0_16 is not set
+# CT_ISL_V_0_15 is not set
+# CT_ISL_NO_VERSIONS is not set
+CT_ISL_VERSION="0.20"
+CT_ISL_MIRRORS="http://isl.gforge.inria.fr"
+CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz"
+CT_ISL_SIGNATURE_FORMAT=""
+CT_ISL_later_than_0_18=y
+CT_ISL_0_18_or_later=y
+CT_ISL_later_than_0_15=y
+CT_ISL_0_15_or_later=y
+CT_ISL_REQUIRE_0_15_or_later=y
+CT_ISL_later_than_0_14=y
+CT_ISL_0_14_or_later=y
+CT_ISL_REQUIRE_0_14_or_later=y
+CT_ISL_later_than_0_13=y
+CT_ISL_0_13_or_later=y
+CT_ISL_later_than_0_12=y
+CT_ISL_0_12_or_later=y
+CT_ISL_REQUIRE_0_12_or_later=y
+# CT_COMP_LIBS_LIBELF is not set
+CT_COMP_LIBS_LIBICONV=y
+CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV"
+CT_LIBICONV_DIR_NAME="libiconv"
+CT_LIBICONV_PKG_NAME="libiconv"
+CT_LIBICONV_SRC_RELEASE=y
+# CT_LIBICONV_SRC_DEVEL is not set
+# CT_LIBICONV_SRC_CUSTOM is not set
+CT_LIBICONV_PATCH_GLOBAL=y
+# CT_LIBICONV_PATCH_BUNDLED is not set
+# CT_LIBICONV_PATCH_LOCAL is not set
+# CT_LIBICONV_PATCH_BUNDLED_LOCAL is not set
+# CT_LIBICONV_PATCH_LOCAL_BUNDLED is not set
+# CT_LIBICONV_PATCH_NONE is not set
+CT_LIBICONV_PATCH_ORDER="global"
+CT_LIBICONV_V_1_15=y
+# CT_LIBICONV_NO_VERSIONS is not set
+CT_LIBICONV_VERSION="1.15"
+CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)"
+CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz"
+CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig"
+CT_COMP_LIBS_MPC=y
+CT_COMP_LIBS_MPC_PKG_KSYM="MPC"
+CT_MPC_DIR_NAME="mpc"
+CT_MPC_PKG_NAME="mpc"
+CT_MPC_SRC_RELEASE=y
+# CT_MPC_SRC_DEVEL is not set
+# CT_MPC_SRC_CUSTOM is not set
+CT_MPC_PATCH_GLOBAL=y
+# CT_MPC_PATCH_BUNDLED is not set
+# CT_MPC_PATCH_LOCAL is not set
+# CT_MPC_PATCH_BUNDLED_LOCAL is not set
+# CT_MPC_PATCH_LOCAL_BUNDLED is not set
+# CT_MPC_PATCH_NONE is not set
+CT_MPC_PATCH_ORDER="global"
+CT_MPC_V_1_1=y
+# CT_MPC_V_1_0 is not set
+# CT_MPC_NO_VERSIONS is not set
+CT_MPC_VERSION="1.1.0"
+CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)"
+CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPC_ARCHIVE_FORMATS=".tar.gz"
+CT_MPC_SIGNATURE_FORMAT="packed/.sig"
+CT_MPC_1_1_0_or_later=y
+CT_MPC_1_1_0_or_older=y
+CT_COMP_LIBS_MPFR=y
+CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR"
+CT_MPFR_DIR_NAME="mpfr"
+CT_MPFR_PKG_NAME="mpfr"
+CT_MPFR_SRC_RELEASE=y
+# CT_MPFR_SRC_DEVEL is not set
+# CT_MPFR_SRC_CUSTOM is not set
+CT_MPFR_PATCH_GLOBAL=y
+# CT_MPFR_PATCH_BUNDLED is not set
+# CT_MPFR_PATCH_LOCAL is not set
+# CT_MPFR_PATCH_BUNDLED_LOCAL is not set
+# CT_MPFR_PATCH_LOCAL_BUNDLED is not set
+# CT_MPFR_PATCH_NONE is not set
+CT_MPFR_PATCH_ORDER="global"
+CT_MPFR_V_4_0=y
+# CT_MPFR_V_3_1 is not set
+# CT_MPFR_NO_VERSIONS is not set
+CT_MPFR_VERSION="4.0.2"
+CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)"
+CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip"
+CT_MPFR_SIGNATURE_FORMAT="packed/.asc"
+CT_MPFR_later_than_4_0_0=y
+CT_MPFR_4_0_0_or_later=y
+CT_MPFR_later_than_3_0_0=y
+CT_MPFR_3_0_0_or_later=y
+CT_MPFR_REQUIRE_3_0_0_or_later=y
+CT_COMP_LIBS_NCURSES=y
+CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES"
+CT_NCURSES_DIR_NAME="ncurses"
+CT_NCURSES_PKG_NAME="ncurses"
+CT_NCURSES_SRC_RELEASE=y
+# CT_NCURSES_SRC_DEVEL is not set
+# CT_NCURSES_SRC_CUSTOM is not set
+CT_NCURSES_PATCH_GLOBAL=y
+# CT_NCURSES_PATCH_BUNDLED is not set
+# CT_NCURSES_PATCH_LOCAL is not set
+# CT_NCURSES_PATCH_BUNDLED_LOCAL is not set
+# CT_NCURSES_PATCH_LOCAL_BUNDLED is not set
+# CT_NCURSES_PATCH_NONE is not set
+CT_NCURSES_PATCH_ORDER="global"
+CT_NCURSES_V_6_1=y
+# CT_NCURSES_V_6_0 is not set
+# CT_NCURSES_NO_VERSIONS is not set
+CT_NCURSES_VERSION="6.1"
+CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)"
+CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_NCURSES_ARCHIVE_FORMATS=".tar.gz"
+CT_NCURSES_SIGNATURE_FORMAT="packed/.sig"
+# CT_NCURSES_NEW_ABI is not set
+CT_NCURSES_HOST_CONFIG_ARGS=""
+CT_NCURSES_HOST_DISABLE_DB=y
+CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100"
+CT_NCURSES_TARGET_CONFIG_ARGS=""
+# CT_NCURSES_TARGET_DISABLE_DB is not set
+CT_NCURSES_TARGET_FALLBACKS=""
+CT_COMP_LIBS_ZLIB=y
+CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB"
+CT_ZLIB_DIR_NAME="zlib"
+CT_ZLIB_PKG_NAME="zlib"
+CT_ZLIB_SRC_RELEASE=y
+# CT_ZLIB_SRC_DEVEL is not set
+# CT_ZLIB_SRC_CUSTOM is not set
+CT_ZLIB_PATCH_GLOBAL=y
+# CT_ZLIB_PATCH_BUNDLED is not set
+# CT_ZLIB_PATCH_LOCAL is not set
+# CT_ZLIB_PATCH_BUNDLED_LOCAL is not set
+# CT_ZLIB_PATCH_LOCAL_BUNDLED is not set
+# CT_ZLIB_PATCH_NONE is not set
+CT_ZLIB_PATCH_ORDER="global"
+CT_ZLIB_V_1_2_11=y
+# CT_ZLIB_NO_VERSIONS is not set
+CT_ZLIB_VERSION="1.2.11"
+CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}"
+CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}"
+CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz"
+CT_ZLIB_SIGNATURE_FORMAT="packed/.asc"
+CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB"
+CT_LIBICONV_NEEDED=y
+CT_GETTEXT_NEEDED=y
+CT_GMP_NEEDED=y
+CT_MPFR_NEEDED=y
+CT_ISL_NEEDED=y
+CT_MPC_NEEDED=y
+CT_EXPAT_NEEDED=y
+CT_NCURSES_NEEDED=y
+CT_ZLIB_NEEDED=y
+CT_LIBICONV=y
+CT_GETTEXT=y
+CT_GMP=y
+CT_MPFR=y
+CT_ISL=y
+CT_MPC=y
+CT_EXPAT=y
+CT_NCURSES=y
+CT_ZLIB=y
+
+#
+# Companion tools
+#
+# CT_COMP_TOOLS_FOR_HOST is not set
+# CT_COMP_TOOLS_AUTOCONF is not set
+# CT_COMP_TOOLS_AUTOMAKE is not set
+# CT_COMP_TOOLS_BISON is not set
+# CT_COMP_TOOLS_DTC is not set
+# CT_COMP_TOOLS_LIBTOOL is not set
+# CT_COMP_TOOLS_M4 is not set
+# CT_COMP_TOOLS_MAKE is not set
+CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE"
+
+#
+# Test suite
+#
+# CT_TEST_SUITE_GCC is not set
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
index b5c6bab..92baf72 160000
--- a/src/doc/rustc-guide
+++ b/src/doc/rustc-guide
@@ -1 +1 @@
-Subproject commit b5c6babcdd4ce1fa90458b7827a5fde082e79e87
+Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7
diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md
deleted file mode 100644
index cdb7449..0000000
--- a/src/doc/unstable-book/src/language-features/slice-patterns.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# `slice_patterns`
-
-The tracking issue for this feature is: [#62254]
-
-[#62254]: https://github.com/rust-lang/rust/issues/62254
-
-------------------------
-
-The `slice_patterns` feature gate lets you use `..` to indicate any number of
-elements inside a pattern matching a slice. This wildcard can only be used once
-for a given array. If there's an pattern before the `..`, the subslice will be
-matched against that pattern. For example:
-
-```rust
-#![feature(slice_patterns)]
-
-fn is_symmetric(list: &[u32]) -> bool {
- match list {
- &[] | &[_] => true,
- &[x, ref inside @ .., y] if x == y => is_symmetric(inside),
- &[..] => false,
- }
-}
-
-fn main() {
- let sym = &[0, 1, 4, 2, 4, 1, 0];
- assert!(is_symmetric(sym));
-
- let not_sym = &[0, 1, 7, 2, 4, 1, 0];
- assert!(!is_symmetric(not_sym));
-}
-```
diff --git a/src/liballoc/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs
index eb5f51d..ea69769 100644
--- a/src/liballoc/benches/btree/map.rs
+++ b/src/liballoc/benches/btree/map.rs
@@ -146,6 +146,36 @@
bench_iter(b, 100000);
}
+fn bench_iter_mut(b: &mut Bencher, size: i32) {
+ let mut map = BTreeMap::<i32, i32>::new();
+ let mut rng = thread_rng();
+
+ for _ in 0..size {
+ map.insert(rng.gen(), rng.gen());
+ }
+
+ b.iter(|| {
+ for kv in map.iter_mut() {
+ black_box(kv);
+ }
+ });
+}
+
+#[bench]
+pub fn iter_mut_20(b: &mut Bencher) {
+ bench_iter_mut(b, 20);
+}
+
+#[bench]
+pub fn iter_mut_1000(b: &mut Bencher) {
+ bench_iter_mut(b, 1000);
+}
+
+#[bench]
+pub fn iter_mut_100000(b: &mut Bencher) {
+ bench_iter_mut(b, 100000);
+}
+
fn bench_first_and_last(b: &mut Bencher, size: i32) {
let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
b.iter(|| {
diff --git a/src/liballoc/benches/btree/set.rs b/src/liballoc/benches/btree/set.rs
index 18502de..d7c1d95 100644
--- a/src/liballoc/benches/btree/set.rs
+++ b/src/liballoc/benches/btree/set.rs
@@ -14,19 +14,13 @@
}
fn neg(n: usize) -> BTreeSet<i32> {
- let mut set = BTreeSet::new();
- for i in -(n as i32)..=-1 {
- set.insert(i);
- }
+ let set: BTreeSet<i32> = (-(n as i32)..=-1).collect();
assert_eq!(set.len(), n);
set
}
fn pos(n: usize) -> BTreeSet<i32> {
- let mut set = BTreeSet::new();
- for i in 1..=(n as i32) {
- set.insert(i);
- }
+ let set: BTreeSet<i32> = (1..=(n as i32)).collect();
assert_eq!(set.len(), n);
set
}
@@ -56,6 +50,43 @@
};
}
+const BUILD_SET_SIZE: usize = 100;
+
+#[bench]
+pub fn build_and_clear(b: &mut Bencher) {
+ b.iter(|| pos(BUILD_SET_SIZE).clear())
+}
+
+#[bench]
+pub fn build_and_drop(b: &mut Bencher) {
+ b.iter(|| pos(BUILD_SET_SIZE))
+}
+
+#[bench]
+pub fn build_and_into_iter(b: &mut Bencher) {
+ b.iter(|| pos(BUILD_SET_SIZE).into_iter().count())
+}
+
+#[bench]
+pub fn build_and_pop_all(b: &mut Bencher) {
+ b.iter(|| {
+ let mut s = pos(BUILD_SET_SIZE);
+ while s.pop_first().is_some() {}
+ s
+ });
+}
+
+#[bench]
+pub fn build_and_remove_all(b: &mut Bencher) {
+ b.iter(|| {
+ let mut s = pos(BUILD_SET_SIZE);
+ while let Some(elt) = s.iter().copied().next() {
+ s.remove(&elt);
+ }
+ s
+ });
+}
+
set_bench! {intersection_100_neg_vs_100_pos, intersection, count, [neg(100), pos(100)]}
set_bench! {intersection_100_neg_vs_10k_pos, intersection, count, [neg(100), pos(10_000)]}
set_bench! {intersection_100_pos_vs_100_neg, intersection, count, [pos(100), neg(100)]}
diff --git a/src/liballoc/benches/string.rs b/src/liballoc/benches/string.rs
index 599c8b1..5c95160 100644
--- a/src/liballoc/benches/string.rs
+++ b/src/liballoc/benches/string.rs
@@ -1,5 +1,5 @@
use std::iter::repeat;
-use test::Bencher;
+use test::{black_box, Bencher};
#[bench]
fn bench_with_capacity(b: &mut Bencher) {
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 302c2bc..e70f881 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -1968,7 +1968,7 @@
(i, false) => i,
},
(_, Unbounded) => 0,
- (true, Included(_)) => min_node.keys().len(),
+ (true, Included(_)) => min_node.len(),
(true, Excluded(_)) => 0,
};
@@ -1987,9 +1987,9 @@
}
(i, false) => i,
},
- (_, Unbounded) => max_node.keys().len(),
+ (_, Unbounded) => max_node.len(),
(true, Included(_)) => 0,
- (true, Excluded(_)) => max_node.keys().len(),
+ (true, Excluded(_)) => max_node.len(),
};
if !diverged {
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index f40e0b0..d9cdebb 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -54,10 +54,8 @@
/// `NodeHeader` because we do not want unnecessary padding between `len` and the keys.
/// Crucially, `NodeHeader` can be safely transmuted to different K and V. (This is exploited
/// by `as_header`.)
-/// See `into_key_slice` for an explanation of K2. K2 cannot be safely transmuted around
-/// because the size of `NodeHeader` depends on its alignment!
#[repr(C)]
-struct NodeHeader<K, V, K2 = ()> {
+struct NodeHeader<K, V> {
/// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
/// This either points to an actual node or is null.
parent: *const InternalNode<K, V>,
@@ -72,9 +70,6 @@
/// This next to `parent_idx` to encourage the compiler to join `len` and
/// `parent_idx` into the same 32-bit word, reducing space overhead.
len: u16,
-
- /// See `into_key_slice`.
- keys_start: [K2; 0],
}
#[repr(C)]
struct LeafNode<K, V> {
@@ -128,7 +123,7 @@
// We use just a header in order to save space, since no operation on an empty tree will
// ever take a pointer past the first key.
static EMPTY_ROOT_NODE: NodeHeader<(), ()> =
- NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [] };
+ NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 };
/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
/// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an
@@ -390,14 +385,13 @@
}
/// Borrows a view into the keys stored in the node.
- /// Works on all possible nodes, including the shared root.
- pub fn keys(&self) -> &[K] {
+ /// The caller must ensure that the node is not the shared root.
+ pub unsafe fn keys(&self) -> &[K] {
self.reborrow().into_key_slice()
}
/// Borrows a view into the values stored in the node.
/// The caller must ensure that the node is not the shared root.
- /// This function is not public, so doesn't have to support shared roots like `keys` does.
fn vals(&self) -> &[V] {
self.reborrow().into_val_slice()
}
@@ -515,7 +509,6 @@
}
/// The caller must ensure that the node is not the shared root.
- /// This function is not public, so doesn't have to support shared roots like `keys` does.
fn keys_mut(&mut self) -> &mut [K] {
unsafe { self.reborrow_mut().into_key_slice_mut() }
}
@@ -527,48 +520,11 @@
}
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
- fn into_key_slice(self) -> &'a [K] {
- // We have to be careful here because we might be pointing to the shared root.
- // In that case, we must not create an `&LeafNode`. We could just return
- // an empty slice whenever the length is 0 (this includes the shared root),
- // but we want to avoid that run-time check.
- // Instead, we create a slice pointing into the node whenever possible.
- // We can sometimes do this even for the shared root, as the slice will be
- // empty and `NodeHeader` contains an empty `keys_start` array.
- // We cannot *always* do this because:
- // - `keys_start` is not correctly typed because we want `NodeHeader`'s size to
- // not depend on the alignment of `K` (needed because `as_header` should be safe).
- // For this reason, `NodeHeader` has this `K2` parameter (that's usually `()`
- // and hence just adds a size-0-align-1 field, not affecting layout).
- // If the correctly typed header is more highly aligned than the allocated header,
- // we cannot transmute safely.
- // - Even if we can transmute, the offset of a correctly typed `keys_start` might
- // be different and outside the bounds of the allocated header!
- // So we do an alignment check and a size check first, that will be evaluated
- // at compile-time, and only do any run-time check in the rare case that
- // the compile-time checks signal danger.
- if (mem::align_of::<NodeHeader<K, V, K>>() > mem::align_of::<NodeHeader<K, V>>()
- || mem::size_of::<NodeHeader<K, V, K>>() != mem::size_of::<NodeHeader<K, V>>())
- && self.is_shared_root()
- {
- &[]
- } else {
- // If we are a `LeafNode<K, V>`, we can always transmute to
- // `NodeHeader<K, V, K>` and `keys_start` always has the same offset
- // as the actual `keys`.
- // Thanks to the checks above, we know that we can transmute to
- // `NodeHeader<K, V, K>` and that `keys_start` will be
- // in-bounds of some allocation even if this is the shared root!
- // (We might be one-past-the-end, but that is allowed by LLVM.)
- // Thus we can use `NodeHeader<K, V, K>`
- // to compute the pointer where the keys start.
- // This entire hack will become unnecessary once
- // <https://github.com/rust-lang/rfcs/pull/2582> lands, then we can just take a raw
- // pointer to the `keys` field of `*const InternalNode<K, V>`.
- let header = self.as_header() as *const _ as *const NodeHeader<K, V, K>;
- let keys = unsafe { &(*header).keys_start as *const _ as *const K };
- unsafe { slice::from_raw_parts(keys, self.len()) }
- }
+ /// The caller must ensure that the node is not the shared root.
+ unsafe fn into_key_slice(self) -> &'a [K] {
+ debug_assert!(!self.is_shared_root());
+ // We cannot be the shared root, so `as_leaf` is okay.
+ slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len())
}
/// The caller must ensure that the node is not the shared root.
@@ -578,9 +534,10 @@
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) }
}
+ /// The caller must ensure that the node is not the shared root.
fn into_slices(self) -> (&'a [K], &'a [V]) {
let k = unsafe { ptr::read(&self) };
- (k.into_key_slice(), self.into_val_slice())
+ (unsafe { k.into_key_slice() }, self.into_val_slice())
}
}
diff --git a/src/liballoc/collections/btree/search.rs b/src/liballoc/collections/btree/search.rs
index 48cbf67..579624c 100644
--- a/src/liballoc/collections/btree/search.rs
+++ b/src/liballoc/collections/btree/search.rs
@@ -61,16 +61,18 @@
{
// This function is defined over all borrow types (immutable, mutable, owned),
// and may be called on the shared root in each case.
- // Crucially, we use `keys()` here, i.e., we work with immutable data.
- // `keys_mut()` does not support the shared root, so we cannot use it.
// Using `keys()` is fine here even if BorrowType is mutable, as all we return
// is an index -- not a reference.
- for (i, k) in node.keys().iter().enumerate() {
- match key.cmp(k.borrow()) {
- Ordering::Greater => {}
- Ordering::Equal => return (i, true),
- Ordering::Less => return (i, false),
+ let len = node.len();
+ if len > 0 {
+ let keys = unsafe { node.keys() }; // safe because a non-empty node cannot be the shared root
+ for (i, k) in keys.iter().enumerate() {
+ match key.cmp(k.borrow()) {
+ Ordering::Greater => {}
+ Ordering::Equal => return (i, true),
+ Ordering::Less => return (i, false),
+ }
}
}
- (node.keys().len(), false)
+ (len, false)
}
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 35ce135..f5be72c 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -4,6 +4,7 @@
use std::fmt::Debug;
use std::iter::FromIterator;
use std::ops::Bound::{self, Excluded, Included, Unbounded};
+use std::ops::RangeBounds;
use std::rc::Rc;
use super::DeterministicRng;
@@ -68,6 +69,11 @@
assert_eq!(map.last_key_value(), None);
assert_eq!(map.keys().count(), 0);
assert_eq!(map.values().count(), 0);
+ assert_eq!(map.range(..).next(), None);
+ assert_eq!(map.range(..1).next(), None);
+ assert_eq!(map.range(1..).next(), None);
+ assert_eq!(map.range(1..=1).next(), None);
+ assert_eq!(map.range(1..2).next(), None);
assert_eq!(map.insert(1, 1), None);
// 1 key-value pair:
@@ -118,6 +124,11 @@
assert_eq!(map.last_key_value(), None);
assert_eq!(map.keys().count(), 0);
assert_eq!(map.values().count(), 0);
+ assert_eq!(map.range(..).next(), None);
+ assert_eq!(map.range(..1).next(), None);
+ assert_eq!(map.range(1..).next(), None);
+ assert_eq!(map.range(1..=1).next(), None);
+ assert_eq!(map.range(1..2).next(), None);
assert_eq!(map.remove(&1), None);
}
@@ -128,7 +139,6 @@
#[cfg(miri)]
let size = 200;
- // Forwards
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
fn test<T>(size: usize, mut iter: T)
@@ -154,7 +164,6 @@
#[cfg(miri)]
let size = 200;
- // Forwards
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
fn test<T>(size: usize, mut iter: T)
@@ -275,7 +284,6 @@
#[cfg(miri)]
let size = 200;
- // Forwards
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
fn test<T>(size: usize, mut iter: T)
@@ -299,27 +307,147 @@
test(size, map.into_iter());
}
-#[test]
-fn test_range_small() {
- let size = 5;
-
- // Forwards
- let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
- let mut j = 0;
- for ((&k, &v), i) in map.range(2..).zip(2..size) {
- assert_eq!(k, i);
- assert_eq!(v, i);
- j += 1;
- }
- assert_eq!(j, size - 2);
+fn range_keys(map: &BTreeMap<i32, i32>, range: impl RangeBounds<i32>) -> Vec<i32> {
+ map.range(range)
+ .map(|(&k, &v)| {
+ assert_eq!(k, v);
+ k
+ })
+ .collect()
}
#[test]
-fn test_range_inclusive() {
- let size = 500;
+fn test_range_small() {
+ let size = 4;
- let map: BTreeMap<_, _> = (0..=size).map(|i| (i, i)).collect();
+ let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect();
+ let all: Vec<_> = (1..=size).collect();
+ let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]);
+
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(0), Included(size))), all);
+ assert_eq!(range_keys(&map, (Included(0), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(1), Included(size))), all);
+ assert_eq!(range_keys(&map, (Included(1), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Unbounded, Included(size))), all);
+ assert_eq!(range_keys(&map, ..), all);
+
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Included(0), Included(1))), first);
+ assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Included(1), Included(1))), first);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Unbounded, Included(1))), first);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last);
+ assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last);
+ assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last);
+ assert_eq!(range_keys(&map, (Included(size), Included(size))), last);
+ assert_eq!(range_keys(&map, (Included(size), Unbounded)), last);
+ assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]);
+
+ assert_eq!(range_keys(&map, ..3), vec![1, 2]);
+ assert_eq!(range_keys(&map, 3..), vec![3, 4]);
+ assert_eq!(range_keys(&map, 2..=3), vec![2, 3]);
+}
+
+#[test]
+fn test_range_depth_2() {
+ // Assuming that node.CAPACITY is 11, having 12 pairs implies a depth 2 tree
+ // with 2 leaves. Depending on details we don't want or need to rely upon,
+ // the single key at the root will be 6 or 7.
+
+ let map: BTreeMap<_, _> = (1..=12).map(|i| (i, i)).collect();
+ for &root in &[6, 7] {
+ assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(root), Included(root + 1))), vec![root + 1]);
+ assert_eq!(range_keys(&map, (Included(root), Excluded(root + 1))), vec![root]);
+ assert_eq!(range_keys(&map, (Included(root), Included(root + 1))), vec![root, root + 1]);
+
+ assert_eq!(range_keys(&map, (Excluded(root - 1), Excluded(root))), vec![]);
+ assert_eq!(range_keys(&map, (Included(root - 1), Excluded(root))), vec![root - 1]);
+ assert_eq!(range_keys(&map, (Excluded(root - 1), Included(root))), vec![root]);
+ assert_eq!(range_keys(&map, (Included(root - 1), Included(root))), vec![root - 1, root]);
+ }
+}
+
+#[test]
+fn test_range_large() {
+ let size = 200;
+
+ let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect();
+ let all: Vec<_> = (1..=size).collect();
+ let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]);
+
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all);
+ assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(0), Included(size))), all);
+ assert_eq!(range_keys(&map, (Included(0), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Included(1), Included(size))), all);
+ assert_eq!(range_keys(&map, (Included(1), Unbounded)), all);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all);
+ assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all);
+ assert_eq!(range_keys(&map, (Unbounded, Included(size))), all);
+ assert_eq!(range_keys(&map, ..), all);
+
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]);
+ assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first);
+ assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Included(0), Included(1))), first);
+ assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Included(1), Included(1))), first);
+ assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first);
+ assert_eq!(range_keys(&map, (Unbounded, Included(1))), first);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last);
+ assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last);
+ assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last);
+ assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last);
+ assert_eq!(range_keys(&map, (Included(size), Included(size))), last);
+ assert_eq!(range_keys(&map, (Included(size), Unbounded)), last);
+ assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]);
+ assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]);
+ assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]);
fn check<'a, L, R>(lhs: L, rhs: R)
where
@@ -331,18 +459,9 @@
assert_eq!(lhs, rhs);
}
- check(map.range(size + 1..=size + 1), vec![]);
- check(map.range(size..=size), vec![(&size, &size)]);
- check(map.range(size..=size + 1), vec![(&size, &size)]);
- check(map.range(0..=0), vec![(&0, &0)]);
- check(map.range(0..=size - 1), map.range(..size));
- check(map.range(-1..=-1), vec![]);
- check(map.range(-1..=size), map.range(..));
- check(map.range(..=size), map.range(..));
- check(map.range(..=200), map.range(..201));
+ check(map.range(..=100), map.range(..101));
check(map.range(5..=8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]);
- check(map.range(-1..=0), vec![(&0, &0)]);
- check(map.range(-1..=2), vec![(&0, &0), (&1, &1), (&2, &2)]);
+ check(map.range(-1..=2), vec![(&1, &1), (&2, &2)]);
}
#[test]
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index beb0bac..2a3d92e 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -21,7 +21,6 @@
extern crate alloc;
use rustc_data_structures::cold_path;
-use rustc_data_structures::sync::MTLock;
use smallvec::SmallVec;
use std::cell::{Cell, RefCell};
@@ -116,11 +115,6 @@
}
impl<T> TypedArena<T> {
- pub fn in_arena(&self, ptr: *const T) -> bool {
- let ptr = ptr as *const T as *mut T;
-
- self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
- }
/// Allocates an object in the `TypedArena`, returning a reference to it.
#[inline]
pub fn alloc(&self, object: T) -> &mut T {
@@ -334,12 +328,6 @@
}
impl DroplessArena {
- pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
- let ptr = ptr as *const u8 as *mut u8;
-
- self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
- }
-
#[inline]
fn align(&self, align: usize) {
let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1);
@@ -500,66 +488,5 @@
}
}
-#[derive(Default)]
-// FIXME(@Zoxc): this type is entirely unused in rustc
-pub struct SyncTypedArena<T> {
- lock: MTLock<TypedArena<T>>,
-}
-
-impl<T> SyncTypedArena<T> {
- #[inline(always)]
- pub fn alloc(&self, object: T) -> &mut T {
- // Extend the lifetime of the result since it's limited to the lock guard
- unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
- }
-
- #[inline(always)]
- pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
- where
- T: Copy,
- {
- // Extend the lifetime of the result since it's limited to the lock guard
- unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
- }
-
- #[inline(always)]
- pub fn clear(&mut self) {
- self.lock.get_mut().clear();
- }
-}
-
-#[derive(Default)]
-pub struct SyncDroplessArena {
- lock: MTLock<DroplessArena>,
-}
-
-impl SyncDroplessArena {
- #[inline(always)]
- pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
- self.lock.lock().in_arena(ptr)
- }
-
- #[inline(always)]
- pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] {
- // Extend the lifetime of the result since it's limited to the lock guard
- unsafe { &mut *(self.lock.lock().alloc_raw(bytes, align) as *mut [u8]) }
- }
-
- #[inline(always)]
- pub fn alloc<T>(&self, object: T) -> &mut T {
- // Extend the lifetime of the result since it's limited to the lock guard
- unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
- }
-
- #[inline(always)]
- pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
- where
- T: Copy,
- {
- // Extend the lifetime of the result since it's limited to the lock guard
- unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
- }
-}
-
#[cfg(test)]
mod tests;
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 4354e1c..09f743f 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -525,7 +525,8 @@
/// The memory may or may not have been deallocated,
/// and should be considered unusable (unless of course it was
/// transferred back to the caller again via the return value of
- /// this method).
+ /// this method). The new memory block is allocated with `layout`, but
+ /// with the `size` updated to `new_size`.
///
/// If this method returns null, then ownership of the memory
/// block has not been transferred to this allocator, and the
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 4afea12..af02e84 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -476,11 +476,15 @@
///
/// This is intended for diagnostic use. The exact contents and format of the
/// string are not specified, other than being a best-effort description of the
-/// type. For example, `type_name_of::<Option<String>>(None)` could return
+/// type. For example, `type_name_of_val::<Option<String>>(None)` could return
/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
/// `"foobar"`. In addition, the output may change between versions of the
/// compiler.
///
+/// This function does not resolve trait objects,
+/// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
+/// may return `"dyn Debug"`, but not `"u32"`.
+///
/// The type name should not be considered a unique identifier of a type;
/// multiple types may share the same type name.
///
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 4fcd0d9..e7eecf7 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -187,8 +187,6 @@
//! ```
//!
-// ignore-tidy-undocumented-unsafe
-
#![stable(feature = "rust1", since = "1.0.0")]
use crate::cmp::Ordering;
@@ -368,6 +366,10 @@
if ptr::eq(self, other) {
return;
}
+ // SAFETY: This can be risky if called from separate threads, but `Cell`
+ // is `!Sync` so this won't happen. This also won't invalidate any
+ // pointers since `Cell` makes sure nothing else will be pointing into
+ // either of these `Cell`s.
unsafe {
ptr::swap(self.value.get(), other.value.get());
}
@@ -387,6 +389,8 @@
/// ```
#[stable(feature = "move_cell", since = "1.17.0")]
pub fn replace(&self, val: T) -> T {
+ // SAFETY: This can cause data races if called from a separate thread,
+ // but `Cell` is `!Sync` so this won't happen.
mem::replace(unsafe { &mut *self.value.get() }, val)
}
@@ -423,6 +427,8 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self) -> T {
+ // SAFETY: This can cause data races if called from a separate thread,
+ // but `Cell` is `!Sync` so this won't happen.
unsafe { *self.value.get() }
}
@@ -491,6 +497,9 @@
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
+ // SAFETY: This can cause data races if called from a separate thread,
+ // but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees
+ // unique access.
unsafe { &mut *self.value.get() }
}
@@ -510,6 +519,7 @@
#[inline]
#[stable(feature = "as_cell", since = "1.37.0")]
pub fn from_mut(t: &mut T) -> &Cell<T> {
+ // SAFETY: `&mut` ensures unique access.
unsafe { &*(t as *mut T as *const Cell<T>) }
}
}
@@ -553,6 +563,7 @@
/// ```
#[stable(feature = "as_cell", since = "1.37.0")]
pub fn as_slice_of_cells(&self) -> &[Cell<T>] {
+ // SAFETY: `Cell<T>` has the same memory layout as `T`.
unsafe { &*(self as *const Cell<[T]> as *const [Cell<T>]) }
}
}
@@ -816,6 +827,8 @@
#[inline]
pub fn try_borrow(&self) -> Result<Ref<'_, T>, BorrowError> {
match BorrowRef::new(&self.borrow) {
+ // SAFETY: `BorrowRef` ensures that there is only immutable access
+ // to the value while borrowed.
Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }),
None => Err(BorrowError { _private: () }),
}
@@ -891,6 +904,7 @@
#[inline]
pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
match BorrowRefMut::new(&self.borrow) {
+ // SAFETY: `BorrowRef` guarantees unique access.
Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }),
None => Err(BorrowMutError { _private: () }),
}
@@ -940,6 +954,7 @@
#[inline]
#[stable(feature = "cell_get_mut", since = "1.11.0")]
pub fn get_mut(&mut self) -> &mut T {
+ // SAFETY: `&mut` guarantees unique access.
unsafe { &mut *self.value.get() }
}
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index e68f3c5..900ef63 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -10,7 +10,6 @@
use crate::num::flt2dec;
use crate::ops::Deref;
use crate::result;
-use crate::slice;
use crate::str;
mod builders;
@@ -234,8 +233,6 @@
precision: Option<usize>,
buf: &'a mut (dyn Write + 'a),
- curarg: slice::Iter<'a, ArgumentV1<'a>>,
- args: &'a [ArgumentV1<'a>],
}
// NB. Argument is essentially an optimized partially applied formatting function,
@@ -1043,8 +1040,6 @@
buf: output,
align: rt::v1::Alignment::Unknown,
fill: ' ',
- args: args.args,
- curarg: args.args.iter(),
};
let mut idx = 0;
@@ -1063,7 +1058,7 @@
// a string piece.
for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
formatter.buf.write_str(*piece)?;
- formatter.run(arg)?;
+ run(&mut formatter, arg, &args.args)?;
idx += 1;
}
}
@@ -1077,6 +1072,39 @@
Ok(())
}
+fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result {
+ fmt.fill = arg.format.fill;
+ fmt.align = arg.format.align;
+ fmt.flags = arg.format.flags;
+ fmt.width = getcount(args, &arg.format.width);
+ fmt.precision = getcount(args, &arg.format.precision);
+
+ // Extract the correct argument
+ let value = {
+ #[cfg(bootstrap)]
+ {
+ match arg.position {
+ rt::v1::Position::At(i) => args[i],
+ }
+ }
+ #[cfg(not(bootstrap))]
+ {
+ args[arg.position]
+ }
+ };
+
+ // Then actually do some printing
+ (value.formatter)(value.value, fmt)
+}
+
+fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> {
+ match *cnt {
+ rt::v1::Count::Is(n) => Some(n),
+ rt::v1::Count::Implied => None,
+ rt::v1::Count::Param(i) => args[i].as_usize(),
+ }
+}
+
/// Padding after the end of something. Returned by `Formatter::padding`.
#[must_use = "don't forget to write the post padding"]
struct PostPadding {
@@ -1114,41 +1142,6 @@
align: self.align,
width: self.width,
precision: self.precision,
-
- // These only exist in the struct for the `run` method,
- // which won’t be used together with this method.
- curarg: self.curarg.clone(),
- args: self.args,
- }
- }
-
- // First up is the collection of functions used to execute a format string
- // at runtime. This consumes all of the compile-time statics generated by
- // the format! syntax extension.
- fn run(&mut self, arg: &rt::v1::Argument) -> Result {
- // Fill in the format parameters into the formatter
- self.fill = arg.format.fill;
- self.align = arg.format.align;
- self.flags = arg.format.flags;
- self.width = self.getcount(&arg.format.width);
- self.precision = self.getcount(&arg.format.precision);
-
- // Extract the correct argument
- let value = match arg.position {
- rt::v1::Position::Next => *self.curarg.next().unwrap(),
- rt::v1::Position::At(i) => self.args[i],
- };
-
- // Then actually do some printing
- (value.formatter)(value.value, self)
- }
-
- fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> {
- match *cnt {
- rt::v1::Count::Is(n) => Some(n),
- rt::v1::Count::Implied => None,
- rt::v1::Count::Param(i) => self.args[i].as_usize(),
- rt::v1::Count::NextParam => self.curarg.next()?.as_usize(),
}
}
diff --git a/src/libcore/fmt/rt/v1.rs b/src/libcore/fmt/rt/v1.rs
index 826ae36..fd81f932 100644
--- a/src/libcore/fmt/rt/v1.rs
+++ b/src/libcore/fmt/rt/v1.rs
@@ -7,7 +7,10 @@
#[derive(Copy, Clone)]
pub struct Argument {
+ #[cfg(bootstrap)]
pub position: Position,
+ #[cfg(not(bootstrap))]
+ pub position: usize,
pub format: FormatSpec,
}
@@ -37,12 +40,11 @@
pub enum Count {
Is(usize),
Param(usize),
- NextParam,
Implied,
}
+#[cfg(bootstrap)]
#[derive(Copy, Clone)]
pub enum Position {
- Next,
At(usize),
}
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index a65d47c..25dfc57 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -208,6 +208,11 @@
#[stable(feature = "iter_empty", since = "1.2.0")]
pub struct Empty<T>(marker::PhantomData<T>);
+#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
+unsafe impl<T> Send for Empty<T> {}
+#[stable(feature = "iter_empty_send_sync", since = "1.42.0")]
+unsafe impl<T> Sync for Empty<T> {}
+
#[stable(feature = "core_impl_debug", since = "1.9.0")]
impl<T> fmt::Debug for Empty<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 15720dd..f77b4d7 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -133,7 +133,7 @@
#![feature(associated_type_bounds)]
#![feature(const_type_id)]
#![feature(const_caller_location)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#[prelude_import]
#[allow(unused)]
diff --git a/src/libcore/mem/manually_drop.rs b/src/libcore/mem/manually_drop.rs
index 3606448..4c3b81e 100644
--- a/src/libcore/mem/manually_drop.rs
+++ b/src/libcore/mem/manually_drop.rs
@@ -87,27 +87,28 @@
slot.value
}
- /// Takes the contained value out.
+ /// Takes the value from the `ManuallyDrop<T>` container out.
///
/// This method is primarily intended for moving out values in drop.
/// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
/// you can use this method to take the value and use it however desired.
- /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
///
- /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
+ /// Whenever possible, it is preferrable to use [`into_inner`][`ManuallyDrop::into_inner`]
+ /// instead, which prevents duplicating the content of the `ManuallyDrop<T>`.
///
/// # Safety
///
- /// This function semantically moves out the contained value without preventing further usage.
- /// It is up to the user of this method to ensure that this container is not used again.
+ /// This function semantically moves out the contained value without preventing further usage,
+ /// leaving the state of this container unchanged.
+ /// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
///
/// [`ManuallyDrop::drop`]: #method.drop
/// [`ManuallyDrop::into_inner`]: #method.into_inner
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
- #[unstable(feature = "manually_drop_take", issue = "55422")]
+ #[stable(feature = "manually_drop_take", since = "1.42.0")]
#[inline]
pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
- ManuallyDrop::into_inner(ptr::read(slot))
+ ptr::read(&slot.value)
}
}
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index d7b351f..c197686 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -169,22 +169,12 @@
/// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
/// manually.
#[stable(feature = "drop_in_place", since = "1.8.0")]
-#[inline(always)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
- real_drop_in_place(&mut *to_drop)
-}
-
-// The real `drop_in_place` -- the one that gets called implicitly when variables go
-// out of scope -- should have a safe reference and not a raw pointer as argument
-// type. When we drop a local variable, we access it with a pointer that behaves
-// like a safe reference; transmuting that to a raw pointer does not mean we can
-// actually access it with raw pointers.
#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
-unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
// Code here does not matter - this is replaced by the
// real drop glue by the compiler.
- real_drop_in_place(to_drop)
+ drop_in_place(to_drop)
}
/// Creates a null raw pointer.
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index 8a1fb9d..88b2bc5 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -3,8 +3,6 @@
use crate::mem;
use crate::str as core_str;
-// ignore-tidy-undocumented-unsafe
-
/// Lossy UTF-8 string.
#[unstable(feature = "str_internals", issue = "none")]
pub struct Utf8Lossy {
@@ -17,6 +15,7 @@
}
pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
+ // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
unsafe { mem::transmute(bytes) }
}
@@ -60,6 +59,8 @@
while i < self.source.len() {
let i_ = i;
+ // SAFETY: `i` starts at `0`, is less than `self.source.len()`, and
+ // only increases, so `0 <= i < self.source.len()`.
let byte = unsafe { *self.source.get_unchecked(i) };
i += 1;
@@ -69,6 +70,7 @@
macro_rules! error {
() => {{
+ // SAFETY: We have checked up to `i` that source is valid UTF-8.
unsafe {
let r = Utf8LossyChunk {
valid: core_str::from_utf8_unchecked(&self.source[0..i_]),
@@ -130,6 +132,7 @@
}
let r = Utf8LossyChunk {
+ // SAFETY: We have checked that the entire source is valid UTF-8.
valid: unsafe { core_str::from_utf8_unchecked(self.source) },
broken: &[],
};
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index ab771b1..5a7cddd 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1,5 +1,4 @@
// ignore-tidy-filelength
-// ignore-tidy-undocumented-unsafe
//! String manipulation.
//!
@@ -341,6 +340,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
run_utf8_validation(v)?;
+ // SAFETY: Just ran validation.
Ok(unsafe { from_utf8_unchecked(v) })
}
@@ -379,6 +379,7 @@
#[stable(feature = "str_mut_extras", since = "1.20.0")]
pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
run_utf8_validation(v)?;
+ // SAFETY: Just ran validation.
Ok(unsafe { from_utf8_unchecked_mut(v) })
}
@@ -581,7 +582,7 @@
#[inline]
fn next(&mut self) -> Option<char> {
next_code_point(&mut self.iter).map(|ch| {
- // str invariant says `ch` is a valid Unicode Scalar Value
+ // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
unsafe { char::from_u32_unchecked(ch) }
})
}
@@ -628,7 +629,7 @@
#[inline]
fn next_back(&mut self) -> Option<char> {
next_code_point_reverse(&mut self.iter).map(|ch| {
- // str invariant says `ch` is a valid Unicode Scalar Value
+ // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value.
unsafe { char::from_u32_unchecked(ch) }
})
}
@@ -658,6 +659,7 @@
#[stable(feature = "iter_to_slice", since = "1.4.0")]
#[inline]
pub fn as_str(&self) -> &'a str {
+ // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
unsafe { from_utf8_unchecked(self.iter.as_slice()) }
}
}
@@ -1102,6 +1104,7 @@
fn get_end(&mut self) -> Option<&'a str> {
if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
self.finished = true;
+ // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
unsafe {
let string = self.matcher.haystack().get_unchecked(self.start..self.end);
Some(string)
@@ -1119,6 +1122,7 @@
let haystack = self.matcher.haystack();
match self.matcher.next_match() {
+ // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
Some((a, b)) => unsafe {
let elt = haystack.get_unchecked(self.start..a);
self.start = b;
@@ -1151,11 +1155,13 @@
let haystack = self.matcher.haystack();
match self.matcher.next_match_back() {
+ // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries.
Some((a, b)) => unsafe {
let elt = haystack.get_unchecked(b..self.end);
self.end = a;
Some(elt)
},
+ // SAFETY: `self.start` and `self.end` always lie on unicode boundaries.
None => unsafe {
self.finished = true;
Some(haystack.get_unchecked(self.start..self.end))
@@ -1297,6 +1303,7 @@
fn next(&mut self) -> Option<(usize, &'a str)> {
self.0
.next_match()
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
.map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
}
@@ -1307,6 +1314,7 @@
{
self.0
.next_match_back()
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
.map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) })
}
}
@@ -1348,6 +1356,7 @@
impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> {
#[inline]
fn next(&mut self) -> Option<&'a str> {
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
self.0.next_match().map(|(a, b)| unsafe {
// Indices are known to be on utf8 boundaries
self.0.haystack().get_unchecked(a..b)
@@ -1359,6 +1368,7 @@
where
P::Searcher: ReverseSearcher<'a>,
{
+ // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries.
self.0.next_match_back().map(|(a, b)| unsafe {
// Indices are known to be on utf8 boundaries
self.0.haystack().get_unchecked(a..b)
@@ -1579,6 +1589,10 @@
if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 {
let ptr = v.as_ptr();
while index < blocks_end {
+ // SAFETY: since `align - index` and `ascii_block_size` are
+ // multiples of `usize_bytes`, `block = ptr.add(index)` is
+ // always aligned with a `usize` so it's safe to dereference
+ // both `block` and `block.offset(1)`.
unsafe {
let block = ptr.add(index) as *const usize;
// break if there is a nonascii byte
@@ -1804,6 +1818,7 @@
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
+ // SAFETY: just checked that `start` and `end` are on a char boundary.
Some(unsafe { self.get_unchecked(slice) })
} else {
None
@@ -1815,6 +1830,7 @@
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
+ // SAFETY: just checked that `start` and `end` are on a char boundary.
Some(unsafe { self.get_unchecked_mut(slice) })
} else {
None
@@ -1845,6 +1861,7 @@
&& slice.is_char_boundary(self.start)
&& slice.is_char_boundary(self.end)
{
+ // SAFETY: just checked that `start` and `end` are on a char boundary.
unsafe { self.get_unchecked_mut(slice) }
} else {
super::slice_error_fail(slice, self.start, self.end)
@@ -1873,6 +1890,7 @@
#[inline]
fn get(self, slice: &str) -> Option<&Self::Output> {
if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary.
Some(unsafe { self.get_unchecked(slice) })
} else {
None
@@ -1881,6 +1899,7 @@
#[inline]
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary.
Some(unsafe { self.get_unchecked_mut(slice) })
} else {
None
@@ -1903,8 +1922,8 @@
}
#[inline]
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- // is_char_boundary checks that the index is in [0, .len()]
if slice.is_char_boundary(self.end) {
+ // SAFETY: just checked that `end` is on a char boundary.
unsafe { self.get_unchecked_mut(slice) }
} else {
super::slice_error_fail(slice, 0, self.end)
@@ -1934,6 +1953,7 @@
#[inline]
fn get(self, slice: &str) -> Option<&Self::Output> {
if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary.
Some(unsafe { self.get_unchecked(slice) })
} else {
None
@@ -1942,6 +1962,7 @@
#[inline]
fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary.
Some(unsafe { self.get_unchecked_mut(slice) })
} else {
None
@@ -1966,8 +1987,8 @@
}
#[inline]
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
- // is_char_boundary checks that the index is in [0, .len()]
if slice.is_char_boundary(self.start) {
+ // SAFETY: just checked that `start` is on a char boundary.
unsafe { self.get_unchecked_mut(slice) }
} else {
super::slice_error_fail(slice, self.start, slice.len())
@@ -2238,7 +2259,6 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "str_as_bytes", since = "1.32.0")]
#[inline(always)]
- // SAFETY: const sound because we transmute two types with the same layout
#[allow(unused_attributes)]
#[allow_internal_unstable(const_fn_union)]
pub const fn as_bytes(&self) -> &[u8] {
@@ -2247,6 +2267,7 @@
str: &'a str,
slice: &'a [u8],
}
+ // SAFETY: const sound because we transmute two types with the same layout
unsafe { Slices { str: self }.slice }
}
@@ -2573,6 +2594,7 @@
pub fn split_at(&self, mid: usize) -> (&str, &str) {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
+ // SAFETY: just checked that `mid` is on a char boundary.
unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) }
} else {
slice_error_fail(self, 0, mid)
@@ -2617,6 +2639,7 @@
if self.is_char_boundary(mid) {
let len = self.len();
let ptr = self.as_mut_ptr();
+ // SAFETY: just checked that `mid` is on a char boundary.
unsafe {
(
from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)),
@@ -3805,10 +3828,8 @@
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
- unsafe {
- // Searcher is known to return valid indices
- self.get_unchecked(i..j)
- }
+ // SAFETY: `Searcher` is known to return valid indices.
+ unsafe { self.get_unchecked(i..j) }
}
/// Returns a string slice with all prefixes that match a pattern
@@ -3844,10 +3865,8 @@
if let Some((a, _)) = matcher.next_reject() {
i = a;
}
- unsafe {
- // Searcher is known to return valid indices
- self.get_unchecked(i..self.len())
- }
+ // SAFETY: `Searcher` is known to return valid indices.
+ unsafe { self.get_unchecked(i..self.len()) }
}
/// Returns a string slice with the prefix removed.
@@ -3878,10 +3897,8 @@
"The first search step from Searcher \
must include the first character"
);
- unsafe {
- // Searcher is known to return valid indices.
- Some(self.get_unchecked(len..))
- }
+ // SAFETY: `Searcher` is known to return valid indices.
+ unsafe { Some(self.get_unchecked(len..)) }
} else {
None
}
@@ -3919,10 +3936,8 @@
"The first search step from ReverseSearcher \
must include the last character"
);
- unsafe {
- // Searcher is known to return valid indices.
- Some(self.get_unchecked(..start))
- }
+ // SAFETY: `Searcher` is known to return valid indices.
+ unsafe { Some(self.get_unchecked(..start)) }
} else {
None
}
@@ -3970,10 +3985,8 @@
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
- unsafe {
- // Searcher is known to return valid indices
- self.get_unchecked(0..j)
- }
+ // SAFETY: `Searcher` is known to return valid indices.
+ unsafe { self.get_unchecked(0..j) }
}
/// Returns a string slice with all prefixes that match a pattern
@@ -4166,6 +4179,7 @@
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
pub fn make_ascii_uppercase(&mut self) {
+ // SAFETY: safe because we transmute two types with the same layout.
let me = unsafe { self.as_bytes_mut() };
me.make_ascii_uppercase()
}
@@ -4191,6 +4205,7 @@
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
pub fn make_ascii_lowercase(&mut self) {
+ // SAFETY: safe because we transmute two types with the same layout.
let me = unsafe { self.as_bytes_mut() };
me.make_ascii_lowercase()
}
@@ -4357,6 +4372,7 @@
impl Default for &mut str {
/// Creates an empty mutable str
fn default() -> Self {
+ // SAFETY: The empty string is valid UTF-8.
unsafe { from_utf8_unchecked_mut(&mut []) }
}
}
@@ -4412,6 +4428,7 @@
#[derive(Clone)]
struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str {
+ // SAFETY: not safe
unsafe { from_utf8_unchecked(bytes) }
};
}
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 46d9499..ef64d8b 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -3,8 +3,6 @@
//! For more details, see the traits [`Pattern`], [`Searcher`],
//! [`ReverseSearcher`], and [`DoubleEndedSearcher`].
-// ignore-tidy-undocumented-unsafe
-
#![unstable(
feature = "pattern",
reason = "API not fully fleshed out and ready to be stabilized",
@@ -271,6 +269,14 @@
#[inline]
fn next(&mut self) -> SearchStep {
let old_finger = self.finger;
+ // SAFETY: 1-4 guarantee safety of `get_unchecked`
+ // 1. `self.finger` and `self.finger_back` are kept on unicode boundaries
+ // (this is invariant)
+ // 2. `self.finger >= 0` since it starts at 0 and only increases
+ // 3. `self.finger < self.finger_back` because otherwise the char `iter`
+ // would return `SearchStep::Done`
+ // 4. `self.finger` comes before the end of the haystack because `self.finger_back`
+ // starts at the end and only decreases
let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) };
let mut iter = slice.chars();
let old_len = iter.iter.len();
@@ -293,6 +299,7 @@
// get the haystack after the last character found
let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?;
// the last byte of the utf8 encoded needle
+ // SAFETY: we have an invariant that `utf8_size < 5`
let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) };
if let Some(index) = memchr::memchr(last_byte, bytes) {
// The new finger is the index of the byte we found,
@@ -336,6 +343,7 @@
#[inline]
fn next_back(&mut self) -> SearchStep {
let old_finger = self.finger_back;
+ // SAFETY: see the comment for next() above
let slice = unsafe { self.haystack.get_unchecked(self.finger..old_finger) };
let mut iter = slice.chars();
let old_len = iter.iter.len();
@@ -363,6 +371,7 @@
return None;
};
// the last byte of the utf8 encoded needle
+ // SAFETY: we have an invariant that `utf8_size < 5`
let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) };
if let Some(index) = memchr::memrchr(last_byte, bytes) {
// we searched a slice that was offset by self.finger,
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index fae95ca..9d449bb 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -112,8 +112,6 @@
//! println!("live threads: {}", old_thread_count + 1);
//! ```
-// ignore-tidy-undocumented-unsafe
-
#![stable(feature = "rust1", since = "1.0.0")]
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
@@ -350,6 +348,7 @@
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn get_mut(&mut self) -> &mut bool {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *(self.v.get() as *mut bool) }
}
@@ -400,6 +399,8 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn load(&self, order: Ordering) -> bool {
+ // SAFETY: any data races are prevented by atomic intrinsics and the raw
+ // pointer passed in is valid because we got it from a reference.
unsafe { atomic_load(self.v.get(), order) != 0 }
}
@@ -432,6 +433,8 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn store(&self, val: bool, order: Ordering) {
+ // SAFETY: any data races are prevented by atomic intrinsics and the raw
+ // pointer passed in is valid because we got it from a reference.
unsafe {
atomic_store(self.v.get(), val as u8, order);
}
@@ -463,6 +466,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn swap(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
}
@@ -558,6 +562,7 @@
success: Ordering,
failure: Ordering,
) -> Result<bool, bool> {
+ // SAFETY: data races are prevented by atomic intrinsics.
match unsafe {
atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure)
} {
@@ -615,6 +620,7 @@
success: Ordering,
failure: Ordering,
) -> Result<bool, bool> {
+ // SAFETY: data races are prevented by atomic intrinsics.
match unsafe {
atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure)
} {
@@ -661,6 +667,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_and(self.v.get(), val as u8, order) != 0 }
}
@@ -756,6 +763,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_or(self.v.get(), val as u8, order) != 0 }
}
@@ -797,6 +805,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "8")]
pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
}
@@ -872,6 +881,7 @@
#[inline]
#[stable(feature = "atomic_access", since = "1.15.0")]
pub fn get_mut(&mut self) -> &mut *mut T {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *self.p.get() }
}
@@ -923,6 +933,7 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn load(&self, order: Ordering) -> *mut T {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T }
}
@@ -957,6 +968,7 @@
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn store(&self, ptr: *mut T, order: Ordering) {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
atomic_store(self.p.get() as *mut usize, ptr as usize, order);
}
@@ -990,6 +1002,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(target_has_atomic = "ptr")]
pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T }
}
@@ -1074,6 +1087,7 @@
success: Ordering,
failure: Ordering,
) -> Result<*mut T, *mut T> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
let res = atomic_compare_exchange(
self.p.get() as *mut usize,
@@ -1137,6 +1151,7 @@
success: Ordering,
failure: Ordering,
) -> Result<*mut T, *mut T> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
let res = atomic_compare_exchange_weak(
self.p.get() as *mut usize,
@@ -1290,6 +1305,7 @@
#[inline]
#[$stable_access]
pub fn get_mut(&mut self) -> &mut $int_type {
+ // SAFETY: the mutable reference guarantees unique ownership.
unsafe { &mut *self.v.get() }
}
}
@@ -1344,6 +1360,7 @@
#[inline]
#[$stable]
pub fn load(&self, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_load(self.v.get(), order) }
}
}
@@ -1378,6 +1395,7 @@
#[inline]
#[$stable]
pub fn store(&self, val: $int_type, order: Ordering) {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_store(self.v.get(), val, order); }
}
}
@@ -1408,6 +1426,7 @@
#[$stable]
#[$cfg_cas]
pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_swap(self.v.get(), val, order) }
}
}
@@ -1510,6 +1529,7 @@
new: $int_type,
success: Ordering,
failure: Ordering) -> Result<$int_type, $int_type> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
}
}
@@ -1562,6 +1582,7 @@
new: $int_type,
success: Ordering,
failure: Ordering) -> Result<$int_type, $int_type> {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe {
atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
}
@@ -1596,6 +1617,7 @@
#[$stable]
#[$cfg_cas]
pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_add(self.v.get(), val, order) }
}
}
@@ -1628,6 +1650,7 @@
#[$stable]
#[$cfg_cas]
pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_sub(self.v.get(), val, order) }
}
}
@@ -1663,6 +1686,7 @@
#[$stable]
#[$cfg_cas]
pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_and(self.v.get(), val, order) }
}
}
@@ -1699,6 +1723,7 @@
#[$stable_nand]
#[$cfg_cas]
pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_nand(self.v.get(), val, order) }
}
}
@@ -1734,6 +1759,7 @@
#[$stable]
#[$cfg_cas]
pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_or(self.v.get(), val, order) }
}
}
@@ -1769,6 +1795,7 @@
#[$stable]
#[$cfg_cas]
pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { atomic_xor(self.v.get(), val, order) }
}
}
@@ -1880,6 +1907,7 @@
issue = "48655")]
#[$cfg_cas]
pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { $max_fn(self.v.get(), val, order) }
}
}
@@ -1932,6 +1960,7 @@
issue = "48655")]
#[$cfg_cas]
pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
+ // SAFETY: data races are prevented by atomic intrinsics.
unsafe { $min_fn(self.v.get(), val, order) }
}
}
@@ -1960,7 +1989,9 @@
}
let mut atomic = ", stringify!($atomic_type), "::new(1);
-unsafe {
+",
+// SAFETY: Safe as long as `my_atomic_op` is atomic.
+"unsafe {
my_atomic_op(atomic.as_mut_ptr());
}
# }
@@ -2526,6 +2557,7 @@
// https://github.com/WebAssembly/tool-conventions/issues/59. We should
// follow that discussion and implement a solution when one comes about!
#[cfg(not(target_arch = "wasm32"))]
+ // SAFETY: using an atomic fence is safe.
unsafe {
match order {
Acquire => intrinsics::atomic_fence_acq(),
@@ -2613,6 +2645,7 @@
#[inline]
#[stable(feature = "compiler_fences", since = "1.21.0")]
pub fn compiler_fence(order: Ordering) {
+ // SAFETY: using an atomic fence is safe.
unsafe {
match order {
Acquire => intrinsics::atomic_singlethreadfence_acq(),
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 8c03493..f042024 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -19,7 +19,7 @@
#![feature(range_is_empty)]
#![feature(raw)]
#![feature(saturating_neg)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(sort_internals)]
#![feature(slice_partition_at_index)]
#![feature(specialization)]
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 323ce3b6..b65635b 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -37,5 +37,4 @@
chalk-engine = { version = "0.9.0", default-features=false }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.7.1"
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index cb3fdff..15e92d8 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -123,6 +123,9 @@
[few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
[] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
+ // Interned types
+ [] tys: rustc::ty::TyS<$tcx>,
+
// HIR types
[few] hir_forest: rustc::hir::map::Forest<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
@@ -176,7 +179,7 @@
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
#[derive(Default)]
pub struct Arena<$tcx> {
- dropless: DroplessArena,
+ pub dropless: DroplessArena,
drop: DropArena,
$($name: arena_for_type!($a[$ty]),)*
}
diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs
index ffb12f1..de82b26 100644
--- a/src/librustc/benches/lib.rs
+++ b/src/librustc/benches/lib.rs
@@ -1,4 +1,4 @@
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(test)]
extern crate test;
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 5a99e79..86eab3d 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -8,7 +8,6 @@
use crate::ty::query::Providers;
use crate::ty::TyCtxt;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -112,7 +111,7 @@
ItemKind::Union(..) => Target::Union,
ItemKind::Trait(..) => Target::Trait,
ItemKind::TraitAlias(..) => Target::TraitAlias,
- ItemKind::Impl(..) => Target::Impl,
+ ItemKind::Impl { .. } => Target::Impl,
}
}
@@ -144,7 +143,7 @@
let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id);
let containing_item = tcx.hir().expect_item(parent_hir_id);
let containing_impl_is_for_trait = match &containing_item.kind {
- hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(),
+ hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(),
_ => bug!("parent of an ImplItem must be an Impl"),
};
if containing_impl_is_for_trait {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 46c5ee2..6d7f531 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -341,7 +341,7 @@
| ItemKind::Use(..)
| ItemKind::ForeignMod(..)
| ItemKind::GlobalAsm(..)
- | ItemKind::Impl(..) => return None,
+ | ItemKind::Impl { .. } => return None,
},
Node::ForeignItem(item) => match item.kind {
ForeignItemKind::Fn(..) => DefKind::Fn,
@@ -604,7 +604,7 @@
| ItemKind::Union(_, ref generics)
| ItemKind::Trait(_, _, ref generics, ..)
| ItemKind::TraitAlias(ref generics, _)
- | ItemKind::Impl(_, _, _, ref generics, ..) => Some(generics),
+ | ItemKind::Impl { ref generics, .. } => Some(generics),
_ => None,
},
_ => None,
@@ -821,7 +821,7 @@
| ItemKind::Struct(..)
| ItemKind::Union(..)
| ItemKind::Trait(..)
- | ItemKind::Impl(..) => true,
+ | ItemKind::Impl { .. } => true,
_ => false,
},
Node::ForeignItem(fi) => match fi.kind {
@@ -1332,7 +1332,7 @@
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
- ItemKind::Impl(..) => "impl",
+ ItemKind::Impl { .. } => "impl",
};
format!("{} {}{}", item_str, path_str(), id_str)
}
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index febf4f2..77182b9 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -65,7 +65,6 @@
Region, Ty, TyCtxt, TypeFoldable,
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_error_codes::*;
use rustc_errors::{pluralize, struct_span_err};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use rustc_hir as hir;
@@ -254,7 +253,7 @@
fn item_scope_tag(item: &hir::Item<'_>) -> &'static str {
match item.kind {
- hir::ItemKind::Impl(..) => "impl",
+ hir::ItemKind::Impl { .. } => "impl",
hir::ItemKind::Struct(..) => "struct",
hir::ItemKind::Union(..) => "union",
hir::ItemKind::Enum(..) => "enum",
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 70f7987..9947dea 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -13,8 +13,6 @@
use rustc_span::Span;
use std::borrow::Cow;
-use rustc_error_codes::*;
-
struct FindLocalByTypeVisitor<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
target_ty: Ty<'tcx>,
diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
index d6e5020..8f4c643 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -5,7 +5,6 @@
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::util::common::ErrorReported;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 2344d40..df37f53 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -5,8 +5,6 @@
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir::{FunctionRetTy, TyKind};
-use rustc_error_codes::*;
-
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// When given a `ConcreteFailure` for a function with parameters containing a named region and
/// an anonymous region, emit an descriptive diagnostic error.
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index 6303104..11dda71 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -5,8 +5,6 @@
use crate::ty::{self, Region};
use rustc_errors::{struct_span_err, DiagnosticBuilder};
-use rustc_error_codes::*;
-
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub(super) fn note_region_origin(
&self,
diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs
index 0bc49a2..18c25ef 100644
--- a/src/librustc/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc/infer/lexical_region_resolve/mod.rs
@@ -19,7 +19,6 @@
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
};
use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_span::Span;
use std::fmt;
@@ -295,62 +294,59 @@
}
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
- let mut process_constraint = |constraint: &Constraint<'tcx>| {
- let (a_region, b_vid, b_data, retain) = match *constraint {
+ let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
+ let mut changes = Vec::new();
+ for constraint in self.data.constraints.keys() {
+ let (a_vid, a_region, b_vid, b_data) = match *constraint {
Constraint::RegSubVar(a_region, b_vid) => {
let b_data = var_values.value_mut(b_vid);
- (a_region, b_vid, b_data, false)
+ (None, a_region, b_vid, b_data)
}
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
- VarValue::ErrorValue => return (false, false),
+ VarValue::ErrorValue => continue,
VarValue::Value(a_region) => {
let b_data = var_values.value_mut(b_vid);
- let retain = match *b_data {
- VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
- _ => true,
- };
- (a_region, b_vid, b_data, retain)
+ (Some(a_vid), a_region, b_vid, b_data)
}
},
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
// These constraints are checked after expansion
// is done, in `collect_errors`.
- return (false, false);
+ continue;
}
};
-
- let changed = self.expand_node(a_region, b_vid, b_data);
- (changed, retain)
- };
-
- // Using bitsets to track the remaining elements is faster than using a
- // `Vec` by itself (which requires removing elements, which requires
- // element shuffling, which is slow).
- let constraints: Vec<_> = self.data.constraints.keys().collect();
- let mut live_indices: BitSet<usize> = BitSet::new_filled(constraints.len());
- let mut killed_indices: BitSet<usize> = BitSet::new_empty(constraints.len());
- let mut changed = true;
- while changed {
- changed = false;
- for index in live_indices.iter() {
- let constraint = constraints[index];
- let (edge_changed, retain) = process_constraint(constraint);
- changed |= edge_changed;
- if !retain {
- let changed = killed_indices.insert(index);
- debug_assert!(changed);
+ if self.expand_node(a_region, b_vid, b_data) {
+ changes.push(b_vid);
+ }
+ if let Some(a_vid) = a_vid {
+ match *b_data {
+ VarValue::Value(ReStatic) | VarValue::ErrorValue => (),
+ _ => {
+ constraints[a_vid].push((a_vid, b_vid));
+ constraints[b_vid].push((a_vid, b_vid));
+ }
}
}
- live_indices.subtract(&killed_indices);
+ }
- // We could clear `killed_indices` here, but we don't need to and
- // it's cheaper not to.
+ while let Some(vid) = changes.pop() {
+ constraints[vid].retain(|&(a_vid, b_vid)| {
+ let a_region = match *var_values.value(a_vid) {
+ VarValue::ErrorValue => return false,
+ VarValue::Value(a_region) => a_region,
+ };
+ let b_data = var_values.value_mut(b_vid);
+ if self.expand_node(a_region, b_vid, b_data) {
+ changes.push(b_vid);
+ }
+ match *b_data {
+ VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
+ _ => true,
+ }
+ });
}
}
- // This function is very hot in some workloads. There's a single callsite
- // so always inlining is ok even though it's large.
- #[inline(always)]
fn expand_node(
&self,
a_region: Region<'tcx>,
@@ -790,8 +786,8 @@
self.var_infos[node_idx].origin.span(),
&format!(
"collect_error_for_expanding_node() could not find \
- error for var {:?} in universe {:?}, lower_bounds={:#?}, \
- upper_bounds={:#?}",
+ error for var {:?} in universe {:?}, lower_bounds={:#?}, \
+ upper_bounds={:#?}",
node_idx, node_universe, lower_bounds, upper_bounds
),
);
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index ee214be..fe3a5d1 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -15,8 +15,6 @@
use rustc_hir::Node;
use rustc_span::Span;
-use rustc_error_codes::*;
-
pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
/// Information about the opaque types whose values we
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index b894aab..69ca406 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -42,7 +42,7 @@
#![feature(optin_builtin_traits)]
#![feature(option_expect_none)]
#![feature(range_is_empty)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(specialization)]
#![feature(unboxed_closures)]
#![feature(thread_local)]
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
index e4af54f..a349b34 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc/middle/exported_symbols.rs
@@ -32,7 +32,9 @@
}
impl<'tcx> ExportedSymbol<'tcx> {
- pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
+ /// This is the symbol name of an instance if it is instantiated in the
+ /// local crate.
+ pub fn symbol_name_for_local_instance(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
match *self {
ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
ExportedSymbol::Generic(def_id, substs) => {
@@ -50,9 +52,22 @@
}
ExportedSymbol::Generic(..) | ExportedSymbol::NoDefId(_) => cmp::Ordering::Less,
},
- ExportedSymbol::Generic(..) => match *other {
+ ExportedSymbol::Generic(self_def_id, self_substs) => match *other {
ExportedSymbol::NonGeneric(_) => cmp::Ordering::Greater,
- ExportedSymbol::Generic(..) => self.symbol_name(tcx).cmp(&other.symbol_name(tcx)),
+ ExportedSymbol::Generic(other_def_id, other_substs) => {
+ // We compare the symbol names because they are cached as query
+ // results which makes them relatively cheap to access repeatedly.
+ //
+ // It might be even faster to build a local cache of stable IDs
+ // for sorting. Exported symbols are really only sorted once
+ // in order to make the `exported_symbols` query result stable.
+ let self_symbol_name =
+ tcx.symbol_name(ty::Instance::new(self_def_id, self_substs));
+ let other_symbol_name =
+ tcx.symbol_name(ty::Instance::new(other_def_id, other_substs));
+
+ self_symbol_name.cmp(&other_symbol_name)
+ }
ExportedSymbol::NoDefId(_) => cmp::Ordering::Less,
},
ExportedSymbol::NoDefId(self_symbol_name) => match *other {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 643359f..27b7697 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -24,8 +24,6 @@
use rustc_span::Span;
use syntax::ast;
-use rustc_error_codes::*;
-
// The actual lang items defined come at the end of this file in one handy table.
// So you probably just want to nip down to the end.
macro_rules! language_item_table {
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index fdffd12..5571f8f 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -15,8 +15,6 @@
use rustc_target::spec::PanicStrategy;
use syntax::ast;
-use rustc_error_codes::*;
-
macro_rules! weak_lang_items {
($($name:ident, $item:ident, $sym:ident;)*) => (
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 42d896af8..349dbd7 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -16,8 +16,6 @@
use rustc_target::spec::abi::Abi;
use std::{any::Any, env, fmt};
-use rustc_error_codes::*;
-
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
pub enum ErrorHandled {
/// Already reported a lint or an error for this evaluation.
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index e7a4c5b..51ce575 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -1,7 +1,6 @@
use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId};
use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
use crate::session::config::OptLevel;
-use crate::traits::TraitQueryMode;
use crate::ty::print::obsolete::DefPathBasedNames;
use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
use rustc_data_structures::base_n;
@@ -168,9 +167,7 @@
MonoItem::GlobalAsm(..) => return true,
};
- // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\
- // to report an error if overflow somehow occurs.
- tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard))
+ tcx.substitute_normalize_and_test_predicates((def_id, &substs))
}
pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index a20e011..deb2d6a 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -557,6 +557,9 @@
desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) }
}
+ /// The `symbol_name` query provides the symbol name for calling a
+ /// given instance from the local crate. In particular, it will also
+ /// look up the correct symbol name of instances from upstream crates.
query symbol_name(key: ty::Instance<'tcx>) -> ty::SymbolName {
no_force
desc { "computing the symbol for `{}`", key }
@@ -971,6 +974,11 @@
}
Linking {
+ /// The list of symbols exported from the given crate.
+ ///
+ /// - All names contained in `exported_symbols(cnum)` are guaranteed to
+ /// correspond to a publicly visible symbol in `cnum` machine code.
+ /// - The `exported_symbols` sets of different crates do not intersect.
query exported_symbols(_: CrateNum)
-> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>> {
desc { "exported_symbols" }
@@ -1148,11 +1156,11 @@
desc { "normalizing `{:?}`", goal }
}
- query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool {
+ query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool {
no_force
desc { |tcx|
- "testing substituted normalized predicates in mode {:?}:`{}`",
- key.2, tcx.def_path_str(key.0)
+ "testing substituted normalized predicates:`{}`",
+ tcx.def_path_str(key.0)
}
}
diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs
index 89b28ae..c97c5c2 100644
--- a/src/librustc/traits/auto_trait.rs
+++ b/src/librustc/traits/auto_trait.rs
@@ -337,7 +337,10 @@
&Err(SelectionError::Unimplemented) => {
if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
already_visited.remove(&pred);
- self.add_user_pred(&mut user_computed_preds, ty::Predicate::Trait(pred));
+ self.add_user_pred(
+ &mut user_computed_preds,
+ ty::Predicate::Trait(pred, ast::Constness::NotConst),
+ );
predicates.push_back(pred);
} else {
debug!(
@@ -405,7 +408,7 @@
let mut should_add_new = true;
user_computed_preds.retain(|&old_pred| {
match (&new_pred, old_pred) {
- (&ty::Predicate::Trait(new_trait), ty::Predicate::Trait(old_trait)) => {
+ (&ty::Predicate::Trait(new_trait, _), ty::Predicate::Trait(old_trait, _)) => {
if new_trait.def_id() == old_trait.def_id() {
let new_substs = new_trait.skip_binder().trait_ref.substs;
let old_substs = old_trait.skip_binder().trait_ref.substs;
@@ -627,7 +630,7 @@
// We check this by calling is_of_param on the relevant types
// from the various possible predicates
match &predicate {
- &ty::Predicate::Trait(p) => {
+ &ty::Predicate::Trait(p, _) => {
if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
&& !only_projections
&& is_new_pred
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs
index 5b80448..84bfc86 100644
--- a/src/librustc/traits/engine.rs
+++ b/src/librustc/traits/engine.rs
@@ -1,6 +1,6 @@
use crate::infer::InferCtxt;
use crate::traits::Obligation;
-use crate::ty::{self, ToPredicate, Ty, TyCtxt};
+use crate::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_hir::def_id::DefId;
use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError};
@@ -33,7 +33,7 @@
cause,
recursion_depth: 0,
param_env,
- predicate: trait_ref.to_predicate(),
+ predicate: trait_ref.without_const().to_predicate(),
},
);
}
diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs
index db31739..d1c369d 100644
--- a/src/librustc/traits/error_reporting/mod.rs
+++ b/src/librustc/traits/error_reporting/mod.rs
@@ -19,7 +19,9 @@
use crate::ty::fast_reject;
use crate::ty::fold::TypeFolder;
use crate::ty::SubtypePredicate;
-use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{
+ self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
@@ -30,8 +32,6 @@
use std::fmt;
use syntax::ast;
-use rustc_error_codes::*;
-
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn report_fulfillment_errors(
&self,
@@ -130,7 +130,7 @@
}
let (cond, error) = match (cond, error) {
- (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error),
+ (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error, _)) => (cond, error),
_ => {
// FIXME: make this work in other cases too.
return false;
@@ -138,7 +138,7 @@
};
for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) {
- if let ty::Predicate::Trait(implication) = implication {
+ if let ty::Predicate::Trait(implication, _) = implication {
let error = error.to_poly_trait_ref();
let implication = implication.to_poly_trait_ref();
// FIXME: I'm just not taking associated types at all here.
@@ -530,7 +530,7 @@
return;
}
match obligation.predicate {
- ty::Predicate::Trait(ref trait_predicate) => {
+ ty::Predicate::Trait(ref trait_predicate, _) => {
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
@@ -583,7 +583,7 @@
"{}",
message.unwrap_or_else(|| format!(
"the trait bound `{}` is not satisfied{}",
- trait_ref.to_predicate(),
+ trait_ref.without_const().to_predicate(),
post_message,
))
);
@@ -695,7 +695,10 @@
trait_pred
});
let unit_obligation = Obligation {
- predicate: ty::Predicate::Trait(predicate),
+ predicate: ty::Predicate::Trait(
+ predicate,
+ ast::Constness::NotConst,
+ ),
..obligation.clone()
};
if self.predicate_may_hold(&unit_obligation) {
@@ -988,7 +991,7 @@
) -> PredicateObligation<'tcx> {
let new_trait_ref =
ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) };
- Obligation::new(cause, param_env, new_trait_ref.to_predicate())
+ Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate())
}
}
@@ -1076,7 +1079,7 @@
}
let mut err = match predicate {
- ty::Predicate::Trait(ref data) => {
+ ty::Predicate::Trait(ref data, _) => {
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
@@ -1269,8 +1272,11 @@
)
.value;
- let obligation =
- Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate());
+ let obligation = Obligation::new(
+ ObligationCause::dummy(),
+ param_env,
+ cleaned_pred.without_const().to_predicate(),
+ );
self.predicate_may_hold(&obligation)
})
diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs
index bf68912..4559007 100644
--- a/src/librustc/traits/error_reporting/suggestions.rs
+++ b/src/librustc/traits/error_reporting/suggestions.rs
@@ -6,7 +6,7 @@
use crate::infer::InferCtxt;
use crate::traits::object_safety::object_safety_violations;
use crate::ty::TypeckTables;
-use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
@@ -20,8 +20,6 @@
use rustc_span::{MultiSpan, Span, DUMMY_SP};
use std::fmt;
-use rustc_error_codes::*;
-
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
crate fn suggest_restricting_param_bound(
&self,
@@ -50,7 +48,7 @@
} else {
" where"
},
- trait_ref.to_predicate(),
+ trait_ref.without_const().to_predicate(),
),
Applicability::MachineApplicable,
);
@@ -88,8 +86,7 @@
..
})
| hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Impl(_, _, _, generics, ..),
- ..
+ kind: hir::ItemKind::Impl { generics, .. }, ..
}) if projection.is_some() => {
// Missing associated type bound.
suggest_restriction(&generics, "the associated type", err);
@@ -115,7 +112,7 @@
..
})
| hir::Node::Item(hir::Item {
- kind: hir::ItemKind::Impl(_, _, _, generics, ..),
+ kind: hir::ItemKind::Impl { generics, .. },
span,
..
})
@@ -341,8 +338,11 @@
let new_self_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, self_ty);
let substs = self.tcx.mk_substs_trait(new_self_ty, &[]);
let new_trait_ref = ty::TraitRef::new(obligation.parent_trait_ref.def_id(), substs);
- let new_obligation =
- Obligation::new(ObligationCause::dummy(), param_env, new_trait_ref.to_predicate());
+ let new_obligation = Obligation::new(
+ ObligationCause::dummy(),
+ param_env,
+ new_trait_ref.without_const().to_predicate(),
+ );
if self.predicate_must_hold_modulo_regions(&new_obligation) {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
// We have a very specific type of error, where just borrowing this argument
@@ -1123,7 +1123,7 @@
// the type. The last generator has information about where the bound was introduced. At
// least one generator should be present for this diagnostic to be modified.
let (mut trait_ref, mut target_ty) = match obligation.predicate {
- ty::Predicate::Trait(p) => {
+ ty::Predicate::Trait(p, _) => {
(Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty()))
}
_ => (None, None),
@@ -1546,7 +1546,7 @@
err.note(&format!("required because it appears within the type `{}`", ty));
obligated_types.push(ty);
- let parent_predicate = parent_trait_ref.to_predicate();
+ let parent_predicate = parent_trait_ref.without_const().to_predicate();
if !self.is_recursive_obligation(obligated_types, &data.parent_code) {
self.note_obligation_cause_code(
err,
@@ -1563,7 +1563,7 @@
parent_trait_ref.print_only_trait_path(),
parent_trait_ref.skip_binder().self_ty()
));
- let parent_predicate = parent_trait_ref.to_predicate();
+ let parent_predicate = parent_trait_ref.without_const().to_predicate();
self.note_obligation_cause_code(
err,
&parent_predicate,
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 9e5abc8..0aac6fb 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -16,7 +16,6 @@
use super::{ConstEvalFailure, Unimplemented};
use super::{FulfillmentError, FulfillmentErrorCode};
use super::{ObligationCause, PredicateObligation};
-use crate::traits::TraitQueryMode;
impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
type Predicate = ty::Predicate<'tcx>;
@@ -63,9 +62,6 @@
// a snapshot (they don't *straddle* a snapshot, so there
// is no trouble there).
usable_in_snapshot: bool,
-
- // The `TraitQueryMode` used when constructing a `SelectionContext`
- query_mode: TraitQueryMode,
}
#[derive(Clone, Debug)]
@@ -79,26 +75,12 @@
static_assert_size!(PendingPredicateObligation<'_>, 136);
impl<'a, 'tcx> FulfillmentContext<'tcx> {
- /// Creates a new fulfillment context with `TraitQueryMode::Standard`
- /// You almost always want to use this instead of `with_query_mode`
+ /// Creates a new fulfillment context.
pub fn new() -> FulfillmentContext<'tcx> {
FulfillmentContext {
predicates: ObligationForest::new(),
register_region_obligations: true,
usable_in_snapshot: false,
- query_mode: TraitQueryMode::Standard,
- }
- }
-
- /// Creates a new fulfillment context with the specified query mode.
- /// This should only be used when you want to ignore overflow,
- /// rather than reporting it as an error.
- pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> {
- FulfillmentContext {
- predicates: ObligationForest::new(),
- register_region_obligations: true,
- usable_in_snapshot: false,
- query_mode,
}
}
@@ -107,7 +89,6 @@
predicates: ObligationForest::new(),
register_region_obligations: true,
usable_in_snapshot: true,
- query_mode: TraitQueryMode::Standard,
}
}
@@ -116,7 +97,6 @@
predicates: ObligationForest::new(),
register_region_obligations: false,
usable_in_snapshot: false,
- query_mode: TraitQueryMode::Standard,
}
}
@@ -237,7 +217,7 @@
&mut self,
infcx: &InferCtxt<'_, 'tcx>,
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
- let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode);
+ let mut selcx = SelectionContext::new(infcx);
self.select(&mut selcx)
}
@@ -331,7 +311,7 @@
}
match obligation.predicate {
- ty::Predicate::Trait(ref data) => {
+ ty::Predicate::Trait(ref data, _) => {
let trait_obligation = obligation.with(data.clone());
if data.is_global() {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 2e5da2b..daaba95 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -29,7 +29,7 @@
use crate::ty::error::{ExpectedFound, TypeError};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::subst::{InternalSubsts, SubstsRef};
-use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt};
+use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness};
use crate::util::common::ErrorReported;
use chalk_engine;
use rustc_hir as hir;
@@ -95,7 +95,7 @@
}
/// The mode that trait queries run in.
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum TraitQueryMode {
// Standard/un-canonicalized queries get accurate
// spans etc. passed in and hence can do reasonable
@@ -732,7 +732,7 @@
param_env,
cause: ObligationCause::misc(span, hir::DUMMY_HIR_ID),
recursion_depth: 0,
- predicate: trait_ref.to_predicate(),
+ predicate: trait_ref.without_const().to_predicate(),
};
let result = infcx.predicate_must_hold_modulo_regions(&obligation);
@@ -1014,17 +1014,16 @@
/// environment. If this returns false, then either normalize
/// encountered an error or one of the predicates did not hold. Used
/// when creating vtables to check for unsatisfiable methods.
-fn normalize_and_test_predicates<'tcx>(
+pub fn normalize_and_test_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
predicates: Vec<ty::Predicate<'tcx>>,
- mode: TraitQueryMode,
) -> bool {
- debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode);
+ debug!("normalize_and_test_predicates(predicates={:?})", predicates);
let result = tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::reveal_all();
- let mut selcx = SelectionContext::with_query_mode(&infcx, mode);
- let mut fulfill_cx = FulfillmentContext::with_query_mode(mode);
+ let mut selcx = SelectionContext::new(&infcx);
+ let mut fulfill_cx = FulfillmentContext::new();
let cause = ObligationCause::dummy();
let Normalized { value: predicates, obligations } =
normalize(&mut selcx, param_env, cause.clone(), &predicates);
@@ -1044,12 +1043,12 @@
fn substitute_normalize_and_test_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
- key: (DefId, SubstsRef<'tcx>, TraitQueryMode),
+ key: (DefId, SubstsRef<'tcx>),
) -> bool {
debug!("substitute_normalize_and_test_predicates(key={:?})", key);
let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
- let result = normalize_and_test_predicates(tcx, predicates, key.2);
+ let result = normalize_and_test_predicates(tcx, predicates);
debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result);
result
@@ -1102,10 +1101,7 @@
// Note that this method could then never be called, so we
// do not want to try and codegen it, in that case (see #23435).
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
- // We don't expect overflow here, so report an error if it somehow ends
- // up happening.
- if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard)
- {
+ if !normalize_and_test_predicates(tcx, predicates.predicates) {
debug!("vtable_methods: predicates do not hold");
return None;
}
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index ce57fb8..15f81bb 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -12,7 +12,7 @@
use crate::traits::{self, Obligation, ObligationCause};
use crate::ty::subst::{InternalSubsts, Subst};
-use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
@@ -234,7 +234,7 @@
.map(|(predicate, _)| predicate.subst_supertrait(tcx, &trait_ref))
.any(|predicate| {
match predicate {
- ty::Predicate::Trait(ref data) => {
+ ty::Predicate::Trait(ref data, _) => {
// In the case of a trait predicate, we can skip the "self" type.
data.skip_binder().input_types().skip(1).any(has_self_ty)
}
@@ -285,7 +285,7 @@
let predicates = tcx.predicates_of(def_id);
let predicates = predicates.instantiate_identity(tcx).predicates;
elaborate_predicates(tcx, predicates).any(|predicate| match predicate {
- ty::Predicate::Trait(ref trait_pred) => {
+ ty::Predicate::Trait(ref trait_pred, _) => {
trait_pred.def_id() == sized_def_id && trait_pred.skip_binder().self_ty().is_param(0)
}
ty::Predicate::Projection(..)
@@ -585,6 +585,7 @@
def_id: unsize_did,
substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
}
+ .without_const()
.to_predicate();
// U: Trait<Arg1, ..., ArgN>
@@ -598,7 +599,7 @@
}
});
- ty::TraitRef { def_id: unsize_did, substs }.to_predicate()
+ ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate()
};
let caller_bounds: Vec<Predicate<'tcx>> = param_env
@@ -620,6 +621,7 @@
def_id: dispatch_from_dyn_did,
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
}
+ .without_const()
.to_predicate();
Obligation::new(ObligationCause::dummy(), param_env, predicate)
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 1afe153..669ec5c 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -11,8 +11,6 @@
use syntax::ast::{MetaItem, NestedMetaItem};
use syntax::attr;
-use rustc_error_codes::*;
-
#[derive(Clone, Debug)]
pub struct OnUnimplementedFormatString(Symbol);
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 5bc211a..62672a7 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -16,7 +16,7 @@
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::ty::subst::{InternalSubsts, Subst};
-use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt};
+use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
@@ -738,7 +738,12 @@
depth: usize,
) -> PredicateObligation<'tcx> {
let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref();
- Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate() }
+ Obligation {
+ cause,
+ recursion_depth: depth,
+ param_env,
+ predicate: trait_ref.without_const().to_predicate(),
+ }
}
/// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
@@ -772,7 +777,7 @@
cause,
recursion_depth: depth,
param_env,
- predicate: trait_ref.to_predicate(),
+ predicate: trait_ref.without_const().to_predicate(),
};
let tcx = selcx.infcx().tcx;
let def_id = projection_ty.item_def_id;
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index 34866b6..2e5ef5a 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -6,8 +6,6 @@
use rustc_span::source_map::Span;
use std::iter::FromIterator;
-use rustc_error_codes::*;
-
impl<'cx, 'tcx> At<'cx, 'tcx> {
/// Given a type `ty` of some value being dropped, computes a set
/// of "kinds" (types, regions) that must be outlive the execution
diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs
index c0a0cbe..15870ec 100644
--- a/src/librustc/traits/query/type_op/prove_predicate.rs
+++ b/src/librustc/traits/query/type_op/prove_predicate.rs
@@ -24,7 +24,7 @@
// `&T`, accounts for about 60% percentage of the predicates
// we have to prove. No need to canonicalize and all that for
// such cases.
- if let Predicate::Trait(trait_ref) = key.value.predicate {
+ if let Predicate::Trait(trait_ref, _) = key.value.predicate {
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
if trait_ref.def_id() == sized_def_id {
if trait_ref.skip_binder().self_ty().is_trivially_sized(tcx) {
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index fb1c468..ac1ca4d 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -37,7 +37,7 @@
use crate::ty::fast_reject;
use crate::ty::relate::TypeRelation;
use crate::ty::subst::{Subst, SubstsRef};
-use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_hir::def_id::DefId;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -51,7 +51,7 @@
use std::fmt::{self, Display};
use std::iter;
use std::rc::Rc;
-use syntax::attr;
+use syntax::{ast, attr};
pub struct SelectionContext<'cx, 'tcx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
@@ -718,7 +718,7 @@
}
match obligation.predicate {
- ty::Predicate::Trait(ref t) => {
+ ty::Predicate::Trait(ref t, _) => {
debug_assert!(!t.has_escaping_bound_vars());
let obligation = obligation.with(t.clone());
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
@@ -945,7 +945,9 @@
// trait refs. This is important because it's only a cycle
// if the regions match exactly.
let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
- let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate));
+ let cycle = cycle.map(|stack| {
+ ty::Predicate::Trait(stack.obligation.predicate, ast::Constness::NotConst)
+ });
if self.coinductive_match(cycle) {
debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref);
Some(EvaluatedToOk)
@@ -1060,7 +1062,7 @@
fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
let result = match predicate {
- ty::Predicate::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()),
+ ty::Predicate::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()),
_ => false,
};
debug!("coinductive_predicate({:?}) = {:?}", predicate, result);
@@ -1417,6 +1419,8 @@
debug!("winnowed to {} candidates for {:?}: {:?}", candidates.len(), stack, candidates);
+ let needs_infer = stack.obligation.predicate.needs_infer();
+
// If there are STILL multiple candidates, we can further
// reduce the list by dropping duplicates -- including
// resolving specializations.
@@ -1424,7 +1428,11 @@
let mut i = 0;
while i < candidates.len() {
let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
- self.candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j])
+ self.candidate_should_be_dropped_in_favor_of(
+ &candidates[i],
+ &candidates[j],
+ needs_infer,
+ )
});
if is_dup {
debug!("Dropping candidate #{}/{}: {:?}", i, candidates.len(), candidates[i]);
@@ -2258,6 +2266,7 @@
&mut self,
victim: &EvaluatedCandidate<'tcx>,
other: &EvaluatedCandidate<'tcx>,
+ needs_infer: bool,
) -> bool {
if victim.candidate == other.candidate {
return true;
@@ -2339,10 +2348,55 @@
match victim.candidate {
ImplCandidate(victim_def) => {
let tcx = self.tcx();
- return tcx.specializes((other_def, victim_def))
- || tcx
- .impls_are_allowed_to_overlap(other_def, victim_def)
- .is_some();
+ if tcx.specializes((other_def, victim_def)) {
+ return true;
+ }
+ return match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
+ Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
+ // Subtle: If the predicate we are evaluating has inference
+ // variables, do *not* allow discarding candidates due to
+ // marker trait impls.
+ //
+ // Without this restriction, we could end up accidentally
+ // constrainting inference variables based on an arbitrarily
+ // chosen trait impl.
+ //
+ // Imagine we have the following code:
+ //
+ // ```rust
+ // #[marker] trait MyTrait {}
+ // impl MyTrait for u8 {}
+ // impl MyTrait for bool {}
+ // ```
+ //
+ // And we are evaluating the predicate `<_#0t as MyTrait>`.
+ //
+ // During selection, we will end up with one candidate for each
+ // impl of `MyTrait`. If we were to discard one impl in favor
+ // of the other, we would be left with one candidate, causing
+ // us to "successfully" select the predicate, unifying
+ // _#0t with (for example) `u8`.
+ //
+ // However, we have no reason to believe that this unification
+ // is correct - we've essentially just picked an arbitrary
+ // *possibility* for _#0t, and required that this be the *only*
+ // possibility.
+ //
+ // Eventually, we will either:
+ // 1) Unify all inference variables in the predicate through
+ // some other means (e.g. type-checking of a function). We will
+ // then be in a position to drop marker trait candidates
+ // without constraining inference variables (since there are
+ // none left to constrin)
+ // 2) Be left with some unconstrained inference variables. We
+ // will then correctly report an inference error, since the
+ // existence of multiple marker trait impls tells us nothing
+ // about which one should actually apply.
+ !needs_infer
+ }
+ Some(_) => true,
+ None => false,
+ };
}
ParamCandidate(ref cand) => {
// Prefer the impl to a global where clause candidate.
@@ -3314,7 +3368,7 @@
tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
tcx.mk_substs_trait(source, &[]),
);
- nested.push(predicate_to_obligation(tr.to_predicate()));
+ nested.push(predicate_to_obligation(tr.without_const().to_predicate()));
// If the type is `Foo + 'a`, ensure that the type
// being cast to `Foo + 'a` outlives `'a`:
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index f5199db..e559ea3 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -25,8 +25,6 @@
use super::util::impl_trait_ref_and_oblig;
use super::{FulfillmentContext, SelectionContext};
-use rustc_error_codes::*;
-
/// Information pertinent to an overlapping impl error.
#[derive(Debug)]
pub struct OverlapError {
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index c176f13..9509b62 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -163,7 +163,7 @@
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
{
match overlap_kind {
- ty::ImplOverlapKind::Permitted => {}
+ ty::ImplOverlapKind::Permitted { marker: _ } => {}
ty::ImplOverlapKind::Issue33140 => {
last_lint = Some(FutureCompatOverlapError {
error: overlap_error(overlap),
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 65fd809..f3bd98b 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -4,7 +4,7 @@
use crate::ty::outlives::Component;
use crate::ty::subst::{GenericArg, Subst, SubstsRef};
-use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt};
+use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -13,8 +13,8 @@
fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
match *pred {
- ty::Predicate::Trait(ref data) => {
- ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data))
+ ty::Predicate::Trait(ref data, constness) => {
+ ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
}
ty::Predicate::RegionOutlives(ref data) => {
@@ -99,14 +99,14 @@
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
- elaborate_predicates(tcx, vec![trait_ref.to_predicate()])
+ elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
}
pub fn elaborate_trait_refs<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
- let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect();
+ let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
elaborate_predicates(tcx, predicates)
}
@@ -127,7 +127,7 @@
fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
let tcx = self.visited.tcx;
match *predicate {
- ty::Predicate::Trait(ref data) => {
+ ty::Predicate::Trait(ref data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());
@@ -358,7 +358,7 @@
fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
let tcx = self.tcx;
let trait_ref = item.trait_ref();
- let pred = trait_ref.to_predicate();
+ let pred = trait_ref.without_const().to_predicate();
debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
@@ -370,13 +370,9 @@
// Don't recurse if this trait alias is already on the stack for the DFS search.
let anon_pred = anonymize_predicate(tcx, &pred);
- if item
- .path
- .iter()
- .rev()
- .skip(1)
- .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred)
- {
+ if item.path.iter().rev().skip(1).any(|(tr, _)| {
+ anonymize_predicate(tcx, &tr.without_const().to_predicate()) == anon_pred
+ }) {
return false;
}
@@ -471,7 +467,7 @@
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(pred) = self.base_iterator.next() {
- if let ty::Predicate::Trait(data) = pred {
+ if let ty::Predicate::Trait(data, _) = pred {
return Some(data.to_poly_trait_ref());
}
}
@@ -545,7 +541,12 @@
trait_ref: ty::TraitRef<'tcx>,
recursion_depth: usize,
) -> PredicateObligation<'tcx> {
- Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() }
+ Obligation {
+ cause,
+ param_env,
+ recursion_depth,
+ predicate: trait_ref.without_const().to_predicate(),
+ }
}
pub fn predicate_for_trait_def(
@@ -651,7 +652,7 @@
match tcx.hir().as_local_hir_id(node_item_def_id) {
Some(hir_id) => {
let item = tcx.hir().expect_item(hir_id);
- if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind {
+ if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
defaultness.is_default()
} else {
false
diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs
index 2301395..a0cb844 100644
--- a/src/librustc/traits/wf.rs
+++ b/src/librustc/traits/wf.rs
@@ -3,7 +3,7 @@
use crate::middle::lang_items;
use crate::traits::{self, AssocTypeBoundData};
use crate::ty::subst::SubstsRef;
-use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::symbol::{kw, Ident};
@@ -62,7 +62,7 @@
// (*) ok to skip binders, because wf code is prepared for it
match *predicate {
- ty::Predicate::Trait(ref t) => {
+ ty::Predicate::Trait(ref t, _) => {
wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
}
ty::Predicate::RegionOutlives(..) => {}
@@ -229,9 +229,9 @@
// |
// = note: expected type `u32`
// found type `()`
- if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) {
+ if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) {
let trait_assoc_item = tcx.associated_item(proj.projection_def_id());
- if let Some(impl_item) = impl_items
+ if let Some(impl_item) = items
.iter()
.filter(|item| item.ident == trait_assoc_item.ident)
.next()
@@ -245,7 +245,7 @@
}
}
}
- ty::Predicate::Trait(proj) => {
+ ty::Predicate::Trait(proj, _) => {
// An associated item obligation born out of the `trait` failed to be met.
// Point at the `impl` that failed the obligation, the associated item that
// needed to meet the obligation, and the definition of that associated item,
@@ -279,14 +279,14 @@
// | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
if let (
ty::Projection(ty::ProjectionTy { item_def_id, .. }),
- Some(hir::ItemKind::Impl(.., impl_items)),
+ Some(hir::ItemKind::Impl { items, .. }),
) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind))
{
if let Some((impl_item, trait_assoc_item)) = trait_assoc_items
.filter(|i| i.def_id == *item_def_id)
.next()
.and_then(|trait_assoc_item| {
- impl_items
+ items
.iter()
.filter(|i| i.ident == trait_assoc_item.ident)
.next()
@@ -350,7 +350,7 @@
self.compute_trait_ref(&trait_ref, Elaborate::None);
if !data.has_escaping_bound_vars() {
- let predicate = trait_ref.to_predicate();
+ let predicate = trait_ref.without_const().to_predicate();
let cause = self.cause(traits::ProjectionWf(data));
self.out.push(traits::Obligation::new(cause, self.param_env, predicate));
}
@@ -378,7 +378,11 @@
def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
substs: self.infcx.tcx.mk_substs_trait(subty, &[]),
};
- self.out.push(traits::Obligation::new(cause, self.param_env, trait_ref.to_predicate()));
+ self.out.push(traits::Obligation::new(
+ cause,
+ self.param_env,
+ trait_ref.without_const().to_predicate(),
+ ));
}
}
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ef776c8..a51f0f7 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -51,10 +51,9 @@
use rustc_session::config::{BorrowckMode, OutputFilenames};
use rustc_session::Session;
-use arena::SyncDroplessArena;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::profiling::SelfProfilerRef;
-use rustc_data_structures::sharded::ShardedHashMap;
+use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{
hash_stable_hashmap, HashStable, StableHasher, StableVec,
};
@@ -83,21 +82,11 @@
use syntax::attr;
use syntax::expand::allocator::AllocatorKind;
-pub struct AllArenas {
- pub interner: SyncDroplessArena,
-}
-
-impl AllArenas {
- pub fn new() -> Self {
- AllArenas { interner: SyncDroplessArena::default() }
- }
-}
-
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
pub struct CtxtInterners<'tcx> {
/// The arena that types, regions, etc. are allocated from.
- arena: &'tcx SyncDroplessArena,
+ arena: &'tcx WorkerLocal<Arena<'tcx>>,
/// Specifically use a speedy hash algorithm for these hash sets, since
/// they're accessed quite often.
@@ -117,7 +106,7 @@
}
impl<'tcx> CtxtInterners<'tcx> {
- fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
+ fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
CtxtInterners {
arena,
type_: Default::default(),
@@ -1125,7 +1114,6 @@
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
local_providers: ty::query::Providers<'tcx>,
extern_providers: ty::query::Providers<'tcx>,
- arenas: &'tcx AllArenas,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
resolutions: ty::ResolverOutputs,
hir: hir_map::Map<'tcx>,
@@ -1136,7 +1124,7 @@
let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
s.fatal(&err);
});
- let interners = CtxtInterners::new(&arenas.interner);
+ let interners = CtxtInterners::new(arena);
let common_types = CommonTypes::new(&interners);
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
@@ -1567,11 +1555,11 @@
}
macro_rules! nop_lift {
- ($ty:ty => $lifted:ty) => {
+ ($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
- if tcx.interners.arena.in_arena(*self as *const _) {
+ if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
Some(unsafe { mem::transmute(*self) })
} else {
None
@@ -1582,14 +1570,14 @@
}
macro_rules! nop_list_lift {
- ($ty:ty => $lifted:ty) => {
+ ($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
type Lifted = &'tcx List<$lifted>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if self.is_empty() {
return Some(List::empty());
}
- if tcx.interners.arena.in_arena(*self as *const _) {
+ if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
Some(unsafe { mem::transmute(*self) })
} else {
None
@@ -1599,21 +1587,21 @@
};
}
-nop_lift! {Ty<'a> => Ty<'tcx>}
-nop_lift! {Region<'a> => Region<'tcx>}
-nop_lift! {Goal<'a> => Goal<'tcx>}
-nop_lift! {&'a Const<'a> => &'tcx Const<'tcx>}
+nop_lift! {type_; Ty<'a> => Ty<'tcx>}
+nop_lift! {region; Region<'a> => Region<'tcx>}
+nop_lift! {goal; Goal<'a> => Goal<'tcx>}
+nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
-nop_list_lift! {Goal<'a> => Goal<'tcx>}
-nop_list_lift! {Clause<'a> => Clause<'tcx>}
-nop_list_lift! {Ty<'a> => Ty<'tcx>}
-nop_list_lift! {ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
-nop_list_lift! {Predicate<'a> => Predicate<'tcx>}
-nop_list_lift! {CanonicalVarInfo => CanonicalVarInfo}
-nop_list_lift! {ProjectionKind => ProjectionKind}
+nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
+nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
+nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
+nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
+nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
+nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
+nop_list_lift! {projs; ProjectionKind => ProjectionKind}
// This is the impl for `&'a InternalSubsts<'a>`.
-nop_list_lift! {GenericArg<'a> => GenericArg<'tcx>}
+nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
@@ -1937,6 +1925,11 @@
}
impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}
+impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
+ fn into_pointer(&self) -> *const () {
+ self.0 as *const _ as *const ()
+ }
+}
// N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
@@ -2089,7 +2082,7 @@
$(impl<'tcx> TyCtxt<'tcx> {
pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
self.interners.$field.intern_ref(v, || {
- Interned(List::from_arena(&self.interners.arena, v))
+ Interned(List::from_arena(&*self.arena, v))
}).0
}
})+
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index b16db6a..0dddca9 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -150,6 +150,15 @@
}
}
+impl TypeFoldable<'tcx> for syntax::ast::Constness {
+ fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
+ *self
+ }
+ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
+ false
+ }
+}
+
/// The `TypeFolder` trait defines the actual *folding*. There is a
/// method defined for every foldable type. Each of these has a
/// default implementation that does an "identity" fold. Within each
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 9be50d1..1ea695e 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -141,7 +141,12 @@
}
pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
- tcx.codegen_fn_attrs(self.def_id()).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
+ match *self {
+ InstanceDef::Item(def_id) => {
+ tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
+ }
+ _ => false,
+ }
}
}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index e6acb6b..0470ab2 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -6,6 +6,7 @@
pub use self::IntVarValue::*;
pub use self::Variance::*;
+use crate::arena::Arena;
use crate::hir::exports::ExportMap;
use crate::hir::map as hir_map;
@@ -25,7 +26,6 @@
use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
use crate::ty::util::{Discr, IntTypeExt};
use crate::ty::walk::TypeWalker;
-use arena::SyncDroplessArena;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
@@ -52,7 +52,7 @@
use std::ops::Range;
use std::slice;
use std::{mem, ptr};
-use syntax::ast::{self, Ident, Name, NodeId};
+use syntax::ast::{self, Constness, Ident, Name, NodeId};
use syntax::attr;
pub use self::sty::BoundRegion::*;
@@ -74,7 +74,7 @@
pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;
-pub use self::context::{keep_local, tls, AllArenas, FreeRegionInfo, TyCtxt};
+pub use self::context::{keep_local, tls, FreeRegionInfo, TyCtxt};
pub use self::context::{
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
UserType, UserTypeAnnotationIndex,
@@ -604,7 +604,7 @@
impl<T: Copy> List<T> {
#[inline]
- fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List<T> {
+ fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
assert!(!mem::needs_drop::<T>());
assert!(mem::size_of::<T>() != 0);
assert!(slice.len() != 0);
@@ -617,7 +617,9 @@
let size = offset + slice.len() * mem::size_of::<T>();
- let mem = arena.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
+ let mem = arena
+ .dropless
+ .alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
unsafe {
let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
// Write the length
@@ -1066,7 +1068,11 @@
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the type parameters.
- Trait(PolyTraitPredicate<'tcx>),
+ ///
+ /// A trait predicate will have `Constness::Const` if it originates
+ /// from a bound on a `const fn` without the `?const` opt-out (e.g.,
+ /// `const fn foobar<Foo: Bar>() {}`).
+ Trait(PolyTraitPredicate<'tcx>, Constness),
/// `where 'a: 'b`
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
@@ -1189,8 +1195,8 @@
let substs = &trait_ref.skip_binder().substs;
match *self {
- Predicate::Trait(ref binder) => {
- Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)))
+ Predicate::Trait(ref binder, constness) => {
+ Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)), constness)
}
Predicate::Subtype(ref binder) => {
Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs)))
@@ -1334,15 +1340,33 @@
fn to_predicate(&self) -> Predicate<'tcx>;
}
-impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
+impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
fn to_predicate(&self) -> Predicate<'tcx> {
- ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }))
+ ty::Predicate::Trait(
+ ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }),
+ self.constness,
+ )
}
}
-impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
+impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> {
fn to_predicate(&self) -> Predicate<'tcx> {
- ty::Predicate::Trait(self.to_poly_trait_predicate())
+ ty::Predicate::Trait(
+ ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }),
+ self.constness,
+ )
+ }
+}
+
+impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
+ fn to_predicate(&self) -> Predicate<'tcx> {
+ ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
+ }
+}
+
+impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&PolyTraitRef<'tcx>> {
+ fn to_predicate(&self) -> Predicate<'tcx> {
+ ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
}
}
@@ -1411,7 +1435,7 @@
/// with depth 0 are bound by the predicate.
pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a {
match *self {
- ty::Predicate::Trait(ref data) => {
+ ty::Predicate::Trait(ref data, _) => {
WalkTysIter::InputTypes(data.skip_binder().input_types())
}
ty::Predicate::Subtype(binder) => {
@@ -1437,7 +1461,7 @@
pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
match *self {
- Predicate::Trait(ref t) => Some(t.to_poly_trait_ref()),
+ Predicate::Trait(ref t, _) => Some(t.to_poly_trait_ref()),
Predicate::Projection(..)
| Predicate::Subtype(..)
| Predicate::RegionOutlives(..)
@@ -1698,6 +1722,33 @@
}
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct ConstnessAnd<T> {
+ pub constness: Constness,
+ pub value: T,
+}
+
+// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate()` to ensure that
+// the constness of trait bounds is being propagated correctly.
+pub trait WithConstness: Sized {
+ #[inline]
+ fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
+ ConstnessAnd { constness, value: self }
+ }
+
+ #[inline]
+ fn with_const(self) -> ConstnessAnd<Self> {
+ self.with_constness(Constness::Const)
+ }
+
+ #[inline]
+ fn without_const(self) -> ConstnessAnd<Self> {
+ self.with_constness(Constness::NotConst)
+ }
+}
+
+impl<T> WithConstness for T {}
+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
pub struct ParamEnvAnd<'tcx, T> {
pub param_env: ParamEnv<'tcx>,
@@ -2589,7 +2640,12 @@
#[derive(Debug, PartialEq, Eq)]
pub enum ImplOverlapKind {
/// These impls are always allowed to overlap.
- Permitted,
+ Permitted {
+ /// Whether or not the impl is permitted due to the trait being
+ /// a marker trait (a trait with #[marker], or a trait with
+ /// no associated items and #![feature(overlapping_marker_traits)] enabled)
+ marker: bool,
+ },
/// These impls are allowed to overlap, but that raises
/// an issue #33140 future-compatibility warning.
///
@@ -2709,7 +2765,7 @@
if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
|| self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
{
- return Some(ImplOverlapKind::Permitted);
+ return Some(ImplOverlapKind::Permitted { marker: false });
}
match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
@@ -2719,7 +2775,7 @@
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
def_id1, def_id2
);
- return Some(ImplOverlapKind::Permitted);
+ return Some(ImplOverlapKind::Permitted { marker: false });
}
(ImplPolarity::Positive, ImplPolarity::Negative)
| (ImplPolarity::Negative, ImplPolarity::Positive) => {
@@ -2755,7 +2811,7 @@
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
def_id1, def_id2
);
- Some(ImplOverlapKind::Permitted)
+ Some(ImplOverlapKind::Permitted { marker: true })
} else {
if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 8b1b2bb..9091de5 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -1791,7 +1791,12 @@
ty::Predicate<'tcx> {
match *self {
- ty::Predicate::Trait(ref data) => p!(print(data)),
+ ty::Predicate::Trait(ref data, constness) => {
+ if let ast::Constness::Const = constness {
+ p!(write("const "));
+ }
+ p!(print(data))
+ }
ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs
index 3fb3720..cbf335a 100644
--- a/src/librustc/ty/query/keys.rs
+++ b/src/librustc/ty/query/keys.rs
@@ -125,15 +125,6 @@
}
}
-impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) {
- fn query_crate(&self) -> CrateNum {
- self.0.krate
- }
- fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
- self.0.default_span(tcx)
- }
-}
-
impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
fn query_crate(&self) -> CrateNum {
self.1.def_id().krate
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 84efbe2..117a38c 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -25,8 +25,6 @@
use std::mem;
use std::ptr;
-use rustc_error_codes::*;
-
pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> {
pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 62e895a..25f9dc5 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -15,6 +15,7 @@
use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
+use syntax::ast;
impl fmt::Debug for ty::GenericParamDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -234,7 +235,12 @@
impl fmt::Debug for ty::Predicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- ty::Predicate::Trait(ref a) => a.fmt(f),
+ ty::Predicate::Trait(ref a, constness) => {
+ if let ast::Constness::Const = constness {
+ write!(f, "const ")?;
+ }
+ a.fmt(f)
+ }
ty::Predicate::Subtype(ref pair) => pair.fmt(f),
ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
@@ -474,7 +480,9 @@
type Lifted = ty::Predicate<'tcx>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
match *self {
- ty::Predicate::Trait(ref binder) => tcx.lift(binder).map(ty::Predicate::Trait),
+ ty::Predicate::Trait(ref binder, constness) => {
+ tcx.lift(binder).map(|binder| ty::Predicate::Trait(binder, constness))
+ }
ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype),
ty::Predicate::RegionOutlives(ref binder) => {
tcx.lift(binder).map(ty::Predicate::RegionOutlives)
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 8423612..13f623a 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -12,7 +12,9 @@
use crate::mir::Promoted;
use crate::ty::layout::VariantIdx;
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
-use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
+use crate::ty::{
+ self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
+};
use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
@@ -665,14 +667,16 @@
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
use crate::ty::ToPredicate;
match *self.skip_binder() {
- ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(),
+ ExistentialPredicate::Trait(tr) => {
+ Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate()
+ }
ExistentialPredicate::Projection(p) => {
ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty)))
}
ExistentialPredicate::AutoTrait(did) => {
let trait_ref =
Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
- trait_ref.to_predicate()
+ trait_ref.without_const().to_predicate()
}
}
}
diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml
index 408e9a7..4b786d6 100644
--- a/src/librustc_ast_lowering/Cargo.toml
+++ b/src/librustc_ast_lowering/Cargo.toml
@@ -17,7 +17,6 @@
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_index = { path = "../librustc_index" }
rustc_span = { path = "../librustc_span" }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_errors = { path = "../librustc_errors" }
rustc_session = { path = "../librustc_session" }
syntax = { path = "../libsyntax" }
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index 2866a16..a24bb52 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -2,7 +2,6 @@
use rustc::bug;
use rustc_data_structures::thin_vec::ThinVec;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::Res;
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index beb53a1..2025d0c 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -3,7 +3,6 @@
use rustc::arena::Arena;
use rustc::bug;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
@@ -67,14 +66,14 @@
if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
- if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind {
- if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) {
+ if let ItemKind::Impl { constness, ref of_trait, .. } = item.kind {
+ if constness == Constness::Const {
this.lctx
.diagnostic()
.span_err(item.span, "const trait impls are not yet implemented");
}
- this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item));
+ this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
} else {
visit::walk_item(this, item);
}
@@ -118,7 +117,7 @@
let old_len = self.in_scope_lifetimes.len();
let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
- hir::ItemKind::Impl(_, _, _, ref generics, ..)
+ hir::ItemKind::Impl { ref generics, .. }
| hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
_ => &[],
};
@@ -173,7 +172,7 @@
vec
}
ItemKind::MacroDef(..) => SmallVec::new(),
- ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id],
+ ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id],
ItemKind::Static(ref ty, ..) => {
let mut ids = smallvec![i.id];
if self.sess.features_untracked().impl_trait_in_bindings {
@@ -361,15 +360,16 @@
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
- ItemKind::Impl(
+ ItemKind::Impl {
unsafety,
polarity,
defaultness,
- ref ast_generics,
- ref trait_ref,
- ref ty,
- ref impl_items,
- ) => {
+ constness,
+ generics: ref ast_generics,
+ of_trait: ref trait_ref,
+ self_ty: ref ty,
+ items: ref impl_items,
+ } => {
let def_id = self.resolver.definitions().local_def_id(id);
// Lower the "impl header" first. This ordering is important
@@ -417,15 +417,16 @@
)
});
- hir::ItemKind::Impl(
+ hir::ItemKind::Impl {
unsafety,
polarity,
- self.lower_defaultness(defaultness, true /* [1] */),
+ defaultness: self.lower_defaultness(defaultness, true /* [1] */),
+ constness,
generics,
- trait_ref,
- lowered_ty,
- new_impl_items,
- )
+ of_trait: trait_ref,
+ self_ty: lowered_ty,
+ items: new_impl_items,
+ }
}
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 76a0889..284ede3 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -41,7 +41,6 @@
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
@@ -1250,10 +1249,16 @@
let bounds =
this.arena.alloc_from_iter(bounds.iter().filter_map(
|bound| match *bound {
- GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
+ GenericBound::Trait(ref ty, TraitBoundModifier::None)
+ | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
}
- GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+ // `?const ?Bound` will cause an error during AST validation
+ // anyways, so treat it like `?Bound` as compilation proceeds.
+ GenericBound::Trait(_, TraitBoundModifier::Maybe)
+ | GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
+ None
+ }
GenericBound::Outlives(ref lifetime) => {
if lifetime_bound.is_none() {
lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2158,10 +2163,6 @@
p: &PolyTraitRef,
mut itctx: ImplTraitContext<'_, 'hir>,
) -> hir::PolyTraitRef<'hir> {
- if p.trait_ref.constness.is_some() {
- self.diagnostic().span_err(p.span, "`?const` on trait bounds is not yet implemented");
- }
-
let bound_generic_params = self.lower_generic_params(
&p.bound_generic_params,
&NodeMap::default(),
@@ -2300,7 +2301,13 @@
fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
match f {
TraitBoundModifier::None => hir::TraitBoundModifier::None,
- TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
+ TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
+
+ // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
+ // placeholder for compilation to proceed.
+ TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
+ hir::TraitBoundModifier::Maybe
+ }
}
}
diff --git a/src/librustc_ast_lowering/path.rs b/src/librustc_ast_lowering/path.rs
index 65347d3..e5f7df6 100644
--- a/src/librustc_ast_lowering/path.rs
+++ b/src/librustc_ast_lowering/path.rs
@@ -3,7 +3,6 @@
use rustc::lint::builtin::ELIDED_LIFETIMES_IN_PATHS;
use rustc::span_bug;
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, PartialRes, Res};
diff --git a/src/librustc_ast_passes/Cargo.toml b/src/librustc_ast_passes/Cargo.toml
index 2d45e28..25b1ace 100644
--- a/src/librustc_ast_passes/Cargo.toml
+++ b/src/librustc_ast_passes/Cargo.toml
@@ -12,7 +12,6 @@
log = "0.4"
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_feature = { path = "../librustc_feature" }
rustc_parse = { path = "../librustc_parse" }
rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index c915b7b..152086b 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -23,8 +23,6 @@
use syntax::visit::{self, Visitor};
use syntax::walk_list;
-use rustc_error_codes::*;
-
/// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`).
#[derive(Clone, Copy)]
enum BoundContext {
@@ -612,9 +610,18 @@
}
match item.kind {
- ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => {
+ ItemKind::Impl {
+ unsafety,
+ polarity,
+ defaultness: _,
+ constness: _,
+ generics: _,
+ of_trait: Some(_),
+ ref self_ty,
+ ref items,
+ } => {
self.invalid_visibility(&item.vis, None);
- if let TyKind::Err = ty.kind {
+ if let TyKind::Err = self_ty.kind {
self.err_handler()
.struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax")
.help("use `auto trait Trait {}` instead")
@@ -629,7 +636,7 @@
)
.emit();
}
- for impl_item in impl_items {
+ for impl_item in items {
self.invalid_visibility(&impl_item.vis, None);
if let AssocItemKind::Fn(ref sig, _) = impl_item.kind {
self.check_trait_fn_not_const(sig.header.constness);
@@ -637,7 +644,16 @@
}
}
}
- ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => {
+ ItemKind::Impl {
+ unsafety,
+ polarity,
+ defaultness,
+ constness,
+ generics: _,
+ of_trait: None,
+ self_ty: _,
+ items: _,
+ } => {
self.invalid_visibility(
&item.vis,
Some("place qualifiers on individual impl items instead"),
@@ -660,6 +676,12 @@
.note("only trait implementations may be annotated with default")
.emit();
}
+ if constness == Constness::Const {
+ self.err_handler()
+ .struct_span_err(item.span, "inherent impls cannot be `const`")
+ .note("only trait implementations may be annotated with `const`")
+ .emit();
+ }
}
ItemKind::Fn(ref sig, ref generics, _) => {
self.visit_fn_header(&sig.header);
@@ -893,23 +915,20 @@
}
fn visit_param_bound(&mut self, bound: &'a GenericBound) {
- if let GenericBound::Trait(poly, maybe_bound) = bound {
- match poly.trait_ref.constness {
- Some(Constness::NotConst) => {
- if *maybe_bound == TraitBoundModifier::Maybe {
- self.err_handler()
- .span_err(bound.span(), "`?const` and `?` are mutually exclusive");
- }
-
- if let Some(ctx) = self.bound_context {
- let msg = format!("`?const` is not permitted in {}", ctx.description());
- self.err_handler().span_err(bound.span(), &msg);
- }
+ match bound {
+ GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => {
+ if let Some(ctx) = self.bound_context {
+ let msg = format!("`?const` is not permitted in {}", ctx.description());
+ self.err_handler().span_err(bound.span(), &msg);
}
-
- Some(Constness::Const) => panic!("Parser should reject bare `const` on bounds"),
- None => {}
}
+
+ GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
+ self.err_handler()
+ .span_err(bound.span(), "`?const` and `?` are mutually exclusive");
+ }
+
+ _ => {}
}
visit::walk_param_bound(self, bound)
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs
index 1e4b1ae..9531274 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -1,4 +1,3 @@
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Handler};
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
use rustc_feature::{Features, GateIssue, UnstableFeatures};
@@ -339,7 +338,7 @@
}
}
- ast::ItemKind::Impl(_, polarity, defaultness, ..) => {
+ ast::ItemKind::Impl { polarity, defaultness, .. } => {
if polarity == ast::ImplPolarity::Negative {
gate_feature_post!(
&self,
@@ -470,29 +469,8 @@
visit::walk_expr(self, e)
}
- fn visit_arm(&mut self, arm: &'a ast::Arm) {
- visit::walk_arm(self, arm)
- }
-
fn visit_pat(&mut self, pattern: &'a ast::Pat) {
match &pattern.kind {
- PatKind::Slice(pats) => {
- for pat in &*pats {
- let span = pat.span;
- let inner_pat = match &pat.kind {
- PatKind::Ident(.., Some(pat)) => pat,
- _ => pat,
- };
- if inner_pat.is_rest() {
- gate_feature_post!(
- &self,
- slice_patterns,
- span,
- "subslice patterns are unstable"
- );
- }
- }
- }
PatKind::Box(..) => {
gate_feature_post!(
&self,
diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs
index eadbc48..5de45f4 100644
--- a/src/librustc_ast_passes/lib.rs
+++ b/src/librustc_ast_passes/lib.rs
@@ -2,7 +2,7 @@
//! parsed by `rustc_parse` and then lowered, after the passes in this crate,
//! by `rustc_ast_lowering`.
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
pub mod ast_validation;
pub mod feature_gate;
diff --git a/src/librustc_builtin_macros/Cargo.toml b/src/librustc_builtin_macros/Cargo.toml
index f291eaf..3ce7f5d 100644
--- a/src/librustc_builtin_macros/Cargo.toml
+++ b/src/librustc_builtin_macros/Cargo.toml
@@ -22,4 +22,3 @@
syntax = { path = "../libsyntax" }
rustc_expand = { path = "../librustc_expand" }
rustc_span = { path = "../librustc_span" }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_builtin_macros/asm.rs b/src/librustc_builtin_macros/asm.rs
index a6b45e0..4723544 100644
--- a/src/librustc_builtin_macros/asm.rs
+++ b/src/librustc_builtin_macros/asm.rs
@@ -12,8 +12,6 @@
use syntax::token::{self, Token};
use syntax::tokenstream::{self, TokenStream};
-use rustc_error_codes::*;
-
enum State {
Asm,
Outputs,
diff --git a/src/librustc_builtin_macros/deriving/default.rs b/src/librustc_builtin_macros/deriving/default.rs
index 72c41ad..b4f059e 100644
--- a/src/librustc_builtin_macros/deriving/default.rs
+++ b/src/librustc_builtin_macros/deriving/default.rs
@@ -9,8 +9,6 @@
use syntax::ast::{Expr, MetaItem};
use syntax::ptr::P;
-use rustc_error_codes::*;
-
pub fn expand_deriving_default(
cx: &mut ExtCtxt<'_>,
span: Span,
diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs
index 9226f45..f891801 100644
--- a/src/librustc_builtin_macros/deriving/generic/mod.rs
+++ b/src/librustc_builtin_macros/deriving/generic/mod.rs
@@ -705,15 +705,16 @@
self.span,
Ident::invalid(),
a,
- ast::ItemKind::Impl(
+ ast::ItemKind::Impl {
unsafety,
- ast::ImplPolarity::Positive,
- ast::Defaultness::Final,
- trait_generics,
- opt_trait_ref,
- self_type,
- methods.into_iter().chain(associated_types).collect(),
- ),
+ polarity: ast::ImplPolarity::Positive,
+ defaultness: ast::Defaultness::Final,
+ constness: ast::Constness::NotConst,
+ generics: trait_generics,
+ of_trait: opt_trait_ref,
+ self_ty: self_type,
+ items: methods.into_iter().chain(associated_types).collect(),
+ },
)
}
diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs
index 4d83a66..914dcdf 100644
--- a/src/librustc_builtin_macros/deriving/mod.rs
+++ b/src/librustc_builtin_macros/deriving/mod.rs
@@ -156,15 +156,16 @@
span,
ast::Ident::invalid(),
attrs,
- ItemKind::Impl(
- ast::Unsafety::Normal,
- ast::ImplPolarity::Positive,
- ast::Defaultness::Final,
+ ItemKind::Impl {
+ unsafety: ast::Unsafety::Normal,
+ polarity: ast::ImplPolarity::Positive,
+ defaultness: ast::Defaultness::Final,
+ constness: ast::Constness::NotConst,
generics,
- Some(trait_ref),
- self_type,
- Vec::new(),
- ),
+ of_trait: Some(trait_ref),
+ self_ty: self_type,
+ items: Vec::new(),
+ },
);
push(Annotatable::Item(newitem));
diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs
index 6fca74e..3f4e24c 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/src/librustc_builtin_macros/format.rs
@@ -590,17 +590,6 @@
parse::NextArgument(ref arg) => {
// Build the position
let pos = {
- let pos = |c, arg| {
- let mut path = Context::rtpath(self.ecx, "Position");
- path.push(self.ecx.ident_of(c, sp));
- match arg {
- Some(i) => {
- let arg = self.ecx.expr_usize(sp, i);
- self.ecx.expr_call_global(sp, path, vec![arg])
- }
- None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
- }
- };
match arg.position {
parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => {
// Map to index in final generated argument array
@@ -615,7 +604,7 @@
arg_idx
}
};
- pos("At", Some(arg_idx))
+ self.ecx.expr_usize(sp, arg_idx)
}
// should never be the case, because names are already
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index eb192b2..9f8b4e7 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -32,5 +32,4 @@
rustc_incremental = { path = "../librustc_incremental" }
rustc_index = { path = "../librustc_index" }
rustc_target = { path = "../librustc_target" }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 11f5d30..4679f650 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -1103,7 +1103,11 @@
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
for &(symbol, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
if level.is_below_threshold(export_threshold) {
- symbols.push(symbol.symbol_name(tcx).to_string());
+ symbols.push(symbol_export::symbol_name_for_instance_in_crate(
+ tcx,
+ symbol,
+ LOCAL_CRATE,
+ ));
}
}
@@ -1124,12 +1128,7 @@
continue;
}
- // FIXME rust-lang/rust#64319, rust-lang/rust#64872:
- // We want to block export of generics from dylibs,
- // but we must fix rust-lang/rust#65890 before we can
- // do that robustly.
-
- symbols.push(symbol.symbol_name(tcx).to_string());
+ symbols.push(symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum));
}
}
}
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index a406b5f..bd44b4a 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -8,6 +8,7 @@
use rustc::ty::subst::SubstsRef;
use rustc::ty::Instance;
use rustc::ty::{SymbolName, TyCtxt};
+use rustc_codegen_utils::symbol_names;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
@@ -358,3 +359,32 @@
SymbolExportLevel::Rust
}
}
+
+/// This is the symbol name of the given instance instantiated in a specific crate.
+pub fn symbol_name_for_instance_in_crate<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ symbol: ExportedSymbol<'tcx>,
+ instantiating_crate: CrateNum,
+) -> String {
+ // If this is something instantiated in the local crate then we might
+ // already have cached the name as a query result.
+ if instantiating_crate == LOCAL_CRATE {
+ return symbol.symbol_name_for_local_instance(tcx).to_string();
+ }
+
+ // This is something instantiated in an upstream crate, so we have to use
+ // the slower (because uncached) version of computing the symbol name.
+ match symbol {
+ ExportedSymbol::NonGeneric(def_id) => symbol_names::symbol_name_for_instance_in_crate(
+ tcx,
+ Instance::mono(tcx, def_id),
+ instantiating_crate,
+ ),
+ ExportedSymbol::Generic(def_id, substs) => symbol_names::symbol_name_for_instance_in_crate(
+ tcx,
+ Instance::new(def_id, substs),
+ instantiating_crate,
+ ),
+ ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(),
+ }
+}
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 801bfde..049faff 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -2,7 +2,7 @@
use super::link::{self, get_linker, remove};
use super::linker::LinkerInfo;
use super::lto::{self, SerializedModule};
-use super::symbol_export::ExportedSymbols;
+use super::symbol_export::{symbol_name_for_instance_in_crate, ExportedSymbols};
use crate::{
CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
RLIB_BYTECODE_EXTENSION,
@@ -956,7 +956,7 @@
let symbols = tcx
.exported_symbols(cnum)
.iter()
- .map(|&(s, lvl)| (s.symbol_name(tcx).to_string(), lvl))
+ .map(|&(s, lvl)| (symbol_name_for_instance_in_crate(tcx, s, cnum), lvl))
.collect();
Arc::new(symbols)
};
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index e4531a7..28b61e0 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -13,8 +13,6 @@
use crate::traits::BuilderMethods;
use rustc_hir as hir;
-use rustc_error_codes::*;
-
pub enum IntPredicate {
IntEQ,
IntNE,
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index ee527ec..aba7723 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -4,7 +4,7 @@
#![feature(box_syntax)]
#![feature(core_intrinsics)]
#![feature(libc)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(stmt_expr_attributes)]
#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 574c06d..8422c62 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -7,8 +7,6 @@
use crate::traits::BuilderMethods;
use crate::traits::*;
-use rustc_error_codes::*;
-
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>) -> Bx {
debug!("codegen_statement(statement={:?})", statement);
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 450dcd3..96a74f9 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -91,8 +91,9 @@
use rustc::mir::mono::{InstantiationMode, MonoItem};
use rustc::session::config::SymbolManglingVersion;
use rustc::ty::query::Providers;
+use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Instance, TyCtxt};
-use rustc_hir::def_id::LOCAL_CRATE;
+use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::Node;
use rustc_span::symbol::Symbol;
@@ -102,15 +103,70 @@
mod legacy;
mod v0;
-pub fn provide(providers: &mut Providers<'_>) {
- *providers = Providers {
- symbol_name: |tcx, instance| ty::SymbolName { name: symbol_name(tcx, instance) },
-
- ..*providers
- };
+/// This function computes the symbol name for the given `instance` and the
+/// given instantiating crate. That is, if you know that instance X is
+/// instantiated in crate Y, this is the symbol name this instance would have.
+pub fn symbol_name_for_instance_in_crate(
+ tcx: TyCtxt<'tcx>,
+ instance: Instance<'tcx>,
+ instantiating_crate: CrateNum,
+) -> String {
+ compute_symbol_name(tcx, instance, || instantiating_crate)
}
-fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol {
+pub fn provide(providers: &mut Providers<'_>) {
+ *providers = Providers { symbol_name: symbol_name_provider, ..*providers };
+}
+
+// The `symbol_name` query provides the symbol name for calling a given
+// instance from the local crate. In particular, it will also look up the
+// correct symbol name of instances from upstream crates.
+fn symbol_name_provider(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::SymbolName {
+ let symbol_name = compute_symbol_name(tcx, instance, || {
+ // This closure determines the instantiating crate for instances that
+ // need an instantiating-crate-suffix for their symbol name, in order
+ // to differentiate between local copies.
+ //
+ // For generics we might find re-usable upstream instances. For anything
+ // else we rely on their being a local copy available.
+
+ if is_generic(instance.substs) {
+ let def_id = instance.def_id();
+
+ if !def_id.is_local() && tcx.sess.opts.share_generics() {
+ // If we are re-using a monomorphization from another crate,
+ // we have to compute the symbol hash accordingly.
+ let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
+
+ upstream_monomorphizations
+ .and_then(|monos| monos.get(&instance.substs).cloned())
+ // If there is no instance available upstream, there'll be
+ // one in the current crate.
+ .unwrap_or(LOCAL_CRATE)
+ } else {
+ // For generic functions defined in the current crate, there
+ // can be no upstream instances. Also, if we don't share
+ // generics, we'll instantiate a local copy too.
+ LOCAL_CRATE
+ }
+ } else {
+ // For non-generic things that need to avoid naming conflicts, we
+ // always instantiate a copy in the local crate.
+ LOCAL_CRATE
+ }
+ });
+
+ ty::SymbolName { name: Symbol::intern(&symbol_name) }
+}
+
+/// Computes the symbol name for the given instance. This function will call
+/// `compute_instantiating_crate` if it needs to factor the instantiating crate
+/// into the symbol name.
+fn compute_symbol_name(
+ tcx: TyCtxt<'tcx>,
+ instance: Instance<'tcx>,
+ compute_instantiating_crate: impl FnOnce() -> CrateNum,
+) -> String {
let def_id = instance.def_id();
let substs = instance.substs;
@@ -121,11 +177,11 @@
if def_id.is_local() {
if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
let disambiguator = tcx.sess.local_crate_disambiguator();
- return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
+ return tcx.sess.generate_plugin_registrar_symbol(disambiguator);
}
if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
let disambiguator = tcx.sess.local_crate_disambiguator();
- return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
+ return tcx.sess.generate_proc_macro_decls_symbol(disambiguator);
}
}
@@ -162,29 +218,28 @@
|| !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id)
{
if let Some(name) = attrs.link_name {
- return name;
+ return name.to_string();
}
- return tcx.item_name(def_id);
+ return tcx.item_name(def_id).to_string();
}
}
if let Some(name) = attrs.export_name {
// Use provided name
- return name;
+ return name.to_string();
}
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
// Don't mangle
- return tcx.item_name(def_id);
+ return tcx.item_name(def_id).to_string();
}
- let is_generic = substs.non_erasable_generics().next().is_some();
let avoid_cross_crate_conflicts =
// If this is an instance of a generic function, we also hash in
// the ID of the instantiating crate. This avoids symbol conflicts
// in case the same instances is emitted in two crates of the same
// project.
- is_generic ||
+ is_generic(substs) ||
// If we're dealing with an instance of a function that's inlined from
// another crate but we're marking it as globally shared to our
@@ -197,25 +252,8 @@
_ => false,
};
- let instantiating_crate = if avoid_cross_crate_conflicts {
- Some(if is_generic {
- if !def_id.is_local() && tcx.sess.opts.share_generics() {
- // If we are re-using a monomorphization from another crate,
- // we have to compute the symbol hash accordingly.
- let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
-
- upstream_monomorphizations
- .and_then(|monos| monos.get(&substs).cloned())
- .unwrap_or(LOCAL_CRATE)
- } else {
- LOCAL_CRATE
- }
- } else {
- LOCAL_CRATE
- })
- } else {
- None
- };
+ let instantiating_crate =
+ if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None };
// Pick the crate responsible for the symbol mangling version, which has to:
// 1. be stable for each instance, whether it's being defined or imported
@@ -232,10 +270,12 @@
tcx.symbol_mangling_version(mangling_version_crate)
};
- let mangled = match mangling_version {
+ match mangling_version {
SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
- };
+ }
+}
- Symbol::intern(&mangled)
+fn is_generic(substs: SubstsRef<'_>) -> bool {
+ substs.non_erasable_generics().next().is_some()
}
diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs
index 004db0a..44cef72 100644
--- a/src/librustc_data_structures/profiling.rs
+++ b/src/librustc_data_structures/profiling.rs
@@ -136,9 +136,11 @@
}
}
+// keep this in sync with the `-Z self-profile-events` help message in librustc_session/options.rs
const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
("none", EventFilter::NONE),
("all", EventFilter::ALL),
+ ("default", EventFilter::DEFAULT),
("generic-activity", EventFilter::GENERIC_ACTIVITIES),
("query-provider", EventFilter::QUERY_PROVIDERS),
("query-cache-hit", EventFilter::QUERY_CACHE_HITS),
diff --git a/src/librustc_data_structures/sharded.rs b/src/librustc_data_structures/sharded.rs
index 8b85d97..ee3f88f 100644
--- a/src/librustc_data_structures/sharded.rs
+++ b/src/librustc_data_structures/sharded.rs
@@ -137,6 +137,20 @@
}
}
+pub trait IntoPointer {
+ /// Returns a pointer which outlives `self`.
+ fn into_pointer(&self) -> *const ();
+}
+
+impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> {
+ pub fn contains_pointer_to<T: Hash + IntoPointer>(&self, value: &T) -> bool {
+ let hash = make_hash(&value);
+ let shard = self.get_shard_by_hash(hash).lock();
+ let value = value.into_pointer();
+ shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some()
+ }
+}
+
#[inline]
fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
let mut state = FxHasher::default();
diff --git a/src/librustc_error_codes/error_codes/E0195.md b/src/librustc_error_codes/error_codes/E0195.md
index 3606521..b8c313d 100644
--- a/src/librustc_error_codes/error_codes/E0195.md
+++ b/src/librustc_error_codes/error_codes/E0195.md
@@ -1,4 +1,5 @@
-Your method's lifetime parameters do not match the trait declaration.
+The lifetime parameters of the method do not match the trait declaration.
+
Erroneous code example:
```compile_fail,E0195
@@ -16,7 +17,7 @@
}
```
-The lifetime constraint `'b` for bar() implementation does not match the
+The lifetime constraint `'b` for `bar()` implementation does not match the
trait declaration. Ensure lifetime declarations match exactly in both trait
declaration and implementation. Example:
diff --git a/src/librustc_error_codes/error_codes/E0197.md b/src/librustc_error_codes/error_codes/E0197.md
index 0d91157..c142b8f 100644
--- a/src/librustc_error_codes/error_codes/E0197.md
+++ b/src/librustc_error_codes/error_codes/E0197.md
@@ -1,13 +1,20 @@
+An inherent implementation was marked unsafe.
+
+Erroneous code example:
+
+```compile_fail,E0197
+struct Foo;
+
+unsafe impl Foo { } // error!
+```
+
Inherent implementations (one that do not implement a trait but provide
methods associated with a type) are always safe because they are not
implementing an unsafe trait. Removing the `unsafe` keyword from the inherent
implementation will resolve this error.
-```compile_fail,E0197
+```
struct Foo;
-// this will cause this error
-unsafe impl Foo { }
-// converting it to this will fix it
-impl Foo { }
+impl Foo { } // ok!
```
diff --git a/src/librustc_error_codes/error_codes/E0198.md b/src/librustc_error_codes/error_codes/E0198.md
index 6504d60..687214a 100644
--- a/src/librustc_error_codes/error_codes/E0198.md
+++ b/src/librustc_error_codes/error_codes/E0198.md
@@ -1,17 +1,18 @@
+A negative implementation was marked as unsafe.
+
+Erroneous code example:
+
+```compile_fail
+struct Foo;
+
+unsafe impl !Clone for Foo { } // error!
+```
+
A negative implementation is one that excludes a type from implementing a
particular trait. Not being able to use a trait is always a safe operation,
so negative implementations are always safe and never need to be marked as
unsafe.
-```compile_fail
-#![feature(optin_builtin_traits)]
-
-struct Foo;
-
-// unsafe is unnecessary
-unsafe impl !Clone for Foo { }
-```
-
This will compile:
```ignore (ignore auto_trait future compatibility warning)
diff --git a/src/librustc_error_codes/error_codes/E0199.md b/src/librustc_error_codes/error_codes/E0199.md
index d0c12dc..88130e8 100644
--- a/src/librustc_error_codes/error_codes/E0199.md
+++ b/src/librustc_error_codes/error_codes/E0199.md
@@ -1,14 +1,23 @@
-Safe traits should not have unsafe implementations, therefore marking an
-implementation for a safe trait unsafe will cause a compiler error. Removing
-the unsafe marker on the trait noted in the error will resolve this problem.
+A trait implementation was marked as unsafe while the trait is safe.
+
+Erroneous code example:
```compile_fail,E0199
struct Foo;
trait Bar { }
-// this won't compile because Bar is safe
-unsafe impl Bar for Foo { }
-// this will compile
-impl Bar for Foo { }
+unsafe impl Bar for Foo { } // error!
+```
+
+Safe traits should not have unsafe implementations, therefore marking an
+implementation for a safe trait unsafe will cause a compiler error. Removing
+the unsafe marker on the trait noted in the error will resolve this problem:
+
+```
+struct Foo;
+
+trait Bar { }
+
+impl Bar for Foo { } // ok!
```
diff --git a/src/librustc_error_codes/error_codes/E0200.md b/src/librustc_error_codes/error_codes/E0200.md
index 865e914..7245bb5 100644
--- a/src/librustc_error_codes/error_codes/E0200.md
+++ b/src/librustc_error_codes/error_codes/E0200.md
@@ -1,14 +1,23 @@
-Unsafe traits must have unsafe implementations. This error occurs when an
-implementation for an unsafe trait isn't marked as unsafe. This may be resolved
-by marking the unsafe implementation as unsafe.
+An unsafe trait was implemented without an unsafe implementation.
+
+Erroneous code example:
```compile_fail,E0200
struct Foo;
unsafe trait Bar { }
-// this won't compile because Bar is unsafe and impl isn't unsafe
-impl Bar for Foo { }
-// this will compile
-unsafe impl Bar for Foo { }
+impl Bar for Foo { } // error!
+```
+
+Unsafe traits must have unsafe implementations. This error occurs when an
+implementation for an unsafe trait isn't marked as unsafe. This may be resolved
+by marking the unsafe implementation as unsafe.
+
+```
+struct Foo;
+
+unsafe trait Bar { }
+
+unsafe impl Bar for Foo { } // ok!
```
diff --git a/src/librustc_error_codes/error_codes/E0201.md b/src/librustc_error_codes/error_codes/E0201.md
index bdbf02f..0e1a7b7 100644
--- a/src/librustc_error_codes/error_codes/E0201.md
+++ b/src/librustc_error_codes/error_codes/E0201.md
@@ -1,7 +1,7 @@
-It is an error to define two associated items (like methods, associated types,
-associated functions, etc.) with the same identifier.
+Two associated items (like methods, associated types, associated functions,
+etc.) were defined with the same identifier.
-For example:
+Erroneous code example:
```compile_fail,E0201
struct Foo(u8);
diff --git a/src/librustc_error_codes/error_codes/E0204.md b/src/librustc_error_codes/error_codes/E0204.md
index 3156901..96e4475 100644
--- a/src/librustc_error_codes/error_codes/E0204.md
+++ b/src/librustc_error_codes/error_codes/E0204.md
@@ -1,21 +1,24 @@
-An attempt to implement the `Copy` trait for a struct failed because one of the
-fields does not implement `Copy`. To fix this, you must implement `Copy` for the
-mentioned field. Note that this may not be possible, as in the example of
+The `Copy` trait was implemented on a type which contains a field that doesn't
+implement the `Copy` trait.
+
+Erroneous code example:
```compile_fail,E0204
struct Foo {
- foo : Vec<u32>,
+ foo: Vec<u32>,
}
-impl Copy for Foo { }
+impl Copy for Foo { } // error!
```
-This fails because `Vec<T>` does not implement `Copy` for any `T`.
+The `Copy` trait is implemented by default only on primitive types. If your
+type only contains primitive types, you'll be able to implement `Copy` on it.
+Otherwise, it won't be possible.
Here's another example that will fail:
```compile_fail,E0204
-#[derive(Copy)]
+#[derive(Copy)] // error!
struct Foo<'a> {
ty: &'a mut bool,
}
diff --git a/src/librustc_error_codes/error_codes/E0527.md b/src/librustc_error_codes/error_codes/E0527.md
index 4bff39d..97ea3126 100644
--- a/src/librustc_error_codes/error_codes/E0527.md
+++ b/src/librustc_error_codes/error_codes/E0527.md
@@ -17,8 +17,6 @@
array. Additional elements can be matched with `..`:
```
-#![feature(slice_patterns)]
-
let r = &[1, 2, 3, 4];
match r {
&[a, b, ..] => { // ok!
diff --git a/src/librustc_error_codes/error_codes/E0528.md b/src/librustc_error_codes/error_codes/E0528.md
index 4b6ea24..54c2c4d 100644
--- a/src/librustc_error_codes/error_codes/E0528.md
+++ b/src/librustc_error_codes/error_codes/E0528.md
@@ -4,8 +4,6 @@
Example of erroneous code:
```compile_fail,E0528
-#![feature(slice_patterns)]
-
let r = &[1, 2];
match r {
&[a, b, c, rest @ ..] => { // error: pattern requires at least 3
@@ -19,8 +17,6 @@
requires. You can match an arbitrary number of remaining elements with `..`:
```
-#![feature(slice_patterns)]
-
let r = &[1, 2, 3, 4, 5];
match r {
&[a, b, c, rest @ ..] => { // ok!
diff --git a/src/librustc_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md
index 803a251..bf1f72b 100644
--- a/src/librustc_error_codes/error_codes/E0730.md
+++ b/src/librustc_error_codes/error_codes/E0730.md
@@ -18,8 +18,6 @@
array. Additional elements can be matched with `..`:
```
-#![feature(slice_patterns)]
-
let r = &[1, 2, 3, 4];
match r {
&[a, b, ..] => { // ok!
diff --git a/src/librustc_error_codes/lib.rs b/src/librustc_error_codes/lib.rs
index 14210fd..f051fdd 100644
--- a/src/librustc_error_codes/lib.rs
+++ b/src/librustc_error_codes/lib.rs
@@ -6,16 +6,8 @@
pub static DIAGNOSTICS: &[(&str, &str)] = &[
$( (stringify!($ecode), $message), )*
];
-
- $(
- pub const $ecode: () = ();
- )*
- $(
- pub const $code: () = ();
- )*
)
}
mod error_codes;
-
-pub use error_codes::*;
+pub use error_codes::DIAGNOSTICS;
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 73f66d5..3c217c1 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -399,8 +399,5 @@
#[macro_export]
macro_rules! error_code {
- ($code:ident) => {{
- let _ = $code;
- $crate::DiagnosticId::Error(stringify!($code).to_owned())
- }};
+ ($code:ident) => {{ $crate::DiagnosticId::Error(stringify!($code).to_owned()) }};
}
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 526b4e2..b0e0cb6 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1476,6 +1476,15 @@
None => return Ok(()),
};
+ // Render the replacements for each suggestion
+ let suggestions = suggestion.splice_lines(&**sm);
+
+ if suggestions.is_empty() {
+ // Suggestions coming from macros can have malformed spans. This is a heavy handed
+ // approach to avoid ICEs by ignoring the suggestion outright.
+ return Ok(());
+ }
+
let mut buffer = StyledBuffer::new();
// Render the suggestion message
@@ -1492,9 +1501,6 @@
Some(Style::HeaderMsg),
);
- // Render the replacements for each suggestion
- let suggestions = suggestion.splice_lines(&**sm);
-
let mut row_num = 2;
let mut notice_capitalization = false;
for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) {
@@ -1505,7 +1511,9 @@
let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim())
&& complete.lines().count() == 1;
- let lines = sm.span_to_lines(parts[0].span).unwrap();
+ let lines = sm
+ .span_to_lines(parts[0].span)
+ .expect("span_to_lines failed when emitting suggestion");
assert!(!lines.lines.is_empty());
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index e24e871..827e9b8 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -10,6 +10,7 @@
pub use emitter::ColorConfig;
+use log::debug;
use Level::*;
use emitter::{is_case_difference, Emitter, EmitterWriter};
@@ -174,6 +175,15 @@
self.substitutions
.iter()
+ .filter(|subst| {
+ // Suggestions coming from macros can have malformed spans. This is a heavy
+ // handed approach to avoid ICEs by ignoring the suggestion outright.
+ let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err());
+ if invalid {
+ debug!("splice_lines: suggestion contains an invalid span: {:?}", subst);
+ }
+ !invalid
+ })
.cloned()
.map(|mut substitution| {
// Assumption: all spans are in the same file, and all spans
diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs
index bd3d6b5..11f94ab 100644
--- a/src/librustc_expand/build.rs
+++ b/src/librustc_expand/build.rs
@@ -110,7 +110,7 @@
}
pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
- ast::TraitRef { path, constness: None, ref_id: ast::DUMMY_NODE_ID }
+ ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
}
pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs
index d880fc8..007cee4 100644
--- a/src/librustc_feature/accepted.rs
+++ b/src/librustc_feature/accepted.rs
@@ -257,6 +257,8 @@
/// Allows relaxing the coherence rules such that
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
(accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
+ /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
+ (accepted, slice_patterns, "1.42.0", Some(62254), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features
diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs
index 4c8c47a..6af9b6c 100644
--- a/src/librustc_feature/active.rs
+++ b/src/librustc_feature/active.rs
@@ -262,9 +262,6 @@
/// Allows using non lexical lifetimes (RFC 2094).
(active, nll, "1.0.0", Some(43234), None),
- /// Allows using slice patterns.
- (active, slice_patterns, "1.0.0", Some(62254), None),
-
/// Allows the definition of `const` functions with some advanced features.
(active, const_fn, "1.2.0", Some(57563), None),
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 5c1d600..b62a7e4 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -364,6 +364,7 @@
pub enum TraitBoundModifier {
None,
Maybe,
+ MaybeConst,
}
/// The AST represents all type param bounds as types.
@@ -2436,15 +2437,19 @@
TraitAlias(Generics<'hir>, GenericBounds<'hir>),
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
- Impl(
- Unsafety,
- ImplPolarity,
- Defaultness,
- Generics<'hir>,
- Option<TraitRef<'hir>>, // (optional) trait this impl implements
- &'hir Ty<'hir>, // self
- &'hir [ImplItemRef<'hir>],
- ),
+ Impl {
+ unsafety: Unsafety,
+ polarity: ImplPolarity,
+ defaultness: Defaultness,
+ constness: Constness,
+ generics: Generics<'hir>,
+
+ /// The trait being implemented, if any.
+ of_trait: Option<TraitRef<'hir>>,
+
+ self_ty: &'hir Ty<'hir>,
+ items: &'hir [ImplItemRef<'hir>],
+ },
}
impl ItemKind<'_> {
@@ -2465,7 +2470,7 @@
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
- ItemKind::Impl(..) => "impl",
+ ItemKind::Impl { .. } => "impl",
}
}
@@ -2478,7 +2483,7 @@
| ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
| ItemKind::Trait(_, _, ref generics, _, _)
- | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics,
+ | ItemKind::Impl { ref generics, .. } => generics,
_ => return None,
})
}
diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs
index 3dbc525..539a0ee 100644
--- a/src/librustc_hir/intravisit.rs
+++ b/src/librustc_hir/intravisit.rs
@@ -566,12 +566,21 @@
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span)
}
- ItemKind::Impl(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => {
+ ItemKind::Impl {
+ unsafety: _,
+ defaultness: _,
+ polarity: _,
+ constness: _,
+ ref generics,
+ ref of_trait,
+ ref self_ty,
+ items,
+ } => {
visitor.visit_id(item.hir_id);
visitor.visit_generics(generics);
- walk_list!(visitor, visit_trait_ref, opt_trait_reference);
- visitor.visit_ty(typ);
- walk_list!(visitor, visit_impl_item_ref, impl_item_refs);
+ walk_list!(visitor, visit_trait_ref, of_trait);
+ visitor.visit_ty(self_ty);
+ walk_list!(visitor, visit_impl_item_ref, items);
}
ItemKind::Struct(ref struct_definition, ref generics)
| ItemKind::Union(ref struct_definition, ref generics) => {
diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs
index 759f423..b9598c9 100644
--- a/src/librustc_hir/print.rs
+++ b/src/librustc_hir/print.rs
@@ -627,15 +627,16 @@
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident.name, item.span, true);
}
- hir::ItemKind::Impl(
+ hir::ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
ref generics,
- ref opt_trait,
- ref ty,
- impl_items,
- ) => {
+ ref of_trait,
+ ref self_ty,
+ items,
+ } => {
self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness);
@@ -647,23 +648,27 @@
self.s.space();
}
+ if constness == ast::Constness::Const {
+ self.word_nbsp("const");
+ }
+
if let hir::ImplPolarity::Negative = polarity {
self.s.word("!");
}
- if let Some(ref t) = opt_trait {
+ if let Some(ref t) = of_trait {
self.print_trait_ref(t);
self.s.space();
self.word_space("for");
}
- self.print_type(&ty);
+ self.print_type(&self_ty);
self.print_where_clause(&generics.where_clause);
self.s.space();
self.bopen();
self.print_inner_attributes(&item.attrs);
- for impl_item in impl_items {
+ for impl_item in items {
self.ann.nested(self, Nested::ImplItem(impl_item.id));
}
self.bclose(item.span);
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index ddfed53..c5e7486 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -315,7 +315,7 @@
//HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT),
// An implementation, eg `impl<A> Trait for Foo { .. }`
- HirItem::Impl(..) => ("ItemKind::Impl", LABELS_IMPL),
+ HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
_ => self.tcx.sess.span_fatal(
attr.span,
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index c4444fb..d62c753 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -15,7 +15,7 @@
use rustc::session::Session;
use rustc::traits;
use rustc::ty::steal::Steal;
-use rustc::ty::{self, AllArenas, GlobalCtxt, ResolverOutputs, TyCtxt};
+use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc::util::common::ErrorReported;
use rustc_builtin_macros;
use rustc_codegen_ssa::back::link::emit_metadata;
@@ -715,7 +715,6 @@
outputs: OutputFilenames,
crate_name: &str,
global_ctxt: &'tcx Once<GlobalCtxt<'tcx>>,
- all_arenas: &'tcx AllArenas,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
) -> QueryContext<'tcx> {
let sess = &compiler.session();
@@ -746,7 +745,6 @@
lint_store,
local_providers,
extern_providers,
- &all_arenas,
arena,
resolver_outputs,
hir_map,
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index bd9717d..0af9b17 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -7,7 +7,7 @@
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::session::Session;
use rustc::ty::steal::Steal;
-use rustc::ty::{AllArenas, GlobalCtxt, ResolverOutputs};
+use rustc::ty::{GlobalCtxt, ResolverOutputs};
use rustc::util::common::ErrorReported;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_data_structures::sync::{Lrc, Once, WorkerLocal};
@@ -66,7 +66,6 @@
compiler: &'tcx Compiler,
gcx: Once<GlobalCtxt<'tcx>>,
- all_arenas: AllArenas,
arena: WorkerLocal<Arena<'tcx>>,
dep_graph_future: Query<Option<DepGraphFuture>>,
@@ -86,7 +85,6 @@
Queries {
compiler,
gcx: Once::new(),
- all_arenas: AllArenas::new(),
arena: WorkerLocal::new(|_| Arena::default()),
dep_graph_future: Default::default(),
parse: Default::default(),
@@ -265,7 +263,6 @@
outputs,
&crate_name,
&self.gcx,
- &self.all_arenas,
&self.arena,
))
})
diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml
index abf9f96..7e23e70 100644
--- a/src/librustc_lint/Cargo.toml
+++ b/src/librustc_lint/Cargo.toml
@@ -13,7 +13,6 @@
unicode-security = "0.0.2"
rustc = { path = "../librustc" }
rustc_errors = { path = "../librustc_errors" }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_hir = { path = "../librustc_hir" }
rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 6314c2b..c8d3d5f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -251,7 +251,7 @@
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
}
- ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
+ ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => {
self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
}
@@ -431,7 +431,7 @@
"a trait"
}
hir::ItemKind::TyAlias(..) => "a type alias",
- hir::ItemKind::Impl(.., Some(ref trait_ref), _, impl_item_refs) => {
+ hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => {
// If the trait is private, add the impl items to `private_traits` so they don't get
// reported for missing docs.
let real_trait = trait_ref.path.res.def_id();
@@ -439,7 +439,7 @@
match cx.tcx.hir().find(hir_id) {
Some(Node::Item(item)) => {
if let hir::VisibilityKind::Inherited = item.vis.node {
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
self.private_traits.insert(impl_item_ref.id.hir_id);
}
}
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 42ec878..3b8cce5 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -26,7 +26,6 @@
use rustc::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId};
diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs
index 5a5aedc..91aeccb 100644
--- a/src/librustc_lint/internal.rs
+++ b/src/librustc_lint/internal.rs
@@ -221,7 +221,7 @@
impl EarlyLintPass for LintPassImpl {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.kind {
+ if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind {
if let Some(last) = lint_pass.path.segments.last() {
if last.ident.name == sym::LintPass {
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs
index bbc3e57..d5bbdc5 100644
--- a/src/librustc_lint/levels.rs
+++ b/src/librustc_lint/levels.rs
@@ -6,7 +6,6 @@
use rustc::ty::query::Providers;
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashMap;
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index a2b7884..394da4a 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -350,7 +350,20 @@
}
fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) {
- if let &PatKind::Binding(_, _, ident, _) = &p.kind {
+ if let &PatKind::Binding(_, hid, ident, _) = &p.kind {
+ if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid))
+ {
+ if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind {
+ for field in field_pats.iter() {
+ if field.ident != ident {
+ // Only check if a new name has been introduced, to avoid warning
+ // on both the struct definition and this pattern.
+ self.check_snake_case(cx, "variable", &ident);
+ }
+ }
+ return;
+ }
+ }
self.check_snake_case(cx, "variable", &ident);
}
}
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 26cbda3..15158c0 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -144,7 +144,7 @@
ty::Opaque(def, _) => {
let mut has_emitted = false;
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
- if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
+ if let ty::Predicate::Trait(ref poly_trait_predicate, _) = predicate {
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
let def_id = trait_ref.def_id;
let descr_pre =
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 0a0bcb1..6da5847 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -26,7 +26,6 @@
rustc_expand = { path = "../librustc_expand" }
rustc_parse = { path = "../librustc_parse" }
rustc_span = { path = "../librustc_span" }
-rustc_error_codes = { path = "../librustc_error_codes" }
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 181f872..351e72d 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -12,7 +12,6 @@
use rustc::ty::TyCtxt;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_expand::base::SyntaxExtension;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 0fec4bf..cf925ab 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -10,7 +10,7 @@
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![feature(rustc_private)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(specialization)]
#![feature(stmt_expr_attributes)]
#![recursion_limit = "256"]
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 4745ad0..5782164 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -241,8 +241,6 @@
use log::{debug, info, warn};
-use rustc_error_codes::*;
-
#[derive(Clone)]
struct CrateMismatch {
path: PathBuf,
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 9426d5e..bbf6973 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -3,7 +3,6 @@
use rustc::session::Session;
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashSet;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 8ad92ce..9d2bea2 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1073,7 +1073,7 @@
ctor: None,
}), adt_def.repr)
}
- hir::ItemKind::Impl(_, _, defaultness, ..) => {
+ hir::ItemKind::Impl { defaultness, .. } => {
let trait_ref = self.tcx.impl_trait_ref(def_id);
let polarity = self.tcx.impl_polarity(def_id);
let parent = if let Some(trait_ref) = trait_ref {
@@ -1149,7 +1149,7 @@
})
)
}
- hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => {
+ hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
record!(self.per_def.children[def_id] <-
associated_item_def_ids.iter().map(|&def_id| {
@@ -1172,13 +1172,13 @@
| hir::ItemKind::Enum(..)
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
- | hir::ItemKind::Impl(..) => self.encode_item_type(def_id),
+ | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
_ => {}
}
if let hir::ItemKind::Fn(..) = item.kind {
record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
}
- if let hir::ItemKind::Impl(..) = item.kind {
+ if let hir::ItemKind::Impl { .. } = item.kind {
if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
record!(self.per_def.impl_trait_ref[def_id] <- trait_ref);
}
@@ -1199,7 +1199,7 @@
| hir::ItemKind::Enum(..)
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
- | hir::ItemKind::Impl(..)
+ | hir::ItemKind::Impl { .. }
| hir::ItemKind::OpaqueTy(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..) => {
@@ -1645,7 +1645,7 @@
hir::ItemKind::Union(..) => {
self.encode_fields(def_id);
}
- hir::ItemKind::Impl(..) => {
+ hir::ItemKind::Impl { .. } => {
for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
self.encode_info_for_impl_item(trait_item_def_id);
}
@@ -1666,7 +1666,7 @@
impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
- if let hir::ItemKind::Impl(..) = item.kind {
+ if let hir::ItemKind::Impl { .. } = item.kind {
let impl_id = self.tcx.hir().local_def_id(item.hir_id);
if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index);
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index f9b61b9..00881e3 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -29,4 +29,3 @@
rustc_span = { path = "../librustc_span" }
rustc_apfloat = { path = "../librustc_apfloat" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
index 9a0c99b..01b7c56 100644
--- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
@@ -2,12 +2,13 @@
use std::collections::VecDeque;
+use rustc::infer::NLLRegionVariableOrigin;
use rustc::mir::{
Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue,
Statement, StatementKind, TerminatorKind,
};
use rustc::ty::adjustment::PointerCast;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, RegionVid, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_index::vec::IndexVec;
@@ -254,6 +255,23 @@
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
+ fn free_region_constraint_info(
+ &self,
+ borrow_region: RegionVid,
+ outlived_region: RegionVid,
+ ) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
+ let (category, from_closure, span) = self.regioncx.best_blame_constraint(
+ &self.body,
+ borrow_region,
+ NLLRegionVariableOrigin::FreeRegion,
+ |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
+ );
+
+ let outlived_fr_name = self.give_region_a_name(outlived_region);
+
+ (category, from_closure, span, outlived_fr_name)
+ }
+
/// Returns structured explanation for *why* the borrow contains the
/// point from `location`. This is key for the "3-point errors"
/// [described in the NLL RFC][d].
@@ -278,14 +296,14 @@
location, borrow, kind_place
);
- let regioncx = &self.nonlexical_regioncx;
+ let regioncx = &self.regioncx;
let body: &Body<'_> = &self.body;
let tcx = self.infcx.tcx;
let borrow_region_vid = borrow.region;
debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid);
- let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, location);
+ let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub);
match find_use::find(body, regioncx, tcx, region_sub, location) {
@@ -329,10 +347,9 @@
}
None => {
- if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) {
- let (category, from_closure, span, region_name) = self
- .nonlexical_regioncx
- .free_region_constraint_info(self, borrow_region_vid, region);
+ if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
+ let (category, from_closure, span, region_name) =
+ self.free_region_constraint_info(borrow_region_vid, region);
if let Some(region_name) = region_name {
let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
BorrowExplanation::MustBeValidFor {
@@ -345,14 +362,14 @@
} else {
debug!(
"explain_why_borrow_contains_point: \
- Could not generate a region name"
+ Could not generate a region name"
);
BorrowExplanation::Unexplained
}
} else {
debug!(
"explain_why_borrow_contains_point: \
- Could not generate an error region vid"
+ Could not generate an error region vid"
);
BorrowExplanation::Unexplained
}
diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs
index 3f3bdb9..0fc73d3 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mod.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs
@@ -32,7 +32,7 @@
crate use mutability_errors::AccessKind;
crate use outlives_suggestion::OutlivesSuggestionBuilder;
crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
-crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource};
+crate use region_name::{RegionName, RegionNameSource};
pub(super) struct IncludingDowncast(pub(super) bool);
diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
index 1425c22..ee94890 100644
--- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs
@@ -12,7 +12,7 @@
use crate::borrow_check::MirBorrowckCtxt;
-use super::{ErrorConstraintInfo, RegionErrorNamingCtx, RegionName, RegionNameSource};
+use super::{ErrorConstraintInfo, RegionName, RegionNameSource};
/// The different things we could suggest.
enum SuggestedConstraint {
@@ -77,19 +77,15 @@
fn region_vid_to_name(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
- renctx: &mut RegionErrorNamingCtx,
region: RegionVid,
) -> Option<RegionName> {
- mbcx.nonlexical_regioncx
- .give_region_a_name(mbcx, renctx, region)
- .filter(Self::region_name_is_suggestable)
+ mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable)
}
/// Compiles a list of all suggestions to be printed in the final big suggestion.
fn compile_all_suggestions(
&self,
mbcx: &MirBorrowckCtxt<'_, '_>,
- renctx: &mut RegionErrorNamingCtx,
) -> SmallVec<[SuggestedConstraint; 2]> {
let mut suggested = SmallVec::new();
@@ -98,7 +94,7 @@
let mut unified_already = FxHashSet::default();
for (fr, outlived) in &self.constraints_to_add {
- let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, renctx, *fr) {
+ let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) {
fr_name
} else {
continue;
@@ -107,9 +103,7 @@
let outlived = outlived
.iter()
// if there is a `None`, we will just omit that constraint
- .filter_map(|fr| {
- self.region_vid_to_name(mbcx, renctx, *fr).map(|rname| (fr, rname))
- })
+ .filter_map(|fr| self.region_vid_to_name(mbcx, *fr).map(|rname| (fr, rname)))
.collect::<Vec<_>>();
// No suggestable outlived lifetimes.
@@ -173,12 +167,11 @@
&mut self,
mbcx: &MirBorrowckCtxt<'_, '_>,
errci: &ErrorConstraintInfo,
- renctx: &mut RegionErrorNamingCtx,
diag: &mut DiagnosticBuilder<'_>,
) {
// Emit an intermediate note.
- let fr_name = self.region_vid_to_name(mbcx, renctx, errci.fr);
- let outlived_fr_name = self.region_vid_to_name(mbcx, renctx, errci.outlived_fr);
+ let fr_name = self.region_vid_to_name(mbcx, errci.fr);
+ let outlived_fr_name = self.region_vid_to_name(mbcx, errci.outlived_fr);
if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) {
if let RegionNameSource::Static = outlived_fr_name.source {
@@ -194,11 +187,7 @@
/// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
/// suggestion including all collected constraints.
- crate fn add_suggestion(
- &self,
- mbcx: &mut MirBorrowckCtxt<'_, '_>,
- renctx: &mut RegionErrorNamingCtx,
- ) {
+ crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) {
// No constraints to add? Done.
if self.constraints_to_add.is_empty() {
debug!("No constraints to suggest.");
@@ -215,7 +204,7 @@
}
// Get all suggestable constraints.
- let suggested = self.compile_all_suggestions(mbcx, renctx);
+ let suggested = self.compile_all_suggestions(mbcx);
// If there are no suggestable constraints...
if suggested.is_empty() {
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
index dc63fa8..b999dfa 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
@@ -1,27 +1,25 @@
//! Error reporting machinery for lifetime errors.
use rustc::infer::{
- error_reporting::nice_region_error::NiceRegionError, region_constraints::GenericKind,
- InferCtxt, NLLRegionVariableOrigin,
+ error_reporting::nice_region_error::NiceRegionError, opaque_types, NLLRegionVariableOrigin,
};
-use rustc::mir::{Body, ConstraintCategory, Location};
+use rustc::mir::ConstraintCategory;
use rustc::ty::{self, RegionVid, Ty};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::def_id::DefId;
-use rustc_index::vec::IndexVec;
use rustc_span::symbol::kw;
use rustc_span::Span;
-use std::collections::VecDeque;
use crate::util::borrowck_errors;
use crate::borrow_check::{
- constraints::OutlivesConstraint, nll::ConstraintDescription,
- region_infer::RegionInferenceContext, type_check::Locations, universal_regions::DefiningTy,
+ nll::ConstraintDescription,
+ region_infer::{values::RegionElement, TypeTest},
+ universal_regions::DefiningTy,
MirBorrowckCtxt,
};
-use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource};
+use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
impl ConstraintDescription for ConstraintCategory {
fn description(&self) -> &'static str {
@@ -46,13 +44,6 @@
}
}
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-enum Trace {
- StartRegion,
- FromOutlivesConstraint(OutlivesConstraint),
- NotVisited,
-}
-
/// A collection of errors encountered during region inference. This is needed to efficiently
/// report errors after borrow checking.
///
@@ -62,23 +53,8 @@
#[derive(Clone, Debug)]
crate enum RegionErrorKind<'tcx> {
- /// An error for a type test: `T: 'a` does not live long enough.
- TypeTestDoesNotLiveLongEnough {
- /// The span of the type test.
- span: Span,
- /// The generic type of the type test.
- generic: GenericKind<'tcx>,
- },
-
- /// A generic bound failure for a type test.
- TypeTestGenericBoundError {
- /// The span of the type test.
- span: Span,
- /// The generic type of the type test.
- generic: GenericKind<'tcx>,
- /// The lower bound region.
- lower_bound_region: ty::Region<'tcx>,
- },
+ /// A generic bound failure for a type test (`T: 'a`).
+ TypeTestError { type_test: TypeTest<'tcx> },
/// An unexpected hidden region for an opaque type.
UnexpectedHiddenRegion {
@@ -94,8 +70,8 @@
BoundUniversalRegionError {
/// The placeholder free region.
longer_fr: RegionVid,
- /// The region that erroneously must be outlived by `longer_fr`.
- error_region: RegionVid,
+ /// The region element that erroneously must be outlived by `longer_fr`.
+ error_element: RegionElement,
/// The origin of the placeholder region.
fr_origin: NLLRegionVariableOrigin,
},
@@ -128,26 +104,26 @@
pub(super) span: Span,
}
-impl<'tcx> RegionInferenceContext<'tcx> {
+impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is
/// existentially bound, then we check its inferred value and try
/// to find a good name from that. Returns `None` if we can't find
/// one (e.g., this is just some random part of the CFG).
- pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
- self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
+ pub(super) fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
+ self.to_error_region_vid(r).and_then(|r| self.regioncx.region_definition(r).external_name)
}
- /// Returns the [RegionVid] corresponding to the region returned by
+ /// Returns the `RegionVid` corresponding to the region returned by
/// `to_error_region`.
- pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
- if self.universal_regions.is_universal_region(r) {
+ pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
+ if self.regioncx.universal_regions().is_universal_region(r) {
Some(r)
} else {
- let r_scc = self.constraint_sccs.scc(r);
- let upper_bound = self.universal_upper_bound(r);
- if self.scc_values.contains(r_scc, upper_bound) {
+ let upper_bound = self.regioncx.universal_upper_bound(r);
+
+ if self.regioncx.upper_bound_in_region_scc(r, upper_bound) {
self.to_error_region_vid(upper_bound)
} else {
None
@@ -155,270 +131,134 @@
}
}
- /// Tries to find the best constraint to blame for the fact that
- /// `R: from_region`, where `R` is some region that meets
- /// `target_test`. This works by following the constraint graph,
- /// creating a constraint path that forces `R` to outlive
- /// `from_region`, and then finding the best choices within that
- /// path to blame.
- fn best_blame_constraint(
- &self,
- body: &Body<'tcx>,
- from_region: RegionVid,
- from_region_origin: NLLRegionVariableOrigin,
- target_test: impl Fn(RegionVid) -> bool,
- ) -> (ConstraintCategory, bool, Span) {
- debug!(
- "best_blame_constraint(from_region={:?}, from_region_origin={:?})",
- from_region, from_region_origin
- );
-
- // Find all paths
- let (path, target_region) =
- self.find_constraint_paths_between_regions(from_region, target_test).unwrap();
- debug!(
- "best_blame_constraint: path={:#?}",
- path.iter()
- .map(|&c| format!(
- "{:?} ({:?}: {:?})",
- c,
- self.constraint_sccs.scc(c.sup),
- self.constraint_sccs.scc(c.sub),
- ))
- .collect::<Vec<_>>()
- );
-
- // Classify each of the constraints along the path.
- let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path
- .iter()
- .map(|constraint| {
- if constraint.category == ConstraintCategory::ClosureBounds {
- self.retrieve_closure_constraint_info(body, &constraint)
- } else {
- (constraint.category, false, constraint.locations.span(body))
- }
- })
- .collect();
- debug!("best_blame_constraint: categorized_path={:#?}", categorized_path);
-
- // To find the best span to cite, we first try to look for the
- // final constraint that is interesting and where the `sup` is
- // not unified with the ultimate target region. The reason
- // for this is that we have a chain of constraints that lead
- // from the source to the target region, something like:
- //
- // '0: '1 ('0 is the source)
- // '1: '2
- // '2: '3
- // '3: '4
- // '4: '5
- // '5: '6 ('6 is the target)
- //
- // Some of those regions are unified with `'6` (in the same
- // SCC). We want to screen those out. After that point, the
- // "closest" constraint we have to the end is going to be the
- // most likely to be the point where the value escapes -- but
- // we still want to screen for an "interesting" point to
- // highlight (e.g., a call site or something).
- let target_scc = self.constraint_sccs.scc(target_region);
- let mut range = 0..path.len();
-
- // As noted above, when reporting an error, there is typically a chain of constraints
- // leading from some "source" region which must outlive some "target" region.
- // In most cases, we prefer to "blame" the constraints closer to the target --
- // but there is one exception. When constraints arise from higher-ranked subtyping,
- // we generally prefer to blame the source value,
- // as the "target" in this case tends to be some type annotation that the user gave.
- // Therefore, if we find that the region origin is some instantiation
- // of a higher-ranked region, we start our search from the "source" point
- // rather than the "target", and we also tweak a few other things.
- //
- // An example might be this bit of Rust code:
- //
- // ```rust
- // let x: fn(&'static ()) = |_| {};
- // let y: for<'a> fn(&'a ()) = x;
- // ```
- //
- // In MIR, this will be converted into a combination of assignments and type ascriptions.
- // In particular, the 'static is imposed through a type ascription:
- //
- // ```rust
- // x = ...;
- // AscribeUserType(x, fn(&'static ())
- // y = x;
- // ```
- //
- // We wind up ultimately with constraints like
- //
- // ```rust
- // !a: 'temp1 // from the `y = x` statement
- // 'temp1: 'temp2
- // 'temp2: 'static // from the AscribeUserType
- // ```
- //
- // and here we prefer to blame the source (the y = x statement).
- let blame_source = match from_region_origin {
- NLLRegionVariableOrigin::FreeRegion
- | NLLRegionVariableOrigin::Existential { from_forall: false } => true,
- NLLRegionVariableOrigin::Placeholder(_)
- | NLLRegionVariableOrigin::Existential { from_forall: true } => false,
- };
-
- let find_region = |i: &usize| {
- let constraint = path[*i];
-
- let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
-
- if blame_source {
- match categorized_path[*i].0 {
- ConstraintCategory::OpaqueType
- | ConstraintCategory::Boring
- | ConstraintCategory::BoringNoLocation
- | ConstraintCategory::Internal => false,
- ConstraintCategory::TypeAnnotation
- | ConstraintCategory::Return
- | ConstraintCategory::Yield => true,
- _ => constraint_sup_scc != target_scc,
- }
- } else {
- match categorized_path[*i].0 {
- ConstraintCategory::OpaqueType
- | ConstraintCategory::Boring
- | ConstraintCategory::BoringNoLocation
- | ConstraintCategory::Internal => false,
- _ => true,
- }
- }
- };
-
- let best_choice =
- if blame_source { range.rev().find(find_region) } else { range.find(find_region) };
-
- debug!(
- "best_blame_constraint: best_choice={:?} blame_source={}",
- best_choice, blame_source
- );
-
- if let Some(i) = best_choice {
- if let Some(next) = categorized_path.get(i + 1) {
- if categorized_path[i].0 == ConstraintCategory::Return
- && next.0 == ConstraintCategory::OpaqueType
+ /// Returns `true` if a closure is inferred to be an `FnMut` closure.
+ fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
+ if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) {
+ if let ty::BoundRegion::BrEnv = free_region.bound_region {
+ if let DefiningTy::Closure(def_id, substs) =
+ self.regioncx.universal_regions().defining_ty
{
- // The return expression is being influenced by the return type being
- // impl Trait, point at the return type and not the return expr.
- return *next;
+ return substs.as_closure().kind(def_id, self.infcx.tcx)
+ == ty::ClosureKind::FnMut;
}
}
- return categorized_path[i];
}
- // If that search fails, that is.. unusual. Maybe everything
- // is in the same SCC or something. In that case, find what
- // appears to be the most interesting point to report to the
- // user via an even more ad-hoc guess.
- categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
- debug!("`: sorted_path={:#?}", categorized_path);
-
- *categorized_path.first().unwrap()
+ false
}
- /// Walks the graph of constraints (where `'a: 'b` is considered
- /// an edge `'a -> 'b`) to find all paths from `from_region` to
- /// `to_region`. The paths are accumulated into the vector
- /// `results`. The paths are stored as a series of
- /// `ConstraintIndex` values -- in other words, a list of *edges*.
- ///
- /// Returns: a series of constraints as well as the region `R`
- /// that passed the target test.
- fn find_constraint_paths_between_regions(
- &self,
- from_region: RegionVid,
- target_test: impl Fn(RegionVid) -> bool,
- ) -> Option<(Vec<OutlivesConstraint>, RegionVid)> {
- let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions);
- context[from_region] = Trace::StartRegion;
+ /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`.
+ pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) {
+ // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are
+ // buffered in the `MirBorrowckCtxt`.
- // Use a deque so that we do a breadth-first search. We will
- // stop at the first match, which ought to be the shortest
- // path (fewest constraints).
- let mut deque = VecDeque::new();
- deque.push_back(from_region);
+ let mut outlives_suggestion = OutlivesSuggestionBuilder::default();
- while let Some(r) = deque.pop_front() {
- debug!(
- "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}",
- from_region,
- r,
- self.region_value_str(r),
- );
+ for nll_error in nll_errors.into_iter() {
+ match nll_error {
+ RegionErrorKind::TypeTestError { type_test } => {
+ // Try to convert the lower-bound region into something named we can print for the user.
+ let lower_bound_region = self.to_error_region(type_test.lower_bound);
- // Check if we reached the region we were looking for. If so,
- // we can reconstruct the path that led to it and return it.
- if target_test(r) {
- let mut result = vec![];
- let mut p = r;
- loop {
- match context[p] {
- Trace::NotVisited => {
- bug!("found unvisited region {:?} on path to {:?}", p, r)
- }
+ let type_test_span = type_test.locations.span(&self.body);
- Trace::FromOutlivesConstraint(c) => {
- result.push(c);
- p = c.sup;
- }
+ if let Some(lower_bound_region) = lower_bound_region {
+ let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
+ self.infcx
+ .construct_generic_bound_failure(
+ region_scope_tree,
+ type_test_span,
+ None,
+ type_test.generic_kind,
+ lower_bound_region,
+ )
+ .buffer(&mut self.errors_buffer);
+ } else {
+ // FIXME. We should handle this case better. It
+ // indicates that we have e.g., some region variable
+ // whose value is like `'a+'b` where `'a` and `'b` are
+ // distinct unrelated univesal regions that are not
+ // known to outlive one another. It'd be nice to have
+ // some examples where this arises to decide how best
+ // to report it; we could probably handle it by
+ // iterating over the universal regions and reporting
+ // an error that multiple bounds are required.
+ self.infcx
+ .tcx
+ .sess
+ .struct_span_err(
+ type_test_span,
+ &format!("`{}` does not live long enough", type_test.generic_kind),
+ )
+ .buffer(&mut self.errors_buffer);
+ }
+ }
- Trace::StartRegion => {
- result.reverse();
- return Some((result, r));
- }
+ RegionErrorKind::UnexpectedHiddenRegion {
+ opaque_type_def_id,
+ hidden_ty,
+ member_region,
+ } => {
+ let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
+ opaque_types::unexpected_hidden_region_diagnostic(
+ self.infcx.tcx,
+ Some(region_scope_tree),
+ opaque_type_def_id,
+ hidden_ty,
+ member_region,
+ )
+ .buffer(&mut self.errors_buffer);
+ }
+
+ RegionErrorKind::BoundUniversalRegionError {
+ longer_fr,
+ fr_origin,
+ error_element,
+ } => {
+ let error_region = self.regioncx.region_from_element(longer_fr, error_element);
+
+ // Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
+ let (_, span) = self.regioncx.find_outlives_blame_span(
+ &self.body,
+ longer_fr,
+ fr_origin,
+ error_region,
+ );
+
+ // FIXME: improve this error message
+ self.infcx
+ .tcx
+ .sess
+ .struct_span_err(span, "higher-ranked subtype error")
+ .buffer(&mut self.errors_buffer);
+ }
+
+ RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {
+ if is_reported {
+ self.report_region_error(
+ longer_fr,
+ fr_origin,
+ shorter_fr,
+ &mut outlives_suggestion,
+ );
+ } else {
+ // We only report the first error, so as not to overwhelm the user. See
+ // `RegRegionErrorKind` docs.
+ //
+ // FIXME: currently we do nothing with these, but perhaps we can do better?
+ // FIXME: try collecting these constraints on the outlives suggestion
+ // builder. Does it make the suggestions any better?
+ debug!(
+ "Unreported region error: can't prove that {:?}: {:?}",
+ longer_fr, shorter_fr
+ );
}
}
}
-
- // Otherwise, walk over the outgoing constraints and
- // enqueue any regions we find, keeping track of how we
- // reached them.
-
- // A constraint like `'r: 'x` can come from our constraint
- // graph.
- let fr_static = self.universal_regions.fr_static;
- let outgoing_edges_from_graph =
- self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static);
-
- // Always inline this closure because it can be hot.
- let mut handle_constraint = #[inline(always)]
- |constraint: OutlivesConstraint| {
- debug_assert_eq!(constraint.sup, r);
- let sub_region = constraint.sub;
- if let Trace::NotVisited = context[sub_region] {
- context[sub_region] = Trace::FromOutlivesConstraint(constraint);
- deque.push_back(sub_region);
- }
- };
-
- // This loop can be hot.
- for constraint in outgoing_edges_from_graph {
- handle_constraint(constraint);
- }
-
- // Member constraints can also give rise to `'r: 'x` edges that
- // were not part of the graph initially, so watch out for those.
- // (But they are extremely rare; this loop is very cold.)
- for constraint in self.applied_member_constraints(r) {
- let p_c = &self.member_constraints[constraint.member_constraint_index];
- let constraint = OutlivesConstraint {
- sup: r,
- sub: constraint.min_choice,
- locations: Locations::All(p_c.definition_span),
- category: ConstraintCategory::OpaqueType,
- };
- handle_constraint(constraint);
- }
}
- None
+ // Emit one outlives suggestions for each MIR def we borrowck
+ outlives_suggestion.add_suggestion(self);
}
/// Report an error because the universal region `fr` was required to outlive
@@ -429,38 +269,38 @@
/// ```
///
/// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
- pub(in crate::borrow_check) fn report_error<'a>(
- &'a self,
- mbcx: &MirBorrowckCtxt<'a, 'tcx>,
+ pub(in crate::borrow_check) fn report_region_error(
+ &mut self,
fr: RegionVid,
fr_origin: NLLRegionVariableOrigin,
outlived_fr: RegionVid,
outlives_suggestion: &mut OutlivesSuggestionBuilder,
- renctx: &mut RegionErrorNamingCtx,
- ) -> DiagnosticBuilder<'a> {
- debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
+ ) {
+ debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
- let (category, _, span) = self.best_blame_constraint(&mbcx.body, fr, fr_origin, |r| {
- self.provides_universal_region(r, fr, outlived_fr)
- });
+ let (category, _, span) =
+ self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| {
+ self.regioncx.provides_universal_region(r, fr, outlived_fr)
+ });
- debug!("report_error: category={:?} {:?}", category, span);
+ debug!("report_region_error: category={:?} {:?}", category, span);
// Check if we can use one of the "nice region errors".
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
- let tables = mbcx.infcx.tcx.typeck_tables_of(mbcx.mir_def_id);
- let nice = NiceRegionError::new_from_span(mbcx.infcx, span, o, f, Some(tables));
+ let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id);
+ let nice = NiceRegionError::new_from_span(self.infcx, span, o, f, Some(tables));
if let Some(diag) = nice.try_report_from_nll() {
- return diag;
+ diag.buffer(&mut self.errors_buffer);
+ return;
}
}
let (fr_is_local, outlived_fr_is_local): (bool, bool) = (
- self.universal_regions.is_local_free_region(fr),
- self.universal_regions.is_local_free_region(outlived_fr),
+ self.regioncx.universal_regions().is_local_free_region(fr),
+ self.regioncx.universal_regions().is_local_free_region(outlived_fr),
);
debug!(
- "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
+ "report_region_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
fr_is_local, outlived_fr_is_local, category
);
@@ -473,52 +313,30 @@
span,
};
- match (category, fr_is_local, outlived_fr_is_local) {
- (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(mbcx.infcx, fr) => {
- self.report_fnmut_error(mbcx, &errci, renctx)
+ let diag = match (category, fr_is_local, outlived_fr_is_local) {
+ (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => {
+ self.report_fnmut_error(&errci)
}
(ConstraintCategory::Assignment, true, false)
| (ConstraintCategory::CallArgument, true, false) => {
- let mut db = self.report_escaping_data_error(mbcx, &errci, renctx);
+ let mut db = self.report_escaping_data_error(&errci);
- outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db);
+ outlives_suggestion.intermediate_suggestion(self, &errci, &mut db);
outlives_suggestion.collect_constraint(fr, outlived_fr);
db
}
_ => {
- let mut db = self.report_general_error(mbcx, &errci, renctx);
+ let mut db = self.report_general_error(&errci);
- outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db);
+ outlives_suggestion.intermediate_suggestion(self, &errci, &mut db);
outlives_suggestion.collect_constraint(fr, outlived_fr);
db
}
- }
- }
-
- /// We have a constraint `fr1: fr2` that is not satisfied, where
- /// `fr2` represents some universal region. Here, `r` is some
- /// region where we know that `fr1: r` and this function has the
- /// job of determining whether `r` is "to blame" for the fact that
- /// `fr1: fr2` is required.
- ///
- /// This is true under two conditions:
- ///
- /// - `r == fr2`
- /// - `fr2` is `'static` and `r` is some placeholder in a universe
- /// that cannot be named by `fr1`; in that case, we will require
- /// that `fr1: 'static` because it is the only way to `fr1: r` to
- /// be satisfied. (See `add_incompatible_universe`.)
- fn provides_universal_region(&self, r: RegionVid, fr1: RegionVid, fr2: RegionVid) -> bool {
- debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2);
- let result = {
- r == fr2 || {
- fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r)
- }
};
- debug!("provides_universal_region: result = {:?}", result);
- result
+
+ diag.buffer(&mut self.errors_buffer);
}
/// Report a specialized error when `FnMut` closures return a reference to a captured variable.
@@ -537,15 +355,10 @@
/// executing...
/// = note: ...therefore, returned references to captured variables will escape the closure
/// ```
- fn report_fnmut_error(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- errci: &ErrorConstraintInfo,
- renctx: &mut RegionErrorNamingCtx,
- ) -> DiagnosticBuilder<'_> {
+ fn report_fnmut_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
- let mut diag = mbcx
+ let mut diag = self
.infcx
.tcx
.sess
@@ -553,7 +366,8 @@
// We should check if the return type of this closure is in fact a closure - in that
// case, we can special case the error further.
- let return_type_is_closure = self.universal_regions.unnormalized_output_ty.is_closure();
+ let return_type_is_closure =
+ self.regioncx.universal_regions().unnormalized_output_ty.is_closure();
let message = if return_type_is_closure {
"returns a closure that contains a reference to a captured variable, which then \
escapes the closure body"
@@ -563,7 +377,7 @@
diag.span_label(*span, message);
- match self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap().source {
+ match self.give_region_a_name(*outlived_fr).unwrap().source {
RegionNameSource::NamedEarlyBoundRegion(fr_span)
| RegionNameSource::NamedFreeRegion(fr_span)
| RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
@@ -598,30 +412,25 @@
/// LL | ref_obj(x)
/// | ^^^^^^^^^^ `x` escapes the function body here
/// ```
- fn report_escaping_data_error(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- errci: &ErrorConstraintInfo,
- renctx: &mut RegionErrorNamingCtx,
- ) -> DiagnosticBuilder<'_> {
+ fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo { span, category, .. } = errci;
- let fr_name_and_span = self.get_var_name_and_span_for_region(
- mbcx.infcx.tcx,
- &mbcx.body,
- &mbcx.local_names,
- &mbcx.upvars,
+ let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
+ self.infcx.tcx,
+ &self.body,
+ &self.local_names,
+ &self.upvars,
errci.fr,
);
- let outlived_fr_name_and_span = self.get_var_name_and_span_for_region(
- mbcx.infcx.tcx,
- &mbcx.body,
- &mbcx.local_names,
- &mbcx.upvars,
+ let outlived_fr_name_and_span = self.regioncx.get_var_name_and_span_for_region(
+ self.infcx.tcx,
+ &self.body,
+ &self.local_names,
+ &self.upvars,
errci.outlived_fr,
);
- let escapes_from = match self.universal_regions.defining_ty {
+ let escapes_from = match self.regioncx.universal_regions().defining_ty {
DefiningTy::Closure(..) => "closure",
DefiningTy::Generator(..) => "generator",
DefiningTy::FnDef(..) => "function",
@@ -634,15 +443,15 @@
|| (*category == ConstraintCategory::Assignment && escapes_from == "function")
|| escapes_from == "const"
{
- return self.report_general_error(
- mbcx,
- &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci },
- renctx,
- );
+ return self.report_general_error(&ErrorConstraintInfo {
+ fr_is_local: true,
+ outlived_fr_is_local: false,
+ ..*errci
+ });
}
let mut diag =
- borrowck_errors::borrowed_data_escapes_closure(mbcx.infcx.tcx, *span, escapes_from);
+ borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from);
if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span {
diag.span_label(
@@ -684,12 +493,7 @@
/// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
/// | is returning data with lifetime `'b`
/// ```
- fn report_general_error(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- errci: &ErrorConstraintInfo,
- renctx: &mut RegionErrorNamingCtx,
- ) -> DiagnosticBuilder<'_> {
+ fn report_general_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> {
let ErrorConstraintInfo {
fr,
fr_is_local,
@@ -701,14 +505,14 @@
} = errci;
let mut diag =
- mbcx.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough");
+ self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough");
let mir_def_name =
- if mbcx.infcx.tcx.is_closure(mbcx.mir_def_id) { "closure" } else { "function" };
+ if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" };
- let fr_name = self.give_region_a_name(mbcx, renctx, *fr).unwrap();
+ let fr_name = self.give_region_a_name(*fr).unwrap();
fr_name.highlight_region_name(&mut diag);
- let outlived_fr_name = self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap();
+ let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap();
outlived_fr_name.highlight_region_name(&mut diag);
match (category, outlived_fr_is_local, fr_is_local) {
@@ -735,7 +539,7 @@
}
}
- self.add_static_impl_trait_suggestion(mbcx.infcx, &mut diag, *fr, fr_name, *outlived_fr);
+ self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
diag
}
@@ -751,8 +555,7 @@
/// ```
fn add_static_impl_trait_suggestion(
&self,
- infcx: &InferCtxt<'_, 'tcx>,
- diag: &mut DiagnosticBuilder<'_>,
+ diag: &mut DiagnosticBuilder<'tcx>,
fr: RegionVid,
// We need to pass `fr_name` - computing it again will label it twice.
fr_name: RegionName,
@@ -761,11 +564,12 @@
if let (Some(f), Some(ty::RegionKind::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr))
{
- if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = infcx
+ if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = self
+ .infcx
.tcx
.is_suitable_region(f)
.map(|r| r.def_id)
- .map(|id| infcx.tcx.return_type_impl_trait(id))
+ .map(|id| self.infcx.tcx.return_type_impl_trait(id))
.unwrap_or(None)
{
// Check whether or not the impl trait return type is intended to capture
@@ -773,8 +577,8 @@
//
// eg. check for `impl Trait + 'static` instead of `impl Trait`.
let has_static_predicate = {
- let predicates_of = infcx.tcx.predicates_of(*did);
- let bounds = predicates_of.instantiate(infcx.tcx, substs);
+ let predicates_of = self.infcx.tcx.predicates_of(*did);
+ let bounds = predicates_of.instantiate(self.infcx.tcx, substs);
let mut found = false;
for predicate in bounds.predicates {
@@ -802,8 +606,8 @@
diag.help(&format!("consider replacing `{}` with `{}`", fr_name, static_str));
} else {
// Otherwise, we should suggest adding a constraint on the return type.
- let span = infcx.tcx.def_span(*did);
- if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(span) {
+ let span = self.infcx.tcx.def_span(*did);
+ if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
let suggestable_fr_name = if fr_name.was_named() {
fr_name.to_string()
} else {
@@ -830,130 +634,4 @@
}
}
}
-
- crate fn free_region_constraint_info(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- borrow_region: RegionVid,
- outlived_region: RegionVid,
- ) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
- let (category, from_closure, span) = self.best_blame_constraint(
- &mbcx.body,
- borrow_region,
- NLLRegionVariableOrigin::FreeRegion,
- |r| self.provides_universal_region(r, borrow_region, outlived_region),
- );
-
- let mut renctx = RegionErrorNamingCtx::new();
- let outlived_fr_name = self.give_region_a_name(mbcx, &mut renctx, outlived_region);
-
- (category, from_closure, span, outlived_fr_name)
- }
-
- // Finds some region R such that `fr1: R` and `R` is live at
- // `elem`.
- crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
- debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem);
- self.find_constraint_paths_between_regions(fr1, |r| {
- // First look for some `r` such that `fr1: r` and `r` is live at `elem`
- debug!(
- "find_sub_region_live_at: liveness_constraints for {:?} are {:?}",
- r,
- self.liveness_constraints.region_value_str(r),
- );
- self.liveness_constraints.contains(r, elem)
- })
- .or_else(|| {
- // If we fail to find that, we may find some `r` such that
- // `fr1: r` and `r` is a placeholder from some universe
- // `fr1` cannot name. This would force `fr1` to be
- // `'static`.
- self.find_constraint_paths_between_regions(fr1, |r| {
- self.cannot_name_placeholder(fr1, r)
- })
- })
- .or_else(|| {
- // If we fail to find THAT, it may be that `fr1` is a
- // placeholder that cannot "fit" into its SCC. In that
- // case, there should be some `r` where `fr1: r`, both
- // `fr1` and `r` are in the same SCC, and `fr1` is a
- // placeholder that `r` cannot name. We can blame that
- // edge.
- self.find_constraint_paths_between_regions(fr1, |r| {
- self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r)
- && self.cannot_name_placeholder(r, fr1)
- })
- })
- .map(|(_path, r)| r)
- .unwrap()
- }
-
- // Finds a good span to blame for the fact that `fr1` outlives `fr2`.
- crate fn find_outlives_blame_span(
- &self,
- body: &Body<'tcx>,
- fr1: RegionVid,
- fr1_origin: NLLRegionVariableOrigin,
- fr2: RegionVid,
- ) -> (ConstraintCategory, Span) {
- let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| {
- self.provides_universal_region(r, fr1, fr2)
- });
- (category, span)
- }
-
- fn retrieve_closure_constraint_info(
- &self,
- body: &Body<'tcx>,
- constraint: &OutlivesConstraint,
- ) -> (ConstraintCategory, bool, Span) {
- let loc = match constraint.locations {
- Locations::All(span) => return (constraint.category, false, span),
- Locations::Single(loc) => loc,
- };
-
- let opt_span_category =
- self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub));
- opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or((
- constraint.category,
- false,
- body.source_info(loc).span,
- ))
- }
-
- /// Returns `true` if a closure is inferred to be an `FnMut` closure.
- crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool {
- if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) {
- if let ty::BoundRegion::BrEnv = free_region.bound_region {
- if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty {
- let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx);
- return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind();
- }
- }
- }
-
- false
- }
-
- /// If `r2` represents a placeholder region, then this returns
- /// `true` if `r1` cannot name that placeholder in its
- /// value; otherwise, returns `false`.
- fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool {
- debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2);
-
- match self.definitions[r2].origin {
- NLLRegionVariableOrigin::Placeholder(placeholder) => {
- let universe1 = self.definitions[r1].universe;
- debug!(
- "cannot_name_value_of: universe1={:?} placeholder={:?}",
- universe1, placeholder
- );
- universe1.cannot_name(placeholder.universe)
- }
-
- NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => {
- false
- }
- }
- }
}
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
index 734e386..47eb2d8 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs
@@ -2,18 +2,14 @@
use rustc::ty::print::RegionHighlightMode;
use rustc::ty::subst::{GenericArgKind, SubstsRef};
-use rustc::ty::{self, RegionVid, Ty, TyCtxt};
-use rustc_data_structures::fx::FxHashMap;
+use rustc::ty::{self, RegionVid, Ty};
use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_span::symbol::kw;
use rustc_span::{symbol::Symbol, Span, DUMMY_SP};
-use crate::borrow_check::{
- nll::ToRegionVid, region_infer::RegionInferenceContext, universal_regions::DefiningTy,
- MirBorrowckCtxt,
-};
+use crate::borrow_check::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt};
/// A name for a particular region used in emitting diagnostics. This name could be a generated
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
@@ -55,46 +51,6 @@
AnonRegionFromAsyncFn(Span),
}
-/// Records region names that have been assigned before so that we can use the same ones in later
-/// diagnostics.
-#[derive(Debug, Clone)]
-crate struct RegionErrorNamingCtx {
- /// Record the region names generated for each region in the given
- /// MIR def so that we can reuse them later in help/error messages.
- renctx: FxHashMap<RegionVid, RegionName>,
-
- /// The counter for generating new region names.
- counter: usize,
-}
-
-impl RegionErrorNamingCtx {
- crate fn new() -> Self {
- Self { counter: 1, renctx: FxHashMap::default() }
- }
-
- /// Get the name of `region` if it has previously been named.
- crate fn get(&self, region: &RegionVid) -> Option<&RegionName> {
- self.renctx.get(region)
- }
-
- /// Give `region` the name `name`.
- crate fn insert(&mut self, region: RegionVid, name: RegionName) {
- self.renctx.insert(region, name);
- }
-
- /// Creates a synthetic region named `'N`, where `N` is the next value of the counter. Then,
- /// increment the counter.
- ///
- /// The name is not memoized. A separate call to `insert` should be made later. (Currently,
- /// this happens at the end of `give_region_a_name`).
- crate fn synthesize_region_name(&mut self) -> Symbol {
- let c = self.counter;
- self.counter += 1;
-
- Symbol::intern(&format!("'{:?}", c))
- }
-}
-
impl RegionName {
crate fn was_named(&self) -> bool {
match self.source {
@@ -161,7 +117,16 @@
}
}
-impl<'tcx> RegionInferenceContext<'tcx> {
+impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
+ /// Generate a synthetic region named `'N`, where `N` is the next value of the counter. Then,
+ /// increment the counter.
+ ///
+ /// This is _not_ idempotent. Call `give_region_a_name` when possible.
+ fn synthesize_region_name(&self) -> Symbol {
+ let c = self.next_region_name.replace_with(|counter| *counter + 1);
+ Symbol::intern(&format!("'{:?}", c))
+ }
+
/// Maps from an internal MIR region vid to something that we can
/// report to the user. In some cases, the region vids will map
/// directly to lifetimes that the user has a name for (e.g.,
@@ -170,6 +135,8 @@
/// that end, this function takes a "diagnostic" so that it can
/// create auxiliary notes as needed.
///
+ /// The names are memoized, so this is both cheap to recompute and idempotent.
+ ///
/// Example (function arguments):
///
/// Suppose we are trying to give a name to the lifetime of the
@@ -187,29 +154,28 @@
/// ```
///
/// and then return the name `'1` for us to use.
- crate fn give_region_a_name(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- renctx: &mut RegionErrorNamingCtx,
- fr: RegionVid,
- ) -> Option<RegionName> {
- debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter);
+ crate fn give_region_a_name(&self, fr: RegionVid) -> Option<RegionName> {
+ debug!(
+ "give_region_a_name(fr={:?}, counter={:?})",
+ fr,
+ self.next_region_name.try_borrow().unwrap()
+ );
- assert!(self.universal_regions.is_universal_region(fr));
+ assert!(self.regioncx.universal_regions().is_universal_region(fr));
- if let Some(value) = renctx.get(&fr) {
+ if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) {
return Some(value.clone());
}
let value = self
- .give_name_from_error_region(mbcx, fr, renctx)
- .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(mbcx, fr, renctx))
- .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(mbcx, fr, renctx))
- .or_else(|| self.give_name_if_anonymous_region_appears_in_output(mbcx, fr, renctx))
- .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(mbcx, fr, renctx));
+ .give_name_from_error_region(fr)
+ .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
+ .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
+ .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
+ .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr));
if let Some(ref value) = value {
- renctx.insert(fr, value.clone());
+ self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
}
debug!("give_region_a_name: gave name {:?}", value);
@@ -220,15 +186,10 @@
/// *user* has a name for. In that case, we'll be able to map
/// `fr` to a `Region<'tcx>`, and that region will be one of
/// named variants.
- fn give_name_from_error_region(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- fr: RegionVid,
- renctx: &mut RegionErrorNamingCtx,
- ) -> Option<RegionName> {
+ fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName> {
let error_region = self.to_error_region(fr)?;
- let tcx = mbcx.infcx.tcx;
+ let tcx = self.infcx.tcx;
debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region {
@@ -267,7 +228,7 @@
// happen if we have an elided name in an async fn for example: the
// compiler will generate a region named `'_`, but reporting such a name is
// not actually useful, so we synthesize a name for it instead.
- let name = renctx.synthesize_region_name();
+ let name = self.synthesize_region_name();
Some(RegionName {
name,
source: RegionNameSource::AnonRegionFromAsyncFn(span),
@@ -276,13 +237,13 @@
}
ty::BoundRegion::BrEnv => {
- let mir_hir_id = mbcx
+ let mir_hir_id = self
.infcx
.tcx
.hir()
- .as_local_hir_id(mbcx.mir_def_id)
+ .as_local_hir_id(self.mir_def_id)
.expect("non-local mir");
- let def_ty = self.universal_regions.defining_ty;
+ let def_ty = self.regioncx.universal_regions().defining_ty;
if let DefiningTy::Closure(def_id, substs) = def_ty {
let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) =
@@ -292,7 +253,7 @@
} else {
bug!("Closure is not defined by a closure expr");
};
- let region_name = renctx.synthesize_region_name();
+ let region_name = self.synthesize_region_name();
let closure_kind_ty = substs.as_closure().kind_ty(def_id, tcx);
let note = match closure_kind_ty.to_opt_closure_kind() {
@@ -346,38 +307,30 @@
/// ```
fn give_name_if_anonymous_region_appears_in_arguments(
&self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
fr: RegionVid,
- renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
- let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
- let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, fr)?;
+ let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs();
+ let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?;
- let arg_ty =
- self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
- if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
- mbcx,
- fr,
- arg_ty,
- argument_index,
- renctx,
- ) {
+ let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys
+ [implicit_inputs + argument_index];
+ if let Some(region_name) =
+ self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index)
+ {
return Some(region_name);
}
- self.give_name_if_we_cannot_match_hir_ty(mbcx, fr, arg_ty, renctx)
+ self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty)
}
fn give_name_if_we_can_match_hir_ty_from_argument(
&self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_index: usize,
- renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
- let mir_hir_id = mbcx.infcx.tcx.hir().as_local_hir_id(mbcx.mir_def_id)?;
- let fn_decl = mbcx.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?;
+ let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?;
+ let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?;
let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?;
match argument_hir_ty.kind {
// This indicates a variable with no type annotation, like
@@ -387,13 +340,7 @@
// (`give_name_if_anonymous_region_appears_in_arguments`).
hir::TyKind::Infer => None,
- _ => self.give_name_if_we_can_match_hir_ty(
- mbcx.infcx.tcx,
- needle_fr,
- argument_ty,
- argument_hir_ty,
- renctx,
- ),
+ _ => self.give_name_if_we_can_match_hir_ty(needle_fr, argument_ty, argument_hir_ty),
}
}
@@ -410,15 +357,13 @@
/// ```
fn give_name_if_we_cannot_match_hir_ty(
&self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
- renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
- let counter = renctx.counter;
+ let counter = *self.next_region_name.try_borrow().unwrap();
let mut highlight = RegionHighlightMode::default();
highlight.highlighting_region_vid(needle_fr, counter);
- let type_name = mbcx.infcx.extract_type_name(&argument_ty, Some(highlight)).0;
+ let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0;
debug!(
"give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -426,10 +371,11 @@
);
let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
// Only add a label if we can confirm that a region was labelled.
- let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, needle_fr)?;
- let (_, span) = self.get_argument_name_and_span_for_region(
- &mbcx.body,
- &mbcx.local_names,
+ let argument_index =
+ self.regioncx.get_argument_index_for_region(self.infcx.tcx, needle_fr)?;
+ let (_, span) = self.regioncx.get_argument_name_and_span_for_region(
+ &self.body,
+ &self.local_names,
argument_index,
);
@@ -437,7 +383,7 @@
// This counter value will already have been used, so this function will increment
// it so the next value will be used next and return the region name that would
// have been used.
- name: renctx.synthesize_region_name(),
+ name: self.synthesize_region_name(),
source: RegionNameSource::CannotMatchHirTy(span, type_name),
})
} else {
@@ -470,11 +416,9 @@
/// to highlighting that closest type instead.
fn give_name_if_we_can_match_hir_ty(
&self,
- tcx: TyCtxt<'tcx>,
needle_fr: RegionVid,
argument_ty: Ty<'tcx>,
argument_hir_ty: &hir::Ty<'_>,
- renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> =
&mut vec![(argument_ty, argument_hir_ty)];
@@ -492,10 +436,10 @@
hir::TyKind::Rptr(_lifetime, referent_hir_ty),
) => {
if region.to_region_vid() == needle_fr {
- let region_name = renctx.synthesize_region_name();
+ let region_name = self.synthesize_region_name();
// Just grab the first character, the `&`.
- let source_map = tcx.sess.source_map();
+ let source_map = self.infcx.tcx.sess.source_map();
let ampersand_span = source_map.start_point(hir_ty.span);
return Some(RegionName {
@@ -525,7 +469,6 @@
substs,
needle_fr,
last_segment,
- renctx,
search_stack,
) {
return Some(name);
@@ -570,7 +513,6 @@
substs: SubstsRef<'tcx>,
needle_fr: RegionVid,
last_segment: &'hir hir::PathSegment<'hir>,
- renctx: &mut RegionErrorNamingCtx,
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>,
) -> Option<RegionName> {
// Did the user give explicit arguments? (e.g., `Foo<..>`)
@@ -582,7 +524,7 @@
| hir::LifetimeName::Error
| hir::LifetimeName::Static
| hir::LifetimeName::Underscore => {
- let region_name = renctx.synthesize_region_name();
+ let region_name = self.synthesize_region_name();
let ampersand_span = lifetime.span;
Some(RegionName {
name: region_name,
@@ -663,16 +605,14 @@
/// | let x = Some(&22);
/// - fully elaborated type of `x` is `Option<&'1 u32>`
/// ```
- fn give_name_if_anonymous_region_appears_in_upvars(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- fr: RegionVid,
- renctx: &mut RegionErrorNamingCtx,
- ) -> Option<RegionName> {
- let upvar_index = self.get_upvar_index_for_region(mbcx.infcx.tcx, fr)?;
- let (upvar_name, upvar_span) =
- self.get_upvar_name_and_span_for_region(mbcx.infcx.tcx, &mbcx.upvars, upvar_index);
- let region_name = renctx.synthesize_region_name();
+ fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option<RegionName> {
+ let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?;
+ let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region(
+ self.infcx.tcx,
+ &self.upvars,
+ upvar_index,
+ );
+ let region_name = self.synthesize_region_name();
Some(RegionName {
name: region_name,
@@ -684,25 +624,20 @@
/// must be a closure since, in a free fn, such an argument would
/// have to either also appear in an argument (if using elision)
/// or be early bound (named, not in argument).
- fn give_name_if_anonymous_region_appears_in_output(
- &self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
- fr: RegionVid,
- renctx: &mut RegionErrorNamingCtx,
- ) -> Option<RegionName> {
- let tcx = mbcx.infcx.tcx;
+ fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option<RegionName> {
+ let tcx = self.infcx.tcx;
- let return_ty = self.universal_regions.unnormalized_output_ty;
+ let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty);
if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
return None;
}
let mut highlight = RegionHighlightMode::default();
- highlight.highlighting_region_vid(fr, renctx.counter);
- let type_name = mbcx.infcx.extract_type_name(&return_ty, Some(highlight)).0;
+ highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
+ let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0;
- let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir");
+ let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir");
let (return_span, mir_description) = match tcx.hir().get(mir_hir_id) {
hir::Node::Expr(hir::Expr {
@@ -719,14 +654,14 @@
kind: hir::ImplItemKind::Method(method_sig, _),
..
}) => (method_sig.decl.output.span(), ""),
- _ => (mbcx.body.span, ""),
+ _ => (self.body.span, ""),
};
Some(RegionName {
// This counter value will already have been used, so this function will increment it
// so the next value will be used next and return the region name that would have been
// used.
- name: renctx.synthesize_region_name(),
+ name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromOutput(
return_span,
mir_description.to_string(),
@@ -737,32 +672,30 @@
fn give_name_if_anonymous_region_appears_in_yield_ty(
&self,
- mbcx: &MirBorrowckCtxt<'_, 'tcx>,
fr: RegionVid,
- renctx: &mut RegionErrorNamingCtx,
) -> Option<RegionName> {
// Note: generators from `async fn` yield `()`, so we don't have to
// worry about them here.
- let yield_ty = self.universal_regions.yield_ty?;
+ let yield_ty = self.regioncx.universal_regions().yield_ty?;
debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,);
- let tcx = mbcx.infcx.tcx;
+ let tcx = self.infcx.tcx;
if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) {
return None;
}
let mut highlight = RegionHighlightMode::default();
- highlight.highlighting_region_vid(fr, renctx.counter);
- let type_name = mbcx.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
+ highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
+ let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0;
- let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir");
+ let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir");
let yield_span = match tcx.hir().get(mir_hir_id) {
hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(_, _, _, span, _), ..
}) => (tcx.sess.source_map().end_point(*span)),
- _ => mbcx.body.span,
+ _ => self.body.span,
};
debug!(
@@ -772,7 +705,7 @@
);
Some(RegionName {
- name: renctx.synthesize_region_name(),
+ name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
})
}
diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/src/librustc_mir/borrow_check/diagnostics/var_name.rs
index 9e3d2a7..5f3585c 100644
--- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/var_name.rs
@@ -16,7 +16,7 @@
fr: RegionVid,
) -> Option<(Option<Symbol>, Span)> {
debug!("get_var_name_and_span_for_region(fr={:?})", fr);
- assert!(self.universal_regions.is_universal_region(fr));
+ assert!(self.universal_regions().is_universal_region(fr));
debug!("get_var_name_and_span_for_region: attempting upvar");
self.get_upvar_index_for_region(tcx, fr)
@@ -35,7 +35,7 @@
/// Search the upvars (if any) to find one that references fr. Return its index.
crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option<usize> {
let upvar_index =
- self.universal_regions.defining_ty.upvar_tys(tcx).position(|upvar_ty| {
+ self.universal_regions().defining_ty.upvar_tys(tcx).position(|upvar_ty| {
debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
tcx.any_free_region_meets(&upvar_ty, |r| {
let r = r.to_region_vid();
@@ -44,7 +44,7 @@
})
})?;
- let upvar_ty = self.universal_regions.defining_ty.upvar_tys(tcx).nth(upvar_index);
+ let upvar_ty = self.universal_regions().defining_ty.upvar_tys(tcx).nth(upvar_index);
debug!(
"get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
@@ -85,9 +85,9 @@
tcx: TyCtxt<'tcx>,
fr: RegionVid,
) -> Option<usize> {
- let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
+ let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
let argument_index =
- self.universal_regions.unnormalized_input_tys.iter().skip(implicit_inputs).position(
+ self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position(
|arg_ty| {
debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty);
tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
@@ -96,7 +96,9 @@
debug!(
"get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
- fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
+ fr,
+ argument_index,
+ self.universal_regions().unnormalized_input_tys[argument_index],
);
Some(argument_index)
@@ -110,7 +112,7 @@
local_names: &IndexVec<Local, Option<Symbol>>,
argument_index: usize,
) -> (Option<Symbol>, Span) {
- let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
+ let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs();
let argument_local = Local::new(implicit_inputs + argument_index + 1);
debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 7b0a103..9092706 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1,6 +1,6 @@
//! This query borrow-checks the MIR to (further) ensure it is not broken.
-use rustc::infer::{opaque_types, InferCtxt};
+use rustc::infer::InferCtxt;
use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT;
use rustc::lint::builtin::UNUSED_MUT;
use rustc::mir::{
@@ -11,7 +11,8 @@
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, RegionVid, TyCtxt};
+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
@@ -21,6 +22,7 @@
use rustc_index::vec::IndexVec;
use smallvec::SmallVec;
+use std::cell::RefCell;
use std::collections::BTreeMap;
use std::mem;
use std::rc::Rc;
@@ -39,9 +41,7 @@
use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
use crate::transform::MirSource;
-use self::diagnostics::{
- AccessKind, OutlivesSuggestionBuilder, RegionErrorKind, RegionErrorNamingCtx, RegionErrors,
-};
+use self::diagnostics::{AccessKind, RegionName};
use self::flows::Flows;
use self::location::LocationTable;
use self::prefixes::PrefixSet;
@@ -285,13 +285,15 @@
move_error_reported: BTreeMap::new(),
uninitialized_error_reported: Default::default(),
errors_buffer,
- nonlexical_regioncx: regioncx,
+ regioncx,
used_mut: Default::default(),
used_mut_upvars: SmallVec::new(),
borrow_set,
dominators,
upvars,
local_names,
+ region_names: RefCell::default(),
+ next_region_name: RefCell::new(1),
};
// Compute and report region errors, if any.
@@ -476,10 +478,9 @@
/// If the function we're checking is a closure, then we'll need to report back the list of
/// mutable upvars that have been used. This field keeps track of them.
used_mut_upvars: SmallVec<[Field; 8]>,
- /// Non-lexical region inference context, if NLL is enabled. This
- /// contains the results from region inference and lets us e.g.
+ /// Region inference context. This contains the results from region inference and lets us e.g.
/// find out which CFG points are contained in each borrow region.
- nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
+ regioncx: Rc<RegionInferenceContext<'tcx>>,
/// The set of borrows extracted from the MIR
borrow_set: Rc<BorrowSet<'tcx>>,
@@ -492,6 +493,13 @@
/// Names of local (user) variables (extracted from `var_debug_info`).
local_names: IndexVec<Local, Option<Name>>,
+
+ /// Record the region names generated for each region in the given
+ /// MIR def so that we can reuse them later in help/error messages.
+ region_names: RefCell<FxHashMap<RegionVid, RegionName>>,
+
+ /// The counter for generating new region names.
+ next_region_name: RefCell<usize>,
}
// Check that:
@@ -631,7 +639,7 @@
debug!(
"visit_terminator_drop \
- loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}",
+ loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}",
loc, term, drop_place, drop_place_ty, span
);
@@ -1465,120 +1473,6 @@
// initial reservation.
}
}
-
- /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`.
- fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) {
- // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are
- // buffered in the `MirBorrowckCtxt`.
-
- // FIXME(mark-i-m): Would be great to get rid of the naming context.
- let mut region_naming = RegionErrorNamingCtx::new();
- let mut outlives_suggestion = OutlivesSuggestionBuilder::default();
-
- for nll_error in nll_errors.into_iter() {
- match nll_error {
- RegionErrorKind::TypeTestDoesNotLiveLongEnough { span, generic } => {
- // FIXME. We should handle this case better. It
- // indicates that we have e.g., some region variable
- // whose value is like `'a+'b` where `'a` and `'b` are
- // distinct unrelated univesal regions that are not
- // known to outlive one another. It'd be nice to have
- // some examples where this arises to decide how best
- // to report it; we could probably handle it by
- // iterating over the universal regions and reporting
- // an error that multiple bounds are required.
- self.infcx
- .tcx
- .sess
- .struct_span_err(span, &format!("`{}` does not live long enough", generic))
- .buffer(&mut self.errors_buffer);
- }
-
- RegionErrorKind::TypeTestGenericBoundError {
- span,
- generic,
- lower_bound_region,
- } => {
- let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
- self.infcx
- .construct_generic_bound_failure(
- region_scope_tree,
- span,
- None,
- generic,
- lower_bound_region,
- )
- .buffer(&mut self.errors_buffer);
- }
-
- RegionErrorKind::UnexpectedHiddenRegion {
- opaque_type_def_id,
- hidden_ty,
- member_region,
- } => {
- let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id);
- opaque_types::unexpected_hidden_region_diagnostic(
- self.infcx.tcx,
- Some(region_scope_tree),
- opaque_type_def_id,
- hidden_ty,
- member_region,
- )
- .buffer(&mut self.errors_buffer);
- }
-
- RegionErrorKind::BoundUniversalRegionError {
- longer_fr,
- fr_origin,
- error_region,
- } => {
- // Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
- let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span(
- &self.body,
- longer_fr,
- fr_origin,
- error_region,
- );
-
- // FIXME: improve this error message
- self.infcx
- .tcx
- .sess
- .struct_span_err(span, "higher-ranked subtype error")
- .buffer(&mut self.errors_buffer);
- }
-
- RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => {
- if is_reported {
- let db = self.nonlexical_regioncx.report_error(
- self,
- longer_fr,
- fr_origin,
- shorter_fr,
- &mut outlives_suggestion,
- &mut region_naming,
- );
-
- db.buffer(&mut self.errors_buffer);
- } else {
- // We only report the first error, so as not to overwhelm the user. See
- // `RegRegionErrorKind` docs.
- //
- // FIXME: currently we do nothing with these, but perhaps we can do better?
- // FIXME: try collecting these constraints on the outlives suggestion
- // builder. Does it make the suggestions any better?
- debug!(
- "Unreported region error: can't prove that {:?}: {:?}",
- longer_fr, shorter_fr
- );
- }
- }
- }
- }
-
- // Emit one outlives suggestions for each MIR def we borrowck
- outlives_suggestion.add_suggestion(self, &mut region_naming);
- }
}
impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
@@ -2225,7 +2119,7 @@
let upvar = &self.upvars[field.index()];
debug!(
"upvar.mutability={:?} local_mutation_is_allowed={:?} \
- place={:?}",
+ place={:?}",
upvar, is_local_mutation_allowed, place
);
match (upvar.mutability, is_local_mutation_allowed) {
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index 7d2384f..26d9cf2 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -1,3 +1,4 @@
+use std::collections::VecDeque;
use std::rc::Rc;
use rustc::infer::canonical::QueryOutlivesConstraint;
@@ -43,49 +44,48 @@
/// variables are identified by their index (`RegionVid`). The
/// definition contains information about where the region came
/// from as well as its final inferred value.
- pub(in crate::borrow_check) definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
+ definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
/// The liveness constraints added to each region. For most
/// regions, these start out empty and steadily grow, though for
/// each universally quantified region R they start out containing
/// the entire CFG and `end(R)`.
- pub(in crate::borrow_check) liveness_constraints: LivenessValues<RegionVid>,
+ liveness_constraints: LivenessValues<RegionVid>,
/// The outlives constraints computed by the type-check.
- pub(in crate::borrow_check) constraints: Rc<OutlivesConstraintSet>,
+ constraints: Rc<OutlivesConstraintSet>,
/// The constraint-set, but in graph form, making it easy to traverse
/// the constraints adjacent to a particular region. Used to construct
/// the SCC (see `constraint_sccs`) and for error reporting.
- pub(in crate::borrow_check) constraint_graph: Rc<NormalConstraintGraph>,
+ constraint_graph: Rc<NormalConstraintGraph>,
/// The SCC computed from `constraints` and the constraint
/// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
/// compute the values of each region.
- pub(in crate::borrow_check) constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
+ constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
/// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
/// exists if `B: A`. Computed lazilly.
- pub(in crate::borrow_check) rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
+ rev_constraint_graph: Option<Rc<VecGraph<ConstraintSccIndex>>>,
/// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
- pub(in crate::borrow_check) member_constraints:
- Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
+ member_constraints: Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
/// Records the member constraints that we applied to each scc.
/// This is useful for error reporting. Once constraint
/// propagation is done, this vector is sorted according to
/// `member_region_scc`.
- pub(in crate::borrow_check) member_constraints_applied: Vec<AppliedMemberConstraint>,
+ member_constraints_applied: Vec<AppliedMemberConstraint>,
/// Map closure bounds to a `Span` that should be used for error reporting.
- pub(in crate::borrow_check) closure_bounds_mapping:
+ closure_bounds_mapping:
FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
/// Contains the minimum universe of any variable within the same
/// SCC. We will ensure that no SCC contains values that are not
/// visible from this index.
- pub(in crate::borrow_check) scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
+ scc_universes: IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
/// Contains a "representative" from each SCC. This will be the
/// minimal RegionVid belonging to that universe. It is used as a
@@ -94,23 +94,23 @@
/// of its SCC and be sure that -- if they have the same repr --
/// they *must* be equal (though not having the same repr does not
/// mean they are unequal).
- pub(in crate::borrow_check) scc_representatives: IndexVec<ConstraintSccIndex, ty::RegionVid>,
+ scc_representatives: IndexVec<ConstraintSccIndex, ty::RegionVid>,
/// The final inferred values of the region variables; we compute
/// one value per SCC. To get the value for any given *region*,
/// you first find which scc it is a part of.
- pub(in crate::borrow_check) scc_values: RegionValues<ConstraintSccIndex>,
+ scc_values: RegionValues<ConstraintSccIndex>,
/// Type constraints that we check after solving.
- pub(in crate::borrow_check) type_tests: Vec<TypeTest<'tcx>>,
+ type_tests: Vec<TypeTest<'tcx>>,
/// Information about the universally quantified regions in scope
/// on this function.
- pub(in crate::borrow_check) universal_regions: Rc<UniversalRegions<'tcx>>,
+ universal_regions: Rc<UniversalRegions<'tcx>>,
/// Information about how the universally quantified regions in
/// scope on this function relate to one another.
- pub(in crate::borrow_check) universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
+ universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
}
/// Each time that `apply_member_constraint` is successful, it appends
@@ -225,6 +225,13 @@
Error,
}
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+enum Trace {
+ StartRegion,
+ FromOutlivesConstraint(OutlivesConstraint),
+ NotVisited,
+}
+
impl<'tcx> RegionInferenceContext<'tcx> {
/// Creates a new region inference context with a total of
/// `num_region_variables` valid inference variables; the first N
@@ -838,39 +845,22 @@
}
// Type-test failed. Report the error.
-
- // Try to convert the lower-bound region into something named we can print for the user.
- let lower_bound_region = self.to_error_region(type_test.lower_bound);
+ let erased_generic_kind = infcx.tcx.erase_regions(&type_test.generic_kind);
// Skip duplicate-ish errors.
- let type_test_span = type_test.locations.span(body);
- let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
- if !deduplicate_errors.insert((
+ if deduplicate_errors.insert((
erased_generic_kind,
- lower_bound_region,
+ type_test.lower_bound,
type_test.locations,
)) {
- continue;
- } else {
debug!(
"check_type_test: reporting error for erased_generic_kind={:?}, \
lower_bound_region={:?}, \
type_test.locations={:?}",
- erased_generic_kind, lower_bound_region, type_test.locations,
+ erased_generic_kind, type_test.lower_bound, type_test.locations,
);
- }
- if let Some(lower_bound_region) = lower_bound_region {
- errors_buffer.push(RegionErrorKind::TypeTestGenericBoundError {
- span: type_test_span,
- generic: type_test.generic_kind,
- lower_bound_region,
- });
- } else {
- errors_buffer.push(RegionErrorKind::TypeTestDoesNotLiveLongEnough {
- span: type_test_span,
- generic: type_test.generic_kind,
- });
+ errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() });
}
}
}
@@ -1355,7 +1345,7 @@
for (longer_fr, shorter_fr) in subset_errors.into_iter() {
debug!(
"check_polonius_subset_errors: subset_error longer_fr={:?},\
- shorter_fr={:?}",
+ shorter_fr={:?}",
longer_fr, shorter_fr
);
@@ -1572,23 +1562,9 @@
debug!("check_bound_universal_region: error_element = {:?}", error_element);
// Find the region that introduced this `error_element`.
- let error_region = match error_element {
- RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
- RegionElement::RootUniversalRegion(r) => r,
- RegionElement::PlaceholderRegion(error_placeholder) => self
- .definitions
- .iter_enumerated()
- .filter_map(|(r, definition)| match definition.origin {
- NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
- _ => None,
- })
- .next()
- .unwrap(),
- };
-
errors_buffer.push(RegionErrorKind::BoundUniversalRegionError {
longer_fr,
- error_region,
+ error_element,
fr_origin: NLLRegionVariableOrigin::Placeholder(placeholder),
});
}
@@ -1628,6 +1604,425 @@
});
}
}
+
+ /// We have a constraint `fr1: fr2` that is not satisfied, where
+ /// `fr2` represents some universal region. Here, `r` is some
+ /// region where we know that `fr1: r` and this function has the
+ /// job of determining whether `r` is "to blame" for the fact that
+ /// `fr1: fr2` is required.
+ ///
+ /// This is true under two conditions:
+ ///
+ /// - `r == fr2`
+ /// - `fr2` is `'static` and `r` is some placeholder in a universe
+ /// that cannot be named by `fr1`; in that case, we will require
+ /// that `fr1: 'static` because it is the only way to `fr1: r` to
+ /// be satisfied. (See `add_incompatible_universe`.)
+ crate fn provides_universal_region(
+ &self,
+ r: RegionVid,
+ fr1: RegionVid,
+ fr2: RegionVid,
+ ) -> bool {
+ debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2);
+ let result = {
+ r == fr2 || {
+ fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r)
+ }
+ };
+ debug!("provides_universal_region: result = {:?}", result);
+ result
+ }
+
+ /// If `r2` represents a placeholder region, then this returns
+ /// `true` if `r1` cannot name that placeholder in its
+ /// value; otherwise, returns `false`.
+ crate fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool {
+ debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2);
+
+ match self.definitions[r2].origin {
+ NLLRegionVariableOrigin::Placeholder(placeholder) => {
+ let universe1 = self.definitions[r1].universe;
+ debug!(
+ "cannot_name_value_of: universe1={:?} placeholder={:?}",
+ universe1, placeholder
+ );
+ universe1.cannot_name(placeholder.universe)
+ }
+
+ NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => {
+ false
+ }
+ }
+ }
+
+ crate fn retrieve_closure_constraint_info(
+ &self,
+ body: &Body<'tcx>,
+ constraint: &OutlivesConstraint,
+ ) -> (ConstraintCategory, bool, Span) {
+ let loc = match constraint.locations {
+ Locations::All(span) => return (constraint.category, false, span),
+ Locations::Single(loc) => loc,
+ };
+
+ let opt_span_category =
+ self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub));
+ opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or((
+ constraint.category,
+ false,
+ body.source_info(loc).span,
+ ))
+ }
+
+ /// Finds a good span to blame for the fact that `fr1` outlives `fr2`.
+ crate fn find_outlives_blame_span(
+ &self,
+ body: &Body<'tcx>,
+ fr1: RegionVid,
+ fr1_origin: NLLRegionVariableOrigin,
+ fr2: RegionVid,
+ ) -> (ConstraintCategory, Span) {
+ let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| {
+ self.provides_universal_region(r, fr1, fr2)
+ });
+ (category, span)
+ }
+
+ /// Walks the graph of constraints (where `'a: 'b` is considered
+ /// an edge `'a -> 'b`) to find all paths from `from_region` to
+ /// `to_region`. The paths are accumulated into the vector
+ /// `results`. The paths are stored as a series of
+ /// `ConstraintIndex` values -- in other words, a list of *edges*.
+ ///
+ /// Returns: a series of constraints as well as the region `R`
+ /// that passed the target test.
+ crate fn find_constraint_paths_between_regions(
+ &self,
+ from_region: RegionVid,
+ target_test: impl Fn(RegionVid) -> bool,
+ ) -> Option<(Vec<OutlivesConstraint>, RegionVid)> {
+ let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions);
+ context[from_region] = Trace::StartRegion;
+
+ // Use a deque so that we do a breadth-first search. We will
+ // stop at the first match, which ought to be the shortest
+ // path (fewest constraints).
+ let mut deque = VecDeque::new();
+ deque.push_back(from_region);
+
+ while let Some(r) = deque.pop_front() {
+ debug!(
+ "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}",
+ from_region,
+ r,
+ self.region_value_str(r),
+ );
+
+ // Check if we reached the region we were looking for. If so,
+ // we can reconstruct the path that led to it and return it.
+ if target_test(r) {
+ let mut result = vec![];
+ let mut p = r;
+ loop {
+ match context[p] {
+ Trace::NotVisited => {
+ bug!("found unvisited region {:?} on path to {:?}", p, r)
+ }
+
+ Trace::FromOutlivesConstraint(c) => {
+ result.push(c);
+ p = c.sup;
+ }
+
+ Trace::StartRegion => {
+ result.reverse();
+ return Some((result, r));
+ }
+ }
+ }
+ }
+
+ // Otherwise, walk over the outgoing constraints and
+ // enqueue any regions we find, keeping track of how we
+ // reached them.
+
+ // A constraint like `'r: 'x` can come from our constraint
+ // graph.
+ let fr_static = self.universal_regions.fr_static;
+ let outgoing_edges_from_graph =
+ self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static);
+
+ // Always inline this closure because it can be hot.
+ let mut handle_constraint = #[inline(always)]
+ |constraint: OutlivesConstraint| {
+ debug_assert_eq!(constraint.sup, r);
+ let sub_region = constraint.sub;
+ if let Trace::NotVisited = context[sub_region] {
+ context[sub_region] = Trace::FromOutlivesConstraint(constraint);
+ deque.push_back(sub_region);
+ }
+ };
+
+ // This loop can be hot.
+ for constraint in outgoing_edges_from_graph {
+ handle_constraint(constraint);
+ }
+
+ // Member constraints can also give rise to `'r: 'x` edges that
+ // were not part of the graph initially, so watch out for those.
+ // (But they are extremely rare; this loop is very cold.)
+ for constraint in self.applied_member_constraints(r) {
+ let p_c = &self.member_constraints[constraint.member_constraint_index];
+ let constraint = OutlivesConstraint {
+ sup: r,
+ sub: constraint.min_choice,
+ locations: Locations::All(p_c.definition_span),
+ category: ConstraintCategory::OpaqueType,
+ };
+ handle_constraint(constraint);
+ }
+ }
+
+ None
+ }
+
+ /// Finds some region R such that `fr1: R` and `R` is live at `elem`.
+ crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
+ debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem);
+ self.find_constraint_paths_between_regions(fr1, |r| {
+ // First look for some `r` such that `fr1: r` and `r` is live at `elem`
+ debug!(
+ "find_sub_region_live_at: liveness_constraints for {:?} are {:?}",
+ r,
+ self.liveness_constraints.region_value_str(r),
+ );
+ self.liveness_constraints.contains(r, elem)
+ })
+ .or_else(|| {
+ // If we fail to find that, we may find some `r` such that
+ // `fr1: r` and `r` is a placeholder from some universe
+ // `fr1` cannot name. This would force `fr1` to be
+ // `'static`.
+ self.find_constraint_paths_between_regions(fr1, |r| {
+ self.cannot_name_placeholder(fr1, r)
+ })
+ })
+ .or_else(|| {
+ // If we fail to find THAT, it may be that `fr1` is a
+ // placeholder that cannot "fit" into its SCC. In that
+ // case, there should be some `r` where `fr1: r`, both
+ // `fr1` and `r` are in the same SCC, and `fr1` is a
+ // placeholder that `r` cannot name. We can blame that
+ // edge.
+ self.find_constraint_paths_between_regions(fr1, |r| {
+ self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r)
+ && self.cannot_name_placeholder(r, fr1)
+ })
+ })
+ .map(|(_path, r)| r)
+ .unwrap()
+ }
+
+ /// Get the region outlived by `longer_fr` and live at `element`.
+ crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid {
+ match element {
+ RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
+ RegionElement::RootUniversalRegion(r) => r,
+ RegionElement::PlaceholderRegion(error_placeholder) => self
+ .definitions
+ .iter_enumerated()
+ .filter_map(|(r, definition)| match definition.origin {
+ NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
+ _ => None,
+ })
+ .next()
+ .unwrap(),
+ }
+ }
+
+ /// Get the region definition of `r`.
+ crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> {
+ &self.definitions[r]
+ }
+
+ /// Check if the SCC of `r` contains `upper`.
+ crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool {
+ let r_scc = self.constraint_sccs.scc(r);
+ self.scc_values.contains(r_scc, upper)
+ }
+
+ crate fn universal_regions(&self) -> &UniversalRegions<'tcx> {
+ self.universal_regions.as_ref()
+ }
+
+ /// Tries to find the best constraint to blame for the fact that
+ /// `R: from_region`, where `R` is some region that meets
+ /// `target_test`. This works by following the constraint graph,
+ /// creating a constraint path that forces `R` to outlive
+ /// `from_region`, and then finding the best choices within that
+ /// path to blame.
+ crate fn best_blame_constraint(
+ &self,
+ body: &Body<'tcx>,
+ from_region: RegionVid,
+ from_region_origin: NLLRegionVariableOrigin,
+ target_test: impl Fn(RegionVid) -> bool,
+ ) -> (ConstraintCategory, bool, Span) {
+ debug!(
+ "best_blame_constraint(from_region={:?}, from_region_origin={:?})",
+ from_region, from_region_origin
+ );
+
+ // Find all paths
+ let (path, target_region) =
+ self.find_constraint_paths_between_regions(from_region, target_test).unwrap();
+ debug!(
+ "best_blame_constraint: path={:#?}",
+ path.iter()
+ .map(|&c| format!(
+ "{:?} ({:?}: {:?})",
+ c,
+ self.constraint_sccs.scc(c.sup),
+ self.constraint_sccs.scc(c.sub),
+ ))
+ .collect::<Vec<_>>()
+ );
+
+ // Classify each of the constraints along the path.
+ let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path
+ .iter()
+ .map(|constraint| {
+ if constraint.category == ConstraintCategory::ClosureBounds {
+ self.retrieve_closure_constraint_info(body, &constraint)
+ } else {
+ (constraint.category, false, constraint.locations.span(body))
+ }
+ })
+ .collect();
+ debug!("best_blame_constraint: categorized_path={:#?}", categorized_path);
+
+ // To find the best span to cite, we first try to look for the
+ // final constraint that is interesting and where the `sup` is
+ // not unified with the ultimate target region. The reason
+ // for this is that we have a chain of constraints that lead
+ // from the source to the target region, something like:
+ //
+ // '0: '1 ('0 is the source)
+ // '1: '2
+ // '2: '3
+ // '3: '4
+ // '4: '5
+ // '5: '6 ('6 is the target)
+ //
+ // Some of those regions are unified with `'6` (in the same
+ // SCC). We want to screen those out. After that point, the
+ // "closest" constraint we have to the end is going to be the
+ // most likely to be the point where the value escapes -- but
+ // we still want to screen for an "interesting" point to
+ // highlight (e.g., a call site or something).
+ let target_scc = self.constraint_sccs.scc(target_region);
+ let mut range = 0..path.len();
+
+ // As noted above, when reporting an error, there is typically a chain of constraints
+ // leading from some "source" region which must outlive some "target" region.
+ // In most cases, we prefer to "blame" the constraints closer to the target --
+ // but there is one exception. When constraints arise from higher-ranked subtyping,
+ // we generally prefer to blame the source value,
+ // as the "target" in this case tends to be some type annotation that the user gave.
+ // Therefore, if we find that the region origin is some instantiation
+ // of a higher-ranked region, we start our search from the "source" point
+ // rather than the "target", and we also tweak a few other things.
+ //
+ // An example might be this bit of Rust code:
+ //
+ // ```rust
+ // let x: fn(&'static ()) = |_| {};
+ // let y: for<'a> fn(&'a ()) = x;
+ // ```
+ //
+ // In MIR, this will be converted into a combination of assignments and type ascriptions.
+ // In particular, the 'static is imposed through a type ascription:
+ //
+ // ```rust
+ // x = ...;
+ // AscribeUserType(x, fn(&'static ())
+ // y = x;
+ // ```
+ //
+ // We wind up ultimately with constraints like
+ //
+ // ```rust
+ // !a: 'temp1 // from the `y = x` statement
+ // 'temp1: 'temp2
+ // 'temp2: 'static // from the AscribeUserType
+ // ```
+ //
+ // and here we prefer to blame the source (the y = x statement).
+ let blame_source = match from_region_origin {
+ NLLRegionVariableOrigin::FreeRegion
+ | NLLRegionVariableOrigin::Existential { from_forall: false } => true,
+ NLLRegionVariableOrigin::Placeholder(_)
+ | NLLRegionVariableOrigin::Existential { from_forall: true } => false,
+ };
+
+ let find_region = |i: &usize| {
+ let constraint = path[*i];
+
+ let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
+
+ if blame_source {
+ match categorized_path[*i].0 {
+ ConstraintCategory::OpaqueType
+ | ConstraintCategory::Boring
+ | ConstraintCategory::BoringNoLocation
+ | ConstraintCategory::Internal => false,
+ ConstraintCategory::TypeAnnotation
+ | ConstraintCategory::Return
+ | ConstraintCategory::Yield => true,
+ _ => constraint_sup_scc != target_scc,
+ }
+ } else {
+ match categorized_path[*i].0 {
+ ConstraintCategory::OpaqueType
+ | ConstraintCategory::Boring
+ | ConstraintCategory::BoringNoLocation
+ | ConstraintCategory::Internal => false,
+ _ => true,
+ }
+ }
+ };
+
+ let best_choice =
+ if blame_source { range.rev().find(find_region) } else { range.find(find_region) };
+
+ debug!(
+ "best_blame_constraint: best_choice={:?} blame_source={}",
+ best_choice, blame_source
+ );
+
+ if let Some(i) = best_choice {
+ if let Some(next) = categorized_path.get(i + 1) {
+ if categorized_path[i].0 == ConstraintCategory::Return
+ && next.0 == ConstraintCategory::OpaqueType
+ {
+ // The return expression is being influenced by the return type being
+ // impl Trait, point at the return type and not the return expr.
+ return *next;
+ }
+ }
+ return categorized_path[i];
+ }
+
+ // If that search fails, that is.. unusual. Maybe everything
+ // is in the same SCC or something. In that case, find what
+ // appears to be the most interesting point to report to the
+ // user via an even more ad-hoc guess.
+ categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
+ debug!("`: sorted_path={:#?}", categorized_path);
+
+ *categorized_path.first().unwrap()
+ }
}
impl<'tcx> RegionDefinition<'tcx> {
diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs
index e17efeb..3126d44 100644
--- a/src/librustc_mir/borrow_check/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/region_infer/values.rs
@@ -114,7 +114,7 @@
/// An individual element in a region value -- the value of a
/// particular region variable consists of a set of these elements.
-#[derive(Debug)]
+#[derive(Debug, Clone)]
crate enum RegionElement {
/// A point in the control-flow graph.
Location(Location),
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index 947bbef..c9a1c46 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -27,12 +27,12 @@
TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
use rustc_span::{Span, DUMMY_SP};
+use syntax::ast;
use crate::dataflow::move_paths::MoveData;
use crate::dataflow::FlowAtLocation;
@@ -1931,12 +1931,15 @@
traits::ObligationCauseCode::RepeatVec(should_suggest),
),
self.param_env,
- ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {
- trait_ref: ty::TraitRef::new(
- self.tcx().lang_items().copy_trait().unwrap(),
- tcx.mk_substs_trait(ty, &[]),
- ),
- })),
+ ty::Predicate::Trait(
+ ty::Binder::bind(ty::TraitPredicate {
+ trait_ref: ty::TraitRef::new(
+ self.tcx().lang_items().copy_trait().unwrap(),
+ tcx.mk_substs_trait(ty, &[]),
+ ),
+ }),
+ ast::Constness::NotConst,
+ ),
),
&traits::SelectionError::Unimplemented,
false,
@@ -2574,7 +2577,10 @@
category: ConstraintCategory,
) {
self.prove_predicates(
- Some(ty::Predicate::Trait(trait_ref.to_poly_trait_ref().to_poly_trait_predicate())),
+ Some(ty::Predicate::Trait(
+ trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
+ ast::Constness::NotConst,
+ )),
locations,
category,
);
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 1c25b26..5e42ba3 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -7,7 +7,7 @@
#![feature(nll)]
#![feature(in_band_lifetimes)]
#![feature(inner_deref)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 8537718..f4611c3 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -954,7 +954,7 @@
// Nothing to do, just keep recursing.
}
- hir::ItemKind::Impl(..) => {
+ hir::ItemKind::Impl { .. } => {
if self.mode == MonoItemCollectionMode::Eager {
create_mono_items_for_default_impls(self.tcx, item, self.output);
}
@@ -1098,7 +1098,7 @@
output: &mut Vec<MonoItem<'tcx>>,
) {
match item.kind {
- hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => {
+ hir::ItemKind::Impl { ref generics, ref items, .. } => {
for param in generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
@@ -1119,7 +1119,7 @@
let param_env = ty::ParamEnv::reveal_all();
let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
let overridden_methods: FxHashSet<_> =
- impl_item_refs.iter().map(|iiref| iiref.ident.modern()).collect();
+ items.iter().map(|iiref| iiref.ident.modern()).collect();
for method in tcx.provided_trait_methods(trait_ref.def_id) {
if overridden_methods.contains(&method.ident.modern()) {
continue;
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 01cecdd..b846161 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -31,9 +31,13 @@
let mut result = match instance {
ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
- ty::InstanceDef::VtableShim(def_id) => {
- build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None)
- }
+ ty::InstanceDef::VtableShim(def_id) => build_call_shim(
+ tcx,
+ instance,
+ Some(Adjustment::DerefMove),
+ CallKind::Direct(def_id),
+ None,
+ ),
ty::InstanceDef::FnPtrShim(def_id, ty) => {
let trait_ = tcx.trait_of_item(def_id).unwrap();
let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
@@ -50,7 +54,7 @@
let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
let arg_tys = sig.inputs();
- build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys))
+ build_call_shim(tcx, instance, Some(adjustment), CallKind::Indirect, Some(arg_tys))
}
// We are generating a call back to our def-id, which the
// codegen backend knows to turn to an actual call, be it
@@ -58,7 +62,7 @@
// indirect calls must be codegen'd differently than direct ones
// (such as `#[track_caller]`).
ty::InstanceDef::ReifyShim(def_id) => {
- build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None)
+ build_call_shim(tcx, instance, None, CallKind::Direct(def_id), None)
}
ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
@@ -68,7 +72,13 @@
.unwrap()
.def_id;
- build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None)
+ build_call_shim(
+ tcx,
+ instance,
+ Some(Adjustment::RefMut),
+ CallKind::Direct(call_mut),
+ None,
+ )
}
ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
ty::InstanceDef::CloneShim(def_id, ty) => {
@@ -648,7 +658,7 @@
fn build_call_shim<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
- rcvr_adjustment: Adjustment,
+ rcvr_adjustment: Option<Adjustment>,
call_kind: CallKind,
untuple_args: Option<&[Ty<'tcx>]>,
) -> BodyAndCache<'tcx> {
@@ -680,14 +690,16 @@
let mut local_decls = local_decls_for_sig(&sig, span);
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
- let rcvr_arg = Local::new(1 + 0);
- let rcvr_l = Place::from(rcvr_arg);
+ let rcvr_place = || {
+ assert!(rcvr_adjustment.is_some());
+ Place::from(Local::new(1 + 0))
+ };
let mut statements = vec![];
- let rcvr = match rcvr_adjustment {
- Adjustment::Identity => Operand::Move(rcvr_l),
- Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
- Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_l)),
+ let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
+ Adjustment::Identity => Operand::Move(rcvr_place()),
+ Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_place())),
+ Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
Adjustment::RefMut => {
// let rcvr = &mut rcvr;
let ref_rcvr = local_decls.push(temp_decl(
@@ -703,15 +715,15 @@
source_info,
kind: StatementKind::Assign(box (
Place::from(ref_rcvr),
- Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l),
+ Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
)),
});
Operand::Move(Place::from(ref_rcvr))
}
- };
+ });
let (callee, mut args) = match call_kind {
- CallKind::Indirect => (rcvr, vec![]),
+ CallKind::Indirect => (rcvr.unwrap(), vec![]),
CallKind::Direct(def_id) => {
let ty = tcx.type_of(def_id);
(
@@ -720,21 +732,35 @@
user_ty: None,
literal: ty::Const::zero_sized(tcx, ty),
}),
- vec![rcvr],
+ rcvr.into_iter().collect::<Vec<_>>(),
)
}
};
- if let Some(untuple_args) = untuple_args {
- args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
- let arg_place = Place::from(Local::new(1 + 1));
- Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
- }));
- } else {
- args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
+ let mut arg_range = 0..sig.inputs().len();
+
+ // Take the `self` ("receiver") argument out of the range (it's adjusted above).
+ if rcvr_adjustment.is_some() {
+ arg_range.start += 1;
}
- let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
+ // Take the last argument, if we need to untuple it (handled below).
+ if untuple_args.is_some() {
+ arg_range.end -= 1;
+ }
+
+ // Pass all of the non-special arguments directly.
+ args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
+
+ // Untuple the last argument, if we have to.
+ if let Some(untuple_args) = untuple_args {
+ let tuple_arg = Local::new(1 + (sig.inputs().len() - 1));
+ args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
+ Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity))
+ }));
+ }
+
+ let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
let mut blocks = IndexVec::with_capacity(n_blocks);
let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
blocks.push(BasicBlockData {
@@ -752,7 +778,7 @@
func: callee,
args,
destination: Some((Place::return_place(), BasicBlock::new(1))),
- cleanup: if let Adjustment::RefMut = rcvr_adjustment {
+ cleanup: if let Some(Adjustment::RefMut) = rcvr_adjustment {
Some(BasicBlock::new(3))
} else {
None
@@ -762,13 +788,13 @@
false,
);
- if let Adjustment::RefMut = rcvr_adjustment {
+ if let Some(Adjustment::RefMut) = rcvr_adjustment {
// BB #1 - drop for Self
block(
&mut blocks,
vec![],
TerminatorKind::Drop {
- location: Place::from(rcvr_arg),
+ location: rcvr_place(),
target: BasicBlock::new(2),
unwind: None,
},
@@ -777,13 +803,13 @@
}
// BB #1/#2 - return
block(&mut blocks, vec![], TerminatorKind::Return, false);
- if let Adjustment::RefMut = rcvr_adjustment {
+ if let Some(Adjustment::RefMut) = rcvr_adjustment {
// BB #3 - drop if closure panics
block(
&mut blocks,
vec![],
TerminatorKind::Drop {
- location: Place::from(rcvr_arg),
+ location: rcvr_place(),
target: BasicBlock::new(4),
unwind: None,
},
diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs
index edb4eb4..3263905 100644
--- a/src/librustc_mir/transform/check_consts/ops.rs
+++ b/src/librustc_mir/transform/check_consts/ops.rs
@@ -10,8 +10,6 @@
use super::{ConstKind, Item};
-use rustc_error_codes::*;
-
/// An operation that is not *always* allowed in a const context.
pub trait NonConstOp: std::fmt::Debug {
/// Whether this operation can be evaluated by miri.
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 10a4b7d..1d5fb33 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -6,7 +6,6 @@
use rustc::traits::{self, TraitEngine};
use rustc::ty::cast::CastTy;
use rustc::ty::{self, TyCtxt};
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir::{def_id::DefId, HirId};
use rustc_index::bit_set::BitSet;
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 072cdf2..4e94354 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -18,8 +18,6 @@
use crate::const_eval::{is_const_fn, is_min_const_fn};
use crate::util;
-use rustc_error_codes::*;
-
pub struct UnsafetyChecker<'a, 'tcx> {
body: &'a Body<'tcx>,
const_context: bool,
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 9d5dbe3..d645f6c 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -14,7 +14,7 @@
SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
UnOp, RETURN_PLACE,
};
-use rustc::traits::TraitQueryMode;
+use rustc::traits;
use rustc::ty::layout::{
HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout,
};
@@ -90,28 +90,28 @@
// If there are unsatisfiable where clauses, then all bets are
// off, and we just give up.
//
- // Note that we use TraitQueryMode::Canonical here, which causes
- // us to treat overflow like any other error. This is because we
- // are "speculatively" evaluating this item with the default substs.
- // While this usually succeeds, it may fail with tricky impls
- // (e.g. the typenum crate). Const-propagation is fundamentally
- // "best-effort", and does not affect correctness in any way.
- // Therefore, it's perfectly fine to just "give up" if we're
- // unable to check the bounds with the default substs.
+ // We manually filter the predicates, skipping anything that's not
+ // "global". We are in a potentially generic context
+ // (e.g. we are evaluating a function without substituting generic
+ // parameters, so this filtering serves two purposes:
//
- // False negatives (failing to run const-prop on something when we actually
- // could) are fine. However, false positives (running const-prop on
- // an item with unsatisfiable bounds) can lead to us generating invalid
- // MIR.
- if !tcx.substitute_normalize_and_test_predicates((
- source.def_id(),
- InternalSubsts::identity_for_item(tcx, source.def_id()),
- TraitQueryMode::Canonical,
- )) {
- trace!(
- "ConstProp skipped for item with unsatisfiable predicates: {:?}",
- source.def_id()
- );
+ // 1. We skip evaluating any predicates that we would
+ // never be able prove are unsatisfiable (e.g. `<T as Foo>`
+ // 2. We avoid trying to normalize predicates involving generic
+ // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
+ // the normalization code (leading to cycle errors), since
+ // it's usually never invoked in this way.
+ let predicates = tcx
+ .predicates_of(source.def_id())
+ .predicates
+ .iter()
+ .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
+ .collect();
+ if !traits::normalize_and_test_predicates(
+ tcx,
+ traits::elaborate_predicates(tcx, predicates).collect(),
+ ) {
+ trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", source.def_id());
return;
}
@@ -288,8 +288,6 @@
}
}
-type Const<'tcx> = OpTy<'tcx>;
-
/// Finds optimization opportunities on the MIR.
struct ConstPropagator<'mir, 'tcx> {
ecx: InterpCx<'mir, 'tcx, ConstPropMachine>,
@@ -387,7 +385,7 @@
}
}
- fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
+ fn get_const(&self, local: Local) -> Option<OpTy<'tcx>> {
if local == RETURN_PLACE {
// Try to read the return place as an immediate so that if it is representable as a
// scalar, we can handle it as such, but otherwise, just return the value as is.
@@ -466,11 +464,7 @@
r
}
- fn eval_constant(
- &mut self,
- c: &Constant<'tcx>,
- source_info: SourceInfo,
- ) -> Option<Const<'tcx>> {
+ fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
self.ecx.tcx.span = c.span;
// FIXME we need to revisit this for #67176
@@ -510,12 +504,12 @@
}
}
- fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
+ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
trace!("eval_place(place={:?})", place);
self.use_ecx(source_info, |this| this.ecx.eval_place_to_op(place, None))
}
- fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
+ fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
match *op {
Operand::Constant(ref c) => self.eval_constant(c, source_info),
Operand::Move(ref place) | Operand::Copy(ref place) => {
@@ -636,28 +630,11 @@
self.check_binary_op(*op, left, right, source_info, place_layout, overflow_check)?;
}
- // Work around: avoid ICE in miri. FIXME(wesleywiser)
- // The Miri engine ICEs when taking a reference to an uninitialized unsized
- // local. There's nothing it can do here: taking a reference needs an allocation
- // which needs to know the size. Normally that's okay as during execution
- // (e.g. for CTFE) it can never happen. But here in const_prop
- // unknown data is uninitialized, so if e.g. a function argument is unsized
- // and has a reference taken, we get an ICE.
+ // Do not try creating references (#67862)
Rvalue::Ref(_, _, place_ref) => {
- trace!("checking Ref({:?})", place_ref);
+ trace!("skipping Ref({:?})", place_ref);
- if let Some(local) = place_ref.as_local() {
- let alive = if let LocalValue::Live(_) = self.ecx.frame().locals[local].value {
- true
- } else {
- false
- };
-
- if !alive {
- trace!("skipping Ref({:?}) to uninitialized local", place);
- return None;
- }
- }
+ return None;
}
_ => {}
@@ -681,7 +658,7 @@
fn replace_with_const(
&mut self,
rval: &mut Rvalue<'tcx>,
- value: Const<'tcx>,
+ value: OpTy<'tcx>,
source_info: SourceInfo,
) {
trace!("attepting to replace {:?} with {:?}", rval, value);
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 7034556..b047e53 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -5,7 +5,7 @@
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use std::borrow::Cow;
-use syntax::attr;
+use syntax::{ast, attr};
type McfResult = Result<(), (Span, Cow<'static, str>)>;
@@ -27,12 +27,19 @@
bug!("closure kind predicate on function: {:#?}", predicate)
}
Predicate::Subtype(_) => bug!("subtype predicate on function: {:#?}", predicate),
- Predicate::Trait(pred) => {
+ Predicate::Trait(pred, constness) => {
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
continue;
}
match pred.skip_binder().self_ty().kind {
ty::Param(ref p) => {
+ // Allow `T: ?const Trait`
+ if *constness == ast::Constness::NotConst
+ && feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out)
+ {
+ continue;
+ }
+
let generics = tcx.generics_of(current);
let def = generics.type_param(p, tcx);
let span = tcx.def_span(def.def_id);
@@ -309,7 +316,11 @@
) -> McfResult {
let span = terminator.source_info.span;
match &terminator.kind {
- TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume => Ok(()),
+ TerminatorKind::FalseEdges { .. }
+ | TerminatorKind::FalseUnwind { .. }
+ | TerminatorKind::Goto { .. }
+ | TerminatorKind::Return
+ | TerminatorKind::Resume => Ok(()),
TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body),
TerminatorKind::DropAndReplace { location, value, .. } => {
@@ -317,13 +328,10 @@
check_operand(tcx, value, span, def_id, body)
}
- TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. }
- if !feature_allowed(tcx, def_id, sym::const_if_match) =>
- {
+ TerminatorKind::SwitchInt { .. } if !feature_allowed(tcx, def_id, sym::const_if_match) => {
Err((span, "loops and conditional expressions are not stable in const fn".into()))
}
- TerminatorKind::FalseEdges { .. } => Ok(()),
TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => {
check_operand(tcx, discr, span, def_id, body)
}
@@ -367,13 +375,5 @@
TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => {
check_operand(tcx, cond, span, def_id, body)
}
-
- TerminatorKind::FalseUnwind { .. } if feature_allowed(tcx, def_id, sym::const_loop) => {
- Ok(())
- }
-
- TerminatorKind::FalseUnwind { .. } => {
- Err((span, "loops are not allowed in const fn".into()))
- }
}
}
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index c275eec..d8ee059 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -1,5 +1,4 @@
use rustc::ty::{self, Ty, TyCtxt};
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
use rustc_span::{MultiSpan, Span};
diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml
index 79c7303..f0d1d4c 100644
--- a/src/librustc_mir_build/Cargo.toml
+++ b/src/librustc_mir_build/Cargo.toml
@@ -25,4 +25,3 @@
rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index 97e7181..d6786ea 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -411,18 +411,21 @@
let def_id = cx.tcx.hir().local_def_id(count.hir_id);
let substs = InternalSubsts::identity_for_item(cx.tcx, def_id);
let span = cx.tcx.def_span(def_id);
- let count =
- match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, None, Some(span)) {
- Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env),
- Err(ErrorHandled::Reported) => 0,
- Err(ErrorHandled::TooGeneric) => {
- let span = cx.tcx.def_span(def_id);
- cx.tcx
- .sess
- .span_err(span, "array lengths can't depend on generic parameters");
- 0
- }
- };
+ let count = match cx.tcx.const_eval_resolve(
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ substs,
+ None,
+ Some(span),
+ ) {
+ Ok(cv) => cv.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()),
+ Err(ErrorHandled::Reported) => 0,
+ Err(ErrorHandled::TooGeneric) => {
+ let span = cx.tcx.def_span(def_id);
+ cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
+ 0
+ }
+ };
ExprKind::Repeat { value: v.to_ref(), count }
}
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index 84d57a8..eac52da 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -9,7 +9,6 @@
use rustc::session::parse::feature_err;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
-use rustc_error_codes::*;
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::*;
diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs
index 205e25f..2657050 100644
--- a/src/librustc_mir_build/hair/pattern/mod.rs
+++ b/src/librustc_mir_build/hair/pattern/mod.rs
@@ -28,8 +28,6 @@
use std::cmp::Ordering;
use std::fmt;
-use rustc_error_codes::*;
-
#[derive(Clone, Debug)]
crate enum PatternError {
AssocConstInPattern(Span),
diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs
index 5a17f36..42292d6 100644
--- a/src/librustc_mir_build/lib.rs
+++ b/src/librustc_mir_build/lib.rs
@@ -5,7 +5,7 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(crate_visibility_modifier)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(bool_to_option)]
#![recursion_limit = "256"]
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
index aa159c5..8071bc6 100644
--- a/src/librustc_parse/Cargo.toml
+++ b/src/librustc_parse/Cargo.toml
@@ -16,7 +16,6 @@
rustc_feature = { path = "../librustc_feature" }
rustc_lexer = { path = "../librustc_lexer" }
rustc_errors = { path = "../librustc_errors" }
-rustc_error_codes = { path = "../librustc_error_codes" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
rustc_session = { path = "../librustc_session" }
rustc_span = { path = "../librustc_span" }
diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs
index 8467acc..bf696fa 100644
--- a/src/librustc_parse/config.rs
+++ b/src/librustc_parse/config.rs
@@ -10,7 +10,6 @@
use crate::{parse_in, validate_attr};
use rustc_data_structures::fx::FxHashMap;
-use rustc_error_codes::*;
use rustc_errors::{error_code, struct_span_err, Applicability, Handler};
use rustc_feature::{Feature, Features, State as FeatureState};
use rustc_feature::{
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index 9227e96..08f4f21 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -2,7 +2,7 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
use syntax::ast;
use syntax::print::pprust;
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 6a18c63..80bc5c1 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1,7 +1,6 @@
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};
use rustc_data_structures::fx::FxHashSet;
-use rustc_error_codes::*;
use rustc_errors::{pluralize, struct_span_err};
use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult};
use rustc_span::source_map::Spanned;
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index d4756df..31db7fc 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -3,9 +3,8 @@
use crate::maybe_whole;
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey};
-use rustc_span::source_map::{self, respan, Span, Spanned};
+use rustc_span::source_map::{self, respan, Span};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::BytePos;
use syntax::ast::{self, AttrKind, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID};
@@ -566,9 +565,9 @@
let constness = if self.eat_keyword(kw::Const) {
let span = self.prev_span;
self.sess.gated_spans.gate(sym::const_trait_impl, span);
- Some(respan(span, Constness::Const))
+ Constness::Const
} else {
- None
+ Constness::NotConst
};
// Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
@@ -631,37 +630,31 @@
err_path(ty_first.span)
}
};
- let constness = constness.map(|c| c.node);
- let trait_ref = TraitRef { path, constness, ref_id: ty_first.id };
+ let trait_ref = TraitRef { path, ref_id: ty_first.id };
- ItemKind::Impl(
+ ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
generics,
- Some(trait_ref),
- ty_second,
- impl_items,
- )
+ of_trait: Some(trait_ref),
+ self_ty: ty_second,
+ items: impl_items,
+ }
}
None => {
- // Reject `impl const Type {}` here
- if let Some(Spanned { node: Constness::Const, span }) = constness {
- self.struct_span_err(span, "`const` cannot modify an inherent impl")
- .help("only a trait impl can be `const`")
- .emit();
- }
-
// impl Type
- ItemKind::Impl(
+ ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
generics,
- None,
- ty_first,
- impl_items,
- )
+ of_trait: None,
+ self_ty: ty_first,
+ items: impl_items,
+ }
}
};
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 1368230..4a90163 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -33,8 +33,6 @@
use std::path::PathBuf;
use std::{cmp, mem, slice};
-use rustc_error_codes::*;
-
bitflags::bitflags! {
struct Restrictions: u8 {
const STMT_EXPR = 1 << 0;
diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index 549acf6..edb9044 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -659,7 +659,6 @@
}
pub(super) fn error_inclusive_range_with_no_end(&self, span: Span) {
- use rustc_error_codes::E0586;
struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end")
.span_suggestion_short(
span,
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index 065a3b1..a4cc9fa 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -3,7 +3,6 @@
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
-use rustc_error_codes::*;
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym};
@@ -27,10 +26,12 @@
}
impl BoundModifiers {
- fn trait_bound_modifier(&self) -> TraitBoundModifier {
- match self.maybe {
- Some(_) => TraitBoundModifier::Maybe,
- None => TraitBoundModifier::None,
+ fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
+ match (self.maybe, self.maybe_const) {
+ (None, None) => TraitBoundModifier::None,
+ (Some(_), None) => TraitBoundModifier::Maybe,
+ (None, Some(_)) => TraitBoundModifier::MaybeConst,
+ (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
}
}
}
@@ -215,7 +216,7 @@
) -> PResult<'a, TyKind> {
assert_ne!(self.token, token::Question);
- let poly_trait_ref = PolyTraitRef::new(generic_params, path, None, lo.to(self.prev_span));
+ let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
if parse_plus {
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
@@ -557,9 +558,9 @@
self.expect(&token::CloseDelim(token::Paren))?;
}
- let constness = modifiers.maybe_const.map(|_| ast::Constness::NotConst);
- let poly_trait = PolyTraitRef::new(lifetime_defs, path, constness, lo.to(self.prev_span));
- Ok(GenericBound::Trait(poly_trait, modifiers.trait_bound_modifier()))
+ let modifier = modifiers.to_trait_bound_modifier();
+ let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
+ Ok(GenericBound::Trait(poly_trait, modifier))
}
/// Optionally parses `for<$generic_params>`.
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 639d863..338808f 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -20,4 +20,3 @@
rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs
index 39ba2fb..faa85f6 100644
--- a/src/librustc_passes/check_const.rs
+++ b/src/librustc_passes/check_const.rs
@@ -12,7 +12,6 @@
use rustc::session::parse::feature_err;
use rustc::ty::query::Providers;
use rustc::ty::TyCtxt;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index f2778b2..2ff9d74 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -405,10 +405,10 @@
}
}
}
- hir::ItemKind::Impl(.., ref opt_trait, _, impl_item_refs) => {
- for impl_item_ref in impl_item_refs {
+ hir::ItemKind::Impl { ref of_trait, items, .. } => {
+ for impl_item_ref in items {
let impl_item = self.krate.impl_item(impl_item_ref.id);
- if opt_trait.is_some()
+ if of_trait.is_some()
|| has_allow_dead_code_or_lang_attr(
self.tcx,
impl_item.hir_id,
@@ -586,7 +586,7 @@
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::Trait(..)
- | hir::ItemKind::Impl(..) => {
+ | hir::ItemKind::Impl { .. } => {
// FIXME(66095): Because item.span is annotated with things
// like expansion data, and ident.span isn't, we use the
// def_span method if it's part of a macro invocation
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index 028d7c6..d36114f 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -12,8 +12,6 @@
use syntax::attr;
use syntax::entry::EntryPointType;
-use rustc_error_codes::*;
-
struct EntryContext<'a, 'tcx> {
session: &'a Session,
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 2c26707..7821990 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -11,8 +11,6 @@
use rustc_span::{sym, Span};
use rustc_target::spec::abi::Abi::RustIntrinsic;
-use rustc_error_codes::*;
-
fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) {
tcx.hir().visit_item_likes_in_module(module_def_id, &mut ItemVisitor { tcx }.as_deep_visitor());
}
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 65eb07b..d746f09 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -7,7 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(in_band_lifetimes)]
#![feature(nll)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs
index 8ae7291..2e306a1 100644
--- a/src/librustc_passes/lib_features.rs
+++ b/src/librustc_passes/lib_features.rs
@@ -15,8 +15,6 @@
use rustc_span::{sym, Span};
use syntax::ast::{Attribute, MetaItem, MetaItemKind};
-use rustc_error_codes::*;
-
fn new_lib_features() -> LibFeatures {
LibFeatures { stable: Default::default(), unstable: Default::default() }
}
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 5ad5795..69d6b38 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -1,7 +1,5 @@
use Context::*;
-use rustc::session::Session;
-
use rustc::hir::map::Map;
use rustc::ty::query::Providers;
use rustc::ty::TyCtxt;
@@ -10,10 +8,9 @@
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::{Destination, Movability, Node};
+use rustc_session::Session;
use rustc_span::Span;
-use rustc_error_codes::*;
-
#[derive(Clone, Copy, Debug, PartialEq)]
enum Context {
Normal,
diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs
index 5ce677f..6678980 100644
--- a/src/librustc_passes/reachable.rs
+++ b/src/librustc_passes/reachable.rs
@@ -35,7 +35,7 @@
hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => {
return true;
}
- hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => {
+ hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => {
let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
generics.requires_monomorphization(tcx)
}
@@ -181,7 +181,7 @@
// does too.
let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap();
match self.tcx.hir().expect_item(impl_hir_id).kind {
- hir::ItemKind::Impl(..) => {
+ hir::ItemKind::Impl { .. } => {
let generics = self.tcx.generics_of(impl_did);
generics.requires_monomorphization(self.tcx)
}
@@ -266,7 +266,7 @@
| hir::ItemKind::Static(..)
| hir::ItemKind::Mod(..)
| hir::ItemKind::ForeignMod(..)
- | hir::ItemKind::Impl(..)
+ | hir::ItemKind::Impl { .. }
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..)
| hir::ItemKind::Struct(..)
@@ -349,9 +349,9 @@
}
// We need only trait impls here, not inherent impls, and only non-exported ones
- if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.kind {
+ if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
if !self.access_levels.is_reachable(item.hir_id) {
- self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id));
+ self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
let trait_def_id = match trait_ref.path.res {
Res::Def(DefKind::Trait, def_id) => def_id,
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index 5ec7e73..320b433 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -26,8 +26,6 @@
use std::mem::replace;
use std::num::NonZeroU32;
-use rustc_error_codes::*;
-
#[derive(PartialEq)]
enum AnnotationKind {
// Annotation is required if not inherited from unstable parents
@@ -219,11 +217,11 @@
// they don't have their own stability. They still can be annotated as unstable
// and propagate this unstability to children, but this annotation is completely
// optional. They inherit stability from their parents when unannotated.
- hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {
+ hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {
self.in_trait_impl = false;
kind = AnnotationKind::Container;
}
- hir::ItemKind::Impl(.., Some(_), _, _) => {
+ hir::ItemKind::Impl { of_trait: Some(_), .. } => {
self.in_trait_impl = true;
}
hir::ItemKind::Struct(ref sd, _) => {
@@ -308,7 +306,7 @@
// they don't have their own stability. They still can be annotated as unstable
// and propagate this unstability to children, but this annotation is completely
// optional. They inherit stability from their parents when unannotated.
- hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {}
+ hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {}
_ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()),
}
@@ -463,9 +461,9 @@
// For implementations of traits, check the stability of each item
// individually as it's possible to have a stable trait with unstable
// items.
- hir::ItemKind::Impl(.., Some(ref t), _, impl_item_refs) => {
+ hir::ItemKind::Impl { of_trait: Some(ref t), items, .. } => {
if let Res::Def(DefKind::Trait, trait_did) = t.path.res {
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
let trait_item_def_id = self
.tcx
diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml
index 41e6c69..2214838 100644
--- a/src/librustc_plugin_impl/Cargo.toml
+++ b/src/librustc_plugin_impl/Cargo.toml
@@ -18,4 +18,3 @@
rustc_metadata = { path = "../librustc_metadata" }
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
index 65661ec..84549c0 100644
--- a/src/librustc_plugin_impl/load.rs
+++ b/src/librustc_plugin_impl/load.rs
@@ -3,7 +3,6 @@
use crate::Registry;
use rustc::middle::cstore::MetadataLoader;
use rustc::session::Session;
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_metadata::locator;
use rustc_span::symbol::sym;
diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml
index 795b6c1..4f341b5 100644
--- a/src/librustc_privacy/Cargo.toml
+++ b/src/librustc_privacy/Cargo.toml
@@ -16,5 +16,4 @@
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }
rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_error_codes = { path = "../librustc_error_codes" }
log = "0.4"
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 70d4841..60bf271 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -27,8 +27,6 @@
use std::marker::PhantomData;
use std::{cmp, fmt, mem};
-use rustc_error_codes::*;
-
////////////////////////////////////////////////////////////////////////////////
/// Generic infrastructure used to implement specific visitors below.
////////////////////////////////////////////////////////////////////////////////
@@ -93,7 +91,7 @@
let ty::GenericPredicates { parent: _, predicates } = predicates;
for (predicate, _span) in predicates {
match predicate {
- ty::Predicate::Trait(poly_predicate) => {
+ ty::Predicate::Trait(poly_predicate, _) => {
let ty::TraitPredicate { trait_ref } = *poly_predicate.skip_binder();
if self.visit_trait(trait_ref) {
return true;
@@ -255,8 +253,8 @@
Node::ImplItem(impl_item) => {
match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) {
Node::Item(item) => match &item.kind {
- hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis,
- hir::ItemKind::Impl(.., Some(trait_ref), _, _) => {
+ hir::ItemKind::Impl { of_trait: None, .. } => &impl_item.vis,
+ hir::ItemKind::Impl { of_trait: Some(trait_ref), .. } => {
return def_id_visibility(tcx, trait_ref.path.res.def_id());
}
kind => bug!("unexpected item kind: {:?}", kind),
@@ -686,7 +684,7 @@
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
let inherited_item_level = match item.kind {
- hir::ItemKind::Impl(..) => {
+ hir::ItemKind::Impl { .. } => {
Option::<AccessLevel>::of_impl(item.hir_id, self.tcx, &self.access_levels)
}
// Foreign modules inherit level from parents.
@@ -730,9 +728,9 @@
}
}
}
- hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => {
- for impl_item_ref in impl_item_refs {
- if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() {
+ hir::ItemKind::Impl { ref of_trait, items, .. } => {
+ for impl_item_ref in items {
+ if of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
self.update(impl_item_ref.id.hir_id, item_level);
}
}
@@ -827,11 +825,11 @@
}
}
// Visit everything except for private impl items.
- hir::ItemKind::Impl(.., impl_item_refs) => {
+ hir::ItemKind::Impl { items, .. } => {
if item_level.is_some() {
self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
let impl_item_level = self.get(impl_item_ref.id.hir_id);
if impl_item_level.is_some() {
self.reach(impl_item_ref.id.hir_id, impl_item_level)
@@ -1237,7 +1235,7 @@
// The traits' privacy in bodies is already checked as a part of trait object types.
let bounds = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref);
- for (trait_predicate, _) in bounds.trait_bounds {
+ for (trait_predicate, _, _) in bounds.trait_bounds {
if self.visit_trait(*trait_predicate.skip_binder()) {
return;
}
@@ -1510,7 +1508,7 @@
// (i.e., we could just return here to not check them at
// all, or some worse estimation of whether an impl is
// publicly visible).
- hir::ItemKind::Impl(.., ref g, ref trait_ref, ref self_, impl_item_refs) => {
+ hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => {
// `impl [... for] Private` is never visible.
let self_contains_private;
// `impl [... for] Public<...>`, but not `impl [... for]
@@ -1525,7 +1523,7 @@
at_outer_type: true,
outer_type_is_public_path: false,
};
- visitor.visit_ty(&self_);
+ visitor.visit_ty(&self_ty);
self_contains_private = visitor.contains_private;
self_is_public_path = visitor.outer_type_is_public_path;
}
@@ -1533,7 +1531,7 @@
// Miscellaneous info about the impl:
// `true` iff this is `impl Private for ...`.
- let not_private_trait = trait_ref.as_ref().map_or(
+ let not_private_trait = of_trait.as_ref().map_or(
true, // no trait counts as public trait
|tr| {
let did = tr.path.res.def_id();
@@ -1554,8 +1552,8 @@
// directly because we might have `impl<T: Foo<Private>> ...`,
// and we shouldn't warn about the generics if all the methods
// are private (because `T` won't be visible externally).
- let trait_or_some_public_method = trait_ref.is_some()
- || impl_item_refs.iter().any(|impl_item_ref| {
+ let trait_or_some_public_method = of_trait.is_some()
+ || items.iter().any(|impl_item_ref| {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item.kind {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => {
@@ -1570,9 +1568,9 @@
if !self_contains_private && not_private_trait && trait_or_some_public_method {
intravisit::walk_generics(self, g);
- match *trait_ref {
+ match of_trait {
None => {
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
// This is where we choose whether to walk down
// further into the impl to check its items. We
// should only walk into public items so that we
@@ -1594,7 +1592,7 @@
}
}
}
- Some(ref tr) => {
+ Some(tr) => {
// Any private types in a trait impl fall into three
// categories.
// 1. mentioned in the trait definition
@@ -1611,7 +1609,7 @@
intravisit::walk_path(self, &tr.path);
// Those in 3. are warned with this call.
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind {
self.visit_ty(ty);
@@ -1619,11 +1617,11 @@
}
}
}
- } else if trait_ref.is_none() && self_is_public_path {
+ } else if of_trait.is_none() && self_is_public_path {
// `impl Public<Private> { ... }`. Any public static
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item_ref.kind {
@@ -1997,12 +1995,12 @@
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity.
- hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => {
+ hir::ItemKind::Impl { ref of_trait, items, .. } => {
let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default());
self.check(item.hir_id, impl_vis).generics().predicates();
- for impl_item_ref in impl_item_refs {
+ for impl_item_ref in items {
let impl_item = tcx.hir().impl_item(impl_item_ref.id);
- let impl_item_vis = if trait_ref.is_none() {
+ let impl_item_vis = if of_trait.is_none() {
min(
ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx),
impl_vis,
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
index af37e7b..c4cc6b0 100644
--- a/src/librustc_resolve/Cargo.toml
+++ b/src/librustc_resolve/Cargo.toml
@@ -23,7 +23,6 @@
rustc_feature = { path = "../librustc_feature" }
rustc_hir = { path = "../librustc_hir" }
rustc_metadata = { path = "../librustc_metadata" }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }
rustc_span = { path = "../librustc_span" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index e8ed64a..7ff0762 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -21,7 +21,6 @@
use rustc::middle::cstore::CrateStore;
use rustc::ty;
use rustc_data_structures::sync::Lrc;
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability};
use rustc_expand::base::SyntaxExtension;
use rustc_expand::expand::AstFragment;
@@ -815,7 +814,7 @@
}
// These items do not add names to modules.
- ItemKind::Impl(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
+ ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
}
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index f564ea6..696ba0e 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -104,7 +104,7 @@
// Pick the def data. This need not be unique, but the more
// information we encapsulate into, the better
let def_data = match &i.kind {
- ItemKind::Impl(..) => DefPathData::Impl,
+ ItemKind::Impl { .. } => DefPathData::Impl,
ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
return visit::walk_item(self, i);
}
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index a433ae8..77dfe3d 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -5,8 +5,9 @@
use rustc::session::Session;
use rustc::ty::{self, DefIdTree};
use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_feature::BUILTIN_ATTRIBUTES;
+use rustc_hir as hir;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -25,8 +26,6 @@
use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError};
use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment};
-use rustc_error_codes::*;
-
type Res = def::Res<ast::NodeId>;
/// A vector of spans and replacements, a message and applicability.
@@ -1447,3 +1446,74 @@
}
}
}
+
+crate fn report_missing_lifetime_specifiers(
+ sess: &Session,
+ span: Span,
+ count: usize,
+) -> DiagnosticBuilder<'_> {
+ struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count))
+}
+
+crate fn add_missing_lifetime_specifiers_label(
+ err: &mut DiagnosticBuilder<'_>,
+ span: Span,
+ count: usize,
+ lifetime_names: &FxHashSet<ast::Ident>,
+ snippet: Option<&str>,
+ missing_named_lifetime_spots: &[&hir::Generics<'_>],
+) {
+ if count > 1 {
+ err.span_label(span, format!("expected {} lifetime parameters", count));
+ } else {
+ let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| {
+ err.span_suggestion(
+ span,
+ "consider using the named lifetime",
+ sugg,
+ Applicability::MaybeIncorrect,
+ );
+ };
+ let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| {
+ err.span_label(span, "expected named lifetime parameter");
+
+ if let Some(generics) = missing_named_lifetime_spots.iter().last() {
+ let mut introduce_suggestion = vec![];
+ introduce_suggestion.push(match &generics.params {
+ [] => (generics.span, "<'lifetime>".to_string()),
+ [param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()),
+ });
+ introduce_suggestion.push((span, sugg));
+ err.multipart_suggestion(
+ "consider introducing a named lifetime parameter",
+ introduce_suggestion,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ };
+
+ match (lifetime_names.len(), lifetime_names.iter().next(), snippet) {
+ (1, Some(name), Some("&")) => {
+ suggest_existing(err, format!("&{} ", name));
+ }
+ (1, Some(name), Some("'_")) => {
+ suggest_existing(err, name.to_string());
+ }
+ (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => {
+ suggest_existing(err, format!("{}<{}>", snippet, name));
+ }
+ (0, _, Some("&")) => {
+ suggest_new(err, "&'lifetime ".to_string());
+ }
+ (0, _, Some("'_")) => {
+ suggest_new(err, "'lifetime".to_string());
+ }
+ (0, _, Some(snippet)) if !snippet.ends_with(">") => {
+ suggest_new(err, format!("{}<'lifetime>", snippet));
+ }
+ _ => {
+ err.span_label(span, "expected lifetime parameter");
+ }
+ }
+ }
+}
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index 9f45983..55ce51e 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -29,8 +29,6 @@
use syntax::unwrap_or;
use syntax::util::lev_distance::find_best_match_for_name;
-use rustc_error_codes::*;
-
use log::*;
use std::cell::Cell;
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index defca49..5e08ac8 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -31,8 +31,6 @@
use std::collections::BTreeSet;
use std::mem::replace;
-use rustc_error_codes::*;
-
mod diagnostics;
type Res = def::Res<NodeId>;
@@ -797,14 +795,14 @@
self.resolve_adt(item, generics);
}
- ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
- self.resolve_implementation(
- generics,
- opt_trait_ref,
- &self_type,
- item.id,
- impl_items,
- )
+ ItemKind::Impl {
+ ref generics,
+ ref of_trait,
+ ref self_ty,
+ items: ref impl_items,
+ ..
+ } => {
+ self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
}
ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 151f3e8..6a98c9e 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -6,7 +6,6 @@
use rustc::session::config::nightly_options;
use rustc_data_structures::fx::FxHashSet;
-use rustc_error_codes::*;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind};
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 60a0049..0e6f40f 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -11,6 +11,7 @@
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
#![feature(nll)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![recursion_limit = "256"]
pub use rustc_hir::def::{Namespace, PerNS};
@@ -61,8 +62,6 @@
use late::{HasGenericParams, PathSource, Rib, RibKind::*};
use macros::{LegacyBinding, LegacyScope};
-use rustc_error_codes::*;
-
type Res = def::Res<NodeId>;
mod build_reduced_graph;
diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs
index d6143ee..6e9ed5f 100644
--- a/src/librustc_resolve/lifetimes.rs
+++ b/src/librustc_resolve/lifetimes.rs
@@ -5,14 +5,16 @@
//! used between functions, and they operate in a purely top-down
//! way. Therefore, we break lifetime name resolution into a separate pass.
+use crate::diagnostics::{
+ add_missing_lifetime_specifiers_label, report_missing_lifetime_specifiers,
+};
use rustc::hir::map::Map;
use rustc::lint;
use rustc::middle::resolve_lifetime::*;
-use rustc::session::Session;
use rustc::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
use rustc::{bug, span_bug};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
@@ -30,8 +32,6 @@
use log::debug;
-use rustc_error_codes::*;
-
// This counts the no of times a lifetime is used
#[derive(Clone, Copy, Debug)]
pub enum LifetimeUseSet<'tcx> {
@@ -183,6 +183,10 @@
xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
lifetime_uses: &'a mut DefIdMap<LifetimeUseSet<'tcx>>,
+
+ /// When encountering an undefined named lifetime, we will suggest introducing it in these
+ /// places.
+ missing_named_lifetime_spots: Vec<&'tcx hir::Generics<'tcx>>,
}
#[derive(Debug)]
@@ -342,6 +346,7 @@
labels_in_fn: vec![],
xcrate_object_lifetime_defaults: Default::default(),
lifetime_uses: &mut Default::default(),
+ missing_named_lifetime_spots: vec![],
};
for (_, item) in &krate.items {
visitor.visit_item(item);
@@ -384,9 +389,11 @@
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
match item.kind {
hir::ItemKind::Fn(ref sig, ref generics, _) => {
+ self.missing_named_lifetime_spots.push(generics);
self.visit_early_late(None, &sig.decl, generics, |this| {
intravisit::walk_item(this, item);
});
+ self.missing_named_lifetime_spots.pop();
}
hir::ItemKind::ExternCrate(_)
@@ -416,11 +423,13 @@
| hir::ItemKind::Union(_, ref generics)
| hir::ItemKind::Trait(_, _, ref generics, ..)
| hir::ItemKind::TraitAlias(ref generics, ..)
- | hir::ItemKind::Impl(_, _, _, ref generics, ..) => {
+ | hir::ItemKind::Impl { ref generics, .. } => {
+ self.missing_named_lifetime_spots.push(generics);
+
// Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
// This is not true for other kinds of items.x
let track_lifetime_uses = match item.kind {
- hir::ItemKind::Impl(..) => true,
+ hir::ItemKind::Impl { .. } => true,
_ => false,
};
// These kinds of items have only early-bound lifetime parameters.
@@ -454,6 +463,7 @@
this.check_lifetime_params(old_scope, &generics.params);
intravisit::walk_item(this, item);
});
+ self.missing_named_lifetime_spots.pop();
}
}
}
@@ -686,6 +696,7 @@
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
use self::hir::TraitItemKind::*;
+ self.missing_named_lifetime_spots.push(&trait_item.generics);
match trait_item.kind {
Method(ref sig, _) => {
let tcx = self.tcx;
@@ -737,10 +748,12 @@
intravisit::walk_trait_item(self, trait_item);
}
}
+ self.missing_named_lifetime_spots.pop();
}
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
use self::hir::ImplItemKind::*;
+ self.missing_named_lifetime_spots.push(&impl_item.generics);
match impl_item.kind {
Method(ref sig, _) => {
let tcx = self.tcx;
@@ -824,6 +837,7 @@
intravisit::walk_impl_item(self, impl_item);
}
}
+ self.missing_named_lifetime_spots.pop();
}
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
@@ -1309,6 +1323,7 @@
let LifetimeContext { tcx, map, lifetime_uses, .. } = self;
let labels_in_fn = take(&mut self.labels_in_fn);
let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
+ let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
let mut this = LifetimeContext {
tcx: *tcx,
map: map,
@@ -1317,7 +1332,8 @@
is_in_fn_syntax: self.is_in_fn_syntax,
labels_in_fn,
xcrate_object_lifetime_defaults,
- lifetime_uses: lifetime_uses,
+ lifetime_uses,
+ missing_named_lifetime_spots,
};
debug!("entering scope {:?}", this.scope);
f(self.scope, &mut this);
@@ -1325,6 +1341,7 @@
debug!("exiting scope {:?}", this.scope);
self.labels_in_fn = this.labels_in_fn;
self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
+ self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
}
/// helper method to determine the span to remove when suggesting the
@@ -1638,7 +1655,7 @@
}
match parent.kind {
hir::ItemKind::Trait(_, _, ref generics, ..)
- | hir::ItemKind::Impl(_, _, _, ref generics, ..) => {
+ | hir::ItemKind::Impl { ref generics, .. } => {
index += generics.params.len() as u32;
}
_ => {}
@@ -1807,15 +1824,29 @@
self.insert_lifetime(lifetime_ref, def);
} else {
- struct_span_err!(
+ let mut err = struct_span_err!(
self.tcx.sess,
lifetime_ref.span,
E0261,
"use of undeclared lifetime name `{}`",
lifetime_ref
- )
- .span_label(lifetime_ref.span, "undeclared lifetime")
- .emit();
+ );
+ err.span_label(lifetime_ref.span, "undeclared lifetime");
+ if !self.is_in_fn_syntax {
+ for generics in &self.missing_named_lifetime_spots {
+ let (span, sugg) = match &generics.params {
+ [] => (generics.span, format!("<{}>", lifetime_ref)),
+ [param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)),
+ };
+ err.span_suggestion(
+ span,
+ &format!("consider introducing lifetime `{}` here", lifetime_ref),
+ sugg,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ err.emit();
}
}
@@ -2067,12 +2098,12 @@
}
Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(_, body), .. }) => {
- if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) =
+ if let hir::ItemKind::Impl { ref self_ty, ref items, .. } =
self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
{
impl_self = Some(self_ty);
assoc_item_kind =
- impl_items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind);
+ items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind);
}
Some(body)
}
@@ -2369,6 +2400,7 @@
lifetime_refs.len(),
&lifetime_names,
self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
+ &self.missing_named_lifetime_spots,
);
}
@@ -2864,34 +2896,3 @@
}
}
}
-
-fn report_missing_lifetime_specifiers(
- sess: &Session,
- span: Span,
- count: usize,
-) -> DiagnosticBuilder<'_> {
- struct_span_err!(sess, span, E0106, "missing lifetime specifier{}", pluralize!(count))
-}
-
-fn add_missing_lifetime_specifiers_label(
- err: &mut DiagnosticBuilder<'_>,
- span: Span,
- count: usize,
- lifetime_names: &FxHashSet<ast::Ident>,
- snippet: Option<&str>,
-) {
- if count > 1 {
- err.span_label(span, format!("expected {} lifetime parameters", count));
- } else if let (1, Some(name), Some("&")) =
- (lifetime_names.len(), lifetime_names.iter().next(), snippet)
- {
- err.span_suggestion(
- span,
- "consider using the named lifetime",
- format!("&{} ", name),
- Applicability::MaybeIncorrect,
- );
- } else {
- err.span_label(span, "expected lifetime parameter");
- }
-}
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 2f2ba56..d252fc5 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1300,8 +1300,8 @@
self.process_struct(item, def, ty_params)
}
Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
- Impl(.., ref ty_params, ref trait_ref, ref typ, ref impl_items) => {
- self.process_impl(item, ty_params, trait_ref, &typ, impl_items)
+ Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => {
+ self.process_impl(item, generics, of_trait, &self_ty, items)
}
Trait(_, _, ref generics, ref trait_refs, ref methods) => {
self.process_trait(item, generics, trait_refs, methods)
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c3221d9..537fe19 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -305,8 +305,8 @@
attributes: lower_attributes(item.attrs.clone(), self),
}))
}
- ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => {
- if let ast::TyKind::Path(None, ref path) = typ.kind {
+ ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => {
+ if let ast::TyKind::Path(None, ref path) = self_ty.kind {
// Common case impl for a struct or something basic.
if generated_code(path.span) {
return None;
@@ -317,14 +317,14 @@
let impl_id = self.next_impl_id();
let span = self.span_from_span(sub_span);
- let type_data = self.lookup_def_id(typ.id);
+ let type_data = self.lookup_def_id(self_ty.id);
type_data.map(|type_data| {
Data::RelationData(
Relation {
kind: RelationKind::Impl { id: impl_id },
span: span.clone(),
from: id_from_def_id(type_data),
- to: trait_ref
+ to: of_trait
.as_ref()
.and_then(|t| self.lookup_def_id(t.ref_id))
.map(id_from_def_id)
@@ -332,14 +332,14 @@
},
Impl {
id: impl_id,
- kind: match *trait_ref {
+ kind: match *of_trait {
Some(_) => ImplKind::Direct,
None => ImplKind::Inherent,
},
span: span,
value: String::new(),
parent: None,
- children: impls
+ children: items
.iter()
.map(|i| id_from_node_id(i.id, self))
.collect(),
@@ -405,9 +405,9 @@
{
Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
Some(Node::Item(item)) => match item.kind {
- hir::ItemKind::Impl(.., ref ty, _) => {
+ hir::ItemKind::Impl { ref self_ty, .. } => {
let mut qualname = String::from("<");
- qualname.push_str(&self.tcx.hir().hir_to_pretty_string(ty.hir_id));
+ qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id));
let trait_id = self.tcx.trait_id_of_impl(impl_id);
let mut decl_id = None;
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index e7b86cf..a9d2bfa 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -482,15 +482,16 @@
Ok(sig)
}
- ast::ItemKind::Impl(
+ ast::ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
ref generics,
- ref opt_trait,
- ref ty,
- _,
- ) => {
+ ref of_trait,
+ ref self_ty,
+ items: _,
+ } => {
let mut text = String::new();
if let ast::Defaultness::Default = defaultness {
text.push_str("default ");
@@ -499,13 +500,16 @@
text.push_str("unsafe ");
}
text.push_str("impl");
+ if constness == ast::Constness::Const {
+ text.push_str(" const");
+ }
let generics_sig = generics.make(offset + text.len(), id, scx)?;
text.push_str(&generics_sig.text);
text.push(' ');
- let trait_sig = if let Some(ref t) = *opt_trait {
+ let trait_sig = if let Some(ref t) = *of_trait {
if polarity == ast::ImplPolarity::Negative {
text.push('!');
}
@@ -517,7 +521,7 @@
text_sig(String::new())
};
- let ty_sig = ty.make(offset + text.len(), id, scx)?;
+ let ty_sig = self_ty.make(offset + text.len(), id, scx)?;
text.push_str(&ty_sig.text);
text.push_str(" {}");
diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml
index 377ea14..47c23bc 100644
--- a/src/librustc_session/Cargo.toml
+++ b/src/librustc_session/Cargo.toml
@@ -10,7 +10,6 @@
[dependencies]
log = "0.4"
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_errors = { path = "../librustc_errors" }
rustc_feature = { path = "../librustc_feature" }
rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index 4b5736a..2a0ed27 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -923,8 +923,12 @@
self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
parse_switch_with_opt_path, [UNTRACKED],
"run the self profiler and output the raw event data"),
+ // keep this in sync with the event filter names in librustc_data_structures/profiling.rs
self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED],
- "specifies which kinds of events get recorded by the self profiler"),
+ "specifies which kinds of events get recorded by the self profiler;
+ for example: `-Z self-profile-events=default,query-keys`
+ all options: none, all, default, generic-activity, query-provider, query-cache-hit
+ query-blocked, incr-cache-load, query-keys"),
emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
"emits a section containing stack size metadata"),
plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index a98cf92..72c68fc 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -6,7 +6,6 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{Lock, Lrc, Once};
-use rustc_error_codes::E0658;
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
use rustc_errors::{error_code, Applicability, DiagnosticBuilder};
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs
index fb5fcf4..9c7c0f0 100644
--- a/src/librustc_span/source_map.rs
+++ b/src/librustc_span/source_map.rs
@@ -473,20 +473,23 @@
lo.line != hi.line
}
- pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
- debug!("span_to_lines(sp={:?})", sp);
-
+ pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> {
let lo = self.lookup_char_pos(sp.lo());
debug!("span_to_lines: lo={:?}", lo);
let hi = self.lookup_char_pos(sp.hi());
debug!("span_to_lines: hi={:?}", hi);
-
if lo.file.start_pos != hi.file.start_pos {
return Err(SpanLinesError::DistinctSources(DistinctSources {
begin: (lo.file.name.clone(), lo.file.start_pos),
end: (hi.file.name.clone(), hi.file.start_pos),
}));
}
+ Ok((lo, hi))
+ }
+
+ pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
+ debug!("span_to_lines(sp={:?})", sp);
+ let (lo, hi) = self.is_valid_span(sp)?;
assert!(hi.line >= lo.line);
let mut lines = Vec::with_capacity(hi.line - lo.line + 1);
diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs
index 17413e7..84c6d72 100644
--- a/src/librustc_target/lib.rs
+++ b/src/librustc_target/lib.rs
@@ -11,7 +11,7 @@
#![feature(box_syntax)]
#![feature(bool_to_option)]
#![feature(nll)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#[macro_use]
extern crate log;
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index 315efe5..7df27e6 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -195,8 +195,8 @@
},
Node::Item(item) => match item.kind {
- ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl,
- ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl,
+ ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
+ ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
ItemKind::Fn(..) => NodeKind::Fn,
_ => NodeKind::Other,
},
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index 4b4fa4b..b77c603 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -94,7 +94,7 @@
use rustc::ty::Predicate;
match self {
- Predicate::Trait(predicate) => predicate.lower(),
+ Predicate::Trait(predicate, _) => predicate.lower(),
Predicate::RegionOutlives(predicate) => predicate.lower(),
Predicate::TypeOutlives(predicate) => predicate.lower(),
Predicate::Projection(predicate) => predicate.lower(),
diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs
index 2548d2c..e5ec987 100644
--- a/src/librustc_ty/lib.rs
+++ b/src/librustc_ty/lib.rs
@@ -8,7 +8,7 @@
#![feature(bool_to_option)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index fc8beb6..8b62403 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -2,7 +2,7 @@
use rustc::session::CrateDisambiguator;
use rustc::traits::{self};
use rustc::ty::subst::Subst;
-use rustc::ty::{self, ToPredicate, Ty, TyCtxt};
+use rustc::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_data_structures::svh::Svh;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -58,6 +58,7 @@
def_id: sized_trait,
substs: tcx.mk_substs_trait(ty, &[]),
})
+ .without_const()
.to_predicate();
let predicates = tcx.predicates_of(adtdef.did).predicates;
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
@@ -128,8 +129,8 @@
let parent_def_id = tcx.hir().local_def_id(parent_id);
let parent_item = tcx.hir().expect_item(parent_id);
match parent_item.kind {
- hir::ItemKind::Impl(.., ref impl_item_refs) => {
- if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) {
+ hir::ItemKind::Impl { ref items, .. } => {
+ if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) {
let assoc_item =
associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref);
debug_assert_eq!(assoc_item.def_id, def_id);
@@ -194,8 +195,8 @@
.map(|trait_item_ref| trait_item_ref.id)
.map(|id| tcx.hir().local_def_id(id.hir_id)),
),
- hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter(
- impl_item_refs
+ hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter(
+ items
.iter()
.map(|impl_item_ref| impl_item_ref.id)
.map(|id| tcx.hir().local_def_id(id.hir_id)),
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index 84e5f56..4b27d86 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -22,4 +22,3 @@
syntax = { path = "../libsyntax" }
rustc_span = { path = "../librustc_span" }
rustc_index = { path = "../librustc_index" }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index a3be264..89eeed8 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -3,6 +3,8 @@
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
//! instance of `AstConv`.
+// ignore-tidy-filelength
+
use crate::collect::PlaceholderHirTyCollector;
use crate::lint;
use crate::middle::lang_items::SizedTraitLangItem;
@@ -17,7 +19,7 @@
use rustc::traits::error_reporting::report_object_safety_error;
use rustc::traits::wf::object_region_bounds;
use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
-use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc::ty::{GenericParamDef, GenericParamDefKind};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
@@ -31,7 +33,7 @@
use rustc_span::{MultiSpan, Span, DUMMY_SP};
use rustc_target::spec::abi;
use smallvec::SmallVec;
-use syntax::ast;
+use syntax::ast::{self, Constness};
use syntax::util::lev_distance::find_best_match_for_name;
use std::collections::BTreeSet;
@@ -39,7 +41,6 @@
use std::slice;
use rustc::mir::interpret::LitToConstInput;
-use rustc_error_codes::*;
#[derive(Debug)]
pub struct PathSeg(pub DefId, pub usize);
@@ -49,6 +50,8 @@
fn item_def_id(&self) -> Option<DefId>;
+ fn default_constness_for_trait_bounds(&self) -> Constness;
+
/// Returns predicates in scope of the form `X: Foo`, where `X` is
/// a type parameter `X` with the given id `def_id`. This is a
/// subset of the full set of predicates.
@@ -919,6 +922,7 @@
&self,
trait_ref: &hir::TraitRef<'_>,
span: Span,
+ constness: Constness,
self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
@@ -947,7 +951,7 @@
);
let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs));
- bounds.trait_bounds.push((poly_trait_ref, span));
+ bounds.trait_bounds.push((poly_trait_ref, span, constness));
let mut dup_bindings = FxHashMap::default();
for binding in &assoc_bindings {
@@ -993,12 +997,14 @@
pub fn instantiate_poly_trait_ref(
&self,
poly_trait_ref: &hir::PolyTraitRef<'_>,
+ constness: Constness,
self_ty: Ty<'tcx>,
bounds: &mut Bounds<'tcx>,
) -> Option<Vec<Span>> {
self.instantiate_poly_trait_ref_inner(
&poly_trait_ref.trait_ref,
poly_trait_ref.span,
+ constness,
self_ty,
bounds,
false,
@@ -1181,18 +1187,22 @@
let mut trait_bounds = Vec::new();
let mut region_bounds = Vec::new();
+ let constness = self.default_constness_for_trait_bounds();
for ast_bound in ast_bounds {
match *ast_bound {
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
- trait_bounds.push(b)
+ trait_bounds.push((b, constness))
+ }
+ hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => {
+ trait_bounds.push((b, Constness::NotConst))
}
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
hir::GenericBound::Outlives(ref l) => region_bounds.push(l),
}
}
- for bound in trait_bounds {
- let _ = self.instantiate_poly_trait_ref(bound, param_ty, bounds);
+ for (bound, constness) in trait_bounds {
+ let _ = self.instantiate_poly_trait_ref(bound, constness, param_ty, bounds);
}
bounds.region_bounds.extend(
@@ -1226,7 +1236,7 @@
let mut bounds = Bounds::default();
self.add_bounds(param_ty, ast_bounds, &mut bounds);
- bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id());
+ bounds.trait_bounds.sort_by_key(|(t, _, _)| t.def_id());
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
if !self.is_unsized(ast_bounds, span) { Some(span) } else { None }
@@ -1320,10 +1330,10 @@
// those that do.
self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, trait_ref),
- &trait_ref.print_only_trait_path().to_string(),
+ || trait_ref.print_only_trait_path().to_string(),
binding.item_name,
path_span,
- match binding.kind {
+ || match binding.kind {
ConvertedBindingKind::Equality(ty) => Some(ty.to_string()),
_ => None,
},
@@ -1417,15 +1427,21 @@
let mut potential_assoc_types = Vec::new();
let dummy_self = self.tcx().types.trait_object_dummy_self;
for trait_bound in trait_bounds.iter().rev() {
- let cur_potential_assoc_types =
- self.instantiate_poly_trait_ref(trait_bound, dummy_self, &mut bounds);
+ let cur_potential_assoc_types = self.instantiate_poly_trait_ref(
+ trait_bound,
+ Constness::NotConst,
+ dummy_self,
+ &mut bounds,
+ );
potential_assoc_types.extend(cur_potential_assoc_types.into_iter().flatten());
}
// Expand trait aliases recursively and check that only one regular (non-auto) trait
// is used and no 'maybe' bounds are used.
- let expanded_traits =
- traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().cloned());
+ let expanded_traits = traits::expand_trait_aliases(
+ tcx,
+ bounds.trait_bounds.iter().map(|&(a, b, _)| (a.clone(), b)),
+ );
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
if regular_traits.len() > 1 {
@@ -1481,16 +1497,18 @@
let regular_traits_refs_spans = bounds
.trait_bounds
.into_iter()
- .filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
+ .filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
- for (base_trait_ref, span) in regular_traits_refs_spans {
+ for (base_trait_ref, span, constness) in regular_traits_refs_spans {
+ assert_eq!(constness, ast::Constness::NotConst);
+
for trait_ref in traits::elaborate_trait_ref(tcx, base_trait_ref) {
debug!(
"conv_object_ty_poly_trait_ref: observing object predicate `{:?}`",
trait_ref
);
match trait_ref {
- ty::Predicate::Trait(pred) => {
+ ty::Predicate::Trait(pred, _) => {
associated_types.entry(span).or_default().extend(
tcx.associated_items(pred.def_id())
.filter(|item| item.kind == ty::AssocKind::Type)
@@ -1880,10 +1898,10 @@
predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()),
)
},
- ¶m_name.as_str(),
+ || param_name.to_string(),
assoc_name,
span,
- None,
+ || None,
)
}
@@ -1892,10 +1910,10 @@
fn one_bound_for_assoc_type<I>(
&self,
all_candidates: impl Fn() -> I,
- ty_param_name: &str,
+ ty_param_name: impl Fn() -> String,
assoc_name: ast::Ident,
span: Span,
- is_equality: Option<String>,
+ is_equality: impl Fn() -> Option<String>,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
@@ -1908,7 +1926,7 @@
None => {
self.complain_about_assoc_type_not_found(
all_candidates,
- ty_param_name,
+ &ty_param_name(),
assoc_name,
span,
);
@@ -1921,6 +1939,7 @@
if let Some(bound2) = matching_candidates.next() {
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
+ let is_equality = is_equality();
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
let mut err = if is_equality.is_some() {
// More specific Error Index entry.
@@ -1930,7 +1949,7 @@
E0222,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
- ty_param_name
+ ty_param_name()
)
} else {
struct_span_err!(
@@ -1939,7 +1958,7 @@
E0221,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
- ty_param_name
+ ty_param_name()
)
};
err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
@@ -1977,7 +1996,7 @@
"use fully qualified syntax to disambiguate",
format!(
"<{} as {}>::{}",
- ty_param_name,
+ ty_param_name(),
bound.print_only_trait_path(),
assoc_name,
),
@@ -1987,7 +2006,7 @@
} else {
err.note(&format!(
"associated type `{}` could derive from `{}`",
- ty_param_name,
+ ty_param_name(),
bound.print_only_trait_path(),
));
}
@@ -1996,7 +2015,7 @@
err.help(&format!(
"consider introducing a new type parameter `T` and adding `where` constraints:\
\n where\n T: {},\n{}",
- ty_param_name,
+ ty_param_name(),
where_bounds.join(",\n"),
));
}
@@ -2110,10 +2129,10 @@
self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
- "Self",
+ || "Self".to_string(),
assoc_ident,
span,
- None,
+ || None,
)?
}
(&ty::Param(_), Res::SelfTy(Some(param_did), None))
@@ -2948,7 +2967,7 @@
/// A list of trait bounds. So if you had `T: Debug` this would be
/// `T: Debug`. Note that the self-type is explicit here.
- pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>,
+ pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, Constness)>,
/// A list of projection equality bounds. So if you had `T:
/// Iterator<Item = u32>` this would include `<T as
@@ -2979,7 +2998,7 @@
def_id: sized,
substs: tcx.mk_substs_trait(param_ty, &[]),
});
- (trait_ref.to_predicate(), span)
+ (trait_ref.without_const().to_predicate(), span)
})
});
@@ -2996,11 +3015,10 @@
let outlives = ty::OutlivesPredicate(param_ty, region_bound);
(ty::Binder::bind(outlives).to_predicate(), span)
})
- .chain(
- self.trait_bounds
- .iter()
- .map(|&(bound_trait_ref, span)| (bound_trait_ref.to_predicate(), span)),
- )
+ .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| {
+ let predicate = bound_trait_ref.with_constness(constness).to_predicate();
+ (predicate, span)
+ }))
.chain(
self.projection_bounds
.iter()
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 8d6b74c..e4dec97 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -5,7 +5,7 @@
use rustc::session::DiagnosticMessageId;
use rustc::traits::{self, TraitEngine};
use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
-use rustc::ty::{self, TraitRef, Ty, TyCtxt};
+use rustc::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
use rustc::ty::{ToPredicate, TypeFoldable};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
@@ -13,8 +13,6 @@
use rustc_span::Span;
use syntax::ast::Ident;
-use rustc_error_codes::*;
-
use std::iter;
#[derive(Copy, Clone, Debug)]
@@ -124,8 +122,11 @@
let cause = traits::ObligationCause::misc(self.span, self.body_id);
- let obligation =
- traits::Obligation::new(cause.clone(), self.param_env, trait_ref.to_predicate());
+ let obligation = traits::Obligation::new(
+ cause.clone(),
+ self.param_env,
+ trait_ref.without_const().to_predicate(),
+ );
if !self.infcx.predicate_may_hold(&obligation) {
debug!("overloaded_deref_ty: cannot match obligation");
return None;
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 58f407b..b33cc52 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -8,7 +8,6 @@
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::{infer, traits};
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::Res;
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index cbbfe2d..d254a84 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -49,8 +49,6 @@
use rustc_span::Span;
use syntax::ast;
-use rustc_error_codes::*;
-
/// Reifies a cast check to be checked once we have full type information for
/// a function context.
pub struct CastCheck<'tcx> {
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index a32fbff..54b32c3 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -65,7 +65,6 @@
use rustc::ty::relate::RelateResult;
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TypeAndMut};
-use rustc_error_codes::*;
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -565,7 +564,7 @@
let obligation = queue.remove(0);
debug!("coerce_unsized resolve step: {:?}", obligation);
let trait_ref = match obligation.predicate {
- ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => {
+ ty::Predicate::Trait(ref tr, _) if traits.contains(&tr.def_id()) => {
if unsize_did == tr.def_id() {
let sty = &tr.skip_binder().input_types().nth(1).unwrap().kind;
if let ty::Tuple(..) = sty {
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index c35661a..414f80d 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -15,8 +15,6 @@
use super::{potentially_plural_count, FnCtxt, Inherited};
-use rustc_error_codes::*;
-
/// Checks that a method from an impl conforms to the signature of
/// the same method as declared in the trait.
///
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 88e7a26..32773e2 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -14,8 +14,6 @@
use rustc_span::Span;
-use rustc_error_codes::*;
-
/// This function confirms that the `Drop` implementation identified by
/// `drop_impl_did` is not any more specialized than the type it is
/// attached to (Issue #8142).
@@ -234,7 +232,7 @@
let predicate_matches_closure = |p: &'_ Predicate<'tcx>| {
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
match (predicate, p) {
- (Predicate::Trait(a), Predicate::Trait(b)) => relator.relate(a, b).is_ok(),
+ (Predicate::Trait(a, _), Predicate::Trait(b, _)) => relator.relate(a, b).is_ok(),
(Predicate::Projection(a), Predicate::Projection(b)) => {
relator.relate(a, b).is_ok()
}
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 35342de..201a09f 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -38,8 +38,6 @@
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
-use rustc_error_codes::*;
-
use std::fmt::Display;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 0441514..3572eda 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -6,7 +6,6 @@
use rustc::traits::{ObligationCause, ObligationCauseCode};
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt};
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_span::symbol::Symbol;
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 636ea5b..2012a2a 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -569,7 +569,7 @@
traits::elaborate_predicates(self.tcx, predicates.predicates.clone())
.filter_map(|predicate| match predicate {
- ty::Predicate::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => {
+ ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => {
Some(trait_pred)
}
_ => None,
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 711c285..c1cf352 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -17,7 +17,7 @@
use rustc::ty::subst::Subst;
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::ty::GenericParamDefKind;
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable};
+use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable, WithConstness};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
@@ -322,7 +322,7 @@
span,
self.body_id,
self.param_env,
- poly_trait_ref.to_predicate(),
+ poly_trait_ref.without_const().to_predicate(),
);
// Now we want to know if this can be matched
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index b2542cc..2adf125 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -25,6 +25,7 @@
use rustc::ty::GenericParamDefKind;
use rustc::ty::{
self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
+ WithConstness,
};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
@@ -38,8 +39,6 @@
use syntax::ast;
use syntax::util::lev_distance::{find_best_match_for_name, lev_distance};
-use rustc_error_codes::*;
-
use smallvec::{smallvec, SmallVec};
use self::CandidateKind::*;
@@ -826,7 +825,7 @@
// FIXME: do we want to commit to this behavior for param bounds?
let bounds = self.param_env.caller_bounds.iter().filter_map(|predicate| match *predicate {
- ty::Predicate::Trait(ref trait_predicate) => {
+ ty::Predicate::Trait(ref trait_predicate, _) => {
match trait_predicate.skip_binder().trait_ref.self_ty().kind {
ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()),
_ => None,
@@ -1396,7 +1395,7 @@
}
TraitCandidate(trait_ref) => {
- let predicate = trait_ref.to_predicate();
+ let predicate = trait_ref.without_const().to_predicate();
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
if !self.predicate_may_hold(&obligation) {
if self.probe(|_| self.select_trait_candidate(trait_ref).is_err()) {
@@ -1430,7 +1429,7 @@
let o = self.resolve_vars_if_possible(&o);
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
- if let &ty::Predicate::Trait(ref pred) = &o.predicate {
+ if let &ty::Predicate::Trait(ref pred, _) = &o.predicate {
possibly_unsatisfied_predicates.push(pred.skip_binder().trait_ref);
}
}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index d6c0d9c..e9942fa 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -9,7 +9,7 @@
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc::traits::Obligation;
use rustc::ty::print::with_crate_prefix;
-use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
@@ -21,8 +21,6 @@
use syntax::ast;
use syntax::util::lev_distance;
-use rustc_error_codes::*;
-
use std::cmp::Ordering;
use super::probe::Mode;
@@ -59,7 +57,7 @@
span,
self.body_id,
self.param_env,
- poly_trait_ref.to_predicate(),
+ poly_trait_ref.without_const().to_predicate(),
);
self.predicate_may_hold(&obligation)
})
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index dff68b9..3818750 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -90,6 +90,7 @@
use crate::astconv::{AstConv, PathSeg};
use crate::middle::lang_items;
use crate::namespace::Namespace;
+use rustc::hir::map::blocks::FnLikeNode;
use rustc::hir::map::Map;
use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282;
@@ -112,7 +113,7 @@
use rustc::ty::util::{Discr, IntTypeExt, Representability};
use rustc::ty::{
self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
- ToPredicate, Ty, TyCtxt, UserType,
+ ToPredicate, Ty, TyCtxt, UserType, WithConstness,
};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -133,8 +134,6 @@
use syntax::attr;
use syntax::util::parser::ExprPrecedence;
-use rustc_error_codes::*;
-
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::cmp;
use std::collections::hash_map::Entry;
@@ -1423,7 +1422,7 @@
inherited.register_predicate(traits::Obligation::new(
cause,
param_env,
- trait_ref.to_predicate(),
+ trait_ref.without_const().to_predicate(),
));
}
}
@@ -1709,17 +1708,11 @@
check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
}
hir::ItemKind::Fn(..) => {} // entirely within check_item_body
- hir::ItemKind::Impl(.., ref impl_item_refs) => {
+ hir::ItemKind::Impl { ref items, .. } => {
debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
let impl_def_id = tcx.hir().local_def_id(it.hir_id);
if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
- check_impl_items_against_trait(
- tcx,
- it.span,
- impl_def_id,
- impl_trait_ref,
- impl_item_refs,
- );
+ check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
let trait_def_id = impl_trait_ref.def_id;
check_on_unimplemented(tcx, trait_def_id, it);
}
@@ -2618,6 +2611,16 @@
None
}
+ fn default_constness_for_trait_bounds(&self) -> ast::Constness {
+ // FIXME: refactor this into a method
+ let node = self.tcx.hir().get(self.body_id);
+ if let Some(fn_like) = FnLikeNode::from_node(node) {
+ fn_like.constness()
+ } else {
+ ast::Constness::NotConst
+ }
+ }
+
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
let tcx = self.tcx;
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -2629,7 +2632,7 @@
parent: None,
predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
|&predicate| match predicate {
- ty::Predicate::Trait(ref data)
+ ty::Predicate::Trait(ref data, _)
if data.skip_binder().self_ty().is_param(index) =>
{
// HACK(eddyb) should get the original `Span`.
@@ -3701,7 +3704,7 @@
ty::Predicate::Projection(ref data) => {
Some((data.to_poly_trait_ref(self.tcx), obligation))
}
- ty::Predicate::Trait(ref data) => Some((data.to_poly_trait_ref(), obligation)),
+ ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
ty::Predicate::Subtype(..) => None,
ty::Predicate::RegionOutlives(..) => None,
ty::Predicate::TypeOutlives(..) => None,
@@ -4004,7 +4007,7 @@
continue;
}
- if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+ if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
// Collect the argument position for all arguments that could have caused this
// `FulfillmentError`.
let mut referenced_in = final_arg_types
@@ -4048,7 +4051,7 @@
if let hir::ExprKind::Path(qpath) = &path.kind {
if let hir::QPath::Resolved(_, path) = &qpath {
for error in errors {
- if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+ if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
// If any of the type arguments in this path segment caused the
// `FullfillmentError`, point at its span (#61860).
for arg in path
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index edf9d19..91e1731 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -11,8 +11,6 @@
use rustc_span::Span;
use syntax::ast::Ident;
-use rustc_error_codes::*;
-
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Checks a `a <op>= b`
pub fn check_binop_assign(
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 1478b35..f9dee0e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -15,8 +15,6 @@
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
-use rustc_error_codes::*;
-
use std::cmp;
use std::collections::hash_map::Entry::{Occupied, Vacant};
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index a496a6e..8281182 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -6,7 +6,9 @@
use rustc::session::parse::feature_err;
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
use rustc::ty::subst::{InternalSubsts, Subst};
-use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::{
+ self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_hir::def_id::DefId;
@@ -18,8 +20,6 @@
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
-use rustc_error_codes::*;
-
/// Helper type of a temporary returned by `.for_item(...)`.
/// This is necessary because we can't write the following bound:
///
@@ -97,7 +97,7 @@
//
// won't be allowed unless there's an *explicit* implementation of `Send`
// for `T`
- hir::ItemKind::Impl(_, _, defaultness, _, ref trait_ref, ref self_ty, _) => {
+ hir::ItemKind::Impl { defaultness, ref of_trait, ref self_ty, .. } => {
let is_auto = tcx
.impl_trait_ref(tcx.hir().local_def_id(item.hir_id))
.map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
@@ -107,11 +107,11 @@
}
match polarity {
ty::ImplPolarity::Positive => {
- check_impl(tcx, item, self_ty, trait_ref);
+ check_impl(tcx, item, self_ty, of_trait);
}
ty::ImplPolarity::Negative => {
// FIXME(#27579): what amount of WF checking do we need for neg impls?
- if trait_ref.is_some() && !is_auto {
+ if of_trait.is_some() && !is_auto {
struct_span_err!(
tcx.sess,
item.span,
@@ -955,7 +955,8 @@
substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
};
- let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate());
+ let obligation =
+ traits::Obligation::new(cause, fcx.param_env, trait_ref.without_const().to_predicate());
if fcx.predicate_must_hold_modulo_regions(&obligation) {
true
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 8b3db15..79a006a 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -12,7 +12,6 @@
use rustc::ty::adjustment::CoerceUnsizedInfo;
use rustc::ty::TypeFoldable;
use rustc::ty::{self, Ty, TyCtxt};
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
@@ -57,7 +56,7 @@
let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT");
let sp = match tcx.hir().expect_item(impl_hir_id).kind {
- ItemKind::Impl(.., ty, _) => ty.span,
+ ItemKind::Impl { self_ty, .. } => self_ty.span,
_ => bug!("expected Drop impl item"),
};
@@ -94,7 +93,7 @@
Ok(()) => {}
Err(CopyImplementationError::InfrigingFields(fields)) => {
let item = tcx.hir().expect_item(impl_hir_id);
- let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.kind {
+ let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind {
tr.path.span
} else {
span
@@ -113,7 +112,8 @@
}
Err(CopyImplementationError::NotAnAdt) => {
let item = tcx.hir().expect_item(impl_hir_id);
- let span = if let ItemKind::Impl(.., ref ty, _) = item.kind { ty.span } else { span };
+ let span =
+ if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span };
struct_span_err!(
tcx.sess,
@@ -490,7 +490,7 @@
return err_info;
} else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_hir_id);
- let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind {
+ let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind {
t.path.span
} else {
tcx.hir().span(impl_hir_id)
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 673c1bd..d4c89b7 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -16,8 +16,6 @@
use rustc_span::Span;
use syntax::ast;
-use rustc_error_codes::*;
-
/// On-demand query: yields a map containing all types mapped to their inherent impls.
pub fn crate_inherent_impls(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateInherentImpls {
assert_eq!(crate_num, LOCAL_CRATE);
@@ -47,7 +45,7 @@
impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
fn visit_item(&mut self, item: &hir::Item<'_>) {
let ty = match item.kind {
- hir::ItemKind::Impl(.., None, ref ty, _) => ty,
+ hir::ItemKind::Impl { of_trait: None, ref self_ty, .. } => self_ty,
_ => return,
};
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index a9228c7..d60c3cf 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -6,8 +6,6 @@
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_error_codes::*;
-
pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
assert_eq!(crate_num, LOCAL_CRATE);
let krate = tcx.hir().krate();
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index fd685e7..5583e34 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -8,7 +8,6 @@
use rustc::traits;
use rustc::ty::query::Providers;
use rustc::ty::{self, TyCtxt, TypeFoldable};
-use rustc_error_codes::*;
use rustc_errors::struct_span_err;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::HirId;
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 1878f93..8052166 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -7,8 +7,6 @@
use rustc_hir as hir;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
-use rustc_error_codes::*;
-
pub fn check(tcx: TyCtxt<'_>) {
let mut orphan = OrphanChecker { tcx };
tcx.hir().krate().visit_all_item_likes(&mut orphan);
@@ -27,7 +25,7 @@
fn visit_item(&mut self, item: &hir::Item<'_>) {
let def_id = self.tcx.hir().local_def_id(item.hir_id);
// "Trait" impl
- if let hir::ItemKind::Impl(.., generics, Some(tr), impl_ty, _) = &item.kind {
+ if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind {
debug!(
"coherence2::orphan check: trait impl {}",
self.tcx.hir().node_to_string(item.hir_id)
@@ -72,7 +70,7 @@
let msg = format!("{} is not defined in the current crate{}", ty, postfix);
if *is_target_ty {
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
- err.span_label(impl_ty.span, &msg);
+ err.span_label(self_ty.span, &msg);
} else {
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
err.span_label(tr.path.span, &msg);
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 3f4035b..a604421 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -7,8 +7,6 @@
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::Unsafety;
-use rustc_error_codes::*;
-
pub fn check(tcx: TyCtxt<'_>) {
let mut unsafety = UnsafetyChecker { tcx };
tcx.hir().krate().visit_all_item_likes(&mut unsafety);
@@ -88,7 +86,7 @@
impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> {
fn visit_item(&mut self, item: &'v hir::Item<'v>) {
- if let hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) = item.kind {
+ if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind {
self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
}
}
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index dca3289..5821977 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -20,6 +20,7 @@
use crate::lint;
use crate::middle::resolve_lifetime as rl;
use crate::middle::weak_lang_items;
+use rustc::hir::map::blocks::FnLikeNode;
use rustc::hir::map::Map;
use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc::mir::mono::Linkage;
@@ -30,7 +31,7 @@
use rustc::ty::subst::{InternalSubsts, Subst};
use rustc::ty::util::Discr;
use rustc::ty::util::IntTypeExt;
-use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness};
use rustc::ty::{ReprOptions, ToPredicate};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
@@ -47,8 +48,6 @@
use syntax::ast::{Ident, MetaItemKind};
use syntax::attr::{list_contains_name, mark_used, InlineAttr, OptimizeAttr};
-use rustc_error_codes::*;
-
struct OnlySelfBounds(bool);
///////////////////////////////////////////////////////////////////////////
@@ -184,7 +183,7 @@
| hir::ItemKind::Enum(_, generics)
| hir::ItemKind::TraitAlias(generics, _)
| hir::ItemKind::Trait(_, _, generics, ..)
- | hir::ItemKind::Impl(_, _, _, generics, ..)
+ | hir::ItemKind::Impl { generics, .. }
| hir::ItemKind::Struct(_, generics) => (generics, true),
hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
| hir::ItemKind::TyAlias(_, generics) => (generics, false),
@@ -288,6 +287,22 @@
Some(self.item_def_id)
}
+ fn default_constness_for_trait_bounds(&self) -> ast::Constness {
+ // FIXME: refactor this into a method
+ let hir_id = self
+ .tcx
+ .hir()
+ .as_local_hir_id(self.item_def_id)
+ .expect("Non-local call to local provider is_const_fn");
+
+ let node = self.tcx.hir().get(hir_id);
+ if let Some(fn_like) = FnLikeNode::from_node(node) {
+ fn_like.constness()
+ } else {
+ ast::Constness::NotConst
+ }
+ }
+
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
self.tcx.at(span).type_param_predicates((self.item_def_id, def_id))
}
@@ -401,7 +416,7 @@
Node::Item(item) => {
match item.kind {
ItemKind::Fn(.., ref generics, _)
- | ItemKind::Impl(_, _, _, ref generics, ..)
+ | ItemKind::Impl { ref generics, .. }
| ItemKind::TyAlias(_, ref generics)
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
| ItemKind::Enum(_, ref generics)
@@ -411,7 +426,8 @@
// Implied `Self: Trait` and supertrait bounds.
if param_id == item_hir_id {
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
- extend = Some((identity_trait_ref.to_predicate(), item.span));
+ extend =
+ Some((identity_trait_ref.without_const().to_predicate(), item.span));
}
generics
}
@@ -432,7 +448,7 @@
icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
.into_iter()
.filter(|(predicate, _)| match predicate {
- ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index),
+ ty::Predicate::Trait(ref data, _) => data.skip_binder().self_ty().is_param(index),
_ => false,
}),
);
@@ -453,6 +469,7 @@
ty: Ty<'tcx>,
only_self_bounds: OnlySelfBounds,
) -> Vec<(ty::Predicate<'tcx>, Span)> {
+ let constness = self.default_constness_for_trait_bounds();
let from_ty_params = ast_generics
.params
.iter()
@@ -461,7 +478,7 @@
_ => None,
})
.flat_map(|bounds| bounds.iter())
- .flat_map(|b| predicates_from_bound(self, ty, b));
+ .flat_map(|b| predicates_from_bound(self, ty, b, constness));
let from_where_clauses = ast_generics
.where_clause
@@ -481,7 +498,7 @@
};
bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b)))
})
- .flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
+ .flat_map(|(bt, b)| predicates_from_bound(self, bt, b, constness));
from_ty_params.chain(from_where_clauses).collect()
}
@@ -531,7 +548,7 @@
tcx.predicates_of(def_id);
convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
}
- hir::ItemKind::Impl(..) => {
+ hir::ItemKind::Impl { .. } => {
tcx.generics_of(def_id);
tcx.type_of(def_id);
tcx.impl_trait_ref(def_id);
@@ -857,7 +874,7 @@
// which will, in turn, reach indirect supertraits.
for &(pred, span) in superbounds {
debug!("superbound: {:?}", pred);
- if let ty::Predicate::Trait(bound) = pred {
+ if let ty::Predicate::Trait(bound, _) = pred {
tcx.at(span).super_predicates_of(bound.def_id());
}
}
@@ -1052,9 +1069,7 @@
Node::Item(item) => {
match item.kind {
- ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => {
- generics
- }
+ ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics,
ItemKind::TyAlias(_, ref generics)
| ItemKind::Enum(_, ref generics)
@@ -1338,7 +1353,9 @@
icx.to_ty(ty)
}
}
- ItemKind::TyAlias(ref ty, _) | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty),
+ ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => {
+ icx.to_ty(self_ty)
+ }
ItemKind::Fn(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
@@ -1956,12 +1973,10 @@
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
match tcx.hir().expect_item(hir_id).kind {
- hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => {
- opt_trait_ref.as_ref().map(|ast_trait_ref| {
- let selfty = tcx.type_of(def_id);
- AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
- })
- }
+ hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| {
+ let selfty = tcx.type_of(def_id);
+ AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
+ }),
_ => bug!(),
}
}
@@ -1971,19 +1986,21 @@
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
let item = tcx.hir().expect_item(hir_id);
match &item.kind {
- hir::ItemKind::Impl(_, hir::ImplPolarity::Negative, ..) => {
+ hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative, .. } => {
if is_rustc_reservation {
tcx.sess.span_err(item.span, "reservation impls can't be negative");
}
ty::ImplPolarity::Negative
}
- hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => {
+ hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
if is_rustc_reservation {
tcx.sess.span_err(item.span, "reservation impls can't be inherent");
}
ty::ImplPolarity::Positive
}
- hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => {
+ hir::ItemKind::Impl {
+ polarity: hir::ImplPolarity::Positive, of_trait: Some(_), ..
+ } => {
if is_rustc_reservation {
ty::ImplPolarity::Reservation
} else {
@@ -2056,7 +2073,7 @@
let span = tcx.def_span(def_id);
result.predicates =
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
- ty::TraitRef::identity(tcx, def_id).to_predicate(),
+ ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(),
span,
))));
}
@@ -2106,6 +2123,7 @@
let mut is_default_impl_trait = None;
let icx = ItemCtxt::new(tcx, def_id);
+ let constness = icx.default_constness_for_trait_bounds();
const NO_GENERICS: &hir::Generics<'_> = &hir::Generics::empty();
@@ -2142,7 +2160,7 @@
Node::Item(item) => {
match item.kind {
- ItemKind::Impl(_, _, defaultness, ref generics, ..) => {
+ ItemKind::Impl { defaultness, ref generics, .. } => {
if defaultness.is_default() {
is_default_impl_trait = tcx.impl_trait_ref(def_id);
}
@@ -2230,7 +2248,10 @@
// (see below). Recall that a default impl is not itself an impl, but rather a
// set of defaults that can be incorporated into another impl.
if let Some(trait_ref) = is_default_impl_trait {
- predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id)));
+ predicates.push((
+ trait_ref.to_poly_trait_ref().without_const().to_predicate(),
+ tcx.def_span(def_id),
+ ));
}
// Collect the region predicates that were declared inline as
@@ -2304,11 +2325,18 @@
for bound in bound_pred.bounds.iter() {
match bound {
- &hir::GenericBound::Trait(ref poly_trait_ref, _) => {
+ &hir::GenericBound::Trait(ref poly_trait_ref, modifier) => {
+ let constness = match modifier {
+ hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst,
+ hir::TraitBoundModifier::None => constness,
+ hir::TraitBoundModifier::Maybe => bug!("this wasn't handled"),
+ };
+
let mut bounds = Bounds::default();
let _ = AstConv::instantiate_poly_trait_ref(
&icx,
poly_trait_ref,
+ constness,
ty,
&mut bounds,
);
@@ -2359,7 +2387,7 @@
// before uses of `U`. This avoids false ambiguity errors
// in trait checking. See `setup_constraining_predicates`
// for details.
- if let Node::Item(&Item { kind: ItemKind::Impl(..), .. }) = node {
+ if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
let self_ty = tcx.type_of(def_id);
let trait_ref = tcx.impl_trait_ref(def_id);
cgp::setup_constraining_predicates(
@@ -2484,11 +2512,18 @@
astconv: &dyn AstConv<'tcx>,
param_ty: Ty<'tcx>,
bound: &'tcx hir::GenericBound<'tcx>,
+ constness: ast::Constness,
) -> Vec<(ty::Predicate<'tcx>, Span)> {
match *bound {
- hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
+ hir::GenericBound::Trait(ref tr, modifier) => {
+ let constness = match modifier {
+ hir::TraitBoundModifier::Maybe => return vec![],
+ hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst,
+ hir::TraitBoundModifier::None => constness,
+ };
+
let mut bounds = Bounds::default();
- let _ = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut bounds);
+ let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds);
bounds.predicates(astconv.tcx(), param_ty)
}
hir::GenericBound::Outlives(ref lifetime) => {
@@ -2496,7 +2531,6 @@
let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region));
vec![(ty::Predicate::TypeOutlives(pred), lifetime.span)]
}
- hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![],
}
}
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index fb87b28..e9c18b5 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -20,8 +20,6 @@
use rustc_span::Span;
-use rustc_error_codes::*;
-
/// Checks that all the type/lifetime parameters on an impl also
/// appear in the trait ref or self type (or are constrained by a
/// where-clause). These rules are needed to ensure that, given a
@@ -75,10 +73,10 @@
impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
- if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.kind {
+ if let hir::ItemKind::Impl { ref items, .. } = item.kind {
let impl_def_id = self.tcx.hir().local_def_id(item.hir_id);
- enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs);
- enforce_impl_items_are_distinct(self.tcx, impl_item_refs);
+ enforce_impl_params_are_constrained(self.tcx, impl_def_id, items);
+ enforce_impl_items_are_distinct(self.tcx, items);
}
}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index b951883..3d27f91 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -64,7 +64,7 @@
#![feature(exhaustive_patterns)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(try_blocks)]
#![feature(never_type)]
#![recursion_limit = "256"]
@@ -109,8 +109,6 @@
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
-use rustc_error_codes::*;
-
use std::iter;
use astconv::{AstConv, Bounds};
@@ -382,6 +380,7 @@
&item_cx,
hir_trait,
DUMMY_SP,
+ syntax::ast::Constness::NotConst,
tcx.types.err,
&mut bounds,
true,
diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs
index 908429c..980d58a 100644
--- a/src/librustc_typeck/outlives/test.rs
+++ b/src/librustc_typeck/outlives/test.rs
@@ -4,8 +4,6 @@
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_span::symbol::sym;
-use rustc_error_codes::*;
-
pub fn test_inferred_outlives(tcx: TyCtxt<'_>) {
tcx.hir().krate().visit_all_item_likes(&mut OutlivesTest { tcx });
}
diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs
index 0688147..99b7b20 100644
--- a/src/librustc_typeck/structured_errors.rs
+++ b/src/librustc_typeck/structured_errors.rs
@@ -3,8 +3,6 @@
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use rustc_span::Span;
-use rustc_error_codes::*;
-
pub trait StructuredDiagnostic<'tcx> {
fn session(&self) -> &Session;
diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs
index 2f41bee1..ee94b10 100644
--- a/src/librustc_typeck/variance/test.rs
+++ b/src/librustc_typeck/variance/test.rs
@@ -4,8 +4,6 @@
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_span::symbol::sym;
-use rustc_error_codes::*;
-
pub fn test_variance(tcx: TyCtxt<'_>) {
tcx.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx });
}
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index f37f692..27f8059 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -462,7 +462,7 @@
.filter(|p| {
!orig_bounds.contains(p)
|| match p {
- &&ty::Predicate::Trait(pred) => pred.def_id() == sized_trait,
+ ty::Predicate::Trait(pred, _) => pred.def_id() == sized_trait,
_ => false,
}
})
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 525b1b2..18ebd25 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -1,7 +1,7 @@
use rustc::infer::InferOk;
use rustc::traits;
use rustc::ty::subst::Subst;
-use rustc::ty::ToPredicate;
+use rustc::ty::{ToPredicate, WithConstness};
use rustc_hir as hir;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_span::DUMMY_SP;
@@ -64,7 +64,7 @@
match infcx.evaluate_obligation(&traits::Obligation::new(
cause,
param_env,
- trait_ref.to_predicate(),
+ trait_ref.without_const().to_predicate(),
)) {
Ok(eval_result) => eval_result.may_apply(),
Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index c7e0f1e..8a6abe0 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -273,6 +273,22 @@
clean::Typedef {
type_: cx.tcx.type_of(did).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
+ item_type: build_type_alias_type(cx, did),
+ }
+}
+
+fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
+ let type_ = cx.tcx.type_of(did).clean(cx);
+ type_.def_id().and_then(|did| build_ty(cx, did))
+}
+
+pub fn build_ty(cx: &DocContext, did: DefId) -> Option<clean::Type> {
+ match cx.tcx.def_kind(did)? {
+ DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => {
+ Some(cx.tcx.type_of(did).clean(cx))
+ }
+ DefKind::TyAlias => build_type_alias_type(cx, did),
+ _ => None,
}
}
@@ -331,7 +347,7 @@
let for_ = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
match tcx.hir().expect_item(hir_id).kind {
- hir::ItemKind::Impl(.., ref t, _) => t.clean(cx),
+ hir::ItemKind::Impl { self_ty, .. } => self_ty.clean(cx),
_ => panic!("did given to build_impl was not an impl"),
}
} else {
@@ -351,9 +367,9 @@
let predicates = tcx.explicit_predicates_of(did);
let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
match tcx.hir().expect_item(hir_id).kind {
- hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => (
- item_ids.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>(),
- gen.clean(cx),
+ hir::ItemKind::Impl { ref generics, ref items, .. } => (
+ items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::<Vec<_>>(),
+ generics.clean(cx),
),
_ => panic!("did given to build_impl was not an impl"),
}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index be96546..7a7d69c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -482,7 +482,7 @@
use rustc::ty::Predicate;
match *self {
- Predicate::Trait(ref pred) => Some(pred.clean(cx)),
+ Predicate::Trait(ref pred, _) => Some(pred.clean(cx)),
Predicate::Subtype(ref pred) => Some(pred.clean(cx)),
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
@@ -1122,7 +1122,9 @@
MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
}
hir::ImplItemKind::TyAlias(ref ty) => {
- TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true)
+ let type_ = ty.clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
+ TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true)
}
hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(
OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() },
@@ -1282,10 +1284,13 @@
AssocTypeItem(bounds, ty.clean(cx))
} else {
+ let type_ = cx.tcx.type_of(self.def_id).clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
TypedefItem(
Typedef {
- type_: cx.tcx.type_of(self.def_id).clean(cx),
+ type_,
generics: Generics { params: Vec::new(), where_predicates: Vec::new() },
+ item_type,
},
true,
)
@@ -1989,6 +1994,8 @@
impl Clean<Item> for doctree::Typedef<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
+ let type_ = self.ty.clean(cx);
+ let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
@@ -1997,10 +2004,7 @@
visibility: self.vis.clean(cx),
stability: cx.stability(self.id).clean(cx),
deprecation: cx.deprecation(self.id).clean(cx),
- inner: TypedefItem(
- Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) },
- false,
- ),
+ inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
}
}
}
@@ -2101,7 +2105,7 @@
build_deref_target_impls(cx, &items, &mut ret);
}
- let provided = trait_
+ let provided: FxHashSet<String> = trait_
.def_id()
.map(|did| {
cx.tcx
@@ -2112,7 +2116,12 @@
})
.unwrap_or_default();
- ret.push(Item {
+ let for_ = self.for_.clean(cx);
+ let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
+ Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)),
+ _ => None,
+ });
+ let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
@@ -2123,15 +2132,19 @@
inner: ImplItem(Impl {
unsafety: self.unsafety,
generics: self.generics.clean(cx),
- provided_trait_methods: provided,
+ provided_trait_methods: provided.clone(),
trait_,
- for_: self.for_.clean(cx),
+ for_,
items,
polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)),
synthetic: false,
blanket_impl: None,
}),
- });
+ };
+ if let Some(type_alias) = type_alias {
+ ret.push(make_item(trait_.clone(), type_alias, items.clone()));
+ }
+ ret.push(make_item(trait_, for_, items));
ret
}
}
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index c7b12d3..2b59c60 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -141,7 +141,7 @@
.predicates
.iter()
.filter_map(|(pred, _)| {
- if let ty::Predicate::Trait(ref pred) = *pred {
+ if let ty::Predicate::Trait(ref pred, _) = *pred {
if pred.skip_binder().trait_ref.self_ty() == self_ty {
Some(pred.def_id())
} else {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5d8e27e..79a078c 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1406,6 +1406,14 @@
pub struct Typedef {
pub type_: Type,
pub generics: Generics,
+ // Type of target item.
+ pub item_type: Option<Type>,
+}
+
+impl GetDefId for Typedef {
+ fn def_id(&self) -> Option<DefId> {
+ self.type_.def_id()
+ }
}
#[derive(Clone, Debug)]
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 178ba69..218674b 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -203,6 +203,7 @@
pub unsafety: hir::Unsafety,
pub polarity: hir::ImplPolarity,
pub defaultness: hir::Defaultness,
+ pub constness: ast::Constness,
pub generics: &'hir hir::Generics<'hir>,
pub trait_: &'hir Option<hir::TraitRef<'hir>>,
pub for_: &'hir hir::Ty<'hir>,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 6434dcc..79923fc 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -361,6 +361,7 @@
let modifier_str = match modifier {
hir::TraitBoundModifier::None => "",
hir::TraitBoundModifier::Maybe => "?",
+ hir::TraitBoundModifier::MaybeConst => "?const",
};
if f.alternate() {
write!(f, "{}{:#}", modifier_str, ty.print())
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index aa52b76..5bea1b5 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -41,7 +41,7 @@
let fm = sess
.source_map()
.new_source_file(FileName::Custom(String::from("rustdoc-highlighting")), src.to_owned());
- let highlight_result = {
+ let highlight_result = rustc_driver::catch_fatal_errors(|| {
let lexer = lexer::StringReader::new(&sess, fm, None);
let mut classifier = Classifier::new(lexer, sess.source_map());
@@ -51,7 +51,8 @@
} else {
Ok(String::from_utf8_lossy(&highlighted_source).into_owned())
}
- };
+ })
+ .unwrap_or(Err(()));
match highlight_result {
Ok(highlighted_source) => {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c5f88f9..c87964a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -380,7 +380,10 @@
}
_ => {}
}
- self.buf.push_back(event);
+ match event {
+ Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
+ event => self.buf.push_back(event),
+ }
}
let id = self.id_map.derive(id);
@@ -395,7 +398,7 @@
let start_tags = format!(
"<h{level} id=\"{id}\" class=\"section-header\">\
- <a href=\"#{id}\">",
+ <a href=\"#{id}\">",
id = id,
level = level
);
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2d932eb..ab38eec 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2321,8 +2321,8 @@
"{}{}{}{}{:#}fn {}{:#}",
it.visibility.print_with_space(),
f.header.constness.print_with_space(),
- f.header.unsafety.print_with_space(),
f.header.asyncness.print_with_space(),
+ f.header.unsafety.print_with_space(),
print_abi_with_space(f.header.abi),
it.name.as_ref().unwrap(),
f.generics.print()
@@ -2332,12 +2332,12 @@
render_attributes(w, it, false);
write!(
w,
- "{vis}{constness}{unsafety}{asyncness}{abi}fn \
+ "{vis}{constness}{asyncness}{unsafety}{abi}fn \
{name}{generics}{decl}{where_clause}</pre>",
vis = it.visibility.print_with_space(),
constness = f.header.constness.print_with_space(),
- unsafety = f.header.unsafety.print_with_space(),
asyncness = f.header.asyncness.print_with_space(),
+ unsafety = f.header.unsafety.print_with_space(),
abi = print_abi_with_space(f.header.abi),
name = it.name.as_ref().unwrap(),
generics = f.generics.print(),
@@ -2832,8 +2832,8 @@
"{}{}{}{}{}{:#}fn {}{:#}",
meth.visibility.print_with_space(),
header.constness.print_with_space(),
- header.unsafety.print_with_space(),
header.asyncness.print_with_space(),
+ header.unsafety.print_with_space(),
print_default_space(meth.is_default()),
print_abi_with_space(header.abi),
name,
@@ -2854,8 +2854,8 @@
if parent == ItemType::Trait { " " } else { "" },
meth.visibility.print_with_space(),
header.constness.print_with_space(),
- header.unsafety.print_with_space(),
header.asyncness.print_with_space(),
+ header.unsafety.print_with_space(),
print_default_space(meth.is_default()),
print_abi_with_space(header.abi),
href = href,
@@ -3469,20 +3469,23 @@
deref_mut: bool,
) {
let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
- let target = impl_
+ let (target, real_target) = impl_
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
- clean::TypedefItem(ref t, true) => Some(&t.type_),
+ clean::TypedefItem(ref t, true) => Some(match *t {
+ clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
+ _ => (&t.type_, &t.type_),
+ }),
_ => None,
})
.next()
.expect("Expected associated type binding");
let what =
- AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut };
+ AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut };
if let Some(did) = target.def_id() {
- render_assoc_items(w, cx, container_item, did, what)
+ render_assoc_items(w, cx, container_item, did, what);
} else {
if let Some(prim) = target.primitive_type() {
if let Some(&did) = cx.cache.primitive_locations.get(&prim) {
@@ -4123,12 +4126,15 @@
.filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
{
- if let Some(target) = impl_
+ if let Some((target, real_target)) = impl_
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
- clean::TypedefItem(ref t, true) => Some(&t.type_),
+ clean::TypedefItem(ref t, true) => Some(match *t {
+ clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
+ _ => (&t.type_, &t.type_),
+ }),
_ => None,
})
.next()
@@ -4147,7 +4153,7 @@
"{:#}",
impl_.inner_impl().trait_.as_ref().unwrap().print()
)),
- Escape(&format!("{:#}", target.print()))
+ Escape(&format!("{:#}", real_target.print()))
));
out.push_str("</a>");
let mut ret = impls
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 2250744..f1f83ac 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -277,7 +277,7 @@
| clean::StructFieldItem(..)
| clean::VariantItem(..) => (
(
- Some(*self.parent_stack.last().unwrap()),
+ Some(*self.parent_stack.last().expect("parent_stack is empty")),
Some(&self.stack[..self.stack.len() - 1]),
),
false,
@@ -286,7 +286,7 @@
if self.parent_stack.is_empty() {
((None, None), false)
} else {
- let last = self.parent_stack.last().unwrap();
+ let last = self.parent_stack.last().expect("parent_stack is empty 2");
let did = *last;
let path = match self.paths.get(&did) {
// The current stack not necessarily has correlation
@@ -468,7 +468,7 @@
self.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
}
} else {
- let trait_did = impl_item.trait_did().unwrap();
+ let trait_did = impl_item.trait_did().expect("no trait did");
self.orphan_trait_impls.push((trait_did, dids, impl_item));
}
None
@@ -478,10 +478,10 @@
});
if pushed {
- self.stack.pop().unwrap();
+ self.stack.pop().expect("stack already empty");
}
if parent_pushed {
- self.parent_stack.pop().unwrap();
+ self.parent_stack.pop().expect("parent stack already empty");
}
self.stripped_mod = orig_stripped_mod;
self.parent_is_trait_impl = orig_parent_is_trait_impl;
@@ -594,7 +594,7 @@
for item in search_index {
item.parent_idx = item.parent.map(|nodeid| {
if nodeid_to_pathid.contains_key(&nodeid) {
- *nodeid_to_pathid.get(&nodeid).unwrap()
+ *nodeid_to_pathid.get(&nodeid).expect("no pathid")
} else {
let pathid = lastpathid;
nodeid_to_pathid.insert(nodeid, pathid);
@@ -639,7 +639,7 @@
items: crate_items,
paths: crate_paths,
})
- .unwrap()
+ .expect("failed serde conversion")
)
}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1da00e3..403c8d0 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -23,7 +23,6 @@
extern crate rustc;
extern crate rustc_data_structures;
extern crate rustc_driver;
-extern crate rustc_error_codes;
extern crate rustc_errors;
extern crate rustc_expand;
extern crate rustc_feature;
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 0bab442..2903fd9 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -40,7 +40,7 @@
dox[code_block.code].to_owned(),
);
- let validation_status = {
+ let validation_status = rustc_driver::catch_fatal_errors(|| {
let mut has_syntax_errors = false;
let mut only_whitespace = true;
// even if there is a syntax error, we need to run the lexer over the whole file
@@ -61,7 +61,8 @@
} else {
None
}
- };
+ })
+ .unwrap_or(Some(CodeBlockInvalid::SyntaxError));
if let Some(code_block_invalid) = validation_status {
let mut diag = if let Some(sp) =
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index f899e72..d89dc2a 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -43,7 +43,7 @@
let crate_types = if options.proc_macro_crate {
vec![config::CrateType::ProcMacro]
} else {
- vec![config::CrateType::Dylib]
+ vec![config::CrateType::Rlib]
};
let sessopts = config::Options {
@@ -117,12 +117,16 @@
intravisit::walk_crate(this, krate);
});
});
+ compiler.session().abort_if_errors();
let ret: Result<_, ErrorReported> = Ok(collector.tests);
ret
})
- })
- .expect("compiler aborted in rustdoc!");
+ });
+ let tests = match tests {
+ Ok(tests) => tests,
+ Err(ErrorReported) => return 1,
+ };
test_args.insert(0, "rustdoctest".to_string());
@@ -905,8 +909,8 @@
}
fn visit_item(&mut self, item: &'hir hir::Item) {
- let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.kind {
- self.map.hir_to_pretty_string(ty.hir_id)
+ let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind {
+ self.map.hir_to_pretty_string(self_ty.hir_id)
} else {
item.ident.to_string()
};
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5fa9270..d3d45cc 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -558,27 +558,29 @@
om.trait_aliases.push(t);
}
- hir::ItemKind::Impl(
+ hir::ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
ref generics,
- ref trait_,
- for_,
- ref item_ids,
- ) => {
+ ref of_trait,
+ self_ty,
+ ref items,
+ } => {
// Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
// them up regardless of where they're located.
- if !self.inlining && trait_.is_none() {
+ if !self.inlining && of_trait.is_none() {
let items =
- item_ids.iter().map(|ii| self.cx.tcx.hir().impl_item(ii.id)).collect();
+ items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect();
let i = Impl {
unsafety,
polarity,
defaultness,
+ constness,
generics,
- trait_,
- for_,
+ trait_: of_trait,
+ for_: self_ty,
items,
attrs: &item.attrs,
id: item.hir_id,
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f906474..dc93ac9 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -275,7 +275,6 @@
#![feature(link_args)]
#![feature(linkage)]
#![feature(log_syntax)]
-#![feature(manually_drop_take)]
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_slice)]
#![feature(needs_panic_runtime)]
@@ -294,7 +293,7 @@
#![feature(shrink_to)]
#![feature(slice_concat_ext)]
#![feature(slice_internals)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 0b6e728..5bc8fe5 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -65,7 +65,7 @@
///
/// | Platform | System call |
/// |:---------:|:--------------------------------------------------------------------:|
-/// | Cloud ABI | [clock_time_get (Monotonic Clock)] |
+/// | CloudABI | [clock_time_get (Monotonic Clock)] |
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime (Monotonic Clock)] |
/// | Darwin | [mach_absolute_time] |
@@ -79,7 +79,7 @@
/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get
/// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime
/// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html
-/// [clock_time_get (Monotonic Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt
+/// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get
///
/// **Disclaimer:** These system calls might change over time.
///
@@ -144,7 +144,7 @@
///
/// | Platform | System call |
/// |:---------:|:--------------------------------------------------------------------:|
-/// | Cloud ABI | [clock_time_get (Realtime Clock)] |
+/// | CloudABI | [clock_time_get (Realtime Clock)] |
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime (Realtime Clock)] |
/// | DARWIN | [gettimeofday] |
@@ -152,7 +152,7 @@
/// | WASI | [__wasi_clock_time_get (Realtime Clock)] |
/// | Windows | [GetSystemTimeAsFileTime] |
///
-/// [clock_time_get (Realtime Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt
+/// [clock_time_get (Realtime Clock)]: https://nuxi.nl/cloudabi/#clock_time_get
/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
/// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index 7d9f715..2e647d2a 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -21,5 +21,4 @@
rustc_lexer = { path = "../librustc_lexer" }
rustc_macros = { path = "../librustc_macros" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
-rustc_error_codes = { path = "../librustc_error_codes" }
rustc_session = { path = "../librustc_session" }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 331eb10..5f38ac4 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -266,12 +266,24 @@
/// small, positive ids.
pub const DUMMY_NODE_ID: NodeId = NodeId::MAX;
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
+/// A modifier on a bound, e.g., `?Sized` or `?const Trait`.
+///
+/// Negative bounds should also be handled here.
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
pub enum TraitBoundModifier {
+ /// No modifiers
None,
+
+ /// `?Trait`
Maybe,
+
+ /// `?const Trait`
+ MaybeConst,
+
+ /// `?const ?Trait`
+ //
+ // This parses but will be rejected during AST validation.
+ MaybeConstMaybe,
}
/// The AST represents all type param bounds as types.
@@ -1033,7 +1045,7 @@
pub fn to_bound(&self) -> Option<GenericBound> {
match &self.kind {
ExprKind::Path(None, path) => Some(GenericBound::Trait(
- PolyTraitRef::new(Vec::new(), path.clone(), None, self.span),
+ PolyTraitRef::new(Vec::new(), path.clone(), self.span),
TraitBoundModifier::None,
)),
_ => None,
@@ -2158,7 +2170,8 @@
}
}
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+#[derive(HashStable_Generic)]
pub enum Constness {
Const,
NotConst,
@@ -2376,15 +2389,6 @@
pub struct TraitRef {
pub path: Path,
pub ref_id: NodeId,
-
- /// The `const` modifier, if any, that appears before this trait.
- ///
- /// | | `constness` |
- /// |----------------|-----------------------------|
- /// | `Trait` | `None` |
- /// | `const Trait` | `Some(Constness::Const)` |
- /// | `?const Trait` | `Some(Constness::NotConst)` |
- pub constness: Option<Constness>,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -2399,15 +2403,10 @@
}
impl PolyTraitRef {
- pub fn new(
- generic_params: Vec<GenericParam>,
- path: Path,
- constness: Option<Constness>,
- span: Span,
- ) -> Self {
+ pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self {
PolyTraitRef {
bound_generic_params: generic_params,
- trait_ref: TraitRef { path, constness, ref_id: DUMMY_NODE_ID },
+ trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
span,
}
}
@@ -2614,15 +2613,19 @@
/// An implementation.
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
- Impl(
- Unsafety,
- ImplPolarity,
- Defaultness,
- Generics,
- Option<TraitRef>, // (optional) trait this impl implements
- P<Ty>, // self
- Vec<AssocItem>,
- ),
+ Impl {
+ unsafety: Unsafety,
+ polarity: ImplPolarity,
+ defaultness: Defaultness,
+ constness: Constness,
+ generics: Generics,
+
+ /// The trait being implemented, if any.
+ of_trait: Option<TraitRef>,
+
+ self_ty: P<Ty>,
+ items: Vec<AssocItem>,
+ },
/// A macro invocation.
///
/// E.g., `foo!(..)`.
@@ -2649,7 +2652,7 @@
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
- ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item",
+ ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item",
}
}
}
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 70f4f47..6cfe4f2 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -12,8 +12,6 @@
use rustc_span::{symbol::sym, symbol::Symbol, Span};
use std::num::NonZeroU32;
-use rustc_error_codes::*;
-
pub fn is_builtin_attr(attr: &Attribute) -> bool {
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 0184a32..b0c2aa3 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -13,7 +13,7 @@
#![feature(label_break_value)]
#![feature(nll)]
#![feature(try_trait)]
-#![feature(slice_patterns)]
+#![cfg_attr(bootstrap, feature(slice_patterns))]
#![feature(unicode_internals)]
#![recursion_limit = "256"]
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 58d4e46..4a460c5 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -838,8 +838,7 @@
}
}
-pub fn noop_visit_trait_ref<T: MutVisitor>(tr: &mut TraitRef, vis: &mut T) {
- let TraitRef { path, ref_id, constness: _ } = tr;
+pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) {
vis.visit_path(path);
vis.visit_id(ref_id);
}
@@ -918,10 +917,19 @@
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
}
- ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => {
+ ItemKind::Impl {
+ unsafety: _,
+ polarity: _,
+ defaultness: _,
+ constness: _,
+ generics,
+ of_trait,
+ self_ty,
+ items,
+ } => {
vis.visit_generics(generics);
- visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref));
- vis.visit_ty(ty);
+ visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
+ vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
}
ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 11c8cb8..3927e4f 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1226,20 +1226,22 @@
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident, item.span, true);
}
- ast::ItemKind::Impl(
+ ast::ItemKind::Impl {
unsafety,
polarity,
defaultness,
+ constness,
ref generics,
- ref opt_trait,
- ref ty,
- ref impl_items,
- ) => {
+ ref of_trait,
+ ref self_ty,
+ ref items,
+ } => {
self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness);
self.print_unsafety(unsafety);
self.word_nbsp("impl");
+ self.print_constness(constness);
if !generics.params.is_empty() {
self.print_generic_params(&generics.params);
@@ -1250,19 +1252,19 @@
self.s.word("!");
}
- if let Some(ref t) = *opt_trait {
+ if let Some(ref t) = *of_trait {
self.print_trait_ref(t);
self.s.space();
self.word_space("for");
}
- self.print_type(ty);
+ self.print_type(self_ty);
self.print_where_clause(&generics.where_clause);
self.s.space();
self.bopen();
self.print_inner_attributes(&item.attrs);
- for impl_item in impl_items {
+ for impl_item in items {
self.print_assoc_item(impl_item);
}
self.bclose(item.span);
@@ -2773,6 +2775,13 @@
}
}
+ crate fn print_constness(&mut self, s: ast::Constness) {
+ match s {
+ ast::Constness::Const => self.word_nbsp("const"),
+ ast::Constness::NotConst => {}
+ }
+ }
+
crate fn print_is_auto(&mut self, s: ast::IsAuto) {
match s {
ast::IsAuto::Yes => self.word_nbsp("auto"),
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 3c2ebac..946a0d2 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -308,11 +308,20 @@
visitor.visit_generics(generics);
visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
}
- ItemKind::Impl(_, _, _, ref generics, ref opt_trait_reference, ref typ, ref impl_items) => {
+ ItemKind::Impl {
+ unsafety: _,
+ polarity: _,
+ defaultness: _,
+ constness: _,
+ ref generics,
+ ref of_trait,
+ ref self_ty,
+ ref items,
+ } => {
visitor.visit_generics(generics);
- walk_list!(visitor, visit_trait_ref, opt_trait_reference);
- visitor.visit_ty(typ);
- walk_list!(visitor, visit_impl_item, impl_items);
+ walk_list!(visitor, visit_trait_ref, of_trait);
+ visitor.visit_ty(self_ty);
+ walk_list!(visitor, visit_impl_item, items);
}
ItemKind::Struct(ref struct_definition, ref generics)
| ItemKind::Union(ref struct_definition, ref generics) => {
diff --git a/src/llvm-project b/src/llvm-project
index 9330ec5..cd87134 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 9330ec5a4c1df5fc1fa62f993ed6a04da68cb040
+Subproject commit cd87134ab77e6bacb2128137065b328b9c35e0e5
diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
index d5ddfb5..27fb3cb 100644
--- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
+++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
@@ -4,7 +4,7 @@
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
struct StructWithDtor(u32);
impl Drop for StructWithDtor {
@@ -16,7 +16,7 @@
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
let x = [StructWithDtor(0), StructWithDtor(1)];
drop_slice_in_place(&x);
@@ -31,7 +31,6 @@
// not have drop-glue for the unsized [StructWithDtor]. This has to be
// generated though when the drop_in_place() intrinsic is used.
//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
}
}
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index 94e79f0..675bdfd 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -37,7 +37,7 @@
struct NonGenericNoDrop(i32);
struct NonGenericWithDrop(i32);
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
impl Drop for NonGenericWithDrop {
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
@@ -47,11 +47,11 @@
//~ MONO_ITEM fn generic_drop_glue::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
@@ -60,17 +60,17 @@
// This is supposed to generate drop-glue because it contains a field that
// needs to be dropped.
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
let _ = match EnumWithDrop::A::<i32, i64>(0) {
EnumWithDrop::A(x) => x,
EnumWithDrop::B(x) => x as i32
};
- //~MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
+ //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
EnumWithDrop::A(x) => x,
diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
index e79b069..db0390b 100644
--- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -24,13 +24,13 @@
fn start(_: isize, _: *const *const u8) -> isize {
let s1 = Struct { _a: 0u32 };
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32>
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32>
let _ = &s1 as &Trait;
let s1 = Struct { _a: 0u64 };
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64>
//~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64>
let _ = &s1 as &Trait;
diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
index f13952b..a899b8b 100644
--- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
@@ -5,7 +5,7 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
struct StructWithDrop {
x: i32
}
@@ -19,7 +19,7 @@
x: i32
}
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
enum EnumWithDrop {
A(i32)
}
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index 14545a3..7e29af4 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -5,11 +5,11 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Root(Intermediate);
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Intermediate(Leaf);
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
struct Leaf;
impl Drop for Leaf {
@@ -30,15 +30,15 @@
fn start(_: isize, _: *const *const u8) -> isize {
let _ = Root(Intermediate(Leaf));
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
let _ = RootGen(IntermediateGen(LeafGen(0u32)));
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
let _ = RootGen(IntermediateGen(LeafGen(0i16)));
diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
index 54aff57..d77de53 100644
--- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
@@ -5,7 +5,7 @@
#![deny(dead_code)]
#![feature(start)]
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
struct Dropped;
impl Drop for Dropped {
@@ -16,11 +16,11 @@
//~ MONO_ITEM fn tuple_drop_glue::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
let x = (0u32, Dropped);
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
let x = (0i16, (Dropped, true));
0
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index fd794df..1ed60dc 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -48,13 +48,13 @@
fn start(_: isize, _: *const *const u8) -> isize {
// simple case
let bool_sized = &true;
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0]
let _bool_unsized = bool_sized as &Trait;
let char_sized = &'a';
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0]
let _char_unsized = char_sized as &Trait;
@@ -64,13 +64,13 @@
_b: 2,
_c: 3.0f64
};
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0]
let _struct_unsized = struct_sized as &Struct<Trait>;
// custom coercion
let wrapper_sized = Wrapper(&0u32);
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0]
let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs
index 0f3d72d..f85ae0c 100644
--- a/src/test/codegen-units/partitioning/extern-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs
@@ -11,14 +11,14 @@
// aux-build:cgu_extern_drop_glue.rs
extern crate cgu_extern_drop_glue;
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
struct LocalStruct(cgu_extern_drop_glue::Struct);
//~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
pub fn user()
{
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
@@ -30,7 +30,7 @@
//~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
pub fn user()
{
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
}
diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs
index 938d4ffb..366af4d 100644
--- a/src/test/codegen-units/partitioning/local-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/local-drop-glue.rs
@@ -7,7 +7,7 @@
#![allow(dead_code)]
#![crate_type="rlib"]
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
struct Struct {
_a: u32
}
@@ -17,7 +17,7 @@
fn drop(&mut self) {}
}
-//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
+//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
struct Outer {
_a: Struct
}
@@ -36,10 +36,10 @@
{
use super::Struct;
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
struct Struct2 {
_a: Struct,
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
_b: (u32, Struct),
}
diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs
index 5d23a4e..06e2ef6 100644
--- a/src/test/codegen-units/partitioning/vtable-through-const.rs
+++ b/src/test/codegen-units/partitioning/vtable-through-const.rs
@@ -66,7 +66,7 @@
//~ MONO_ITEM fn vtable_through_const::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
- //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ vtable_through_const[Internal]
+ //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ vtable_through_const[Internal]
// Since Trait1::do_something() is instantiated via its default implementation,
// it is considered a generic and is instantiated here only because it is
diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs
index 959929f..0c7f3bb 100644
--- a/src/test/codegen/drop.rs
+++ b/src/test/codegen/drop.rs
@@ -21,7 +21,7 @@
// regular function exit. We used to have problems with quadratic growths of drop calls in such
// functions.
// FIXME(eddyb) the `void @` forces a match on the instruction, instead of the
-// comment, that's `; call core::ptr::real_drop_in_place::<drop::SomeUniqueName>`
+// comment, that's `; call core::intrinsics::drop_in_place::<drop::SomeUniqueName>`
// for the `v0` mangling, should switch to matching on that once `legacy` is gone.
// CHECK-NOT: invoke void @{{.*}}drop_in_place{{.*}}SomeUniqueName
// CHECK: call void @{{.*}}drop_in_place{{.*}}SomeUniqueName
diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs
index 5808a8b..ca539fb 100644
--- a/src/test/mir-opt/const_prop/ref_deref_project.rs
+++ b/src/test/mir-opt/const_prop/ref_deref_project.rs
@@ -1,5 +1,5 @@
fn main() {
- *(&(4, 5).1);
+ *(&(4, 5).1); // This does not currently propagate (#67862)
}
// END RUST SOURCE
@@ -35,7 +35,7 @@
// ...
// _4 = const main::promoted[0];
// _2 = &((*_4).1: i32);
-// _1 = const 5i32;
+// _1 = (*_2);
// ...
// }
// END rustc.main.ConstProp.after.mir
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index ccecaea..1c88a9e 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -113,8 +113,8 @@
// }
// }
// END rustc.main-{{closure}}.EraseRegions.after.mir
-// START rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
-// fn std::ptr::real_drop_in_place(_1: &mut Test) -> () {
+// START rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+// fn std::intrinsics::drop_in_place(_1: *mut Test) -> () {
// ...
// bb0: {
// Retag([raw] _1);
@@ -126,4 +126,4 @@
// return;
// }
// }
-// END rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+// END rustc.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir
diff --git a/src/test/mir-opt/slice-drop-shim.rs b/src/test/mir-opt/slice-drop-shim.rs
index 5a37b67..a253755 100644
--- a/src/test/mir-opt/slice-drop-shim.rs
+++ b/src/test/mir-opt/slice-drop-shim.rs
@@ -6,7 +6,7 @@
// END RUST SOURCE
-// START rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir
+// START rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir
// let mut _2: usize;
// let mut _3: usize;
// let mut _4: usize;
@@ -87,4 +87,4 @@
// _3 = Len((*_1));
// switchInt(move _2) -> [0usize: bb8, otherwise: bb14];
// }
-// END rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir
+// END rustc.ptr-drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs
index f2e1864..d587d23 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/uniform_array_move_out.rs
@@ -1,5 +1,4 @@
#![feature(box_syntax)]
-#![feature(slice_patterns)]
fn move_out_from_end() {
let a = [box 1, box 2];
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
index f4d848d..88cfb62 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -45,7 +45,7 @@
// }
// END rustc.E-V-{{constant}}.mir_map.0.mir
-// START rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
+// START rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
// bb0: {
// goto -> bb7;
// }
@@ -71,7 +71,7 @@
// _2 = &mut (*_1);
// _3 = const <std::vec::Vec<i32> as std::ops::Drop>::drop(move _2) -> [return: bb6, unwind: bb5];
// }
-// END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
+// END rustc.ptr-drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
// START rustc.Test-X-{{constructor}}.mir_map.0.mir
// fn Test::X(_1: usize) -> Test {
diff --git a/src/test/run-make-fulldeps/issue64319/Makefile b/src/test/run-make-fulldeps/issue64319/Makefile
new file mode 100644
index 0000000..5592f5a
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue64319/Makefile
@@ -0,0 +1,39 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# Different optimization levels imply different values for `-Zshare-generics`,
+# so try out a whole bunch of combinations to make sure everything is compatible
+all:
+ # First up, try some defaults
+ $(RUSTC) --crate-type rlib foo.rs
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=3
+
+ # Next try mixing up some things explicitly
+ $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+ $(RUSTC) --crate-type rlib foo.rs -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+ $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+ $(RUSTC) --crate-type rlib foo.rs -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+
+ # Now combine a whole bunch of options together
+ $(RUSTC) --crate-type rlib foo.rs
+ $(RUSTC) --crate-type dylib bar.rs
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=1
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=1 -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=2
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=2 -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=3
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=3 -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=s
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=s -Z share-generics=yes
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=z
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=no
+ $(RUSTC) --crate-type dylib bar.rs -C opt-level=z -Z share-generics=yes
diff --git a/src/test/run-make-fulldeps/issue64319/bar.rs b/src/test/run-make-fulldeps/issue64319/bar.rs
new file mode 100644
index 0000000..3895c0b
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue64319/bar.rs
@@ -0,0 +1,5 @@
+extern crate foo;
+
+pub fn bar() {
+ foo::foo();
+}
diff --git a/src/test/run-make-fulldeps/issue64319/foo.rs b/src/test/run-make-fulldeps/issue64319/foo.rs
new file mode 100644
index 0000000..c54a238
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue64319/foo.rs
@@ -0,0 +1,9 @@
+pub fn foo() {
+ bar::<usize>();
+}
+
+pub fn bar<T>() {
+ baz();
+}
+
+fn baz() {}
diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile
deleted file mode 100644
index 7f5e904..0000000
--- a/src/test/run-make-fulldeps/sanitizer-address/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# needs-sanitizer-support
-
--include ../tools.mk
-
-LOG := $(TMPDIR)/log.txt
-
-# NOTE the address sanitizer only supports x86_64 linux and macOS
-
-ifeq ($(TARGET),x86_64-apple-darwin)
-EXTRA_RUSTFLAG=-C rpath
-else
-ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-
-# Apparently there are very specific Linux kernels, notably the one that's
-# currently on Travis CI, which contain a buggy commit that triggers failures in
-# the ASan implementation, detailed at google/sanitizers#837. As noted in
-# google/sanitizers#856 the "fix" is to avoid using PIE binaries, so we pass a
-# different relocation model to avoid generating a PIE binary. Once Travis is no
-# longer running kernel 4.4.0-93 we can remove this and pass an empty set of
-# flags again.
-EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic
-endif
-endif
-
-all:
- $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) rustc_rt.asan
- # Verify that stack buffer overflow is detected:
- $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow
- # Verify that variable name is included in address sanitizer report:
- $(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'"
diff --git a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs
deleted file mode 100644
index b997a74..0000000
--- a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
- let xs = [0, 1, 2, 3];
- let _y = unsafe { *xs.as_ptr().offset(4) };
-}
diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile
deleted file mode 100644
index 2a23f0f..0000000
--- a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
--include ../tools.mk
-
-all:
- $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | \
- $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target'
diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs
deleted file mode 100644
index d3dd5ed..0000000
--- a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![feature(no_core)]
-#![no_core]
-#![no_main]
diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile
deleted file mode 100644
index da37033..0000000
--- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
--include ../tools.mk
-
-# needs-sanitizer-support
-
-all:
- $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan
- $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks'
diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile
deleted file mode 100644
index 8bc9df1..0000000
--- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
--include ../tools.mk
-
-# needs-sanitizer-support
-# only-linux
-# only-x86_64
-
-all:
- $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) rustc_rt.msan
- $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value
- $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) rustc_rt.msan
- $(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value
diff --git a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs
deleted file mode 100644
index a9ae85f..0000000
--- a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use std::mem::MaybeUninit;
-
-fn main() {
- // This is technically not sound -- but we're literally trying to test
- // that the sanitizer catches this, so I guess "intentionally unsound"?
- let xs: [u8; 4] = unsafe { MaybeUninit::uninit().assume_init() };
- let y = xs[0] + xs[1];
-}
diff --git a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs
deleted file mode 100644
index eae5250..0000000
--- a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
- // This is technically not sound -- but we're literally trying to test
- // that the sanitizer catches this, so I guess "intentionally unsound"?
- #[allow(deprecated)]
- let xs: [u8; 4] = unsafe { std::mem::uninitialized() };
- let y = xs[0] + xs[1];
-}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/Makefile b/src/test/run-make-fulldeps/share-generics-dylib/Makefile
new file mode 100644
index 0000000..c6b5efc
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/Makefile
@@ -0,0 +1,22 @@
+# This test makes sure all generic instances get re-exported from Rust dylibs for use by
+# `-Zshare-generics`. There are two rlibs (`instance_provider_a` and `instance_provider_b`)
+# which both provide an instance of `Cell<i32>::set`. There is `instance_user_dylib` which is
+# supposed to re-export both these instances, and then there are `instance_user_a_rlib` and
+# `instance_user_b_rlib` which each rely on a specific instance to be available.
+#
+# In the end everything is linked together into `linked_leaf`. If `instance_user_dylib` does
+# not export both then we'll get an `undefined reference` error for one of the instances.
+#
+# This is regression test for https://github.com/rust-lang/rust/issues/67276.
+
+-include ../../run-make-fulldeps/tools.mk
+
+COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Zsymbol-mangling-version=v0
+
+all:
+ $(RUSTC) instance_provider_a.rs $(COMMON_ARGS) --crate-type=rlib
+ $(RUSTC) instance_provider_b.rs $(COMMON_ARGS) --crate-type=rlib
+ $(RUSTC) instance_user_dylib.rs $(COMMON_ARGS) --crate-type=dylib
+ $(RUSTC) instance_user_a_rlib.rs $(COMMON_ARGS) --crate-type=rlib
+ $(RUSTC) instance_user_b_rlib.rs $(COMMON_ARGS) --crate-type=rlib
+ $(RUSTC) linked_leaf.rs $(COMMON_ARGS) --crate-type=bin
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs
new file mode 100644
index 0000000..b4e125a
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs
@@ -0,0 +1,6 @@
+use std::cell::Cell;
+
+pub fn foo() {
+ let a: Cell<i32> = Cell::new(1);
+ a.set(123);
+}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs
new file mode 100644
index 0000000..f613db8
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs
@@ -0,0 +1,6 @@
+use std::cell::Cell;
+
+pub fn foo() {
+ let b: Cell<i32> = Cell::new(1);
+ b.set(123);
+}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs
new file mode 100644
index 0000000..c8e6ab9
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs
@@ -0,0 +1,9 @@
+extern crate instance_provider_a as upstream;
+use std::cell::Cell;
+
+pub fn foo() {
+ upstream::foo();
+
+ let b: Cell<i32> = Cell::new(1);
+ b.set(123);
+}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs
new file mode 100644
index 0000000..7c34af6
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs
@@ -0,0 +1,9 @@
+extern crate instance_provider_b as upstream;
+use std::cell::Cell;
+
+pub fn foo() {
+ upstream::foo();
+
+ let b: Cell<i32> = Cell::new(1);
+ b.set(123);
+}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs
new file mode 100644
index 0000000..7c8368e
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs
@@ -0,0 +1,7 @@
+extern crate instance_provider_a;
+extern crate instance_provider_b;
+
+pub fn foo() {
+ instance_provider_a::foo();
+ instance_provider_b::foo();
+}
diff --git a/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs b/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs
new file mode 100644
index 0000000..e510dad
--- /dev/null
+++ b/src/test/run-make-fulldeps/share-generics-dylib/linked_leaf.rs
@@ -0,0 +1,15 @@
+extern crate instance_user_dylib;
+extern crate instance_user_a_rlib;
+extern crate instance_user_b_rlib;
+
+use std::cell::Cell;
+
+fn main() {
+
+ instance_user_a_rlib::foo();
+ instance_user_b_rlib::foo();
+ instance_user_dylib::foo();
+
+ let a: Cell<i32> = Cell::new(1);
+ a.set(123);
+}
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
index 34e92c4..72037dd 100644
--- a/src/test/rustdoc-ui/invalid-syntax.rs
+++ b/src/test/rustdoc-ui/invalid-syntax.rs
@@ -93,3 +93,9 @@
///
pub fn indent_after_fenced() {}
//~^^^ WARNING could not parse code block as Rust code
+
+/// ```
+/// "invalid
+/// ```
+pub fn invalid() {}
+//~^^^^ WARNING could not parse code block as Rust code
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 32cc207..a90d3bb 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -132,3 +132,18 @@
|
= note: error from rustc: unknown start of token: \
+warning: could not parse code block as Rust code
+ --> $DIR/invalid-syntax.rs:97:5
+ |
+LL | /// ```
+ | _____^
+LL | | /// "invalid
+LL | | /// ```
+ | |_______^
+ |
+ = note: error from rustc: unterminated double quote string
+help: mark blocks that do not contain Rust code as text
+ |
+LL | /// ```text
+ | ^^^^^^^
+
diff --git a/src/test/rustdoc-ui/test-compile-fail1.rs b/src/test/rustdoc-ui/test-compile-fail1.rs
new file mode 100644
index 0000000..a053902
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail1.rs
@@ -0,0 +1,8 @@
+// compile-flags:--test
+
+/// ```
+/// assert!(true)
+/// ```
+pub fn f() {}
+
+pub fn f() {}
diff --git a/src/test/rustdoc-ui/test-compile-fail1.stderr b/src/test/rustdoc-ui/test-compile-fail1.stderr
new file mode 100644
index 0000000..2b38ba9
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail1.stderr
@@ -0,0 +1,14 @@
+error[E0428]: the name `f` is defined multiple times
+ --> $DIR/test-compile-fail1.rs:8:1
+ |
+6 | pub fn f() {}
+ | ---------- previous definition of the value `f` here
+7 |
+8 | pub fn f() {}
+ | ^^^^^^^^^^ `f` redefined here
+ |
+ = note: `f` must be defined only once in the value namespace of this module
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/rustdoc-ui/test-compile-fail2.rs b/src/test/rustdoc-ui/test-compile-fail2.rs
new file mode 100644
index 0000000..651ded0
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail2.rs
@@ -0,0 +1,3 @@
+// compile-flags:--test
+
+fail
diff --git a/src/test/rustdoc-ui/test-compile-fail2.stderr b/src/test/rustdoc-ui/test-compile-fail2.stderr
new file mode 100644
index 0000000..cee5b63
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail2.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!` or `::`, found `<eof>`
+ --> $DIR/test-compile-fail2.rs:3:1
+ |
+3 | fail
+ | ^^^^ expected one of `!` or `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/rustdoc-ui/test-compile-fail3.rs b/src/test/rustdoc-ui/test-compile-fail3.rs
new file mode 100644
index 0000000..faa30ad
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail3.rs
@@ -0,0 +1,3 @@
+// compile-flags:--test
+
+"fail
diff --git a/src/test/rustdoc-ui/test-compile-fail3.stderr b/src/test/rustdoc-ui/test-compile-fail3.stderr
new file mode 100644
index 0000000..7a2f181
--- /dev/null
+++ b/src/test/rustdoc-ui/test-compile-fail3.stderr
@@ -0,0 +1,8 @@
+error: unterminated double quote string
+ --> $DIR/test-compile-fail3.rs:3:1
+ |
+3 | "fail
+ | ^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/rustdoc-ui/test-no_std.rs b/src/test/rustdoc-ui/test-no_std.rs
new file mode 100644
index 0000000..166a873
--- /dev/null
+++ b/src/test/rustdoc-ui/test-no_std.rs
@@ -0,0 +1,12 @@
+// compile-flags:--test
+// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
+// build-pass
+
+#![no_std]
+
+extern crate alloc;
+
+/// ```
+/// assert!(true)
+/// ```
+pub fn f() {}
diff --git a/src/test/rustdoc-ui/test-no_std.stdout b/src/test/rustdoc-ui/test-no_std.stdout
new file mode 100644
index 0000000..9cdcac2
--- /dev/null
+++ b/src/test/rustdoc-ui/test-no_std.stdout
@@ -0,0 +1,6 @@
+
+running 1 test
+test $DIR/test-no_std.rs - f (line 9) ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
+
diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs
index 5f9708a..5a03e82 100644
--- a/src/test/rustdoc/async-fn.rs
+++ b/src/test/rustdoc/async-fn.rs
@@ -15,6 +15,11 @@
a
}
+// @has async_fn/fn.qux.html '//pre[@class="rust fn"]' 'pub async unsafe fn qux() -> char'
+pub async unsafe fn qux() -> char {
+ 'âš '
+}
+
trait Bar {}
impl Bar for () {}
@@ -26,8 +31,10 @@
// @has async_fn/struct.Foo.html
// @matches - '//code' 'pub async fn f\(\)$'
+// @matches - '//code' 'pub async unsafe fn g\(\)$'
pub struct Foo;
impl Foo {
pub async fn f() {}
+ pub async unsafe fn g() {}
}
diff --git a/src/test/rustdoc/bad-codeblock-syntax.rs b/src/test/rustdoc/bad-codeblock-syntax.rs
index ae8fbe4..afef86e 100644
--- a/src/test/rustdoc/bad-codeblock-syntax.rs
+++ b/src/test/rustdoc/bad-codeblock-syntax.rs
@@ -33,3 +33,10 @@
/// <script>alert("not valid Rust");</script>
/// ```
pub fn escape() {}
+
+// @has bad_codeblock_syntax/fn.unterminated.html
+// @has - '//*[@class="docblock"]/pre/code' '"unterminated'
+/// ```
+/// "unterminated
+/// ```
+pub fn unterminated() {}
diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs
new file mode 100644
index 0000000..770f8d7
--- /dev/null
+++ b/src/test/rustdoc/deref-typedef.rs
@@ -0,0 +1,33 @@
+#![crate_name = "foo"]
+
+// @has 'foo/struct.Bar.html'
+// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref<Target = FooC>'
+// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)'
+// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
+// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
+// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref<Target=FooC>'
+// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a'
+// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b'
+// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c'
+
+pub struct FooA;
+pub type FooB = FooA;
+pub type FooC = FooB;
+
+impl FooA {
+ pub fn foo_a(&self) {}
+}
+
+impl FooB {
+ pub fn foo_b(&self) {}
+}
+
+impl FooC {
+ pub fn foo_c(&self) {}
+}
+
+pub struct Bar;
+impl std::ops::Deref for Bar {
+ type Target = FooC;
+ fn deref(&self) -> &Self::Target { unimplemented!() }
+}
diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs
new file mode 100644
index 0000000..9761c1d
--- /dev/null
+++ b/src/test/rustdoc/remove-url-from-headings.rs
@@ -0,0 +1,17 @@
+#![crate_name = "foo"]
+
+// @has foo/fn.foo.html
+// !@has - '//a[@href="http://a.a"]'
+// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere'
+// @has - '//a[@href="#another-one-urg"]' 'Another one urg'
+
+/// fooo
+///
+/// # Implementing [stuff](http://a.a "title") somewhere
+///
+/// hello
+///
+/// # Another [one][two] urg
+///
+/// [two]: http://a.a
+pub fn foo() {}
diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs
similarity index 95%
rename from src/test/ui/match/match-vec-mismatch.rs
rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs
index a0ef927..34adb42 100644
--- a/src/test/ui/match/match-vec-mismatch.rs
+++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn main() {
match "foo".to_string() {
['f', 'o', ..] => {}
diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr
similarity index 80%
rename from src/test/ui/match/match-vec-mismatch.stderr
rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr
index a3523bb..c454814 100644
--- a/src/test/ui/match/match-vec-mismatch.stderr
+++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr
@@ -1,29 +1,29 @@
error[E0425]: cannot find value `does_not_exist` in this scope
- --> $DIR/match-vec-mismatch.rs:28:11
+ --> $DIR/slice-pat-type-mismatches.rs:26:11
|
LL | match does_not_exist {
| ^^^^^^^^^^^^^^ not found in this scope
error[E0529]: expected an array or slice, found `std::string::String`
- --> $DIR/match-vec-mismatch.rs:5:9
+ --> $DIR/slice-pat-type-mismatches.rs:3:9
|
LL | ['f', 'o', ..] => {}
| ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String`
error[E0527]: pattern requires 1 element but array has 3
- --> $DIR/match-vec-mismatch.rs:20:9
+ --> $DIR/slice-pat-type-mismatches.rs:18:9
|
LL | [0] => {},
| ^^^ expected 3 elements
error[E0528]: pattern requires at least 4 elements but array has 3
- --> $DIR/match-vec-mismatch.rs:25:9
+ --> $DIR/slice-pat-type-mismatches.rs:23:9
|
LL | [0, 1, 2, 3, x @ ..] => {}
| ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
error[E0282]: type annotations needed
- --> $DIR/match-vec-mismatch.rs:36:9
+ --> $DIR/slice-pat-type-mismatches.rs:34:9
|
LL | [] => {}
| ^^ cannot infer type
diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs
similarity index 75%
rename from src/test/ui/parser/match-vec-invalid.rs
rename to src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs
index 00f4374..97e3362 100644
--- a/src/test/ui/parser/match-vec-invalid.rs
+++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs
@@ -3,8 +3,6 @@
match a {
[1, tail @ .., tail @ ..] => {},
//~^ ERROR identifier `tail` is bound more than once in the same pattern
- //~| ERROR subslice patterns are unstable
- //~| ERROR subslice patterns are unstable
//~| ERROR `..` can only be used once per slice pattern
_ => ()
}
diff --git a/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr
new file mode 100644
index 0000000..4d60787
--- /dev/null
+++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr
@@ -0,0 +1,24 @@
+error[E0416]: identifier `tail` is bound more than once in the same pattern
+ --> $DIR/subslice-only-once-semantic-restriction.rs:4:24
+ |
+LL | [1, tail @ .., tail @ ..] => {},
+ | ^^^^ used in a pattern more than once
+
+error: `..` can only be used once per slice pattern
+ --> $DIR/subslice-only-once-semantic-restriction.rs:4:31
+ |
+LL | [1, tail @ .., tail @ ..] => {},
+ | -- ^^ can only be used once per slice pattern
+ | |
+ | previously used here
+
+error[E0308]: mismatched types
+ --> $DIR/subslice-only-once-semantic-restriction.rs:11:30
+ |
+LL | const RECOVERY_WITNESS: () = 0;
+ | ^ expected `()`, found integer
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0416.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs
index 0e767d9..69c3392 100644
--- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs
+++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs
@@ -2,7 +2,7 @@
// run-pass
-#![feature(slice_patterns, const_fn, const_if_match)]
+#![feature(const_fn, const_if_match)]
#[derive(PartialEq, Debug, Clone)]
struct N(u8);
diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs
index 5444f8a..0b793fa 100644
--- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs
+++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs
@@ -2,8 +2,6 @@
// run-pass
-#![feature(slice_patterns)]
-
#[derive(PartialEq, Debug, Clone)]
struct N(u8);
diff --git a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs
index 1ebf3de..e0579091 100644
--- a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs
+++ b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs
@@ -4,8 +4,6 @@
// run-pass
-#![feature(slice_patterns)]
-
#![allow(unreachable_patterns)]
use std::convert::identity;
diff --git a/src/test/ui/array-slice-vec/vec-matching-fixed.rs b/src/test/ui/array-slice-vec/vec-matching-fixed.rs
index 5253bc1..fdeb7e4 100644
--- a/src/test/ui/array-slice-vec/vec-matching-fixed.rs
+++ b/src/test/ui/array-slice-vec/vec-matching-fixed.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(slice_patterns)]
-
fn a() {
let x = [1, 2, 3];
match x {
diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs
index f416160..9988992 100644
--- a/src/test/ui/array-slice-vec/vec-matching-fold.rs
+++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(slice_patterns)]
-
use std::fmt::Debug;
fn foldl<T, U, F>(values: &[T],
diff --git a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs
index f0602c3..ed34f07 100644
--- a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs
+++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs
@@ -1,7 +1,6 @@
// run-pass
-#![allow(unused_variables)]
-#![feature(slice_patterns)]
+#![allow(unused_variables)]
pub fn main() {
let x = &[1, 2, 3, 4, 5];
diff --git a/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs
index 49c736b..7009244 100644
--- a/src/test/ui/array-slice-vec/vec-matching.rs
+++ b/src/test/ui/array-slice-vec/vec-matching.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(slice_patterns)]
-
fn a() {
let x = [1];
match x {
diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs
index 3c7b160..5f16992 100644
--- a/src/test/ui/array-slice-vec/vec-tail-matching.rs
+++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs
@@ -1,7 +1,5 @@
// run-pass
-#![feature(slice_patterns)]
-
struct Foo {
string: &'static str
}
diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs
index 645c903..ceeebbc 100644
--- a/src/test/ui/async-await/async-fn-nonsend.rs
+++ b/src/test/ui/async-await/async-fn-nonsend.rs
@@ -2,15 +2,15 @@
// edition:2018
// compile-flags: --crate-type lib
-use std::{
- cell::RefCell,
- fmt::Debug,
- rc::Rc,
-};
+use std::{cell::RefCell, fmt::Debug, rc::Rc};
-fn non_sync() -> impl Debug { RefCell::new(()) }
+fn non_sync() -> impl Debug {
+ RefCell::new(())
+}
-fn non_send() -> impl Debug { Rc::new(()) }
+fn non_send() -> impl Debug {
+ Rc::new(())
+}
fn take_ref<T>(_: &T) {}
@@ -53,5 +53,4 @@
//~^ ERROR future cannot be sent between threads safely
assert_send(non_sync_with_method_call());
//~^ ERROR future cannot be sent between threads safely
- //~^^ ERROR future cannot be sent between threads safely
}
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 5c870ca..105fd23 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -62,27 +62,5 @@
LL | }
| - `f` is later dropped here
-error: future cannot be sent between threads safely
- --> $DIR/async-fn-nonsend.rs:54:5
- |
-LL | fn assert_send(_: impl Send) {}
- | ----------- ---- required by this bound in `assert_send`
-...
-LL | assert_send(non_sync_with_method_call());
- | ^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
- |
- = help: within `std::fmt::ArgumentV1<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
-note: future is not `Send` as this value is used across an await
- --> $DIR/async-fn-nonsend.rs:43:9
- |
-LL | let f: &mut std::fmt::Formatter = panic!();
- | - has type `&mut std::fmt::Formatter<'_>`
-LL | if non_sync().fmt(f).unwrap() == () {
-LL | fut().await;
- | ^^^^^^^^^^^ await occurs here, with `f` maybe used later
-LL | }
-LL | }
- | - `f` is later dropped here
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
diff --git a/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs
index 4271ffb..0d0dbca 100644
--- a/src/test/ui/binding/empty-types-in-patterns.rs
+++ b/src/test/ui/binding/empty-types-in-patterns.rs
@@ -1,7 +1,8 @@
// run-pass
+
#![feature(never_type, never_type_fallback)]
#![feature(exhaustive_patterns)]
-#![feature(slice_patterns)]
+
#![allow(unreachable_patterns)]
#![allow(unreachable_code)]
#![allow(unused_variables)]
diff --git a/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs
index ac733ef..048e1e5 100644
--- a/src/test/ui/binding/irrefutable-slice-patterns.rs
+++ b/src/test/ui/binding/irrefutable-slice-patterns.rs
@@ -1,7 +1,6 @@
// run-pass
-// #47096
-#![feature(slice_patterns)]
+// Regression test for #47096.
fn foo(s: &[i32]) -> &[i32] {
let &[ref xs @ ..] = s;
diff --git a/src/test/ui/binding/match-byte-array-patterns.rs b/src/test/ui/binding/match-byte-array-patterns.rs
index e877457..f0c988c 100644
--- a/src/test/ui/binding/match-byte-array-patterns.rs
+++ b/src/test/ui/binding/match-byte-array-patterns.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn main() {
let buf = &[0u8; 4];
diff --git a/src/test/ui/binding/match-vec-alternatives.rs b/src/test/ui/binding/match-vec-alternatives.rs
index 9b06a86..af95eb9 100644
--- a/src/test/ui/binding/match-vec-alternatives.rs
+++ b/src/test/ui/binding/match-vec-alternatives.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str {
match (l1, l2) {
diff --git a/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs
index 5326fa6..187c298 100644
--- a/src/test/ui/binding/zero_sized_subslice_match.rs
+++ b/src/test/ui/binding/zero_sized_subslice_match.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn main() {
let x = [(), ()];
diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
index a70ccb7..0229ca3 100644
--- a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
+++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
@@ -1,6 +1,5 @@
// Check that closure captures for slice patterns are inferred correctly
-#![feature(slice_patterns)]
#![allow(unused_variables)]
// run-pass
diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs
index 984eb88..32057d5 100644
--- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs
+++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs
@@ -1,7 +1,5 @@
// Check that closure captures for slice patterns are inferred correctly
-#![feature(slice_patterns)]
-
fn arr_by_ref(mut x: [String; 3]) {
let f = || {
let [ref y, ref z @ ..] = x;
diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
index c5b27f5..483975e 100644
--- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
+++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
@@ -1,5 +1,5 @@
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-closures-slice-patterns.rs:9:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:7:13
|
LL | let f = || {
| -- immutable borrow occurs here
@@ -13,7 +13,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-closures-slice-patterns.rs:18:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:16:13
|
LL | let mut f = || {
| -- mutable borrow occurs here
@@ -27,7 +27,7 @@
| - mutable borrow later used here
error[E0382]: borrow of moved value: `x`
- --> $DIR/borrowck-closures-slice-patterns.rs:27:5
+ --> $DIR/borrowck-closures-slice-patterns.rs:25:5
|
LL | fn arr_by_move(x: [String; 3]) {
| - move occurs because `x` has type `[std::string::String; 3]`, which does not implement the `Copy` trait
@@ -40,7 +40,7 @@
| ^^ value borrowed here after move
error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-closures-slice-patterns.rs:35:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:33:13
|
LL | let f = || {
| -- immutable borrow occurs here
@@ -54,7 +54,7 @@
| - immutable borrow later used here
error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access
- --> $DIR/borrowck-closures-slice-patterns.rs:44:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:42:13
|
LL | let mut f = || {
| -- closure construction occurs here
@@ -68,7 +68,7 @@
| - first borrow later used here
error[E0382]: borrow of moved value: `x`
- --> $DIR/borrowck-closures-slice-patterns.rs:53:5
+ --> $DIR/borrowck-closures-slice-patterns.rs:51:5
|
LL | fn arr_box_by_move(x: Box<[String; 3]>) {
| - move occurs because `x` has type `std::boxed::Box<[std::string::String; 3]>`, which does not implement the `Copy` trait
@@ -81,7 +81,7 @@
| ^^ value borrowed here after move
error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-closures-slice-patterns.rs:61:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:59:13
|
LL | let f = || {
| -- immutable borrow occurs here
@@ -95,7 +95,7 @@
| - immutable borrow later used here
error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access
- --> $DIR/borrowck-closures-slice-patterns.rs:70:13
+ --> $DIR/borrowck-closures-slice-patterns.rs:68:13
|
LL | let mut f = || {
| -- closure construction occurs here
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs
index 8425960..c8bfbe0 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs
@@ -1,7 +1,5 @@
// ignore-tidy-linelength
-#![feature(slice_patterns)]
-
pub struct Foo {
x: u32
}
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
index 4213523..075e0e2 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -1,5 +1,5 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
- --> $DIR/borrowck-describe-lvalue.rs:258:13
+ --> $DIR/borrowck-describe-lvalue.rs:256:13
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
@@ -9,7 +9,7 @@
| ------ first borrow later used here
error[E0499]: cannot borrow `x` as mutable more than once at a time
- --> $DIR/borrowck-describe-lvalue.rs:268:20
+ --> $DIR/borrowck-describe-lvalue.rs:266:20
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
@@ -19,7 +19,7 @@
| ------ first borrow later used here
error: captured variable cannot escape `FnMut` closure body
- --> $DIR/borrowck-describe-lvalue.rs:266:16
+ --> $DIR/borrowck-describe-lvalue.rs:264:16
|
LL | || {
| - inferred to be a `FnMut` closure
@@ -35,7 +35,7 @@
= note: ...therefore, they cannot allow references to captured variables to escape
error[E0503]: cannot use `f.x` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:41:9
+ --> $DIR/borrowck-describe-lvalue.rs:39:9
|
LL | let x = f.x();
| - borrow of `f` occurs here
@@ -45,7 +45,7 @@
| - borrow later used here
error[E0503]: cannot use `g.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:48:9
+ --> $DIR/borrowck-describe-lvalue.rs:46:9
|
LL | let x = g.x();
| - borrow of `g` occurs here
@@ -55,7 +55,7 @@
| - borrow later used here
error[E0503]: cannot use `h.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:55:9
+ --> $DIR/borrowck-describe-lvalue.rs:53:9
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
@@ -65,7 +65,7 @@
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:63:20
+ --> $DIR/borrowck-describe-lvalue.rs:61:20
|
LL | let x = e.x();
| - borrow of `e` occurs here
@@ -77,7 +77,7 @@
| - borrow later used here
error[E0503]: cannot use `u.a` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:71:9
+ --> $DIR/borrowck-describe-lvalue.rs:69:9
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
@@ -87,7 +87,7 @@
| - borrow later used here
error[E0503]: cannot use `f.x` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:78:9
+ --> $DIR/borrowck-describe-lvalue.rs:76:9
|
LL | let x = f.x();
| - borrow of `*f` occurs here
@@ -97,7 +97,7 @@
| - borrow later used here
error[E0503]: cannot use `g.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:85:9
+ --> $DIR/borrowck-describe-lvalue.rs:83:9
|
LL | let x = g.x();
| - borrow of `*g` occurs here
@@ -107,7 +107,7 @@
| - borrow later used here
error[E0503]: cannot use `h.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:92:9
+ --> $DIR/borrowck-describe-lvalue.rs:90:9
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
@@ -117,7 +117,7 @@
| - borrow later used here
error[E0503]: cannot use `e.0` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:100:20
+ --> $DIR/borrowck-describe-lvalue.rs:98:20
|
LL | let x = e.x();
| - borrow of `*e` occurs here
@@ -129,7 +129,7 @@
| - borrow later used here
error[E0503]: cannot use `u.a` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:109:9
+ --> $DIR/borrowck-describe-lvalue.rs:107:9
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
@@ -139,7 +139,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:117:15
+ --> $DIR/borrowck-describe-lvalue.rs:115:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -151,7 +151,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:122:18
+ --> $DIR/borrowck-describe-lvalue.rs:120:18
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -163,7 +163,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:127:25
+ --> $DIR/borrowck-describe-lvalue.rs:125:25
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -175,7 +175,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:132:28
+ --> $DIR/borrowck-describe-lvalue.rs:130:28
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -187,7 +187,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:143:15
+ --> $DIR/borrowck-describe-lvalue.rs:141:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -199,7 +199,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:148:18
+ --> $DIR/borrowck-describe-lvalue.rs:146:18
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -211,7 +211,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:153:15
+ --> $DIR/borrowck-describe-lvalue.rs:151:15
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -223,7 +223,7 @@
| - borrow later used here
error[E0503]: cannot use `v[..]` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:158:18
+ --> $DIR/borrowck-describe-lvalue.rs:156:18
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -235,7 +235,7 @@
| - borrow later used here
error[E0503]: cannot use `e` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:171:13
+ --> $DIR/borrowck-describe-lvalue.rs:169:13
|
LL | let x = &mut e;
| ------ borrow of `e` occurs here
@@ -247,7 +247,7 @@
| - borrow later used here
error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:171:18
+ --> $DIR/borrowck-describe-lvalue.rs:169:18
|
LL | let x = &mut e;
| ------ mutable borrow occurs here
@@ -259,7 +259,7 @@
| - mutable borrow later used here
error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:175:23
+ --> $DIR/borrowck-describe-lvalue.rs:173:23
|
LL | let x = &mut e;
| ------ mutable borrow occurs here
@@ -271,7 +271,7 @@
| - mutable borrow later used here
error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:188:22
+ --> $DIR/borrowck-describe-lvalue.rs:186:22
|
LL | let x = &mut s;
| ------ mutable borrow occurs here
@@ -283,7 +283,7 @@
| - mutable borrow later used here
error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:194:28
+ --> $DIR/borrowck-describe-lvalue.rs:192:28
|
LL | let x = &mut s;
| ------ mutable borrow occurs here
@@ -295,7 +295,7 @@
| - mutable borrow later used here
error[E0503]: cannot use `*v` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:236:9
+ --> $DIR/borrowck-describe-lvalue.rs:234:9
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -306,7 +306,7 @@
| - borrow later used here
error[E0503]: cannot use `v[_].y` because it was mutably borrowed
- --> $DIR/borrowck-describe-lvalue.rs:236:9
+ --> $DIR/borrowck-describe-lvalue.rs:234:9
|
LL | let x = &mut v;
| ------ borrow of `v` occurs here
@@ -317,7 +317,7 @@
| - borrow later used here
error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:247:24
+ --> $DIR/borrowck-describe-lvalue.rs:245:24
|
LL | let x = &mut v;
| ------ mutable borrow occurs here
@@ -329,7 +329,7 @@
| - mutable borrow later used here
error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:210:29
+ --> $DIR/borrowck-describe-lvalue.rs:208:29
|
LL | let x = &mut block;
| ---------- mutable borrow occurs here
@@ -340,7 +340,7 @@
| - mutable borrow later used here
error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-describe-lvalue.rs:225:33
+ --> $DIR/borrowck-describe-lvalue.rs:223:33
|
LL | let x = &mut block;
| ---------- mutable borrow occurs here
@@ -351,7 +351,7 @@
| - mutable borrow later used here
error[E0382]: use of moved value: `x`
- --> $DIR/borrowck-describe-lvalue.rs:278:22
+ --> $DIR/borrowck-describe-lvalue.rs:276:22
|
LL | drop(x);
| - value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs
index 232d436..c1513fc 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
index e46a58a..84930b0 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-match.rs:15:14
+ --> $DIR/borrowck-move-out-from-array-match.rs:13:14
|
LL | [_, _, _x] => {}
| -- value moved here
@@ -10,7 +10,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-match.rs:25:14
+ --> $DIR/borrowck-move-out-from-array-match.rs:23:14
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -21,7 +21,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array-match.rs:35:15
+ --> $DIR/borrowck-move-out-from-array-match.rs:33:15
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -32,7 +32,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-match.rs:46:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:44:11
|
LL | [_x, _, _] => {}
| -- value moved here
@@ -43,7 +43,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-match.rs:57:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:55:11
|
LL | [.., _x] => {}
| -- value moved here
@@ -54,7 +54,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-match.rs:68:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:66:11
|
LL | [(_x, _), _, _] => {}
| -- value moved here
@@ -65,7 +65,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-match.rs:79:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:77:11
|
LL | [.., (_x, _)] => {}
| -- value moved here
@@ -76,7 +76,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array-match.rs:91:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:89:11
|
LL | [_y @ .., _, _] => {}
| ------- value moved here
@@ -87,7 +87,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array-match.rs:101:15
+ --> $DIR/borrowck-move-out-from-array-match.rs:99:15
|
LL | [_, _, _y @ ..] => {}
| ------- value moved here
@@ -98,7 +98,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-match.rs:112:11
+ --> $DIR/borrowck-move-out-from-array-match.rs:110:11
|
LL | [x @ .., _] => {}
| ------ value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
index e5e6169..056b8e6 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
@@ -3,8 +3,6 @@
// Once the bug is fixed, the test, which is derived from a
// passing test for `let` statements, should become check-pass.
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
index 72cd420..ff5eab2 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:19:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:17:11
|
LL | [_, _, _x] => {}
| -- value moved here
@@ -10,7 +10,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:30:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:28:11
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -21,7 +21,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:43:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:41:11
|
LL | [_x, _, _] => {}
| -- value moved here
@@ -32,7 +32,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:54:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:52:11
|
LL | [.., _x] => {}
| -- value moved here
@@ -43,7 +43,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:65:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:63:11
|
LL | [(_x, _), _, _] => {}
| -- value moved here
@@ -54,7 +54,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:76:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:74:11
|
LL | [.., (_x, _)] => {}
| -- value moved here
@@ -65,7 +65,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:87:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11
|
LL | [_, _y @ ..] => {}
| ------- value moved here
@@ -76,7 +76,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:98:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11
|
LL | [_y @ .., _] => {}
| ------- value moved here
@@ -87,7 +87,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:111:11
+ --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11
|
LL | [x @ .., _, _] => {}
| ------ value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs
index 8f274cf..c91b428 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs
index 1ca3df5..604a25c 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
index 028442a..0ef6310 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
@@ -1,5 +1,5 @@
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:15:14
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:13:14
|
LL | [_, _, _x] => {}
| -- value moved here
@@ -10,7 +10,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:25:14
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:23:14
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -21,7 +21,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:35:15
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:33:15
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -32,7 +32,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:46:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:44:11
|
LL | [_x, _, _] => {}
| -- value moved here
@@ -43,7 +43,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:57:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:55:11
|
LL | [.., _x] => {}
| -- value moved here
@@ -54,7 +54,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:68:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:66:11
|
LL | [(_x, _), _, _] => {}
| -- value moved here
@@ -65,7 +65,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:79:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:77:11
|
LL | [.., (_x, _)] => {}
| -- value moved here
@@ -76,7 +76,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:91:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:89:11
|
LL | [_y @ .., _, _] => {}
| ------- value moved here
@@ -87,7 +87,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:101:15
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:99:15
|
LL | [_, _, _y @ ..] => {}
| ------- value moved here
@@ -98,7 +98,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:112:11
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:110:11
|
LL | [x @ .., _] => {}
| ------ value moved here
@@ -109,7 +109,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:125:5
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:123:5
|
LL | [_, _, _x] => {}
| -- value moved here
@@ -120,7 +120,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:133:5
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:131:5
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -131,7 +131,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:141:5
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:139:5
|
LL | [_, _, _x @ ..] => {}
| ------- value moved here
@@ -142,7 +142,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-match.rs:149:5
+ --> $DIR/borrowck-move-out-from-array-use-match.rs:147:5
|
LL | [_, _, _x @ ..] => {}
| ------- value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
index 79fe593..5afd683 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
@@ -3,8 +3,6 @@
// Once the bug is fixed, the test, which is derived from a
// passing test for `let` statements, should become check-pass.
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
index 43ba2b6..a4042ce 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:19:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:17:11
|
LL | [_, _, _x] => {}
| -- value moved here
@@ -10,7 +10,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:30:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:28:11
|
LL | [_, _, (_x, _)] => {}
| -- value moved here
@@ -21,7 +21,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:43:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:41:11
|
LL | [_x, _, _] => {}
| -- value moved here
@@ -32,7 +32,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:54:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:52:11
|
LL | [.., _x] => {}
| -- value moved here
@@ -43,7 +43,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:65:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:63:11
|
LL | [(_x, _), _, _] => {}
| -- value moved here
@@ -54,7 +54,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:76:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:74:11
|
LL | [.., (_x, _)] => {}
| -- value moved here
@@ -65,7 +65,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:87:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11
|
LL | [_, _y @ ..] => {}
| ------- value moved here
@@ -76,7 +76,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:98:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11
|
LL | [_y @ .., _] => {}
| ------- value moved here
@@ -87,7 +87,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:111:11
+ --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11
|
LL | [x @ .., _, _] => {}
| ------ value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs
index 57ce241..e3498ce 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs
index 778beef..ad08367 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
index 2a7b891..7ad4116 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr
@@ -1,5 +1,5 @@
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use.rs:12:14
+ --> $DIR/borrowck-move-out-from-array-use.rs:10:14
|
LL | let [_, _, _x] = a;
| -- value moved here
@@ -9,7 +9,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use.rs:18:14
+ --> $DIR/borrowck-move-out-from-array-use.rs:16:14
|
LL | let [_, _, (_x, _)] = a;
| -- value moved here
@@ -19,7 +19,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array-use.rs:24:15
+ --> $DIR/borrowck-move-out-from-array-use.rs:22:15
|
LL | let [_, _, (_x, _)] = a;
| -- value moved here
@@ -29,7 +29,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:32:10
+ --> $DIR/borrowck-move-out-from-array-use.rs:30:10
|
LL | let [_x, _, _] = a;
| -- value moved here
@@ -39,7 +39,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:38:16
+ --> $DIR/borrowck-move-out-from-array-use.rs:36:16
|
LL | let [.., _x] = a;
| -- value moved here
@@ -49,7 +49,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:44:10
+ --> $DIR/borrowck-move-out-from-array-use.rs:42:10
|
LL | let [(_x, _), _, _] = a;
| -- value moved here
@@ -59,7 +59,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:50:16
+ --> $DIR/borrowck-move-out-from-array-use.rs:48:16
|
LL | let [.., (_x, _)] = a;
| -- value moved here
@@ -69,7 +69,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use.rs:56:11
+ --> $DIR/borrowck-move-out-from-array-use.rs:54:11
|
LL | let [_y @ .., _, _] = a;
| ------- value moved here
@@ -79,7 +79,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array-use.rs:62:15
+ --> $DIR/borrowck-move-out-from-array-use.rs:60:15
|
LL | let [_, _, _y @ ..] = a;
| ------- value moved here
@@ -89,7 +89,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: borrow of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:70:13
+ --> $DIR/borrowck-move-out-from-array-use.rs:68:13
|
LL | let [x @ .., _] = a;
| ------ value moved here
@@ -99,7 +99,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:78:5
+ --> $DIR/borrowck-move-out-from-array-use.rs:76:5
|
LL | let [_, _, _x] = a;
| -- value moved here
@@ -109,7 +109,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:84:5
+ --> $DIR/borrowck-move-out-from-array-use.rs:82:5
|
LL | let [_, _, (_x, _)] = a;
| -- value moved here
@@ -119,7 +119,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:90:5
+ --> $DIR/borrowck-move-out-from-array-use.rs:88:5
|
LL | let [_, _, _x @ ..] = a;
| ------- value moved here
@@ -129,7 +129,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array-use.rs:96:5
+ --> $DIR/borrowck-move-out-from-array-use.rs:94:5
|
LL | let [_, _, _x @ ..] = a;
| ------- value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs
index f9d3f6f..8375581 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn array() -> [(String, String); 3] {
Default::default()
}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
index 08134a2..b7babd9 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array.rs:12:14
+ --> $DIR/borrowck-move-out-from-array.rs:10:14
|
LL | let [_, _, _x] = a;
| -- value moved here
@@ -9,7 +9,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..]`
- --> $DIR/borrowck-move-out-from-array.rs:18:14
+ --> $DIR/borrowck-move-out-from-array.rs:16:14
|
LL | let [_, _, (_x, _)] = a;
| -- value moved here
@@ -19,7 +19,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array.rs:24:15
+ --> $DIR/borrowck-move-out-from-array.rs:22:15
|
LL | let [_, _, (_x, _)] = a;
| -- value moved here
@@ -29,7 +29,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array.rs:32:10
+ --> $DIR/borrowck-move-out-from-array.rs:30:10
|
LL | let [_x, _, _] = a;
| -- value moved here
@@ -39,7 +39,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array.rs:38:16
+ --> $DIR/borrowck-move-out-from-array.rs:36:16
|
LL | let [.., _x] = a;
| -- value moved here
@@ -49,7 +49,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array.rs:44:10
+ --> $DIR/borrowck-move-out-from-array.rs:42:10
|
LL | let [(_x, _), _, _] = a;
| -- value moved here
@@ -59,7 +59,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array.rs:50:16
+ --> $DIR/borrowck-move-out-from-array.rs:48:16
|
LL | let [.., (_x, _)] = a;
| -- value moved here
@@ -69,7 +69,7 @@
= note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array.rs:56:11
+ --> $DIR/borrowck-move-out-from-array.rs:54:11
|
LL | let [_y @ .., _, _] = a;
| ------- value moved here
@@ -79,7 +79,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a[..].0`
- --> $DIR/borrowck-move-out-from-array.rs:62:15
+ --> $DIR/borrowck-move-out-from-array.rs:60:15
|
LL | let [_, _, _y @ ..] = a;
| ------- value moved here
@@ -89,7 +89,7 @@
= note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait
error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-move-out-from-array.rs:70:13
+ --> $DIR/borrowck-move-out-from-array.rs:68:13
|
LL | let [x @ .., _] = a;
| ------ value moved here
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
index fa9a3c2..8ece81a 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
@@ -1,7 +1,5 @@
// Test that we do not permit moves from &[] matched by a vec pattern.
-#![feature(slice_patterns)]
-
#[derive(Clone, Debug)]
struct Foo {
string: String
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr
index 8fb4c06..a345c12 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr
@@ -1,5 +1,5 @@
error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
- --> $DIR/borrowck-move-out-of-vec-tail.rs:19:19
+ --> $DIR/borrowck-move-out-of-vec-tail.rs:17:19
|
LL | match tail {
| ^^^^ cannot move out of here
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs
index 7d91a21..a8e56f6 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(slice_patterns)]
-
fn nop(_s: &[& i32]) {}
fn nop_subslice(_s: &[i32]) {}
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs
index f03a2ab..6b210d7 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn nop(_s: &[& i32]) {}
fn nop_subslice(_s: &[i32]) {}
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
index e50e7eb..0432aaf 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr
@@ -1,5 +1,5 @@
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:8:13
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:6:13
|
LL | let [ref first, ref second, ..] = *s;
| ---------- immutable borrow occurs here
@@ -9,7 +9,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:14:14
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:12:14
|
LL | let [.., ref fourth, ref third, _, ref first] = *s;
| --------- immutable borrow occurs here
@@ -19,7 +19,7 @@
| ----- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:16
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:19:16
|
LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s;
| ------------- immutable borrow occurs here
@@ -30,7 +30,7 @@
| --------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:23:19
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:19
|
LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s;
| ------------- immutable borrow occurs here
@@ -41,7 +41,7 @@
| --------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:28:14
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:26:14
|
LL | let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s;
| --------------- immutable borrow occurs here
@@ -52,7 +52,7 @@
| ----------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:34:13
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:32:13
|
LL | let [ref first, ref second, ..] = *s;
| ---------- immutable borrow occurs here
@@ -62,7 +62,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:41:10
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:39:10
|
LL | let [.., ref second, ref first] = *s;
| ---------- immutable borrow occurs here
@@ -72,7 +72,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-array.rs:48:10
+ --> $DIR/borrowck-slice-pattern-element-loan-array.rs:46:10
|
LL | let [_, ref s1 @ ..] = *s;
| ----------- immutable borrow occurs here
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
index 048813b..4367596 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
@@ -1,7 +1,4 @@
// run-pass
-//compile-flags: -Z borrowck=mir
-
-#![feature(slice_patterns)]
fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> {
match *v {
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs
index e69071f..6390dc3 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs
@@ -1,7 +1,5 @@
// check-pass
-#![feature(slice_patterns)]
-
fn nop(_s: &[& i32]) {}
fn nop_subslice(_s: &[i32]) {}
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs
index 2ef9874..0e1c90a 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn nop(_s: &[& i32]) {}
fn nop_subslice(_s: &[i32]) {}
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
index b6f5ac6..d3388e0 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr
@@ -1,5 +1,5 @@
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:8:20
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:6:20
|
LL | if let [ref first, ref second, ..] = *s {
| ---------- immutable borrow occurs here
@@ -9,7 +9,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:16:21
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:14:21
|
LL | if let [.., ref fourth, ref third, _, ref first] = *s {
| --------- immutable borrow occurs here
@@ -19,7 +19,7 @@
| ----- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:24:20
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:22:20
|
LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
| ------------- immutable borrow occurs here
@@ -29,7 +29,7 @@
| --------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:27:23
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:25:23
|
LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
| ------------- immutable borrow occurs here
@@ -40,7 +40,7 @@
| --------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:30:26
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:28:26
|
LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s {
| ------------- immutable borrow occurs here
@@ -51,7 +51,7 @@
| --------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:35:21
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:33:21
|
LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
| --------------- immutable borrow occurs here
@@ -61,7 +61,7 @@
| ----------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:38:21
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:36:21
|
LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
| --------------- immutable borrow occurs here
@@ -72,7 +72,7 @@
| ----------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:41:21
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:39:21
|
LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
| --------------- immutable borrow occurs here
@@ -83,7 +83,7 @@
| ----------- immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:49:20
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:47:20
|
LL | if let [ref first, ref second, ..] = *s {
| ---------- immutable borrow occurs here
@@ -93,7 +93,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:58:17
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:56:17
|
LL | if let [.., ref second, ref first] = *s {
| ---------- immutable borrow occurs here
@@ -103,7 +103,7 @@
| ------ immutable borrow later used here
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:67:17
+ --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:65:17
|
LL | if let [_, _, _, ref s1 @ ..] = *s {
| ----------- immutable borrow occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
index 53a9bce..cd853b8 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn a<'a>() -> &'a [isize] {
let vec = vec![1, 2, 3, 4];
let vec: &[isize] = &vec;
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr
index da6d929..170982b 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr
@@ -1,5 +1,5 @@
error[E0515]: cannot return value referencing local variable `vec`
- --> $DIR/borrowck-vec-pattern-element-loan.rs:10:5
+ --> $DIR/borrowck-vec-pattern-element-loan.rs:8:5
|
LL | let vec: &[isize] = &vec;
| ---- `vec` is borrowed here
@@ -8,7 +8,7 @@
| ^^^^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing local variable `vec`
- --> $DIR/borrowck-vec-pattern-element-loan.rs:20:5
+ --> $DIR/borrowck-vec-pattern-element-loan.rs:18:5
|
LL | let vec: &[isize] = &vec;
| ---- `vec` is borrowed here
@@ -17,7 +17,7 @@
| ^^^^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing local variable `vec`
- --> $DIR/borrowck-vec-pattern-element-loan.rs:30:5
+ --> $DIR/borrowck-vec-pattern-element-loan.rs:28:5
|
LL | let vec: &[isize] = &vec;
| ---- `vec` is borrowed here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
index dd9023f..05859c9 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn a() {
let mut v = vec![1, 2, 3];
let vb: &mut [isize] = &mut v;
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr
index 251f445..5141fcc 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr
@@ -1,5 +1,5 @@
error[E0499]: cannot borrow `v` as mutable more than once at a time
- --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:8:13
+ --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:6:13
|
LL | let vb: &mut [isize] = &mut v;
| ------ first mutable borrow occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
index 4202230..9b8ba2e 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
@@ -1,7 +1,3 @@
-// http://rust-lang.org/COPYRIGHT.
-
-#![feature(slice_patterns)]
-
fn main() {
let mut a = [1, 2, 3, 4];
let t = match a {
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
index 9f8e6fe..ff70ba9f 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
@@ -1,5 +1,5 @@
error[E0506]: cannot assign to `a[_]` because it is borrowed
- --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5
+ --> $DIR/borrowck-vec-pattern-move-tail.rs:8:5
|
LL | [1, 2, ref tail @ ..] => tail,
| ------------- borrow of `a[_]` occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
index e274d10..67b6c12 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -1,6 +1,5 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
-#![feature(slice_patterns)]
fn a() {
let mut vec = [box 1, box 2, box 3];
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index a3324f2..e2c0852 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -1,5 +1,5 @@
error[E0506]: cannot assign to `vec[_]` because it is borrowed
- --> $DIR/borrowck-vec-pattern-nesting.rs:10:13
+ --> $DIR/borrowck-vec-pattern-nesting.rs:9:13
|
LL | [box ref _a, _, _] => {
| ------ borrow of `vec[_]` occurs here
@@ -11,7 +11,7 @@
| -- borrow later used here
error[E0506]: cannot assign to `vec[_]` because it is borrowed
- --> $DIR/borrowck-vec-pattern-nesting.rs:24:13
+ --> $DIR/borrowck-vec-pattern-nesting.rs:23:13
|
LL | &mut [ref _b @ ..] => {
| ----------- borrow of `vec[_]` occurs here
@@ -23,7 +23,7 @@
| -- borrow later used here
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:35:11
+ --> $DIR/borrowck-vec-pattern-nesting.rs:34:11
|
LL | match vec {
| ^^^ cannot move out of here
@@ -45,7 +45,7 @@
|
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:47:13
+ --> $DIR/borrowck-vec-pattern-nesting.rs:46:13
|
LL | let a = vec[0];
| ^^^^^^
@@ -55,7 +55,7 @@
| help: consider borrowing here: `&vec[0]`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:56:11
+ --> $DIR/borrowck-vec-pattern-nesting.rs:55:11
|
LL | match vec {
| ^^^ cannot move out of here
@@ -74,7 +74,7 @@
|
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:66:13
+ --> $DIR/borrowck-vec-pattern-nesting.rs:65:13
|
LL | let a = vec[0];
| ^^^^^^
@@ -84,7 +84,7 @@
| help: consider borrowing here: `&vec[0]`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:75:11
+ --> $DIR/borrowck-vec-pattern-nesting.rs:74:11
|
LL | match vec {
| ^^^ cannot move out of here
@@ -100,7 +100,7 @@
= note: move occurs because these variables have types that don't implement the `Copy` trait
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
- --> $DIR/borrowck-vec-pattern-nesting.rs:86:13
+ --> $DIR/borrowck-vec-pattern-nesting.rs:85:13
|
LL | let a = vec[0];
| ^^^^^^
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
index c35be2f..3987282 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn a<'a>() -> &'a isize {
let vec = vec![1, 2, 3, 4];
let vec: &[isize] = &vec;
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr
index c1290a6..7e21c55 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr
@@ -1,5 +1,5 @@
error[E0515]: cannot return value referencing local variable `vec`
- --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:10:5
+ --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:8:5
|
LL | let vec: &[isize] = &vec;
| ---- `vec` is borrowed here
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
index 8b70b15..89107e7 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
@@ -87,12 +87,12 @@
--> $DIR/variadic-ffi-4.rs:24:11
|
LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
- | - let's call the lifetime of this reference `'1`
+ | - let's call the lifetime of this reference `'3`
LL | ap0 = &mut ap1;
| ------^^^^^^^^
| | |
| | borrowed value does not live long enough
- | assignment requires that `ap1` is borrowed for `'1`
+ | assignment requires that `ap1` is borrowed for `'3`
...
LL | }
| - `ap1` dropped here while still borrowed
diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs
new file mode 100644
index 0000000..30fbfda
--- /dev/null
+++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn takes_closure_of_array_3<F>(f: F) where F: Fn([i32; 3]) {
+ f([1, 2, 3]);
+}
+
+fn takes_closure_of_array_3_apit(f: impl Fn([i32; 3])) {
+ f([1, 2, 3]);
+}
+
+fn returns_closure_of_array_3() -> impl Fn([i32; 3]) {
+ |_| {}
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr
new file mode 100644
index 0000000..7f37f3e
--- /dev/null
+++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/integer-literal-generic-arg-in-where-clause.rs:3:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs
index 64aeb46..af63d1f 100644
--- a/src/test/ui/consts/array-literal-index-oob.rs
+++ b/src/test/ui/consts/array-literal-index-oob.rs
@@ -1,4 +1,5 @@
// build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
#![warn(const_err)]
diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr
index 50ad8e8..e93aa32 100644
--- a/src/test/ui/consts/array-literal-index-oob.stderr
+++ b/src/test/ui/consts/array-literal-index-oob.stderr
@@ -1,17 +1,17 @@
warning: index out of bounds: the len is 3 but the index is 4
- --> $DIR/array-literal-index-oob.rs:6:8
+ --> $DIR/array-literal-index-oob.rs:7:8
|
LL | &{ [1, 2, 3][4] };
| ^^^^^^^^^^^^
|
note: lint level defined here
- --> $DIR/array-literal-index-oob.rs:3:9
+ --> $DIR/array-literal-index-oob.rs:4:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
- --> $DIR/array-literal-index-oob.rs:6:8
+ --> $DIR/array-literal-index-oob.rs:7:8
|
LL | &{ [1, 2, 3][4] };
| ---^^^^^^^^^^^^--
@@ -19,7 +19,7 @@
| indexing out of bounds: the len is 3 but the index is 4
warning: erroneous constant used
- --> $DIR/array-literal-index-oob.rs:6:5
+ --> $DIR/array-literal-index-oob.rs:7:5
|
LL | &{ [1, 2, 3][4] };
| ^^^^^^^^^^^^^^^^^ referenced constant has errors
diff --git a/src/test/ui/consts/associated_const_generic.rs b/src/test/ui/consts/associated_const_generic.rs
new file mode 100644
index 0000000..dee376c
--- /dev/null
+++ b/src/test/ui/consts/associated_const_generic.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+trait TraitA {
+ const VALUE: usize;
+}
+
+struct A;
+impl TraitA for A {
+ const VALUE: usize = 1;
+}
+
+trait TraitB {
+ type MyA: TraitA;
+ const VALUE: usize = Self::MyA::VALUE;
+}
+
+struct B;
+impl TraitB for B {
+ type MyA = A;
+}
+
+fn main() {
+ let _ = [0; A::VALUE];
+ let _ = [0; B::VALUE]; // Indirectly refers to `A::VALUE`
+}
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index fee2321..22f863f 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,4 +1,5 @@
// build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
// compile-flags: -O
#![warn(const_err)]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 4de22fd..b4330de 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,59 +1,59 @@
warning: this expression will panic at runtime
- --> $DIR/promoted_errors.rs:8:14
+ --> $DIR/promoted_errors.rs:9:14
|
LL | let _x = 0u32 - 1;
| ^^^^^^^^ attempt to subtract with overflow
|
note: lint level defined here
- --> $DIR/promoted_errors.rs:4:9
+ --> $DIR/promoted_errors.rs:5:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: attempt to divide by zero
- --> $DIR/promoted_errors.rs:10:20
+ --> $DIR/promoted_errors.rs:11:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
- --> $DIR/promoted_errors.rs:10:20
+ --> $DIR/promoted_errors.rs:11:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^ dividing by zero
warning: erroneous constant used
- --> $DIR/promoted_errors.rs:10:20
+ --> $DIR/promoted_errors.rs:11:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^ referenced constant has errors
warning: attempt to divide by zero
- --> $DIR/promoted_errors.rs:14:14
+ --> $DIR/promoted_errors.rs:15:14
|
LL | let _x = 1 / (1 - 1);
| ^^^^^^^^^^^
warning: attempt to divide by zero
- --> $DIR/promoted_errors.rs:16:20
+ --> $DIR/promoted_errors.rs:17:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
- --> $DIR/promoted_errors.rs:16:20
+ --> $DIR/promoted_errors.rs:17:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^ dividing by zero
warning: erroneous constant used
- --> $DIR/promoted_errors.rs:16:20
+ --> $DIR/promoted_errors.rs:17:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^ referenced constant has errors
warning: attempt to divide by zero
- --> $DIR/promoted_errors.rs:20:14
+ --> $DIR/promoted_errors.rs:21:14
|
LL | let _x = 1 / (false as u32);
| ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs
index 41a989d..62c77f7 100644
--- a/src/test/ui/consts/const-eval/promoted_errors2.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors2.rs
@@ -1,4 +1,5 @@
// build-pass
+// ignore-pass (emit codegen-time warnings and verify that they are indeed warnings and not errors)
// compile-flags: -C overflow-checks=on -O
#![warn(const_err)]
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr
index 4f7ba8b..a4dad29 100644
--- a/src/test/ui/consts/const-eval/promoted_errors2.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr
@@ -1,65 +1,65 @@
warning: attempt to subtract with overflow
- --> $DIR/promoted_errors2.rs:7:20
+ --> $DIR/promoted_errors2.rs:8:20
|
LL | println!("{}", 0u32 - 1);
| ^^^^^^^^
|
note: lint level defined here
- --> $DIR/promoted_errors2.rs:4:9
+ --> $DIR/promoted_errors2.rs:5:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
warning: attempt to subtract with overflow
- --> $DIR/promoted_errors2.rs:9:14
+ --> $DIR/promoted_errors2.rs:10:14
|
LL | let _x = 0u32 - 1;
| ^^^^^^^^
warning: attempt to divide by zero
- --> $DIR/promoted_errors2.rs:11:20
+ --> $DIR/promoted_errors2.rs:12:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
- --> $DIR/promoted_errors2.rs:11:20
+ --> $DIR/promoted_errors2.rs:12:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^ dividing by zero
warning: erroneous constant used
- --> $DIR/promoted_errors2.rs:11:20
+ --> $DIR/promoted_errors2.rs:12:20
|
LL | println!("{}", 1 / (1 - 1));
| ^^^^^^^^^^^ referenced constant has errors
warning: attempt to divide by zero
- --> $DIR/promoted_errors2.rs:15:14
+ --> $DIR/promoted_errors2.rs:16:14
|
LL | let _x = 1 / (1 - 1);
| ^^^^^^^^^^^
warning: attempt to divide by zero
- --> $DIR/promoted_errors2.rs:17:20
+ --> $DIR/promoted_errors2.rs:18:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^
warning: reaching this expression at runtime will panic or abort
- --> $DIR/promoted_errors2.rs:17:20
+ --> $DIR/promoted_errors2.rs:18:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^ dividing by zero
warning: erroneous constant used
- --> $DIR/promoted_errors2.rs:17:20
+ --> $DIR/promoted_errors2.rs:18:20
|
LL | println!("{}", 1 / (false as u32));
| ^^^^^^^^^^^^^^^^^^ referenced constant has errors
warning: attempt to divide by zero
- --> $DIR/promoted_errors2.rs:21:14
+ --> $DIR/promoted_errors2.rs:22:14
|
LL | let _x = 1 / (false as u32);
| ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/consts/const_prop_slice_pat_ice.rs b/src/test/ui/consts/const_prop_slice_pat_ice.rs
index 5fec36e..60b06a4 100644
--- a/src/test/ui/consts/const_prop_slice_pat_ice.rs
+++ b/src/test/ui/consts/const_prop_slice_pat_ice.rs
@@ -1,5 +1,4 @@
// check-pass
-#![feature(slice_patterns)]
fn main() {
match &[0, 1] as &[i32] {
diff --git a/src/test/ui/consts/issue-67529.rs b/src/test/ui/consts/issue-67529.rs
new file mode 100644
index 0000000..df4bc66
--- /dev/null
+++ b/src/test/ui/consts/issue-67529.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Z mir-opt-level=2
+// run-pass
+
+struct Baz<T: ?Sized> {
+ a: T
+}
+
+fn main() {
+ let d : Baz<[i32; 4]> = Baz { a: [1,2,3,4] };
+ assert_eq!([1, 2, 3, 4], d.a);
+}
diff --git a/src/test/ui/consts/issue-67640.rs b/src/test/ui/consts/issue-67640.rs
new file mode 100644
index 0000000..bc0ee8d
--- /dev/null
+++ b/src/test/ui/consts/issue-67640.rs
@@ -0,0 +1,24 @@
+// compile-flags: -Z mir-opt-level=3
+// run-pass
+
+struct X {
+ x: isize
+}
+
+fn f1(a: &mut X, b: &mut isize, c: isize) -> isize {
+ let r = a.x + *b + c;
+ a.x = 0;
+ *b = 10;
+ return r;
+}
+
+fn f2<F>(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; }
+
+pub fn main() {
+ let mut a = X {x: 1};
+ let mut b = 2;
+ let c = 3;
+ assert_eq!(f1(&mut a, &mut b, c), 6);
+ assert_eq!(a.x, 0);
+ assert_eq!(f2(a.x, |_| a.x = 50), 0);
+}
diff --git a/src/test/ui/consts/issue-67641.rs b/src/test/ui/consts/issue-67641.rs
new file mode 100644
index 0000000..f50fba2
--- /dev/null
+++ b/src/test/ui/consts/issue-67641.rs
@@ -0,0 +1,24 @@
+// compile-flags: -Z mir-opt-level=2
+// run-pass
+
+use std::cell::Cell;
+
+#[derive(Debug)]
+struct B<'a> {
+ a: [Cell<Option<&'a B<'a>>>; 2]
+}
+
+impl<'a> B<'a> {
+ fn new() -> B<'a> {
+ B { a: [Cell::new(None), Cell::new(None)] }
+ }
+}
+
+fn f() {
+ let b2 = B::new();
+ b2.a[0].set(Some(&b2));
+}
+
+fn main() {
+ f();
+}
diff --git a/src/test/ui/consts/issue-67862.rs b/src/test/ui/consts/issue-67862.rs
new file mode 100644
index 0000000..84f7215
--- /dev/null
+++ b/src/test/ui/consts/issue-67862.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z mir-opt-level=2
+// run-pass
+
+fn e220() -> (i64, i64) {
+ #[inline(never)]
+ fn get_displacement() -> [i64; 2] {
+ [139776, 963904]
+ }
+
+ let res = get_displacement();
+ match (&res[0], &res[1]) {
+ (arg0, arg1) => (*arg0, *arg1),
+ }
+}
+
+fn main() {
+ assert_eq!(e220(), (139776, 963904));
+}
diff --git a/src/test/ui/consts/issue-68264-overflow.rs b/src/test/ui/consts/issue-68264-overflow.rs
new file mode 100644
index 0000000..8f21e06
--- /dev/null
+++ b/src/test/ui/consts/issue-68264-overflow.rs
@@ -0,0 +1,43 @@
+// check-pass
+// compile-flags: --emit=mir,link
+// Regression test for issue #68264
+// Checks that we don't encounter overflow
+// when running const-prop on functions with
+// complicated bounds
+pub trait Query {}
+
+pub trait AsQuery {
+ type Query: Query;
+}
+pub trait Table: AsQuery + Sized {}
+
+pub trait LimitDsl {
+ type Output;
+}
+
+pub(crate) trait LoadQuery<Conn, U>: RunQueryDsl<Conn> {}
+
+impl<T: Query> AsQuery for T {
+ type Query = Self;
+}
+
+impl<T> LimitDsl for T
+where
+ T: Table,
+ T::Query: LimitDsl,
+{
+ type Output = <T::Query as LimitDsl>::Output;
+}
+
+pub(crate) trait RunQueryDsl<Conn>: Sized {
+ fn first<U>(self, _conn: &Conn) -> U
+ where
+ Self: LimitDsl,
+ Self::Output: LoadQuery<Conn, U>,
+ {
+ // Overflow is caused by this function body
+ unimplemented!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr
index 2cdeb59..2439d52 100644
--- a/src/test/ui/consts/miri_unleashed/drop.stderr
+++ b/src/test/ui/consts/miri_unleashed/drop.stderr
@@ -7,17 +7,17 @@
error[E0080]: could not evaluate static initializer
--> $SRC_DIR/libcore/ptr/mod.rs:LL:COL
|
-LL | / unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
+LL | / pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
LL | | // Code here does not matter - this is replaced by the
LL | | // real drop glue by the compiler.
-LL | | real_drop_in_place(to_drop)
+LL | | drop_in_place(to_drop)
LL | | }
| |_^ calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
|
::: $DIR/drop.rs:23:1
|
LL | };
- | - inside call to `std::ptr::real_drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at $DIR/drop.rs:23:1
+ | - inside call to `std::intrinsics::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at $DIR/drop.rs:23:1
error: aborting due to previous error
diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr
index 655c317..0d7fb84 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr
@@ -10,7 +10,7 @@
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17
+thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: internal compiler error: unexpected panic
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index 91063ed..30a8960 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -7,7 +7,6 @@
// edition:2018
// ignore-wasm32-bare compiled with panic=abort by default
-#![feature(slice_patterns)]
#![allow(unused)]
use std::{
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index 0f0ec0b..b440620 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -1,11 +1,10 @@
// run-pass
-#![allow(unused_assignments)]
-#![allow(unused_variables)]
-
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(generators, generator_trait, untagged_unions)]
-#![feature(slice_patterns)]
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
use std::cell::{Cell, RefCell};
use std::mem::ManuallyDrop;
diff --git a/src/test/ui/error-codes/E0106.rs b/src/test/ui/error-codes/E0106.rs
index d6537d1..cc34387 100644
--- a/src/test/ui/error-codes/E0106.rs
+++ b/src/test/ui/error-codes/E0106.rs
@@ -16,7 +16,7 @@
struct Quux {
baz: Baz,
//~^ ERROR E0106
- //~| expected lifetime parameter
+ //~| expected named lifetime parameter
buzz: Buzz,
//~^ ERROR E0106
//~| expected 2 lifetime parameters
diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr
index cea9581..e01e0a6 100644
--- a/src/test/ui/error-codes/E0106.stderr
+++ b/src/test/ui/error-codes/E0106.stderr
@@ -2,25 +2,49 @@
--> $DIR/E0106.rs:2:8
|
LL | x: &bool,
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Foo<'lifetime> {
+LL | x: &'lifetime bool,
+ |
error[E0106]: missing lifetime specifier
--> $DIR/E0106.rs:7:7
|
LL | B(&bool),
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | enum Bar<'lifetime> {
+LL | A(u8),
+LL | B(&'lifetime bool),
+ |
error[E0106]: missing lifetime specifier
--> $DIR/E0106.rs:10:14
|
LL | type MyStr = &str;
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | type MyStr<'lifetime> = &'lifetime str;
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/E0106.rs:17:10
|
LL | baz: Baz,
- | ^^^ expected lifetime parameter
+ | ^^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Quux<'lifetime> {
+LL | baz: Baz<'lifetime>,
+ |
error[E0106]: missing lifetime specifiers
--> $DIR/E0106.rs:20:11
diff --git a/src/test/ui/error-codes/E0261.stderr b/src/test/ui/error-codes/E0261.stderr
index 3bf5e9d..0eab2dc 100644
--- a/src/test/ui/error-codes/E0261.stderr
+++ b/src/test/ui/error-codes/E0261.stderr
@@ -2,11 +2,15 @@
--> $DIR/E0261.rs:1:12
|
LL | fn foo(x: &'a str) { }
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/E0261.rs:5:9
|
+LL | struct Foo {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | x: &'a str,
| ^^ undeclared lifetime
diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs
index 17d03b14..0a337c9 100644
--- a/src/test/ui/error-codes/E0528.rs
+++ b/src/test/ui/error-codes/E0528.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn main() {
let r = &[1, 2];
match r {
diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr
index 0f56609..21615f9 100644
--- a/src/test/ui/error-codes/E0528.stderr
+++ b/src/test/ui/error-codes/E0528.stderr
@@ -1,5 +1,5 @@
error[E0528]: pattern requires at least 3 elements but array has 2
- --> $DIR/E0528.rs:6:10
+ --> $DIR/E0528.rs:4:10
|
LL | &[a, b, c, rest @ ..] => {
| ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements
diff --git a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr
index 5c64bf6..bbf3ea8 100644
--- a/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr
+++ b/src/test/ui/feature-gates/feature-gate-in_band_lifetimes.stderr
@@ -2,103 +2,207 @@
--> $DIR/feature-gate-in_band_lifetimes.rs:3:12
|
LL | fn foo(x: &'x u8) -> &'x u8 { x }
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'x` here: `<'x>`
error[E0261]: use of undeclared lifetime name `'x`
--> $DIR/feature-gate-in_band_lifetimes.rs:3:23
|
LL | fn foo(x: &'x u8) -> &'x u8 { x }
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'x` here: `<'x>`
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:15:12
|
LL | impl<'a> X<'b> {
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'b` here: `'b,`
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:17:27
|
LL | fn inner_2(&self) -> &'b u8 {
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b, 'a> X<'b> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn inner_2<'b>(&self) -> &'b u8 {
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:23:8
|
LL | impl X<'b> {
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'b` here: `<'b>`
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:25:27
|
LL | fn inner_3(&self) -> &'b u8 {
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b> X<'b> {
+ | ^^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn inner_3<'b>(&self) -> &'b u8 {
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:33:9
|
LL | impl Y<&'a u8> {
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:35:25
|
LL | fn inner(&self) -> &'a u8 {
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'a` here
+ |
+LL | impl<'a> Y<&'a u8> {
+ | ^^^^
+help: consider introducing lifetime `'a` here
+ |
+LL | fn inner<'a>(&self) -> &'a u8 {
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:43:27
|
LL | fn any_lifetime() -> &'b u8;
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | trait MyTrait<'b, 'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn any_lifetime<'b>() -> &'b u8;
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:45:27
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8;
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | trait MyTrait<'b, 'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8;
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:45:40
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8;
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | trait MyTrait<'b, 'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8;
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:50:14
|
LL | impl MyTrait<'a> for Y<&'a u8> {
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:50:25
|
LL | impl MyTrait<'a> for Y<&'a u8> {
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/feature-gate-in_band_lifetimes.rs:53:31
|
LL | fn my_lifetime(&self) -> &'a u8 { self.0 }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'a` here
+ |
+LL | impl<'a> MyTrait<'a> for Y<&'a u8> {
+ | ^^^^
+help: consider introducing lifetime `'a` here
+ |
+LL | fn my_lifetime<'a>(&self) -> &'a u8 { self.0 }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:55:27
|
LL | fn any_lifetime() -> &'b u8 { &0 }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
+ | ^^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn any_lifetime<'b>() -> &'b u8 { &0 }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:57:27
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
+ | ^^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/feature-gate-in_band_lifetimes.rs:57:40
|
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
+ | ^^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
+ | ^^^^
error: aborting due to 17 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs
deleted file mode 100644
index f2a1b13..0000000
--- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Test that slice pattern syntax with `..` is gated by `slice_patterns` feature gate
-
-fn main() {
- let x = [1, 2, 3, 4, 5];
- match x {
- [1, 2, ..] => {} //~ ERROR subslice patterns are unstable
- [1, .., 5] => {} //~ ERROR subslice patterns are unstable
- [.., 4, 5] => {} //~ ERROR subslice patterns are unstable
- }
-
- let x = [ 1, 2, 3, 4, 5 ];
- match x {
- [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable
- [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable
- [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable
- }
-}
diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
deleted file mode 100644
index d4946a4..0000000
--- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
+++ /dev/null
@@ -1,57 +0,0 @@
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:6:16
- |
-LL | [1, 2, ..] => {}
- | ^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:7:13
- |
-LL | [1, .., 5] => {}
- | ^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:8:10
- |
-LL | [.., 4, 5] => {}
- | ^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:13:11
- |
-LL | [ xs @ .., 4, 5 ] => {}
- | ^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:14:14
- |
-LL | [ 1, xs @ .., 5 ] => {}
- | ^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/feature-gate-slice-patterns.rs:15:17
- |
-LL | [ 1, 2, xs @ .. ] => {}
- | ^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
index 81137e8..fc2ce1c 100644
--- a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
+++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
@@ -3,12 +3,30 @@
|
LL | + Deref<Target = Self::Item<'b>>;
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | trait Iterable<'b> {
+ | ^^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | type Iter<'b, 'a>: Iterator<Item = Self::Item<'a>>
+ | ^^^
error[E0261]: use of undeclared lifetime name `'undeclared`
--> $DIR/generic_associated_type_undeclared_lifetimes.rs:12:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
| ^^^^^^^^^^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'undeclared` here
+ |
+LL | trait Iterable<'undeclared> {
+ | ^^^^^^^^^^^^^
+help: consider introducing lifetime `'undeclared` here
+ |
+LL | fn iter<'undeclared, 'a>(&'a self) -> Self::Iter<'undeclared>;
+ | ^^^^^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs
index 8c046a2..5980e1a 100644
--- a/src/test/ui/ignore-all-the-things.rs
+++ b/src/test/ui/ignore-all-the-things.rs
@@ -3,9 +3,6 @@
#![allow(non_shorthand_field_patterns)]
#![allow(dead_code)]
#![allow(unused_variables)]
-// pretty-expanded FIXME #23616
-
-#![feature(slice_patterns)]
struct Foo(isize, isize, isize, isize);
struct Bar{a: isize, b: isize, c: isize, d: isize}
diff --git a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr
index 492ca87..14c53f9 100644
--- a/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/assoc-type.stderr
@@ -2,13 +2,23 @@
--> $DIR/assoc-type.rs:11:19
|
LL | type Output = &i32;
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | type Output<'lifetime> = &'lifetime i32;
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/assoc-type.rs:16:20
|
LL | type Output = &'_ i32;
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | type Output<'lifetime> = &'lifetime i32;
+ | ^^^^^^^^^^^ ^^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr
index 9579abb..5f101a2 100644
--- a/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr
+++ b/src/test/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.stderr
@@ -2,7 +2,12 @@
--> $DIR/issue-61124-anon-lifetime-in-struct-declaration.rs:8:19
|
LL | struct Heartbreak(Betrayal);
- | ^^^^^^^^ expected lifetime parameter
+ | ^^^^^^^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Heartbreak<'lifetime>(Betrayal<'lifetime>);
+ | ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr
index a270dd0..fe656f7 100644
--- a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr
+++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr
@@ -1,12 +1,16 @@
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_in_band_in_struct.rs:5:9
|
+LL | struct Foo {
+ | - help: consider introducing lifetime `'test` here: `<'test>`
LL | x: &'test u32,
| ^^^^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_in_band_in_struct.rs:9:10
|
+LL | enum Bar {
+ | - help: consider introducing lifetime `'test` here: `<'test>`
LL | Baz(&'test u32),
| ^^^^^ undeclared lifetime
diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr
index c307066..bfb20ad 100644
--- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr
+++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr
@@ -1,6 +1,8 @@
error[E0261]: use of undeclared lifetime name `'test`
--> $DIR/no_introducing_in_band_in_locals.rs:5:13
|
+LL | fn foo(x: &u32) {
+ | - help: consider introducing lifetime `'test` here: `<'test>`
LL | let y: &'test u32 = x;
| ^^^^^ undeclared lifetime
diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs
index 0866131..0481c1f 100644
--- a/src/test/ui/issues/issue-12369.rs
+++ b/src/test/ui/issues/issue-12369.rs
@@ -1,4 +1,3 @@
-#![feature(slice_patterns)]
#![deny(unreachable_patterns)]
fn main() {
diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr
index f27425e..754b94b 100644
--- a/src/test/ui/issues/issue-12369.stderr
+++ b/src/test/ui/issues/issue-12369.stderr
@@ -1,11 +1,11 @@
error: unreachable pattern
- --> $DIR/issue-12369.rs:10:9
+ --> $DIR/issue-12369.rs:9:9
|
LL | &[10,a, ref rest @ ..] => 10
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
- --> $DIR/issue-12369.rs:2:9
+ --> $DIR/issue-12369.rs:1:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-12567.rs b/src/test/ui/issues/issue-12567.rs
index 643d9a2..1b2a37d 100644
--- a/src/test/ui/issues/issue-12567.rs
+++ b/src/test/ui/issues/issue-12567.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) {
match (l1, l2) {
//~^ ERROR: cannot move out of type `[T]`, a non-copy slice
diff --git a/src/test/ui/issues/issue-12567.stderr b/src/test/ui/issues/issue-12567.stderr
index 9d9a88f..2a88d8f 100644
--- a/src/test/ui/issues/issue-12567.stderr
+++ b/src/test/ui/issues/issue-12567.stderr
@@ -1,5 +1,5 @@
error[E0508]: cannot move out of type `[T]`, a non-copy slice
- --> $DIR/issue-12567.rs:4:11
+ --> $DIR/issue-12567.rs:2:11
|
LL | match (l1, l2) {
| ^^^^^^^^ cannot move out of here
@@ -13,7 +13,7 @@
= note: move occurs because these variables have types that don't implement the `Copy` trait
error[E0508]: cannot move out of type `[T]`, a non-copy slice
- --> $DIR/issue-12567.rs:4:11
+ --> $DIR/issue-12567.rs:2:11
|
LL | match (l1, l2) {
| ^^^^^^^^ cannot move out of here
diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs
index b11b1cd..4dd6981 100644
--- a/src/test/ui/issues/issue-15080.rs
+++ b/src/test/ui/issues/issue-15080.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn main() {
let mut x: &[_] = &[1, 2, 3, 4];
diff --git a/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs
index ee97754..47b207e 100644
--- a/src/test/ui/issues/issue-15104.rs
+++ b/src/test/ui/issues/issue-15104.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn main() {
assert_eq!(count_members(&[1, 2, 3, 4]), 4);
diff --git a/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs
index fefa3f2..126e01d 100644
--- a/src/test/ui/issues/issue-17877.rs
+++ b/src/test/ui/issues/issue-17877.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn main() {
assert_eq!(match [0u8; 1024] {
diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr
index c85ce0e..8a627bc 100644
--- a/src/test/ui/issues/issue-19707.stderr
+++ b/src/test/ui/issues/issue-19707.stderr
@@ -2,17 +2,25 @@
--> $DIR/issue-19707.rs:3:28
|
LL | type Foo = fn(&u8, &u8) -> &u8;
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: consider introducing a named lifetime parameter
+ |
+LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8;
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-19707.rs:5:27
|
LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: consider introducing a named lifetime parameter
+ |
+LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
+ | ^^^^^^^^^^ ^^^^^^^^^^
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-23311.rs b/src/test/ui/issues/issue-23311.rs
index f275c63..62c9684 100644
--- a/src/test/ui/issues/issue-23311.rs
+++ b/src/test/ui/issues/issue-23311.rs
@@ -1,7 +1,6 @@
// run-pass
-// Test that we do not ICE when pattern matching an array against a slice.
-#![feature(slice_patterns)]
+// Test that we do not ICE when pattern matching an array against a slice.
fn main() {
match "foo".as_bytes() {
diff --git a/src/test/ui/issues/issue-26619.rs b/src/test/ui/issues/issue-26619.rs
index 00e09f3..b9d34b0 100644
--- a/src/test/ui/issues/issue-26619.rs
+++ b/src/test/ui/issues/issue-26619.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
pub struct History<'a> { pub _s: &'a str }
impl<'a> History<'a> {
diff --git a/src/test/ui/issues/issue-26619.stderr b/src/test/ui/issues/issue-26619.stderr
index d1157cd..1282fd7 100644
--- a/src/test/ui/issues/issue-26619.stderr
+++ b/src/test/ui/issues/issue-26619.stderr
@@ -1,5 +1,5 @@
error[E0515]: cannot return value referencing function parameter
- --> $DIR/issue-26619.rs:7:76
+ --> $DIR/issue-26619.rs:5:76
|
LL | for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) {
| -------- ^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr
index 6d7c1b0..85d5d9c 100644
--- a/src/test/ui/issues/issue-26638.stderr
+++ b/src/test/ui/issues/issue-26638.stderr
@@ -2,9 +2,13 @@
--> $DIR/issue-26638.rs:1:62
|
LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn parse_type<'lifetime>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'lifetime str { iter.next() }
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:4:40
diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr
index c53129b..c940227 100644
--- a/src/test/ui/issues/issue-30255.stderr
+++ b/src/test/ui/issues/issue-30255.stderr
@@ -2,25 +2,37 @@
--> $DIR/issue-30255.rs:9:24
|
LL | fn f(a: &S, b: i32) -> &i32 {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-30255.rs:14:34
|
LL | fn g(a: &S, b: bool, c: &i32) -> &i32 {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-30255.rs:19:44
|
LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs
index 31b3aba..458e999 100644
--- a/src/test/ui/issues/issue-37598.rs
+++ b/src/test/ui/issues/issue-37598.rs
@@ -1,5 +1,4 @@
// check-pass
-#![feature(slice_patterns)]
fn check(list: &[u8]) {
match list {
diff --git a/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs
index 5b70bd6..b7323f0 100644
--- a/src/test/ui/issues/issue-7784.rs
+++ b/src/test/ui/issues/issue-7784.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
use std::ops::Add;
diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
index 3f7c393..1d5eeac 100644
--- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
+++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -10,17 +10,25 @@
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
|
LL | fn g(_x: &isize, _y: &isize) -> &isize {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
|
LL | fn h(_x: &Foo) -> &isize {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
index a4e0d71..2990ab8 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -2,9 +2,13 @@
--> $DIR/ex1b-return-no-names-if-else.rs:1:29
|
LL | fn foo(x: &i32, y: &i32) -> &i32 {
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 {
+ | ^^^^^^^^^^^ ^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs
new file mode 100644
index 0000000..c2b8195
--- /dev/null
+++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs
@@ -0,0 +1,29 @@
+#![deny(non_snake_case)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+
+enum Foo {
+ Bad {
+ lowerCamelCaseName: bool,
+ //~^ ERROR structure field `lowerCamelCaseName` should have a snake case name
+ },
+ Good {
+ snake_case_name: bool,
+ },
+}
+
+fn main() {
+ let b = Foo::Bad { lowerCamelCaseName: true };
+
+ match b {
+ Foo::Bad { lowerCamelCaseName } => {}
+ Foo::Good { snake_case_name: lowerCamelCaseBinding } => { }
+ //~^ ERROR variable `lowerCamelCaseBinding` should have a snake case name
+ }
+
+ if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { }
+ //~^ ERROR variable `anotherLowerCamelCaseBinding` should have a snake case name
+
+ if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { }
+ //~^ ERROR variable `yetAnotherLowerCamelCaseBinding` should have a snake case name
+}
diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr
new file mode 100644
index 0000000..68956f2
--- /dev/null
+++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr
@@ -0,0 +1,32 @@
+error: structure field `lowerCamelCaseName` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9
+ |
+LL | lowerCamelCaseName: bool,
+ | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name`
+ |
+note: lint level defined here
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9
+ |
+LL | #![deny(non_snake_case)]
+ | ^^^^^^^^^^^^^^
+
+error: variable `lowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38
+ |
+LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { }
+ | ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding`
+
+error: variable `anotherLowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41
+ |
+LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding`
+
+error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name
+ --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43
+ |
+LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs
new file mode 100644
index 0000000..0af7066
--- /dev/null
+++ b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs
@@ -0,0 +1,17 @@
+// check-pass
+// Regression test for issue #61651
+// Verifies that we don't try to constrain inference
+// variables due to the presence of multiple applicable
+// marker trait impls
+
+#![feature(marker_trait_attr)]
+
+#[marker] // Remove this line and it works?!?
+trait Foo<T> {}
+impl Foo<u16> for u8 {}
+impl Foo<[u8; 1]> for u8 {}
+fn foo<T: Foo<U>, U>(_: T) -> U { unimplemented!() }
+
+fn main() {
+ let _: u16 = foo(0_u8);
+}
diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
index 67fd8d7..c9f235c 100644
--- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
+++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr
@@ -1,6 +1,8 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
+LL | fn main() {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | 0.clone::<'a>();
| ^^ undeclared lifetime
diff --git a/src/test/ui/moves/move-out-of-array-ref.rs b/src/test/ui/moves/move-out-of-array-ref.rs
index 4ca60dd..343f00f 100644
--- a/src/test/ui/moves/move-out-of-array-ref.rs
+++ b/src/test/ui/moves/move-out-of-array-ref.rs
@@ -1,7 +1,5 @@
// Ensure that we cannot move out of a reference to a fixed-size array
-#![feature(slice_patterns)]
-
struct D { _x: u8 }
impl Drop for D { fn drop(&mut self) { } }
diff --git a/src/test/ui/moves/move-out-of-array-ref.stderr b/src/test/ui/moves/move-out-of-array-ref.stderr
index ae3d2f5..fd682e5 100644
--- a/src/test/ui/moves/move-out-of-array-ref.stderr
+++ b/src/test/ui/moves/move-out-of-array-ref.stderr
@@ -1,5 +1,5 @@
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
- --> $DIR/move-out-of-array-ref.rs:10:24
+ --> $DIR/move-out-of-array-ref.rs:8:24
|
LL | let [_, e, _, _] = *a;
| - ^^
@@ -10,7 +10,7 @@
| move occurs because `e` has type `D`, which does not implement the `Copy` trait
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
- --> $DIR/move-out-of-array-ref.rs:15:27
+ --> $DIR/move-out-of-array-ref.rs:13:27
|
LL | let [_, s @ .. , _] = *a;
| ------ ^^
@@ -21,7 +21,7 @@
| move occurs because `s` has type `[D; 2]`, which does not implement the `Copy` trait
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
- --> $DIR/move-out-of-array-ref.rs:20:24
+ --> $DIR/move-out-of-array-ref.rs:18:24
|
LL | let [_, e, _, _] = *a;
| - ^^
@@ -32,7 +32,7 @@
| move occurs because `e` has type `D`, which does not implement the `Copy` trait
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
- --> $DIR/move-out-of-array-ref.rs:25:27
+ --> $DIR/move-out-of-array-ref.rs:23:27
|
LL | let [_, s @ .. , _] = *a;
| ------ ^^
diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs
index d7c191b..8b0be2e 100644
--- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs
+++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs
@@ -1,5 +1,5 @@
#![feature(or_patterns)]
-#![feature(slice_patterns)]
+
#![allow(incomplete_features)]
#![deny(unreachable_patterns)]
diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.rs b/src/test/ui/or-patterns/exhaustiveness-pass.rs
index ce0fe6f..f0dc344 100644
--- a/src/test/ui/or-patterns/exhaustiveness-pass.rs
+++ b/src/test/ui/or-patterns/exhaustiveness-pass.rs
@@ -1,5 +1,5 @@
#![feature(or_patterns)]
-#![feature(slice_patterns)]
+
#![allow(incomplete_features)]
#![deny(unreachable_patterns)]
diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
index 860c7a1..81bc117 100644
--- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
+++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs
@@ -1,5 +1,5 @@
#![feature(or_patterns)]
-#![feature(slice_patterns)]
+
#![allow(incomplete_features)]
#![deny(unreachable_patterns)]
diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr
deleted file mode 100644
index 58343e8..0000000
--- a/src/test/ui/parser/match-vec-invalid.stderr
+++ /dev/null
@@ -1,42 +0,0 @@
-error[E0416]: identifier `tail` is bound more than once in the same pattern
- --> $DIR/match-vec-invalid.rs:4:24
- |
-LL | [1, tail @ .., tail @ ..] => {},
- | ^^^^ used in a pattern more than once
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/match-vec-invalid.rs:4:13
- |
-LL | [1, tail @ .., tail @ ..] => {},
- | ^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error[E0658]: subslice patterns are unstable
- --> $DIR/match-vec-invalid.rs:4:24
- |
-LL | [1, tail @ .., tail @ ..] => {},
- | ^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
-error: `..` can only be used once per slice pattern
- --> $DIR/match-vec-invalid.rs:4:31
- |
-LL | [1, tail @ .., tail @ ..] => {},
- | -- ^^ can only be used once per slice pattern
- | |
- | previously used here
-
-error[E0308]: mismatched types
- --> $DIR/match-vec-invalid.rs:13:30
- |
-LL | const RECOVERY_WITNESS: () = 0;
- | ^ expected `()`, found integer
-
-error: aborting due to 5 previous errors
-
-Some errors have detailed explanations: E0308, E0416, E0658.
-For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs
index f27caa5..7becffa 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.rs
+++ b/src/test/ui/parser/pat-lt-bracket-6.rs
@@ -4,7 +4,6 @@
let Test(&desc[..]) = x;
//~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
- //~^^ ERROR subslice patterns are unstable
}
const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index fe9603c..035d0db 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -7,22 +7,12 @@
| expected one of `)`, `,`, `@`, or `|`
| help: missing `,`
-error[E0658]: subslice patterns are unstable
- --> $DIR/pat-lt-bracket-6.rs:5:20
- |
-LL | let Test(&desc[..]) = x;
- | ^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/62254
- = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
-
error[E0308]: mismatched types
- --> $DIR/pat-lt-bracket-6.rs:10:30
+ --> $DIR/pat-lt-bracket-6.rs:9:30
|
LL | const RECOVERY_WITNESS: () = 0;
| ^ expected `()`, found integer
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr
index 03fb764..4b9f494 100644
--- a/src/test/ui/parser/trait-object-trait-parens.stderr
+++ b/src/test/ui/parser/trait-object-trait-parens.stderr
@@ -33,6 +33,9 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/trait-object-trait-parens.rs:11:31
|
+LL | fn main() {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+...
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
| ^^ undeclared lifetime
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
index 1d9f341..2cd375d 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
@@ -1,7 +1,6 @@
// Test that moving on both sides of an `@` pattern is not allowed.
#![feature(bindings_after_at)]
-#![feature(slice_patterns)]
fn main() {
struct U; // Not copy!
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
index f3f8fd6..12ebcb7 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
@@ -1,53 +1,53 @@
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:12:9
+ --> $DIR/borrowck-move-and-move.rs:11:9
|
LL | let a @ b = U;
| ^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:16:9
+ --> $DIR/borrowck-move-and-move.rs:15:9
|
LL | let a @ (b, c) = (U, U);
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:20:9
+ --> $DIR/borrowck-move-and-move.rs:19:9
|
LL | let a @ (b, c) = (u(), u());
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:25:9
+ --> $DIR/borrowck-move-and-move.rs:24:9
|
LL | a @ Ok(b) | a @ Err(b) => {}
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:25:21
+ --> $DIR/borrowck-move-and-move.rs:24:21
|
LL | a @ Ok(b) | a @ Err(b) => {}
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:37:9
+ --> $DIR/borrowck-move-and-move.rs:36:9
|
LL | xs @ [a, .., b] => {}
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:43:9
+ --> $DIR/borrowck-move-and-move.rs:42:9
|
LL | xs @ [_, ys @ .., _] => {}
| ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-move-and-move.rs:32:12
+ --> $DIR/borrowck-move-and-move.rs:31:12
|
LL | fn fun(a @ b: U) {}
| ^^^^^ binds an already bound by-move value by moving it
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:12:13
+ --> $DIR/borrowck-move-and-move.rs:11:13
|
LL | let a @ b = U;
| ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait
@@ -56,7 +56,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:16:17
+ --> $DIR/borrowck-move-and-move.rs:15:17
|
LL | let a @ (b, c) = (U, U);
| --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@@ -65,7 +65,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:20:17
+ --> $DIR/borrowck-move-and-move.rs:19:17
|
LL | let a @ (b, c) = (u(), u());
| --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@@ -74,7 +74,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:25:16
+ --> $DIR/borrowck-move-and-move.rs:24:16
|
LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@@ -85,7 +85,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:25:29
+ --> $DIR/borrowck-move-and-move.rs:24:29
|
LL | match Ok(U) {
| ----- move occurs because value has type `std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@@ -96,7 +96,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:37:22
+ --> $DIR/borrowck-move-and-move.rs:36:22
|
LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait
@@ -107,7 +107,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:43:18
+ --> $DIR/borrowck-move-and-move.rs:42:18
|
LL | match [u(), u(), u(), u()] {
| -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait
@@ -118,7 +118,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-move-and-move.rs:32:16
+ --> $DIR/borrowck-move-and-move.rs:31:16
|
LL | fn fun(a @ b: U) {}
| ----^
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
index afac8d9..092bd11 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
@@ -4,7 +4,6 @@
#![feature(bindings_after_at)]
#![feature(box_patterns)]
-#![feature(slice_patterns)]
#[derive(Copy, Clone)]
struct C;
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
index fce3140..3b2f598 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
@@ -2,7 +2,6 @@
#![feature(bindings_after_at)]
#![feature(box_patterns)]
-#![feature(slice_patterns)]
#[derive(Copy, Clone)]
struct C;
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
index 5772fad..e96c15b 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr
@@ -1,23 +1,23 @@
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-at-and-box.rs:17:9
+ --> $DIR/borrowck-pat-at-and-box.rs:16:9
|
LL | let a @ box &b = Box::new(&C);
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-at-and-box.rs:21:9
+ --> $DIR/borrowck-pat-at-and-box.rs:20:9
|
LL | let a @ box b = Box::new(C);
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-at-and-box.rs:33:25
+ --> $DIR/borrowck-pat-at-and-box.rs:32:25
|
LL | match Box::new(C) { a @ box b => {} }
| ^^^^^^^^^ binds an already bound by-move value by moving it
error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/borrowck-pat-at-and-box.rs:37:21
+ --> $DIR/borrowck-pat-at-and-box.rs:36:21
|
LL | let ref a @ box b = Box::new(NC);
| ------------^
@@ -26,7 +26,7 @@
| by-ref pattern here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-at-and-box.rs:39:9
+ --> $DIR/borrowck-pat-at-and-box.rs:38:9
|
LL | let ref a @ box ref mut b = Box::new(nc());
| -----^^^^^^^---------
@@ -35,7 +35,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-at-and-box.rs:41:9
+ --> $DIR/borrowck-pat-at-and-box.rs:40:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
@@ -44,7 +44,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-at-and-box.rs:43:9
+ --> $DIR/borrowck-pat-at-and-box.rs:42:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
@@ -53,7 +53,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-at-and-box.rs:46:9
+ --> $DIR/borrowck-pat-at-and-box.rs:45:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
@@ -62,7 +62,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:52:9
+ --> $DIR/borrowck-pat-at-and-box.rs:51:9
|
LL | let ref mut a @ box ref b = Box::new(NC);
| ---------^^^^^^^-----
@@ -71,7 +71,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:66:9
+ --> $DIR/borrowck-pat-at-and-box.rs:65:9
|
LL | ref mut a @ box ref b => {
| ---------^^^^^^^-----
@@ -80,7 +80,7 @@
| mutable borrow occurs here
error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/borrowck-pat-at-and-box.rs:75:38
+ --> $DIR/borrowck-pat-at-and-box.rs:74:38
|
LL | box [Ok(a), ref xs @ .., Err(b)] => {}
| ----------- ^ by-move pattern here
@@ -88,7 +88,7 @@
| by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern
- --> $DIR/borrowck-pat-at-and-box.rs:81:46
+ --> $DIR/borrowck-pat-at-and-box.rs:80:46
|
LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {}
| ----- ----------- ^ --------- by-ref pattern here
@@ -98,19 +98,19 @@
| by-ref pattern here
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-at-and-box.rs:25:11
+ --> $DIR/borrowck-pat-at-and-box.rs:24:11
|
LL | fn f1(a @ box &b: Box<&C>) {}
| ^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-at-and-box.rs:29:11
+ --> $DIR/borrowck-pat-at-and-box.rs:28:11
|
LL | fn f2(a @ box b: Box<C>) {}
| ^^^^^^^^^ binds an already bound by-move value by moving it
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:58:11
+ --> $DIR/borrowck-pat-at-and-box.rs:57:11
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ---------^^^^^^^-----
@@ -119,7 +119,7 @@
| mutable borrow occurs here
error[E0382]: use of moved value
- --> $DIR/borrowck-pat-at-and-box.rs:17:18
+ --> $DIR/borrowck-pat-at-and-box.rs:16:18
|
LL | let a @ box &b = Box::new(&C);
| ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait
@@ -128,7 +128,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-pat-at-and-box.rs:21:17
+ --> $DIR/borrowck-pat-at-and-box.rs:20:17
|
LL | let a @ box b = Box::new(C);
| --------^ ----------- move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
@@ -137,7 +137,7 @@
| value moved here
error[E0382]: use of moved value
- --> $DIR/borrowck-pat-at-and-box.rs:33:33
+ --> $DIR/borrowck-pat-at-and-box.rs:32:33
|
LL | match Box::new(C) { a @ box b => {} }
| ----------- --------^
@@ -147,7 +147,7 @@
| move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-at-and-box.rs:46:21
+ --> $DIR/borrowck-pat-at-and-box.rs:45:21
|
LL | let ref a @ box ref mut b = Box::new(NC);
| ------------^^^^^^^^^
@@ -159,7 +159,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:52:25
+ --> $DIR/borrowck-pat-at-and-box.rs:51:25
|
LL | let ref mut a @ box ref b = Box::new(NC);
| ----------------^^^^^
@@ -171,7 +171,7 @@
| -- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:66:25
+ --> $DIR/borrowck-pat-at-and-box.rs:65:25
|
LL | ref mut a @ box ref b => {
| ----------------^^^^^
@@ -183,7 +183,7 @@
| -- mutable borrow later used here
error[E0382]: use of moved value
- --> $DIR/borrowck-pat-at-and-box.rs:25:20
+ --> $DIR/borrowck-pat-at-and-box.rs:24:20
|
LL | fn f1(a @ box &b: Box<&C>) {}
| ---------^
@@ -193,7 +193,7 @@
| move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait
error[E0382]: use of moved value
- --> $DIR/borrowck-pat-at-and-box.rs:29:19
+ --> $DIR/borrowck-pat-at-and-box.rs:28:19
|
LL | fn f2(a @ box b: Box<C>) {}
| --------^
@@ -203,7 +203,7 @@
| move occurs because value has type `std::boxed::Box<C>`, which does not implement the `Copy` trait
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-at-and-box.rs:58:27
+ --> $DIR/borrowck-pat-at-and-box.rs:57:27
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ----------------^^^^^
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
index be19e5f..c4ce50c 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
@@ -2,7 +2,6 @@
// Test `Copy` bindings in the rhs of `@` patterns.
-#![feature(slice_patterns)]
#![feature(bindings_after_at)]
#[derive(Copy, Clone)]
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs
index edf9fb3..fb24301 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs
@@ -4,7 +4,6 @@
// of an `@` pattern according to NLL borrowck.
#![feature(bindings_after_at)]
-#![feature(slice_patterns)]
fn main() {
struct U; // Not copy!
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
index 559925c..e8510df 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
@@ -1,5 +1,4 @@
#![feature(bindings_after_at)]
-#![feature(slice_patterns)]
enum Option<T> {
None,
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
index b5c26a1..0d7b703 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
@@ -1,5 +1,5 @@
error: cannot borrow `z` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9
|
LL | ref mut z @ &mut Some(ref a) => {
| ---------^^^^^^^^^^^^^-----^
@@ -8,7 +8,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9
|
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| ---------^^^^-----------------^
@@ -18,7 +18,7 @@
| first mutable borrow occurs here
error: cannot borrow `b` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:22
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22
|
LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub
| -----^^^---------
@@ -27,7 +27,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:36:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9
|
LL | let ref a @ ref mut b = U;
| -----^^^---------
@@ -36,7 +36,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:38:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9
|
LL | let ref mut a @ ref b = U;
| ---------^^^-----
@@ -45,7 +45,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:40:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
@@ -55,7 +55,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:42:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9
|
LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^
@@ -65,7 +65,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9
|
LL | let ref mut a @ ref b = u();
| ---------^^^-----
@@ -74,7 +74,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9
|
LL | let ref a @ ref mut b = u();
| -----^^^---------
@@ -83,7 +83,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:56:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9
|
LL | let ref mut a @ ref b = U;
| ---------^^^-----
@@ -92,7 +92,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:60:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9
|
LL | let ref a @ ref mut b = U;
| -----^^^---------
@@ -101,7 +101,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^-----^
@@ -110,7 +110,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => {
| ---------^^^^^^^-----^
@@ -119,7 +119,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^---------^
@@ -128,7 +128,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----^^^^^^^---------^
@@ -137,7 +137,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^---------^
@@ -146,7 +146,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| -----^^^^^^^---------^
@@ -155,7 +155,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^-----^
@@ -164,7 +164,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ---------^^^^^^^-----^
@@ -173,7 +173,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^---------^
@@ -182,7 +182,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| -----^^^^^^^---------^
@@ -191,7 +191,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^-----^
@@ -200,7 +200,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:33
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ---------^^^^^^^-----^
@@ -209,7 +209,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:116:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
@@ -219,7 +219,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
@@ -229,7 +229,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| -----^^^^---------^^---------^
@@ -239,7 +239,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9
|
LL | let ref mut a @ (ref b, ref c) = (U, U);
| ---------^^^^-----^^-----^
@@ -249,7 +249,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11
|
LL | fn f1(ref a @ ref mut b: U) {}
| -----^^^---------
@@ -258,7 +258,7 @@
| immutable borrow occurs here
error: cannot borrow `a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11
|
LL | fn f2(ref mut a @ ref b: U) {}
| ---------^^^-----
@@ -267,7 +267,7 @@
| mutable borrow occurs here
error: cannot borrow `a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11
|
LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {}
| -----^^^^^^^^^^^----------------^^^^^^^^
@@ -276,7 +276,7 @@
| immutable borrow occurs here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31
|
LL | ref mut z @ &mut Some(ref a) => {
| ----------------------^^^^^-
@@ -288,7 +288,7 @@
| ---------- mutable borrow later used here
error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:21
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21
|
LL | let ref mut a @ ref b = u();
| ------------^^^^^
@@ -300,7 +300,7 @@
| -------- mutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:17
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17
|
LL | let ref a @ ref mut b = u();
| --------^^^^^^^^^
@@ -312,7 +312,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:20
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| -----------^^^^^^^^^-
@@ -324,7 +324,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:45
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
| ------------^^^^^^^^^-
@@ -336,7 +336,7 @@
| - immutable borrow later used here
error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:61
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
| ^^^^^^ cannot assign
@@ -344,7 +344,7 @@
= note: variables bound in patterns are immutable until the end of the pattern guard
error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:61
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
| ^^^^^^^^^^^ cannot assign
@@ -352,7 +352,7 @@
= note: variables bound in patterns are immutable until the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait
@@ -360,7 +360,7 @@
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `b` in pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66
|
LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
| ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait
@@ -368,7 +368,7 @@
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `a` in pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@@ -376,7 +376,7 @@
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0507]: cannot move out of `a` in pattern guard
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66
|
LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
| ^ move occurs because `a` has type `&mut std::result::Result<main::U, main::U>`, which does not implement the `Copy` trait
@@ -384,7 +384,7 @@
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:18
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------
@@ -396,7 +396,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:29
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| --------------------^^^^^^^^^-
@@ -408,7 +408,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:18
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| ---------^^^^^^^^^------------
@@ -420,7 +420,7 @@
| - immutable borrow later used here
error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:29
+ --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29
|
LL | let ref a @ (ref mut b, ref mut c) = (U, U);
| --------------------^^^^^^^^^-
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
index 6b8b754..f425b35 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
@@ -1,7 +1,6 @@
// Test that `ref mut x @ ref mut y` and varieties of that are not allowed.
#![feature(bindings_after_at)]
-#![feature(slice_patterns)]
fn main() {
struct U;
diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index 1b5e6c7..d07ad14 100644
--- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -1,5 +1,5 @@
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
@@ -8,7 +8,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
@@ -17,7 +17,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
@@ -26,7 +26,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
@@ -35,7 +35,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9
|
LL | let ref mut a @ ref mut b = U;
| ---------^^^---------
@@ -44,7 +44,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:43:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9
|
LL | let ref mut a @ (
| ^--------
@@ -66,7 +66,7 @@
| |_____^
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:53:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9
|
LL | let ref mut a @ (
| ^--------
@@ -88,31 +88,31 @@
| |_________^
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-ref-mut-twice.rs:63:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9
|
LL | let a @ (ref mut b, ref mut c) = (U, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-ref-mut-twice.rs:67:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9
|
LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-ref-mut-twice.rs:71:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9
|
LL | let a @ &mut ref mut b = &mut U;
| ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0007]: cannot bind by-move with sub-bindings
- --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9
|
LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:79:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
@@ -121,7 +121,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:79:37
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
@@ -130,7 +130,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:85:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
@@ -139,7 +139,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:85:37
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
@@ -148,7 +148,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:92:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
@@ -157,7 +157,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:92:37
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
@@ -166,7 +166,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:104:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^---------^
@@ -175,7 +175,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:104:37
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------^^^^^^^---------^
@@ -184,7 +184,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11
|
LL | fn f1(ref mut a @ ref mut b: U) {}
| ---------^^^---------
@@ -193,7 +193,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11
|
LL | fn f2(ref mut a @ ref mut b: U) {}
| ---------^^^---------
@@ -202,7 +202,7 @@
| first mutable borrow occurs here
error: cannot borrow `a` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9
|
LL | ref mut a @ [
| ^--------
@@ -220,7 +220,7 @@
| |_________^
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:25:21
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21
|
LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^
@@ -232,7 +232,7 @@
| - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:35:21
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21
|
LL | let ref mut a @ ref mut b = U;
| ------------^^^^^^^^^
@@ -244,7 +244,7 @@
| ------ first borrow later used here
error[E0382]: borrow of moved value
- --> $DIR/borrowck-pat-ref-mut-twice.rs:63:25
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25
|
LL | let a @ (ref mut b, ref mut c) = (U, U);
| ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait
@@ -253,7 +253,7 @@
| value moved here
error[E0382]: borrow of moved value
- --> $DIR/borrowck-pat-ref-mut-twice.rs:67:21
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21
|
LL | let a @ (b, [c, d]) = &mut val; // Same as ^--
| ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait
@@ -262,7 +262,7 @@
| value moved here
error[E0382]: borrow of moved value
- --> $DIR/borrowck-pat-ref-mut-twice.rs:71:18
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18
|
LL | let a @ &mut ref mut b = &mut U;
| ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait
@@ -271,7 +271,7 @@
| value moved here
error[E0382]: borrow of moved value
- --> $DIR/borrowck-pat-ref-mut-twice.rs:74:30
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30
|
LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
| ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait
@@ -280,7 +280,7 @@
| value moved here
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:92:24
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------------^^^^^^^^^-
@@ -292,7 +292,7 @@
| ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:92:53
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ----------------^^^^^^^^^-
@@ -304,7 +304,7 @@
| ----------- first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:104:24
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ---------------^^^^^^^^^-
@@ -316,7 +316,7 @@
| - first borrow later used here
error[E0499]: cannot borrow `_` as mutable more than once at a time
- --> $DIR/borrowck-pat-ref-mut-twice.rs:104:53
+ --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53
|
LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
| ----------------^^^^^^^^^-
diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs
similarity index 65%
rename from src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs
rename to src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs
index c910cde..5b0482d 100644
--- a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs
+++ b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs
@@ -1,8 +1,6 @@
// check-pass
-// This used to cause a stack overflow in the compiler.
-
-#![feature(slice_patterns)]
+// This used to cause a stack overflow during exhaustiveness checking in the compiler.
fn main() {
const LARGE_SIZE: usize = 1024 * 1024;
diff --git a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs b/src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs
similarity index 89%
rename from src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs
rename to src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs
index 6c54c93..54dfa88 100644
--- a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs
+++ b/src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs
@@ -1,5 +1,5 @@
// check-pass
-#![feature(slice_patterns)]
+
#![deny(unreachable_patterns)]
const C0: &'static [u8] = b"\x00";
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs
index 7541ea3..9b6c8bd 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs
@@ -1,4 +1,3 @@
-#![feature(slice_patterns)]
#![deny(unreachable_patterns)]
fn main() {
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr
index b28646b..0948469 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr
@@ -1,53 +1,53 @@
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:9:9
+ --> $DIR/match-byte-array-patterns.rs:8:9
|
LL | &[0x41, 0x41, 0x41, 0x41] => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
- --> $DIR/match-byte-array-patterns.rs:2:9
+ --> $DIR/match-byte-array-patterns.rs:1:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:15:9
+ --> $DIR/match-byte-array-patterns.rs:14:9
|
LL | b"AAAA" => {},
| ^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:21:9
+ --> $DIR/match-byte-array-patterns.rs:20:9
|
LL | b"AAAA" => {},
| ^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:27:9
+ --> $DIR/match-byte-array-patterns.rs:26:9
|
LL | b"AAAA" => {},
| ^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:35:9
+ --> $DIR/match-byte-array-patterns.rs:34:9
|
LL | &[0x41, 0x41, 0x41, 0x41] => {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:41:9
+ --> $DIR/match-byte-array-patterns.rs:40:9
|
LL | b"AAAA" => {},
| ^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:47:9
+ --> $DIR/match-byte-array-patterns.rs:46:9
|
LL | b"AAAA" => {},
| ^^^^^^^
error: unreachable pattern
- --> $DIR/match-byte-array-patterns.rs:53:9
+ --> $DIR/match-byte-array-patterns.rs:52:9
|
LL | b"AAAA" => {},
| ^^^^^^^
diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.rs b/src/test/ui/pattern/usefulness/match-slice-patterns.rs
index af7fd53..92d74b8 100644
--- a/src/test/ui/pattern/usefulness/match-slice-patterns.rs
+++ b/src/test/ui/pattern/usefulness/match-slice-patterns.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn check(list: &[Option<()>]) {
match list {
//~^ ERROR `&[_, Some(_), .., None, _]` not covered
diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
index 72ae5d5..977a112 100644
--- a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered
- --> $DIR/match-slice-patterns.rs:4:11
+ --> $DIR/match-slice-patterns.rs:2:11
|
LL | match list {
| ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs
index 7881052..3342389 100644
--- a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs
+++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs
@@ -1,4 +1,3 @@
-#![feature(slice_patterns)]
#![deny(unreachable_patterns)]
fn main() {
diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr
index 415c24a..e9a7510 100644
--- a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr
+++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr
@@ -1,23 +1,23 @@
error: unreachable pattern
- --> $DIR/match-vec-unreachable.rs:9:9
+ --> $DIR/match-vec-unreachable.rs:8:9
|
LL | [(1, 2), (2, 3), b] => (),
| ^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
- --> $DIR/match-vec-unreachable.rs:2:9
+ --> $DIR/match-vec-unreachable.rs:1:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/match-vec-unreachable.rs:19:9
+ --> $DIR/match-vec-unreachable.rs:18:9
|
LL | [_, _, _, _, _] => { }
| ^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/match-vec-unreachable.rs:27:9
+ --> $DIR/match-vec-unreachable.rs:26:9
|
LL | ['a', 'b', 'c'] => {}
| ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
index 9423a28..d198144 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
enum T { A(U), B }
enum U { C, D }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
index 67c818e..72b4b52 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered
- --> $DIR/non-exhaustive-match-nested.rs:7:11
+ --> $DIR/non-exhaustive-match-nested.rs:5:11
|
LL | match (l1, l2) {
| ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered
@@ -7,7 +7,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `A(C)` not covered
- --> $DIR/non-exhaustive-match-nested.rs:17:11
+ --> $DIR/non-exhaustive-match-nested.rs:15:11
|
LL | enum T { A(U), B }
| ------------------
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index bfca535..9947989 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -1,4 +1,3 @@
-#![feature(slice_patterns)]
#![allow(illegal_floating_point_literal_pattern)]
enum T { A, B }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index 577867e..a06ad57 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `A` not covered
- --> $DIR/non-exhaustive-match.rs:8:11
+ --> $DIR/non-exhaustive-match.rs:7:11
|
LL | enum T { A, B }
| ---------------
@@ -13,7 +13,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `false` not covered
- --> $DIR/non-exhaustive-match.rs:9:11
+ --> $DIR/non-exhaustive-match.rs:8:11
|
LL | match true {
| ^^^^ pattern `false` not covered
@@ -21,7 +21,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
- --> $DIR/non-exhaustive-match.rs:12:11
+ --> $DIR/non-exhaustive-match.rs:11:11
|
LL | match Some(10) {
| ^^^^^^^^ pattern `Some(_)` not covered
@@ -29,7 +29,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
- --> $DIR/non-exhaustive-match.rs:15:11
+ --> $DIR/non-exhaustive-match.rs:14:11
|
LL | match (2, 3, 4) {
| ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
@@ -37,7 +37,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `(A, A)` not covered
- --> $DIR/non-exhaustive-match.rs:19:11
+ --> $DIR/non-exhaustive-match.rs:18:11
|
LL | match (T::A, T::A) {
| ^^^^^^^^^^^^ pattern `(A, A)` not covered
@@ -45,7 +45,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `B` not covered
- --> $DIR/non-exhaustive-match.rs:23:11
+ --> $DIR/non-exhaustive-match.rs:22:11
|
LL | enum T { A, B }
| ---------------
@@ -59,7 +59,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `[]` not covered
- --> $DIR/non-exhaustive-match.rs:34:11
+ --> $DIR/non-exhaustive-match.rs:33:11
|
LL | match *vec {
| ^^^^ pattern `[]` not covered
@@ -67,7 +67,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
- --> $DIR/non-exhaustive-match.rs:47:11
+ --> $DIR/non-exhaustive-match.rs:46:11
|
LL | match *vec {
| ^^^^ pattern `[_, _, _, _, ..]` not covered
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
index 4ca1cbc..abb4ea8 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
struct Foo {
first: bool,
second: Option<[usize; 4]>
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
index a0b497d..2a9fa07 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:9:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:7:11
|
LL | / struct Foo {
LL | | first: bool,
@@ -13,7 +13,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Red` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:25:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:23:11
|
LL | / enum Color {
LL | | Red,
@@ -29,7 +29,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:37:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:35:11
|
LL | / enum Direction {
LL | | North, East, South, West
@@ -46,7 +46,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:48:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:46:11
|
LL | / enum ExcessiveEnum {
LL | | First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth
@@ -59,7 +59,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:56:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:54:11
|
LL | / enum Color {
LL | | Red,
@@ -75,7 +75,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:72:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:70:11
|
LL | match *x {
| ^^ pattern `[Second(true), Second(false)]` not covered
@@ -83,7 +83,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `((), false)` not covered
- --> $DIR/non-exhaustive-pattern-witness.rs:85:11
+ --> $DIR/non-exhaustive-pattern-witness.rs:83:11
|
LL | match ((), false) {
| ^^^^^^^^^^^ pattern `((), false)` not covered
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
index 41ba2cc..52d1320 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
fn main() {
let s: &[bool] = &[true; 0];
let s1: &[bool; 1] = &[false; 1];
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
index 8cb342f..b3701ef 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `&[false, _]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:10:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:8:11
|
LL | match s2 {
| ^^ pattern `&[false, _]` not covered
@@ -7,7 +7,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:14:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:12:11
|
LL | match s3 {
| ^^ pattern `&[false, ..]` not covered
@@ -15,7 +15,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:18:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:16:11
|
LL | match s10 {
| ^^^ pattern `&[false, ..]` not covered
@@ -23,7 +23,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:27:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:25:11
|
LL | match s2 {
| ^^ pattern `&[false, true]` not covered
@@ -31,7 +31,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:32:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:30:11
|
LL | match s3 {
| ^^ pattern `&[false, .., true]` not covered
@@ -39,7 +39,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:37:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:35:11
|
LL | match s {
| ^ pattern `&[false, .., true]` not covered
@@ -47,7 +47,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:44:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:42:11
|
LL | match s {
| ^ pattern `&[_, ..]` not covered
@@ -55,7 +55,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:48:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:46:11
|
LL | match s {
| ^ pattern `&[_, _, ..]` not covered
@@ -63,7 +63,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:53:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:51:11
|
LL | match s {
| ^ pattern `&[false, ..]` not covered
@@ -71,7 +71,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:58:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:56:11
|
LL | match s {
| ^ pattern `&[false, _, ..]` not covered
@@ -79,7 +79,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:64:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:62:11
|
LL | match s {
| ^ pattern `&[_, .., false]` not covered
@@ -87,7 +87,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:71:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:69:11
|
LL | match s {
| ^ pattern `&[_, _, .., true]` not covered
@@ -95,7 +95,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:78:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:76:11
|
LL | match s {
| ^ pattern `&[true, _, .., _]` not covered
@@ -103,7 +103,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:87:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:85:11
|
LL | match s {
| ^ pattern `&[..]` not covered
@@ -111,7 +111,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:91:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:89:11
|
LL | match s {
| ^ pattern `&[true]` not covered
@@ -119,7 +119,7 @@
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:99:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:97:11
|
LL | match s1 {
| ^^ pattern `&[false]` not covered
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs
index 3b716ba..cbf64e2 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs
+++ b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs
@@ -1,5 +1,4 @@
// check-pass
-#![feature(slice_patterns)]
fn main() {
let s: &[bool] = &[true; 0];
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs
index cd229a0..7c747b5 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs
+++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs
@@ -1,4 +1,3 @@
-#![feature(slice_patterns)]
#![deny(unreachable_patterns)]
fn main() {
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr
index 333ce17..e24d102 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr
+++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr
@@ -1,41 +1,41 @@
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:9:9
+ --> $DIR/slice-patterns-reachability.rs:8:9
|
LL | [true, ..] => {}
| ^^^^^^^^^^
|
note: lint level defined here
- --> $DIR/slice-patterns-reachability.rs:2:9
+ --> $DIR/slice-patterns-reachability.rs:1:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:10:9
+ --> $DIR/slice-patterns-reachability.rs:9:9
|
LL | [true] => {}
| ^^^^^^
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:15:9
+ --> $DIR/slice-patterns-reachability.rs:14:9
|
LL | [.., true] => {}
| ^^^^^^^^^^
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:16:9
+ --> $DIR/slice-patterns-reachability.rs:15:9
|
LL | [true] => {}
| ^^^^^^
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:21:9
+ --> $DIR/slice-patterns-reachability.rs:20:9
|
LL | [false, .., true] => {}
| ^^^^^^^^^^^^^^^^^
error: unreachable pattern
- --> $DIR/slice-patterns-reachability.rs:22:9
+ --> $DIR/slice-patterns-reachability.rs:21:9
|
LL | [false, true] => {}
| ^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/item-error.stderr b/src/test/ui/proc-macro/item-error.stderr
index e801c26..01eadbe 100644
--- a/src/test/ui/proc-macro/item-error.stderr
+++ b/src/test/ui/proc-macro/item-error.stderr
@@ -2,7 +2,13 @@
--> $DIR/item-error.rs:10:8
|
LL | a: &u64
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct A<'lifetime> {
+LL | a: &'lifetime u64
+ |
error: aborting due to previous error
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
index 0fcf77d..d9996b8 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs
@@ -1,6 +1,6 @@
// Dropck shouldn't hit a recursion limit from checking `S<u32>` since it has
// no free regions or type parameters.
-// Codegen however, has to error for the infinitely many `real_drop_in_place`
+// Codegen however, has to error for the infinitely many `drop_in_place`
// functions it has been asked to create.
// build-fail
diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
index 77309a8..de6df4c 100644
--- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
+++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr
@@ -1,4 +1,4 @@
-error: reached the recursion limit while instantiating `std::ptr::real_drop_in_place::<S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>> - shim(Some(S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>))`
+error: reached the recursion limit while instantiating `std::intrinsics::drop_in_place::<S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>> - shim(Some(S<fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(fn(u32))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))>))`
error: aborting due to previous error
diff --git a/src/test/ui/regions/regions-in-enums-anon.stderr b/src/test/ui/regions/regions-in-enums-anon.stderr
index ae06e76..41655a2 100644
--- a/src/test/ui/regions/regions-in-enums-anon.stderr
+++ b/src/test/ui/regions/regions-in-enums-anon.stderr
@@ -2,7 +2,13 @@
--> $DIR/regions-in-enums-anon.rs:4:9
|
LL | Bar(&isize)
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | enum Foo<'lifetime> {
+LL | Bar(&'lifetime isize)
+ |
error: aborting due to previous error
diff --git a/src/test/ui/regions/regions-in-enums.stderr b/src/test/ui/regions/regions-in-enums.stderr
index cfed9fe..6653765 100644
--- a/src/test/ui/regions/regions-in-enums.stderr
+++ b/src/test/ui/regions/regions-in-enums.stderr
@@ -1,12 +1,16 @@
error[E0261]: use of undeclared lifetime name `'foo`
--> $DIR/regions-in-enums.rs:13:9
|
+LL | enum No0 {
+ | - help: consider introducing lifetime `'foo` here: `<'foo>`
LL | X5(&'foo usize)
| ^^^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-in-enums.rs:17:9
|
+LL | enum No1 {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | X6(&'a usize)
| ^^ undeclared lifetime
diff --git a/src/test/ui/regions/regions-in-structs-anon.stderr b/src/test/ui/regions/regions-in-structs-anon.stderr
index a1d4ebb..fbe8036 100644
--- a/src/test/ui/regions/regions-in-structs-anon.stderr
+++ b/src/test/ui/regions/regions-in-structs-anon.stderr
@@ -2,7 +2,13 @@
--> $DIR/regions-in-structs-anon.rs:4:8
|
LL | x: &isize
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Foo<'lifetime> {
+LL | x: &'lifetime isize
+ |
error: aborting due to previous error
diff --git a/src/test/ui/regions/regions-in-structs.stderr b/src/test/ui/regions/regions-in-structs.stderr
index 8314942..5dfdc2e 100644
--- a/src/test/ui/regions/regions-in-structs.stderr
+++ b/src/test/ui/regions/regions-in-structs.stderr
@@ -1,12 +1,17 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-in-structs.rs:10:9
|
+LL | struct StructDecl {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | a: &'a isize,
| ^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-in-structs.rs:11:9
|
+LL | struct StructDecl {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+LL | a: &'a isize,
LL | b: &'a isize,
| ^^ undeclared lifetime
diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr
index 5f6a48a..79ebef4 100644
--- a/src/test/ui/regions/regions-name-undeclared.stderr
+++ b/src/test/ui/regions/regions-name-undeclared.stderr
@@ -3,34 +3,67 @@
|
LL | fn m4(&self, arg: &'b isize) { }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b, 'a> Foo<'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn m4<'b>(&self, arg: &'b isize) { }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/regions-name-undeclared.rs:16:12
|
LL | fn m5(&'b self) { }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b, 'a> Foo<'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn m5<'b>(&'b self) { }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/regions-name-undeclared.rs:17:27
|
LL | fn m6(&self, arg: Foo<'b>) { }
| ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b, 'a> Foo<'a> {
+ | ^^^
+help: consider introducing lifetime `'b` here
+ |
+LL | fn m6<'b>(&self, arg: Foo<'b>) { }
+ | ^^^^
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-name-undeclared.rs:25:22
|
LL | type X = Option<&'a isize>;
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-name-undeclared.rs:27:13
|
+LL | enum E {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | E1(&'a isize)
| ^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-name-undeclared.rs:30:13
|
+LL | struct S {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | f: &'a isize
| ^^ undeclared lifetime
@@ -38,13 +71,17 @@
--> $DIR/regions-name-undeclared.rs:32:14
|
LL | fn f(a: &'a isize) { }
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-name-undeclared.rs:40:17
|
LL | fn fn_types(a: &'a isize,
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/regions-name-undeclared.rs:42:36
@@ -61,6 +98,9 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-name-undeclared.rs:46:17
|
+LL | fn fn_types(a: &'a isize,
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+...
LL | c: &'a isize)
| ^^ undeclared lifetime
diff --git a/src/test/ui/regions/regions-undeclared.stderr b/src/test/ui/regions/regions-undeclared.stderr
index 495aec3..6bfde55 100644
--- a/src/test/ui/regions/regions-undeclared.stderr
+++ b/src/test/ui/regions/regions-undeclared.stderr
@@ -7,12 +7,17 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-undeclared.rs:4:10
|
+LL | enum EnumDecl {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | Foo(&'a isize),
| ^^ undeclared lifetime
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-undeclared.rs:5:10
|
+LL | enum EnumDecl {
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+LL | Foo(&'a isize),
LL | Bar(&'a isize),
| ^^ undeclared lifetime
@@ -20,11 +25,15 @@
--> $DIR/regions-undeclared.rs:8:15
|
LL | fn fnDecl(x: &'a isize,
- | ^^ undeclared lifetime
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `<'a>`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/regions-undeclared.rs:9:15
|
+LL | fn fnDecl(x: &'a isize,
+ | - help: consider introducing lifetime `'a` here: `<'a>`
LL | y: &'a isize)
| ^^ undeclared lifetime
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
index 1484b8c..363a0e3 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
@@ -1,5 +1,3 @@
-#![feature(slice_patterns)]
-
pub fn main() {
let sl: &[u8] = b"foo";
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
index f1e91a0..c234fdf 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr
@@ -1,5 +1,5 @@
error[E0004]: non-exhaustive patterns: `&[]` not covered
- --> $DIR/slice.rs:6:11
+ --> $DIR/slice.rs:4:11
|
LL | match sl {
| ^^ pattern `&[]` not covered
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
new file mode 100644
index 0000000..0407eaf
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(track_caller)]
+
+fn pass_to_ptr_call<T>(f: fn(T), x: T) {
+ f(x);
+}
+
+#[track_caller]
+fn tracked_unit(_: ()) {
+ let expected_line = line!() - 1;
+ let location = std::panic::Location::caller();
+ assert_eq!(location.file(), file!());
+ assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
+}
+
+fn main() {
+ pass_to_ptr_call(tracked_unit, ());
+}
diff --git a/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
new file mode 100644
index 0000000..a4baaa2
--- /dev/null
+++ b/src/test/ui/rfc-2091-track-caller/tracked-fn-ptr.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(track_caller)]
+
+fn ptr_call(f: fn()) {
+ f();
+}
+
+#[track_caller]
+fn tracked() {
+ let expected_line = line!() - 1;
+ let location = std::panic::Location::caller();
+ assert_eq!(location.file(), file!());
+ assert_eq!(location.line(), expected_line, "call shims report location as fn definition");
+}
+
+fn main() {
+ ptr_call(tracked);
+}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr
index 0bf337a..e4f4d42 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.gated.stderr
@@ -1,8 +1,8 @@
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/feature-gate.rs:11:29
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/feature-gate.rs:16:1
|
-LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
- | ^^^^^^^^
+LL | fn main() {}
+ | ^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs
index cf1ed30..d600b53 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs
@@ -3,6 +3,7 @@
#![cfg_attr(gated, feature(const_trait_bound_opt_out))]
#![allow(incomplete_features)]
+#![feature(rustc_attrs)]
trait T {
const CONST: i32;
@@ -10,6 +11,6 @@
const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
//[stock]~^ ERROR `?const` on trait bounds is experimental
-//[stock,gated]~^^ ERROR `?const` on trait bounds is not yet implemented
-fn main() {}
+#[rustc_error]
+fn main() {} //[gated]~ ERROR fatal error triggered by #[rustc_error]
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr
index 6438800..fbd3840 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.stock.stderr
@@ -1,5 +1,5 @@
error[E0658]: `?const` on trait bounds is experimental
- --> $DIR/feature-gate.rs:11:29
+ --> $DIR/feature-gate.rs:12:29
|
LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
| ^^^^^^
@@ -7,12 +7,6 @@
= note: for more information, see https://github.com/rust-lang/rust/issues/67794
= help: add `#![feature(const_trait_bound_opt_out)]` to the crate attributes to enable
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/feature-gate.rs:11:29
- |
-LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
- | ^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs
index e4e6bed..f5561a9 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs
@@ -8,18 +8,14 @@
fn rpit() -> impl ?const T { S }
//~^ ERROR `?const` is not permitted in `impl Trait`
-//~| ERROR `?const` on trait bounds is not yet implemented
fn apit(_: impl ?const T) {}
//~^ ERROR `?const` is not permitted in `impl Trait`
-//~| ERROR `?const` on trait bounds is not yet implemented
fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
//~^ ERROR `?const` is not permitted in `impl Trait`
-//~| ERROR `?const` on trait bounds is not yet implemented
fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
//~^ ERROR `?const` is not permitted in `impl Trait`
-//~| ERROR `?const` on trait bounds is not yet implemented
fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr
index f4abd4b..06cd00a 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.stderr
@@ -5,46 +5,22 @@
| ^^^^^^^^
error: `?const` is not permitted in `impl Trait`
- --> $DIR/in-impl-trait.rs:13:17
+ --> $DIR/in-impl-trait.rs:12:17
|
LL | fn apit(_: impl ?const T) {}
| ^^^^^^^^
error: `?const` is not permitted in `impl Trait`
- --> $DIR/in-impl-trait.rs:17:50
+ --> $DIR/in-impl-trait.rs:15:50
|
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
| ^^^^^^^^
error: `?const` is not permitted in `impl Trait`
- --> $DIR/in-impl-trait.rs:21:48
+ --> $DIR/in-impl-trait.rs:18:48
|
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
| ^^^^^^^^
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-impl-trait.rs:9:19
- |
-LL | fn rpit() -> impl ?const T { S }
- | ^^^^^^^^
-
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-impl-trait.rs:13:17
- |
-LL | fn apit(_: impl ?const T) {}
- | ^^^^^^^^
-
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-impl-trait.rs:17:50
- |
-LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ?const T> { Some(S) }
- | ^^^^^^^^
-
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-impl-trait.rs:21:48
- |
-LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ?const T>) {}
- | ^^^^^^^^
-
-error: aborting due to 8 previous errors
+error: aborting due to 4 previous errors
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs
index 4523b46..fc9ed5b 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs
@@ -4,6 +4,5 @@
trait Super {}
trait T: ?const Super {}
//~^ ERROR `?const` is not permitted in supertraits
-//~| ERROR `?const` on trait bounds is not yet implemented
fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr
index 8003361..a0d8f95 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.stderr
@@ -4,11 +4,5 @@
LL | trait T: ?const Super {}
| ^^^^^^^^^^^^
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-trait-bounds.rs:5:10
- |
-LL | trait T: ?const Super {}
- | ^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs
index 6cfca71..b3d1f48 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs
@@ -9,14 +9,11 @@
// An inherent impl for the trait object `?const T`.
impl ?const T {}
//~^ ERROR `?const` is not permitted in trait objects
-//~| ERROR `?const` on trait bounds is not yet implemented
fn trait_object() -> &'static dyn ?const T { &S }
//~^ ERROR `?const` is not permitted in trait objects
-//~| ERROR `?const` on trait bounds is not yet implemented
fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
//~^ ERROR `?const` is not permitted in trait objects
-//~| ERROR `?const` on trait bounds is not yet implemented
fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr
index c059f16..331fe04 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.stderr
@@ -5,34 +5,16 @@
| ^^^^^^^^
error: `?const` is not permitted in trait objects
- --> $DIR/in-trait-object.rs:14:35
+ --> $DIR/in-trait-object.rs:13:35
|
LL | fn trait_object() -> &'static dyn ?const T { &S }
| ^^^^^^^^
error: `?const` is not permitted in trait objects
- --> $DIR/in-trait-object.rs:18:61
+ --> $DIR/in-trait-object.rs:16:61
|
LL | fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
| ^^^^^^^^
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-trait-object.rs:10:6
- |
-LL | impl ?const T {}
- | ^^^^^^^^
-
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-trait-object.rs:14:35
- |
-LL | fn trait_object() -> &'static dyn ?const T { &S }
- | ^^^^^^^^
-
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/in-trait-object.rs:18:61
- |
-LL | fn trait_object_in_apit(_: impl IntoIterator<Item = Box<dyn ?const T>>) {}
- | ^^^^^^^^
-
-error: aborting due to 6 previous errors
+error: aborting due to 3 previous errors
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs
index 425784f..c2c8689 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs
@@ -3,6 +3,5 @@
struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
//~^ ERROR `?const` and `?` are mutually exclusive
-//~| ERROR `?const` on trait bounds is not yet implemented
fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr
index 44f6d46..e8e9d6c 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.stderr
@@ -4,11 +4,5 @@
LL | struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
| ^^^^^^^^^^^^^
-error: `?const` on trait bounds is not yet implemented
- --> $DIR/with-maybe-sized.rs:4:13
- |
-LL | struct S<T: ?const ?Sized>(std::marker::PhantomData<T>);
- | ^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs
index 9cffe75..7f064c0 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.rs
@@ -1,5 +1,3 @@
-// compile-flags: -Z parse-only
-
#![feature(const_trait_impl)]
#![feature(const_trait_bound_opt_out)]
#![allow(incomplete_features)]
@@ -8,7 +6,12 @@
struct S;
trait T {}
+impl const S {}
+//~^ ERROR inherent impls cannot be `const`
+//~| ERROR const trait impls are not yet implemented
+
impl const T {}
-//~^ ERROR `const` cannot modify an inherent impl
+//~^ ERROR inherent impls cannot be `const`
+//~| ERROR const trait impls are not yet implemented
fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr
index 1d24557..508c6f4 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr
@@ -1,10 +1,30 @@
-error: `const` cannot modify an inherent impl
- --> $DIR/inherent-impl.rs:11:6
+error: inherent impls cannot be `const`
+ --> $DIR/inherent-impl.rs:9:1
+ |
+LL | impl const S {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: only trait implementations may be annotated with `const`
+
+error: inherent impls cannot be `const`
+ --> $DIR/inherent-impl.rs:13:1
|
LL | impl const T {}
- | ^^^^^
+ | ^^^^^^^^^^^^^^^
|
- = help: only a trait impl can be `const`
+ = note: only trait implementations may be annotated with `const`
-error: aborting due to previous error
+error: const trait impls are not yet implemented
+ --> $DIR/inherent-impl.rs:9:1
+ |
+LL | impl const S {}
+ | ^^^^^^^^^^^^^^^
+
+error: const trait impls are not yet implemented
+ --> $DIR/inherent-impl.rs:13:1
+ |
+LL | impl const T {}
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr
index 171c00b..5b665e1 100644
--- a/src/test/ui/rfc1623.stderr
+++ b/src/test/ui/rfc1623.stderr
@@ -2,7 +2,7 @@
--> $DIR/rfc1623.rs:8:42
|
LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 =
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
@@ -10,7 +10,7 @@
--> $DIR/rfc1623.rs:10:39
|
LL | &(non_elidable as fn(&u8, &u8) -> &u8);
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
index 38b0941..33229a2 100644
--- a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
@@ -1,5 +1,4 @@
// run-pass
-#![feature(slice_patterns)]
fn slice_pat() {
let sl: &[u8] = b"foo";
diff --git a/src/test/ui/sanitizer-address.rs b/src/test/ui/sanitizer-address.rs
new file mode 100644
index 0000000..d27a30a
--- /dev/null
+++ b/src/test/ui/sanitizer-address.rs
@@ -0,0 +1,21 @@
+// needs-sanitizer-support
+// only-x86_64
+//
+// compile-flags: -Z sanitizer=address -O
+//
+// run-fail
+// error-pattern: AddressSanitizer: stack-buffer-overflow
+// error-pattern: 'xs' <== Memory access at offset
+
+#![feature(test)]
+
+use std::hint::black_box;
+use std::mem;
+
+fn main() {
+ let xs = [0, 1, 2, 3];
+ // Avoid optimizing everything out.
+ let xs = black_box(xs.as_ptr());
+ let code = unsafe { *xs.offset(4) };
+ std::process::exit(code);
+}
diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/ui/sanitizer-leak.rs
similarity index 61%
rename from src/test/run-make-fulldeps/sanitizer-leak/leak.rs
rename to src/test/ui/sanitizer-leak.rs
index fb0a917..5c2f2cb 100644
--- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs
+++ b/src/test/ui/sanitizer-leak.rs
@@ -1,3 +1,11 @@
+// needs-sanitizer-support
+// only-x86_64
+//
+// compile-flags: -Z sanitizer=leak -O
+//
+// run-fail
+// error-pattern: LeakSanitizer: detected memory leaks
+
#![feature(test)]
use std::hint::black_box;
diff --git a/src/test/ui/sanitizer-memory.rs b/src/test/ui/sanitizer-memory.rs
new file mode 100644
index 0000000..3e1cf45
--- /dev/null
+++ b/src/test/ui/sanitizer-memory.rs
@@ -0,0 +1,44 @@
+// needs-sanitizer-support
+// only-linux
+// only-x86_64
+//
+// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+//
+// run-fail
+// error-pattern: MemorySanitizer: use-of-uninitialized-value
+// error-pattern: Uninitialized value was created by an allocation
+// error-pattern: in the stack frame of function 'random'
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![feature(test)]
+
+use std::hint::black_box;
+use std::mem::MaybeUninit;
+
+#[inline(never)]
+#[no_mangle]
+fn random() -> [isize; 32] {
+ let r = unsafe { MaybeUninit::uninit().assume_init() };
+ // Avoid optimizing everything out.
+ black_box(r)
+}
+
+#[inline(never)]
+#[no_mangle]
+fn xor(a: &[isize]) -> isize {
+ let mut s = 0;
+ for i in 0..a.len() {
+ s = s ^ a[i];
+ }
+ s
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ let r = random();
+ xor(&r)
+}
diff --git a/src/test/ui/sanitizer-unsupported-target.rs b/src/test/ui/sanitizer-unsupported-target.rs
new file mode 100644
index 0000000..444333c
--- /dev/null
+++ b/src/test/ui/sanitizer-unsupported-target.rs
@@ -0,0 +1,7 @@
+// ignore-tidy-linelength
+// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu
+// error-pattern: error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/src/test/ui/sanitizer-unsupported-target.stderr b/src/test/ui/sanitizer-unsupported-target.stderr
new file mode 100644
index 0000000..38be58d
--- /dev/null
+++ b/src/test/ui/sanitizer-unsupported-target.stderr
@@ -0,0 +1,4 @@
+error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
index 44beb9d..2f6d35f 100644
--- a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
+++ b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
@@ -88,6 +88,7 @@
is_sync_send!((1..));
is_sync_send!(repeat(1));
is_sync_send!(empty::<usize>());
+ is_sync_send!(empty::<*mut i32>());
is_sync_send!(once(1));
// for option.rs
diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs
index 929c35a..97006ae 100644
--- a/src/test/ui/trailing-comma.rs
+++ b/src/test/ui/trailing-comma.rs
@@ -1,8 +1,6 @@
// run-pass
// pretty-expanded FIXME #23616
-#![feature(slice_patterns)]
-
fn f<T,>(_: T,) {}
struct Foo<T,>(T);
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
index 9fb9a07..0a028e4 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr
@@ -2,9 +2,18 @@
--> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:39
|
LL | let _: dyn Foo(&isize, &usize) -> &usize;
- | ^ expected lifetime parameter
+ | ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
+help: consider introducing a named lifetime parameter
+ |
+LL | fn main<'lifetime>() {
+LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>,
+LL | dyn Foo(&isize) -> &isize >();
+LL | eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>,
+LL | dyn Foo(&isize) -> (&isize, &isize) >();
+LL |
+ ...
error: aborting due to previous error
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
index b20c23a..04df2e4 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr
@@ -2,7 +2,13 @@
--> $DIR/dyn-trait-underscore-in-struct.rs:9:24
|
LL | x: Box<dyn Debug + '_>,
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Foo<'lifetime> {
+LL | x: Box<dyn Debug + 'lifetime>,
+ |
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/dyn-trait-underscore-in-struct.rs:9:12
diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
index ed61bdf..cf82024 100644
--- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
+++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr
@@ -2,9 +2,13 @@
--> $DIR/in-fn-return-illegal.rs:5:30
|
LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } }
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } }
+ | ^^^^^^^^^^^ ^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/underscore-lifetime/in-struct.stderr b/src/test/ui/underscore-lifetime/in-struct.stderr
index 6bbdc71..e01b39a 100644
--- a/src/test/ui/underscore-lifetime/in-struct.stderr
+++ b/src/test/ui/underscore-lifetime/in-struct.stderr
@@ -2,13 +2,25 @@
--> $DIR/in-struct.rs:6:9
|
LL | x: &'_ u32,
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | struct Foo<'lifetime> {
+LL | x: &'lifetime u32,
+ |
error[E0106]: missing lifetime specifier
--> $DIR/in-struct.rs:10:14
|
LL | Variant(&'_ u32),
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | enum Bar<'lifetime> {
+LL | Variant(&'lifetime u32),
+ |
error: aborting due to 2 previous errors
diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index ef9e7e3..517904e 100644
--- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -14,7 +14,7 @@
--> $DIR/underscore-lifetime-binders.rs:2:17
|
LL | struct Baz<'a>(&'_ &'a u8);
- | ^^ expected lifetime parameter
+ | ^^ help: consider using the named lifetime: `'a`
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:10:33
@@ -28,9 +28,13 @@
--> $DIR/underscore-lifetime-binders.rs:16:35
|
LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
- | ^^ expected lifetime parameter
+ | ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y }
+ | ^^^^^^^^^^^ ^^^^^^^^^
error: aborting due to 5 previous errors
diff --git a/src/test/ui/uninhabited/uninhabited-patterns.rs b/src/test/ui/uninhabited/uninhabited-patterns.rs
index 1bf0118..58c726d 100644
--- a/src/test/ui/uninhabited/uninhabited-patterns.rs
+++ b/src/test/ui/uninhabited/uninhabited-patterns.rs
@@ -2,7 +2,7 @@
#![feature(box_syntax)]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
-#![feature(slice_patterns)]
+
#![deny(unreachable_patterns)]
mod foo {
diff --git a/src/test/ui/where-clauses/where-lifetime-resolution.stderr b/src/test/ui/where-clauses/where-lifetime-resolution.stderr
index 0081ae0..49799a9 100644
--- a/src/test/ui/where-clauses/where-lifetime-resolution.stderr
+++ b/src/test/ui/where-clauses/where-lifetime-resolution.stderr
@@ -1,6 +1,9 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/where-lifetime-resolution.rs:6:38
|
+LL | fn f() where
+ | - help: consider introducing lifetime `'a` here: `<'a>`
+LL | for<'a> dyn Trait1<'a>: Trait1<'a>, // OK
LL | (dyn for<'a> Trait1<'a>): Trait1<'a>,
| ^^ undeclared lifetime
@@ -13,6 +16,9 @@
error[E0261]: use of undeclared lifetime name `'b`
--> $DIR/where-lifetime-resolution.rs:8:52
|
+LL | fn f() where
+ | - help: consider introducing lifetime `'b` here: `<'b>`
+...
LL | for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>,
| ^^ undeclared lifetime
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 481163a..cff04e1 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -110,6 +110,7 @@
"riscv32imac-unknown-none-elf",
"riscv64imac-unknown-none-elf",
"riscv64gc-unknown-none-elf",
+ "riscv64gc-unknown-linux-gnu",
"s390x-unknown-linux-gnu",
"sparc64-unknown-linux-gnu",
"sparcv9-sun-solaris",
diff --git a/src/tools/clippy b/src/tools/clippy
index a8d90f6..fd0428f 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit a8d90f6a57925d204efb21b3f6d9726d6674f9bd
+Subproject commit fd0428f622feee209e6014b802f5717d48d9e978