Merge branch 'master' of https://github.com/rust-lang/rust into doc

This commit is contained in:
Ryan Thomas 2016-02-02 10:54:05 +11:00
commit 66eb588476
31 changed files with 282 additions and 214 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 =

View File

@ -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
################################################################################

View File

@ -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)) \

View File

@ -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

View File

@ -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.%) \

View File

@ -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))) \
))

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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).

View File

@ -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

View File

@ -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<T>` rather than
//! `Into<U>`, 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<T>` or a `Result<T, E>`.
//!
//! # Generic impl
//!
//! - `AsRef` and `AsMut` auto-dereference if the inner type is a reference
//! - `From<U> for T` implies `Into<T> 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<T>` or a `Result<T, E>`.
///
/// # Examples
///
/// Both `String` and `&str` implement `AsRef<str>`:
@ -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<T: ?Sized> {
/// Performs the conversion.
@ -53,6 +80,15 @@ pub trait AsRef<T: ?Sized> {
}
/// 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<T>` or a `Result<T, E>`.
///
/// # 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<T: ?Sized> {
/// Performs the conversion.
@ -62,6 +98,13 @@ pub trait AsMut<T: ?Sized> {
/// 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<T>` or a `Result<T, E>`.
///
/// 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<Vec<u8>>`:
@ -75,6 +118,12 @@ pub trait AsMut<T: ?Sized> {
/// let s = "hello".to_string();
/// is_hello(s);
/// ```
///
/// # Generic Impls
///
/// - `From<T> for U` implies `Into<U> for T`
/// - `into()` is reflexive, which means that `Into<T> for T` is implemented
///
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Into<T>: Sized {
/// Performs the conversion.
@ -84,6 +133,9 @@ pub trait Into<T>: 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<T>` or a `Result<T, E>`.
///
/// # Examples
///
/// `String` implements `From<&str>`:
@ -94,6 +146,11 @@ pub trait Into<T>: Sized {
///
/// assert_eq!(string, other_string);
/// ```
/// # Generic impls
///
/// - `From<T> for U` implies `Into<U> for T`
/// - `from()` is reflexive, which means that `From<T> for T` is implemented
///
#[stable(feature = "rust1", since = "1.0.0")]
pub trait From<T>: Sized {
/// Performs the conversion.

View File

@ -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()
},
}
}

View File

@ -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()
},
}
}

View File

@ -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<T: ToNameBinding<'b>>(&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, &note);
}
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

View File

@ -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;
}

View File

@ -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<Option<Def>>,
is_public: bool,
is_extern_crate: bool,
children: RefCell<HashMap<(Name, Namespace), NameBinding<'a>>>,
imports: RefCell<Vec<ImportDirective>>,
// The external module children of this node that were declared with
// `extern crate`.
external_module_children: RefCell<HashMap<Name, Module<'a>>>,
// 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<NameBinding<'a>> {
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<F: FnMut(Name, Namespace, &NameBinding<'a>)>(&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<Rib<'a>> {
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<Module<'a>> {
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<Module<'a>> {
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_);

View File

@ -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"),

View File

@ -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);

View File

@ -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

View File

@ -356,7 +356,7 @@ pub fn pat_is_ident(pat: P<ast::Pat>) -> 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[..]))
}

View File

@ -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<Span> {
if self.expn_id != other.expn_id {
@ -192,15 +200,6 @@ pub struct Spanned<T> {
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<S: Encoder>(&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)
});

View File

@ -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 {
"<command line option>".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 {})",

View File

@ -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() {
}

View File

@ -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() {}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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::<Univariant>());
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::<UnivariantWithoutDescr>());
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);
}
}