diff --git a/mk/cfg/aarch64-linux-android.mk b/mk/cfg/aarch64-linux-android.mk index 274f73834d4..140c4af8297 100644 --- a/mk/cfg/aarch64-linux-android.mk +++ b/mk/cfg/aarch64-linux-android.mk @@ -1,5 +1,4 @@ # aarch64-linux-android configuration -# CROSS_PREFIX_aarch64-linux-android- CC_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-gcc CXX_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-g++ CPP_aarch64-linux-android=$(CFG_AARCH64_LINUX_ANDROID_NDK)/bin/aarch64-linux-android-gcc -E diff --git a/mk/cfg/mips-unknown-linux-gnu.mk b/mk/cfg/mips-unknown-linux-gnu.mk index 65b08774d49..9e7042befa9 100644 --- a/mk/cfg/mips-unknown-linux-gnu.mk +++ b/mk/cfg/mips-unknown-linux-gnu.mk @@ -20,5 +20,5 @@ CFG_UNIXY_mips-unknown-linux-gnu := 1 CFG_LDPATH_mips-unknown-linux-gnu := CFG_RUN_mips-unknown-linux-gnu= CFG_RUN_TARG_mips-unknown-linux-gnu= -RUSTC_FLAGS_mips-unknown-linux-gnu := -C target-cpu=mips32r2 -C target-feature="+mips32r2" -C soft-float +RUSTC_FLAGS_mips-unknown-linux-gnu := CFG_GNU_TRIPLE_mips-unknown-linux-gnu := mips-unknown-linux-gnu diff --git a/mk/cfg/mipsel-unknown-linux-gnu.mk b/mk/cfg/mipsel-unknown-linux-gnu.mk index 4dadfc275d3..f15a086b64e 100644 --- a/mk/cfg/mipsel-unknown-linux-gnu.mk +++ b/mk/cfg/mipsel-unknown-linux-gnu.mk @@ -20,5 +20,5 @@ CFG_UNIXY_mipsel-unknown-linux-gnu := 1 CFG_LDPATH_mipsel-unknown-linux-gnu := CFG_RUN_mipsel-unknown-linux-gnu= CFG_RUN_TARG_mipsel-unknown-linux-gnu= -RUSTC_FLAGS_mipsel-unknown-linux-gnu := -C target-cpu=mips32 -C target-feature="+mips32" +RUSTC_FLAGS_mipsel-unknown-linux-gnu := CFG_GNU_TRIPLE_mipsel-unknown-linux-gnu := mipsel-unknown-linux-gnu diff --git a/mk/cfg/x86_64-apple-ios.mk b/mk/cfg/x86_64-apple-ios.mk index dd6080fdb0b..3faf0c6a3f2 100644 --- a/mk/cfg/x86_64-apple-ios.mk +++ b/mk/cfg/x86_64-apple-ios.mk @@ -29,4 +29,4 @@ CFG_UNIXY_x86_64-apple-ios := 1 CFG_LDPATH_x86_64-apple-ios := CFG_RUN_x86_64-apple-ios = $(2) CFG_RUN_TARG_x86_64-apple-ios = $(call CFG_RUN_x86_64-apple-ios,,$(2)) -CFG_GNU_TRIPLE_i386-apple-ios := x86_64-apple-ios +CFG_GNU_TRIPLE_x86_64-apple-ios := x86_64-apple-ios diff --git a/mk/cfg/x86_64-unknown-bitrig.mk b/mk/cfg/x86_64-unknown-bitrig.mk index afffec1a53a..3ed94011c48 100644 --- a/mk/cfg/x86_64-unknown-bitrig.mk +++ b/mk/cfg/x86_64-unknown-bitrig.mk @@ -9,7 +9,7 @@ CFG_LIB_GLOB_x86_64-unknown-bitrig=lib$(1)-*.so CFG_LIB_DSYM_GLOB_x86_64-unknown-bitrig=$(1)-*.dylib.dSYM CFG_JEMALLOC_CFLAGS_x86_64-unknown-bitrig := -m64 -I/usr/include $(CFLAGS) CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -Wall -Werror -fPIE -fPIC -m64 -I/usr/include $(CFLAGS) -CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 $(LDFLAGS) +CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 CFG_GCCISH_DEF_FLAG_x86_64-unknown-bitrig := -Wl,--export-dynamic,--dynamic-list= CFG_LLC_FLAGS_x86_64-unknown-bitrig := CFG_INSTALL_NAME_x86_64-unknown-bitrig = diff --git a/mk/crates.mk b/mk/crates.mk index f47c4857ef8..4db8f32bb16 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -139,13 +139,13 @@ ONLY_RLIB_alloc_system := 1 # Documented-by-default crates DOC_CRATES := std alloc collections core libc rustc_unicode -ifeq ($(CFG_DISABLE_JEMALLOC),) +ifdef CFG_DISABLE_JEMALLOC +RUSTFLAGS_rustc_back := --cfg disable_jemalloc +else TARGET_CRATES += alloc_jemalloc DEPS_std += alloc_jemalloc DEPS_alloc_jemalloc := core libc native:jemalloc ONLY_RLIB_alloc_jemalloc := 1 -else -RUSTFLAGS_rustc_back := --cfg disable_jemalloc endif ################################################################################ diff --git a/mk/docs.mk b/mk/docs.mk index f76368e3d0b..81aabe60ff3 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -71,7 +71,7 @@ DOC_L10N_TARGETS := # If NO_REBUILD is set then break the dependencies on rustdoc so we # build the documentation without having to rebuild rustdoc. -ifeq ($(NO_REBUILD),) +ifndef NO_REBUILD HTML_DEPS := $(RUSTDOC_EXE) else HTML_DEPS := @@ -152,7 +152,7 @@ define DEF_LIB_DOC # If NO_REBUILD is set then break the dependencies on rustdoc so we # build crate documentation without having to rebuild rustdoc. -ifeq ($(NO_REBUILD),) +ifndef NO_REBUILD LIB_DOC_DEP_$(1) = \ $$(CRATEFILE_$(1)) \ $$(RSINPUTS_$(1)) \ diff --git a/mk/grammar.mk b/mk/grammar.mk index 0d527bd0688..8956983e3be 100644 --- a/mk/grammar.mk +++ b/mk/grammar.mk @@ -41,8 +41,8 @@ $(BG)RustLexer.class: $(BG) $(SG)RustLexer.g4 check-build-lexer-verifier: $(BG)verify -ifeq ($(NO_REBUILD),) -VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.rustc +ifndef NO_REBUILD +VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.rustc else VERIFY_DEPS := endif diff --git a/mk/host.mk b/mk/host.mk index 59a00950b5c..2faed75ac07 100644 --- a/mk/host.mk +++ b/mk/host.mk @@ -18,7 +18,7 @@ # $(5) - the name of the crate being processed define CP_HOST_STAGE_N_CRATE -ifeq ($$(ONLY_RLIB_$(5)),) +ifndef ONLY_RLIB_$(5) $$(HLIB$(2)_H_$(4))/stamp.$(5): \ $$(TLIB$(1)_T_$(3)_H_$(4))/stamp.$(5) \ $$(RUST_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \ diff --git a/mk/install.mk b/mk/install.mk index af6f3ff6ad2..6d9d86c3eb8 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -121,7 +121,7 @@ install-runtime-target-$(1)-cleanup: endef $(foreach target,$(CFG_TARGET), \ - $(if $(findstring $(CFG_ADB_DEVICE_STATUS),"true"), \ + $(if $(findstring $(CFG_ADB_DEVICE_STATUS),true), \ $(eval $(call INSTALL_RUNTIME_TARGET_N,$(taget),$(CFG_BUILD))) \ $(eval $(call INSTALL_RUNTIME_TARGET_CLEANUP_N,$(target))) \ )) diff --git a/mk/llvm.mk b/mk/llvm.mk index a4174efa5ef..d250ede9958 100644 --- a/mk/llvm.mk +++ b/mk/llvm.mk @@ -71,7 +71,7 @@ $$(LLVM_STAMP_$(1)): $$(S)src/rustllvm/llvm-auto-clean-trigger @$$(call E, make: done cleaning llvm) touch -r $$@.start_time $$@ && rm $$@.start_time -ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1) +ifdef CFG_ENABLE_LLVM_STATIC_STDCPP LLVM_STDCPP_RUSTFLAGS_$(1) = -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \ -print-file-name=lib$(CFG_STDCPP_NAME).a))" else @@ -95,9 +95,6 @@ endef $(foreach host,$(CFG_HOST), \ $(eval $(call DEF_LLVM_RULES,$(host)))) -$(foreach host,$(CFG_HOST), \ - $(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host)))) - # This can't be done in target.mk because it's included before this file. define LLVM_LINKAGE_DEPS $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $$(LLVM_LINKAGE_PATH_$(2)) diff --git a/mk/main.mk b/mk/main.mk index 9d75771dc80..b272a80eaf7 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -86,13 +86,13 @@ CFG_INFO := $(info cfg: version $(CFG_VERSION)) MKFILE_DEPS := config.stamp $(call rwildcard,$(CFG_SRC_DIR)mk/,*) MKFILES_FOR_TARBALL:=$(MKFILE_DEPS) -ifneq ($(NO_MKFILE_DEPS),) +ifdef NO_MKFILE_DEPS MKFILE_DEPS := endif NON_BUILD_HOST = $(filter-out $(CFG_BUILD),$(CFG_HOST)) NON_BUILD_TARGET = $(filter-out $(CFG_BUILD),$(CFG_TARGET)) -ifneq ($(MAKE_RESTARTS),) +ifdef MAKE_RESTARTS CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS)) endif @@ -107,28 +107,40 @@ ifneq ($(wildcard $(NON_BUILD_TARGET)),) CFG_INFO := $(info cfg: non-build target triples $(NON_BUILD_TARGET)) endif -CFG_RUSTC_FLAGS := $(RUSTFLAGS) +CFG_RUSTC_FLAGS := +ifdef RUSTFLAGS + CFG_RUSTC_FLAGS += $(RUSTFLAGS) +endif CFG_GCCISH_CFLAGS := CFG_GCCISH_LINK_FLAGS := CFG_JEMALLOC_FLAGS := +ifdef JEMALLOC_FLAGS + CFG_JEMALLOC_FLAGS += $(JEMALLOC_FLAGS) +endif ifdef CFG_DISABLE_OPTIMIZE $(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE)) - CFG_RUSTC_FLAGS += CFG_JEMALLOC_FLAGS += --enable-debug else # The rtopt cfg turns off runtime sanity checks CFG_RUSTC_FLAGS += -O --cfg rtopt endif -CFG_JEMALLOC_FLAGS += $(JEMALLOC_FLAGS) - ifdef CFG_ENABLE_DEBUG_ASSERTIONS $(info cfg: enabling debug assertions (CFG_ENABLE_DEBUG_ASSERTIONS)) CFG_RUSTC_FLAGS += -C debug-assertions=on endif +define DEF_RUSTFLAGS_STAGE +RUSTFLAGS_STAGE$(1) := +endef + +STAGES = 0 1 2 3 + +$(foreach stage,$(STAGES), \ + $(eval $(call DEF_RUSTFLAGS_STAGE,$(stage)))) + ifdef CFG_ENABLE_DEBUGINFO $(info cfg: enabling debuginfo (CFG_ENABLE_DEBUGINFO)) CFG_RUSTC_FLAGS += -g @@ -186,9 +198,9 @@ endif ifndef CFG_DISABLE_VALGRIND_RPASS - $(info cfg: enabling valgrind run-pass tests (CFG_ENABLE_VALGRIND_RPASS)) + $(info cfg: enabling valgrind run-pass tests) $(info cfg: valgrind-rpass command set to $(CFG_VALGRIND)) - CFG_VALGRIND_RPASS :=$(CFG_VALGRIND) + CFG_VALGRIND_RPASS := $(CFG_VALGRIND) else $(info cfg: disabling valgrind run-pass tests) CFG_VALGRIND_RPASS := @@ -372,8 +384,6 @@ export CFG_BOOTSTRAP_KEY TRIPLE_TO_DEBUGGER_SCRIPT_SETTING=\ $(if $(findstring windows,$(1)),none,$(if $(findstring darwin,$(1)),lldb,gdb)) -STAGES = 0 1 2 3 - define SREQ # $(1) is the stage number # $(2) is the target triple diff --git a/mk/platform.mk b/mk/platform.mk index 9c74e657a84..d702cca209d 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -82,12 +82,11 @@ AR := ar define SET_FROM_CFG ifdef CFG_$(1) ifeq ($(origin $(1)),undefined) - $$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1))) - $(1)=$(CFG_$(1)) - endif - ifeq ($(origin $(1)),default) - $$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1))) - $(1)=$(CFG_$(1)) + $$(info cfg: using $(1)=$$(CFG_$(1)) (CFG_$(1))) + $(1)=$$(CFG_$(1)) + else ifeq ($(origin $(1)),default) + $$(info cfg: using $(1)=$$(CFG_$(1)) (CFG_$(1))) + $(1)=$$(CFG_$(1)) endif endif endef @@ -101,7 +100,9 @@ include $(wildcard $(CFG_SRC_DIR)mk/cfg/*.mk) define ADD_INSTALLED_OBJECTS INSTALLED_OBJECTS_$(1) += $$(CFG_INSTALLED_OBJECTS_$(1)) - REQUIRED_OBJECTS_$(1) += $$(CFG_THIRD_PARTY_OBJECTS_$(1)) + ifdef CFG_THIRD_PARTY_OBJECTS_$(1) + REQUIRED_OBJECTS_$(1) += $$(CFG_THIRD_PARTY_OBJECTS_$(1)) + endif INSTALLED_OBJECTS_$(1) += $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt) REQUIRED_OBJECTS_$(1) += $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt) endef @@ -163,15 +164,15 @@ define CFG_MAKE_TOOLCHAIN # Prepend the tools with their prefix if cross compiling ifneq ($(CFG_BUILD),$(1)) ifneq ($$(findstring msvc,$(1)),msvc) - CC_$(1)=$(CROSS_PREFIX_$(1))$(CC_$(1)) - CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1)) - CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1)) - AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1)) - LINK_$(1)=$(CROSS_PREFIX_$(1))$(LINK_$(1)) - RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(LINK_$(1))) \ - -C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1)) + CC_$(1)=$(CROSS_PREFIX_$(1))$(CC_$(1)) + CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1)) + CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1)) + AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1)) + LINK_$(1)=$(CROSS_PREFIX_$(1))$(LINK_$(1)) + RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(LINK_$(1))) \ + -C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1)) - RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1)) + RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1)) endif endif diff --git a/mk/rt.mk b/mk/rt.mk index 9dbbcbebb97..394fbe1ba0f 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -107,8 +107,6 @@ $$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1)) endef -$(foreach target,$(CFG_TARGET), \ - $(eval $(call RUNTIME_RULES,$(target)))) $(foreach lib,$(NATIVE_LIBS), \ $(foreach target,$(CFG_TARGET), \ $(eval $(call THIRD_PARTY_LIB,$(target),$(lib))))) @@ -171,7 +169,7 @@ endif # See #17183 for details, this file is touched during the build process so we # don't want to consider it as a dependency. -JEMALLOC_DEPS := $(filter-out $(S)src/jemalloc/VERSION,$(JEMALLOC_DEPS)) +JEMALLOC_DEPS := $(filter-out $(S)src/jemalloc/VERSION,$$(JEMALLOC_DEPS)) JEMALLOC_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc) ifeq ($$(CFG_WINDOWSY_$(1)),1) diff --git a/mk/target.mk b/mk/target.mk index 32a3eb5c20d..1fcc87f0c35 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -138,12 +138,12 @@ define TARGET_RUSTRT_STARTUP_OBJ $$(TLIB$(1)_T_$(2)_H_$(3))/$(4).o: \ $(S)src/rtstartup/$(4).rs \ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.core \ - $$(HSREQ$(1)_T_$(2)_H_$(3)) \ + $$(HSREQ$(1)_H_$(3)) \ | $$(TBIN$(1)_T_$(2)_H_$(3))/ @$$(call E, rustc: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) --emit=obj -o $$@ $$< -ifeq ($$(CFG_RUSTRT_HAS_STARTUP_OBJS_$(2)), 1) +ifdef CFG_RUSTRT_HAS_STARTUP_OBJS_$(2) # Add dependencies on Rust startup objects to all crates that depend on core. # This ensures that they are built after core (since they depend on it), # but before everything else (since they are needed for linking dylib crates). diff --git a/mk/tests.mk b/mk/tests.mk index 19587a28d55..bce5a52118b 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -36,6 +36,8 @@ TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES) # Environment configuration ###################################################################### +TESTARGS := + # The arguments to all test runners ifdef TESTNAME TESTARGS += $(TESTNAME) @@ -48,6 +50,8 @@ endif # Arguments to the cfail/rfail/rpass tests ifdef CFG_VALGRIND CTEST_RUNTOOL = --runtool "$(CFG_VALGRIND)" +else + CTEST_RUNTOOL = endif CTEST_TESTARGS := $(TESTARGS) @@ -143,10 +147,11 @@ else CFG_ADB_TEST_DIR= endif +DOC_NAMES := # $(1) - name of doc test # $(2) - file of the test define DOCTEST -DOC_NAMES := $$(DOC_NAMES) $(1) +DOC_NAMES += $(1) DOCFILE_$(1) := $(2) endef @@ -362,7 +367,7 @@ define TEST_RUNNER # If NO_REBUILD is set then break the dependencies on everything but # the source files so we can test crates without rebuilding any of the # parent crates. -ifeq ($(NO_REBUILD),) +ifndef NO_REBUILD TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \ $$(foreach crate,$$(TARGET_CRATES), \ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \ @@ -447,7 +452,7 @@ $(foreach host,$(CFG_HOST), \ $(if $(findstring $(target),$(CFG_BUILD)), \ $(eval $(call DEF_TEST_CRATE_RULES,$(stage),$(target),$(host),$(crate))), \ $(if $(findstring android, $(target)), \ - $(if $(findstring $(CFG_ADB_DEVICE_STATUS),"true"), \ + $(if $(findstring $(CFG_ADB_DEVICE_STATUS),true), \ $(eval $(call DEF_TEST_CRATE_RULES_android,$(stage),$(target),$(host),$(crate))), \ $(eval $(call DEF_TEST_CRATE_RULES_null,$(stage),$(target),$(host),$(crate))) \ ), \ @@ -700,14 +705,14 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4 # (Encoded as a separate variable because GNU make does not have a # good way to express OR on ifeq commands) -ifneq ($$(CTEST_DISABLE_$(4)),) +ifdef CTEST_DISABLE_$(4) # Test suite is disabled for all configured targets. CTEST_DONT_RUN_$(1)-T-$(2)-H-$(3)-$(4) := $$(CTEST_DISABLE_$(4)) else # else, check if non-self-hosted target (i.e. target not-in hosts) ... ifeq ($$(findstring $(2),$$(CFG_HOST)),) # ... if so, then check if this test suite is disabled for non-selfhosts. -ifneq ($$(CTEST_DISABLE_NONSELFHOST_$(4)),) +ifdef CTEST_DISABLE_NONSELFHOST_$(4) # Test suite is disabled for this target. CTEST_DONT_RUN_$(1)-T-$(2)-H-$(3)-$(4) := $$(CTEST_DISABLE_NONSELFHOST_$(4)) endif @@ -715,7 +720,7 @@ endif # Neither DISABLE nor DISABLE_NONSELFHOST is set ==> okay, run the test. endif -ifeq ($$(CTEST_DONT_RUN_$(1)-T-$(2)-H-$(3)-$(4)),) +ifndef CTEST_DONT_RUN_$(1)-T-$(2)-H-$(3)-$(4) $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3)) @@ -824,7 +829,7 @@ check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3) # If NO_REBUILD is set then break the dependencies on everything but # the source files so we can test documentation without rebuilding # rustdoc etc. -ifeq ($(NO_REBUILD),) +ifndef NO_REBUILD DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \ $$(DOCFILE_$(4)) \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ @@ -859,7 +864,7 @@ define DEF_CRATE_DOC_TEST # If NO_REBUILD is set then break the dependencies on everything but # the source files so we can test crate documentation without # rebuilding any of the parent crates. -ifeq ($(NO_REBUILD),) +ifndef NO_REBUILD CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \ @@ -922,8 +927,7 @@ TEST_GROUPS = \ pretty-rpass-full \ pretty-rfail-full \ pretty-rfail \ - pretty-pretty \ - $(NULL) + pretty-pretty define DEF_CHECK_FOR_STAGE_AND_TARGET_AND_HOST check-stage$(1)-T-$(2)-H-$(3): check-stage$(1)-T-$(2)-H-$(3)-exec diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index b02b2a06b75..c207ad16595 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -17,6 +17,24 @@ //! Like many traits, these are often used as bounds for generic functions, to //! support arguments of multiple types. //! +//! - Impl the `As*` traits for reference-to-reference conversions +//! - Impl the `Into` trait when you want to consume the value in the conversion +//! - The `From` trait is the most flexible, usefull for values _and_ references conversions +//! +//! As a library writer, you should prefer implementing `From` rather than +//! `Into`, as `From` provides greater flexibility and offer the equivalent `Into` +//! implementation for free, thanks to a blanket implementation in the standard library. +//! +//! **Note: these traits must not fail**. If the conversion can fail, you must use a dedicated +//! method which return an `Option` or a `Result`. +//! +//! # Generic impl +//! +//! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference +//! - `From for T` implies `Into for U` +//! - `From` and `Into` are reflexive, which means that all types can `into()` +//! themselves and `from()` themselves +//! //! See each trait for usage examples. #![stable(feature = "rust1", since = "1.0.0")] @@ -30,6 +48,9 @@ use marker::Sized; /// /// [book]: ../../book/borrow-and-asref.html /// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// return an `Option` or a `Result`. +/// /// # Examples /// /// Both `String` and `&str` implement `AsRef`: @@ -45,6 +66,12 @@ use marker::Sized; /// let s = "hello".to_string(); /// is_hello(s); /// ``` +/// +/// # Generic Impls +/// +/// - `AsRef` auto-dereference if the inner type is a reference or a mutable +/// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRef { /// Performs the conversion. @@ -53,6 +80,15 @@ pub trait AsRef { } /// A cheap, mutable reference-to-mutable reference conversion. +/// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// return an `Option` or a `Result`. +/// +/// # Generic Impls +/// +/// - `AsMut` auto-dereference if the inner type is a reference or a mutable +/// reference (eg: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`) +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait AsMut { /// Performs the conversion. @@ -62,6 +98,13 @@ pub trait AsMut { /// A conversion that consumes `self`, which may or may not be expensive. /// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// return an `Option` or a `Result`. +/// +/// Library writer should not implement directly this trait, but should prefer the implementation +/// of the `From` trait, which offer greater flexibility and provide the equivalent `Into` +/// implementation for free, thanks to a blanket implementation in the standard library. +/// /// # Examples /// /// `String` implements `Into>`: @@ -75,6 +118,12 @@ pub trait AsMut { /// let s = "hello".to_string(); /// is_hello(s); /// ``` +/// +/// # Generic Impls +/// +/// - `From for U` implies `Into for T` +/// - `into()` is reflexive, which means that `Into for T` is implemented +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait Into: Sized { /// Performs the conversion. @@ -84,6 +133,9 @@ pub trait Into: Sized { /// Construct `Self` via a conversion. /// +/// **Note: this trait must not fail**. If the conversion can fail, use a dedicated method which +/// return an `Option` or a `Result`. +/// /// # Examples /// /// `String` implements `From<&str>`: @@ -94,6 +146,11 @@ pub trait Into: Sized { /// /// assert_eq!(string, other_string); /// ``` +/// # Generic impls +/// +/// - `From for U` implies `Into for T` +/// - `from()` is reflexive, which means that `From for T` is implemented +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait From: Sized { /// Performs the conversion. diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs index 357499c48ec..01f2de4a269 100644 --- a/src/librustc_back/target/mips_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::Target; +use target::{Target, TargetOptions}; pub fn target() -> Target { Target { @@ -19,6 +19,10 @@ pub fn target() -> Target { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), - options: super::linux_base::opts() + options: TargetOptions { + cpu: "mips32r2".to_string(), + features: "+mips32r2,+soft-float".to_string(), + ..super::linux_base::opts() + }, } } diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs index 3d0088add0d..e9eef72e8c3 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::Target; +use target::{Target, TargetOptions}; pub fn target() -> Target { Target { @@ -20,6 +20,10 @@ pub fn target() -> Target { target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), - options: super::linux_base::opts() + options: TargetOptions { + cpu: "mips32".to_string(), + features: "+mips32".to_string(), + ..super::linux_base::opts() + }, } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a1d866fc48b..8f4913f0420 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -107,20 +107,37 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// otherwise, reports an error. fn define>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T) { - let name_binding = def.to_name_binding(); - let span = name_binding.span.unwrap_or(DUMMY_SP); - self.check_for_conflicts_between_external_crates_and_items(&parent, name, span); - if !parent.try_define_child(name, ns, name_binding) { + let binding = def.to_name_binding(); + let old_binding = match parent.try_define_child(name, ns, binding.clone()) { + Some(old_binding) => old_binding, + None => return, + }; + + let span = binding.span.unwrap_or(DUMMY_SP); + if !old_binding.is_extern_crate() && !binding.is_extern_crate() { // Record an error here by looking up the namespace that had the duplicate let ns_str = match ns { TypeNS => "type or module", ValueNS => "value" }; let resolution_error = ResolutionError::DuplicateDefinition(ns_str, name); let mut err = resolve_struct_error(self, span, resolution_error); - if let Some(sp) = parent.children.borrow().get(&(name, ns)).unwrap().span { + if let Some(sp) = old_binding.span { let note = format!("first definition of {} `{}` here", ns_str, name); err.span_note(sp, ¬e); } err.emit(); + } else if old_binding.is_extern_crate() && binding.is_extern_crate() { + span_err!(self.session, + span, + E0259, + "an external crate named `{}` has already been imported into this module", + name); + } else { + span_err!(self.session, + span, + E0260, + "the name `{}` conflicts with an external crate \ + that has been imported into this module", + name); } } @@ -289,14 +306,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { self.external_exports.insert(def_id); let parent_link = ModuleParentLink(parent, name); let def = Def::Mod(def_id); - let external_module = self.new_module(parent_link, Some(def), false, true); + let external_module = self.new_extern_crate_module(parent_link, def); + self.define(parent, name, TypeNS, (external_module, sp)); - debug!("(build reduced graph for item) found extern `{}`", - module_to_string(&*external_module)); - self.check_for_conflicts_for_external_crate(parent, name, sp); - parent.external_module_children - .borrow_mut() - .insert(name, external_module); self.build_reduced_graph_for_external_crate(&external_module); } parent diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 7f740f9c033..178e2a4d1bc 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -117,7 +117,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. - if item.vis == hir::Public || item.span == DUMMY_SP { + if item.vis == hir::Public || item.span.source_equal(&DUMMY_SP) { return; } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6c78f98c0cb..6f35d10c994 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -120,8 +120,6 @@ enum SuggestionType { } pub enum ResolutionError<'a> { - /// error E0260: name conflicts with an extern crate - NameConflictsWithExternCrate(Name), /// error E0401: can't use type parameters from outer function TypeParametersFromOuterFunction, /// error E0402: cannot use an outer type parameter in this context @@ -228,14 +226,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>, } match resolution_error { - ResolutionError::NameConflictsWithExternCrate(name) => { - struct_span_err!(resolver.session, - span, - E0260, - "the name `{}` conflicts with an external crate \ - that has been imported into this module", - name) - } ResolutionError::TypeParametersFromOuterFunction => { struct_span_err!(resolver.session, span, @@ -801,14 +791,11 @@ pub struct ModuleS<'a> { parent_link: ParentLink<'a>, def: Cell>, is_public: bool, + is_extern_crate: bool, children: RefCell>>, imports: RefCell>, - // The external module children of this node that were declared with - // `extern crate`. - external_module_children: RefCell>>, - // The anonymous children of this node. Anonymous children are pseudo- // modules that are implicitly created around items contained within // blocks. @@ -854,9 +841,9 @@ impl<'a> ModuleS<'a> { parent_link: parent_link, def: Cell::new(def), is_public: is_public, + is_extern_crate: false, children: RefCell::new(HashMap::new()), imports: RefCell::new(Vec::new()), - external_module_children: RefCell::new(HashMap::new()), anonymous_children: RefCell::new(NodeMap()), import_resolutions: RefCell::new(HashMap::new()), glob_count: Cell::new(0), @@ -871,10 +858,21 @@ impl<'a> ModuleS<'a> { self.children.borrow().get(&(name, ns)).cloned() } - fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>) -> bool { + // If the name is not yet defined, define the name and return None. + // Otherwise, return the existing definition. + fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>) + -> Option> { match self.children.borrow_mut().entry((name, ns)) { - hash_map::Entry::Vacant(entry) => { entry.insert(binding); true } - hash_map::Entry::Occupied(_) => false, + hash_map::Entry::Vacant(entry) => { entry.insert(binding); None } + hash_map::Entry::Occupied(entry) => { Some(entry.get().clone()) }, + } + } + + fn for_each_local_child)>(&self, mut f: F) { + for (&(name, ns), name_binding) in self.children.borrow().iter() { + if !name_binding.is_extern_crate() { + f(name, ns, name_binding) + } } } @@ -1005,6 +1003,10 @@ impl<'a> NameBinding<'a> { let def = self.def().unwrap(); (def, LastMod(if self.is_public() { AllPublic } else { DependsOn(def.def_id()) })) } + + fn is_extern_crate(&self) -> bool { + self.module().map(|module| module.is_extern_crate).unwrap_or(false) + } } /// Interns the names of the primitive types. @@ -1184,6 +1186,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public)) } + fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def) -> Module<'a> { + let mut module = ModuleS::new(parent_link, Some(def), false, true); + module.is_extern_crate = true; + self.arenas.modules.alloc(module) + } + fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec> { match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs } } @@ -1211,32 +1219,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - /// Check that an external crate doesn't collide with items or other external crates. - fn check_for_conflicts_for_external_crate(&self, module: Module<'a>, name: Name, span: Span) { - if module.external_module_children.borrow().contains_key(&name) { - span_err!(self.session, - span, - E0259, - "an external crate named `{}` has already been imported into this module", - name); - } - if let Some(name_binding) = module.get_child(name, TypeNS) { - resolve_error(self, - name_binding.span.unwrap_or(codemap::DUMMY_SP), - ResolutionError::NameConflictsWithExternCrate(name)); - } - } - - /// Checks that the names of items don't collide with external crates. - fn check_for_conflicts_between_external_crates_and_items(&self, - module: Module<'a>, - name: Name, - span: Span) { - if module.external_module_children.borrow().contains_key(&name) { - resolve_error(self, span, ResolutionError::NameConflictsWithExternCrate(name)); - } - } - /// Resolves the given module path from the given root `module_`. fn resolve_module_path_from_root(&mut self, module_: Module<'a>, @@ -1245,11 +1227,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span, lp: LastPrivate) -> ResolveResult<(Module<'a>, LastPrivate)> { - fn search_parent_externals<'a>(needle: Name, module: Module<'a>) - -> Option> { - match module.external_module_children.borrow().get(&needle) { - Some(_) => Some(module), - None => match module.parent_link { + fn search_parent_externals<'a>(needle: Name, module: Module<'a>) -> Option> { + match module.get_child(needle, TypeNS) { + Some(ref binding) if binding.is_extern_crate() => Some(module), + _ => match module.parent_link { ModuleParentLink(ref parent, _) => { search_parent_externals(needle, parent) } @@ -1480,17 +1461,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - // Search for external modules. - if namespace == TypeNS { - let children = module_.external_module_children.borrow(); - if let Some(module) = children.get(&name) { - let name_binding = NameBinding::create_from_module(module, None); - debug!("lower name bindings succeeded"); - return Success((Target::new(module_, name_binding, Shadowable::Never), - false)); - } - } - // Finally, proceed up the scope chain looking for parent modules. let mut search_module = module_; loop { @@ -1684,16 +1654,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(..) | None => {} // Continue. } - // Finally, search through external children. - if namespace == TypeNS { - let children = module_.external_module_children.borrow(); - if let Some(module) = children.get(&name) { - let name_binding = NameBinding::create_from_module(module, None); - return Success((Target::new(module_, name_binding, Shadowable::Never), - false)); - } - } - // We're out of luck. debug!("(resolving name in module) failed to resolve `{}`", name); return Failed(None); @@ -1712,7 +1672,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Descend into children and anonymous children. build_reduced_graph::populate_module_if_necessary(self, &module_); - for (_, child_node) in module_.children.borrow().iter() { + module_.for_each_local_child(|_, _, child_node| { match child_node.module() { None => { // Continue. @@ -1721,7 +1681,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.report_unresolved_imports(child_module); } } - } + }); for (_, module_) in module_.anonymous_children.borrow().iter() { self.report_unresolved_imports(module_); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 07f6a0f9549..47b91ccb9d6 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -213,7 +213,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { self.resolver.current_module = orig_module; build_reduced_graph::populate_module_if_necessary(self.resolver, &module_); - for (_, child_node) in module_.children.borrow().iter() { + module_.for_each_local_child(|_, _, child_node| { match child_node.module() { None => { // Nothing to do. @@ -222,7 +222,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { errors.extend(self.resolve_imports_for_module_subtree(child_module)); } } - } + }); for (_, child_module) in module_.anonymous_children.borrow().iter() { errors.extend(self.resolve_imports_for_module_subtree(child_module)); @@ -386,18 +386,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { -> (ResolveResult<(Module<'b>, NameBinding<'b>)>, bool) { build_reduced_graph::populate_module_if_necessary(self.resolver, module); if let Some(name_binding) = module.get_child(name, ns) { - return (Success((module, name_binding)), false); - } - - if ns == TypeNS { - if let Some(extern_crate) = module.external_module_children.borrow().get(&name) { + if name_binding.is_extern_crate() { // track the extern crate as used. - if let Some(DefId{ krate: kid, .. }) = extern_crate.def_id() { - self.resolver.used_crates.insert(kid); + if let Some(DefId { krate, .. }) = name_binding.module().unwrap().def_id() { + self.resolver.used_crates.insert(krate); } - let name_binding = NameBinding::create_from_module(extern_crate, None); - return (Success((module, name_binding)), false); } + return (Success((module, name_binding)), false) } // If there is an unresolved glob at this point in the containing module, bail out. @@ -725,13 +720,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // Add all children from the containing module. build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module); - for (&name, name_binding) in target_module.children.borrow().iter() { + target_module.for_each_local_child(|name, ns, name_binding| { self.merge_import_resolution(module_, target_module, import_directive, - name, + (name, ns), name_binding.clone()); - } + }); // Record the destination of this import if let Some(did) = target_module.def_id() { @@ -798,9 +793,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { dest_import_resolution.is_public = is_public; self.add_export(module_, name, &dest_import_resolution); } - } else { - // FIXME #30159: This is required for backwards compatability. - dest_import_resolution.is_public |= is_public; } self.check_for_conflicts_between_imports_and_items(module_, @@ -881,21 +873,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { import: &ImportResolution<'b>, import_span: Span, (name, ns): (Name, Namespace)) { - // First, check for conflicts between imports and `extern crate`s. - if ns == TypeNS { - if module.external_module_children.borrow().contains_key(&name) { - match import.target { - Some(ref target) if target.shadowable != Shadowable::Always => { - let msg = format!("import `{0}` conflicts with imported crate \ - in this module (maybe you meant `use {0}::*`?)", - name); - span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]); - } - Some(_) | None => {} - } - } - } - // Check for item conflicts. let name_binding = match module.get_child(name, ns) { None => { @@ -924,6 +901,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { } else { match import.target { Some(ref target) if target.shadowable != Shadowable::Always => { + if name_binding.is_extern_crate() { + let msg = format!("import `{0}` conflicts with imported crate \ + in this module (maybe you meant `use {0}::*`?)", + name); + span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]); + return; + } + let (what, note) = match name_binding.module() { Some(ref module) if module.is_normal() => ("existing submodule", "note conflicting module here"), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index af343e0b079..f811eb872fc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4250,14 +4250,9 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let def_id = ccx.tcx.map.local_def_id(id); let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); - if hint != attr::ReprAny && vs.len() <= 1 { - if vs.len() == 1 { - span_err!(ccx.tcx.sess, sp, E0083, - "unsupported representation for univariant enum"); - } else { - span_err!(ccx.tcx.sess, sp, E0084, - "unsupported representation for zero-variant enum"); - }; + if hint != attr::ReprAny && vs.is_empty() { + span_err!(ccx.tcx.sess, sp, E0084, + "unsupported representation for zero-variant enum"); } do_check(ccx, vs, id, hint); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8f7692c7945..df09cd26134 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1062,13 +1062,6 @@ Note also that without a representation manually defined, the compiler will optimize by using the smallest integer type possible. "##, -E0083: r##" -At present, it's not possible to define a custom representation for an enum with -a single variant. As a workaround you can add a `Dummy` variant. - -See: https://github.com/rust-lang/rust/issues/10292 -"##, - E0084: r##" It is impossible to define an integer type to be used to represent zero-variant enum values because there are no zero-variant enum values. There is no way to diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index ba4d1e2193e..03dc25e1b3c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -356,7 +356,7 @@ pub fn pat_is_ident(pat: P) -> bool { // since I'm using this to replace ==, it seems appropriate // to compare the span, global, etc. fields as well. pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { - (a.span == b.span) + (a.span.source_equal(&b.span)) && (a.global == b.global) && (segments_name_eq(&a.segments[..], &b.segments[..])) } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index ca01623fef9..9557310f318 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -123,7 +123,7 @@ impl Sub for CharPos { /// able to use many of the functions on spans in codemap and you cannot assume /// that the length of the span = hi - lo; there may be space in the BytePos /// range between files. -#[derive(Clone, Copy, Hash)] +#[derive(Clone, Copy, Hash, PartialEq, Eq)] pub struct Span { pub lo: BytePos, pub hi: BytePos, @@ -151,13 +151,21 @@ pub const COMMAND_LINE_SP: Span = Span { lo: BytePos(0), impl Span { /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { - if self == DUMMY_SP { other } else { self } + if self.source_equal(&DUMMY_SP) { other } else { self } } pub fn contains(self, other: Span) -> bool { self.lo <= other.lo && other.hi <= self.hi } + /// Return true if the spans are equal with regards to the source text. + /// + /// Use this instead of `==` when either span could be generated code, + /// and you only care that they point to the same bytes of source text. + pub fn source_equal(&self, other: &Span) -> bool { + self.lo == other.lo && self.hi == other.hi + } + /// Returns `Some(span)`, a union of `self` and `other`, on overlap. pub fn merge(self, other: Span) -> Option { if self.expn_id != other.expn_id { @@ -192,15 +200,6 @@ pub struct Spanned { pub span: Span, } -impl PartialEq for Span { - fn eq(&self, other: &Span) -> bool { - return (*self).lo == (*other).lo && (*self).hi == (*other).hi; - } - fn ne(&self, other: &Span) -> bool { !(*self).eq(other) } -} - -impl Eq for Span {} - impl Encodable for Span { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_struct("Span", 2, |s| { @@ -940,7 +939,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().is_empty() && sp == DUMMY_SP { + if self.files.borrow().is_empty() && sp.source_equal(&DUMMY_SP) { return "no-location".to_string(); } @@ -1307,7 +1306,7 @@ impl CodeMap { expninfo.map_or(/* hit the top level */ true, |info| { let span_comes_from_this_expansion = - info.callee.span.map_or(span == info.call_site, |mac_span| { + info.callee.span.map_or(span.source_equal(&info.call_site), |mac_span| { mac_span.contains(span) }); diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index c1239bfd66d..7e0e17423de 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -10,7 +10,7 @@ use self::Destination::*; -use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, DUMMY_SP, Pos, Span, MultiSpan}; +use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Pos, Span, MultiSpan}; use diagnostics; use errors::{Level, RenderSpan, CodeSuggestion, DiagnosticBuilder}; @@ -175,9 +175,7 @@ impl EmitterWriter { let msp = rsp.span(); let bounds = msp.to_span_bounds(); - // We cannot check equality directly with COMMAND_LINE_SP - // since PartialEq is manually implemented to ignore the ExpnId - let ss = if bounds.expn_id == COMMAND_LINE_EXPN { + let ss = if bounds == COMMAND_LINE_SP { "".to_string() } else if let EndSpan(_) = *rsp { let span_end = Span { lo: bounds.hi, hi: bounds.hi, expn_id: bounds.expn_id}; @@ -606,7 +604,7 @@ impl EmitterWriter { }; // Don't print recursive invocations - if span != last_span { + if !span.source_equal(&last_span) { let mut diag_string = macro_decl_name; if let Some(def_site_span) = def_site_span { diag_string.push_str(&format!(" (defined in {})", diff --git a/src/test/compile-fail/resolve-conflict-item-vs-extern-crate.rs b/src/test/compile-fail/resolve-conflict-item-vs-extern-crate.rs index e685353592f..07f80cf03d1 100644 --- a/src/test/compile-fail/resolve-conflict-item-vs-extern-crate.rs +++ b/src/test/compile-fail/resolve-conflict-item-vs-extern-crate.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn std() {} //~ ERROR the name `std` conflicts with an external crate +fn std() {} +mod std {} //~ ERROR the name `std` conflicts with an external crate fn main() { } diff --git a/src/test/compile-fail/shadowed-use-visibility.rs b/src/test/compile-fail/shadowed-use-visibility.rs index bfc6a4ec9b8..1bf7f393384 100644 --- a/src/test/compile-fail/shadowed-use-visibility.rs +++ b/src/test/compile-fail/shadowed-use-visibility.rs @@ -17,6 +17,10 @@ mod foo { mod bar { use foo::bar::f as g; //~ ERROR unresolved import + + use foo as f; + pub use foo::*; } +use bar::f::f; //~ ERROR unresolved import fn main() {} diff --git a/src/test/run-pass/enum-univariant-repr.rs b/src/test/run-pass/enum-univariant-repr.rs new file mode 100644 index 00000000000..ef4cc60bf0d --- /dev/null +++ b/src/test/run-pass/enum-univariant-repr.rs @@ -0,0 +1,47 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +use std::mem; + +// Univariant C-like enum +#[repr(i32)] +enum Univariant { + X = 17 +} + +#[repr(u16)] +enum UnivariantWithoutDescr { + Y +} + +pub fn main() { + { + assert_eq!(4, mem::size_of::()); + assert_eq!(17, Univariant::X as i32); + + let enums: &[Univariant] = + &[Univariant::X, Univariant::X, Univariant::X]; + let ints: &[i32] = unsafe { mem::transmute(enums) }; + // check it has the same memory layout as i32 + assert_eq!(&[17, 17, 17], ints); + } + + { + assert_eq!(2, mem::size_of::()); + let descr = UnivariantWithoutDescr::Y as u16; + + let enums: &[UnivariantWithoutDescr] = + &[UnivariantWithoutDescr::Y, UnivariantWithoutDescr::Y, UnivariantWithoutDescr::Y]; + let ints: &[u16] = unsafe { mem::transmute(enums) }; + // check it has the same memory layout as u16 + assert_eq!(&[descr, descr, descr], ints); + } +}