From 1ec520a531b544079690f8178a7660421e8a713a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Jun 2015 14:51:29 -0700 Subject: [PATCH 01/36] mk: Move logic out of MSVC's 64-bit cfg makefile This logic applies to all MSVC targets, so instead refactor it into platform.mk so it can one day apply to 32-bit MSVC. --- mk/cfg/x86_64-pc-windows-msvc.mk | 58 --------------------------- mk/platform.mk | 69 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 58 deletions(-) diff --git a/mk/cfg/x86_64-pc-windows-msvc.mk b/mk/cfg/x86_64-pc-windows-msvc.mk index 69a26c03fb664..edeffcdd09b9b 100644 --- a/mk/cfg/x86_64-pc-windows-msvc.mk +++ b/mk/cfg/x86_64-pc-windows-msvc.mk @@ -23,64 +23,6 @@ CFG_RUN_x86_64-pc-windows-msvc=$(2) CFG_RUN_TARG_x86_64-pc-windows-msvc=$(call CFG_RUN_x86_64-pc-windows-msvc,,$(2)) CFG_GNU_TRIPLE_x86_64-pc-windows-msvc := x86_64-pc-win32 -# These two environment variables are scraped by the `./configure` script and -# are necessary for `cl.exe` to find standard headers (the INCLUDE variable) and -# for `link.exe` to find standard libraries (the LIB variable). -ifdef CFG_MSVC_INCLUDE_PATH -export INCLUDE := $(CFG_MSVC_INCLUDE_PATH) -endif -ifdef CFG_MSVC_LIB_PATH -export LIB := $(CFG_MSVC_LIB_PATH) -endif - -# Unfortunately `link.exe` is also a program in `/usr/bin` on MinGW installs, -# but it's not the one that we want. As a result we make sure that our detected -# `link.exe` shows up in PATH first. -ifdef CFG_MSVC_LINK -export PATH := $(CFG_MSVC_ROOT)/VC/bin/amd64:$(PATH) -endif - -# There are more comments about this available in the target specification for -# Windows MSVC in the compiler, but the gist of it is that we use `llvm-ar.exe` -# instead of `lib.exe` for assembling archives, so we need to inject this custom -# dependency here. -NATIVE_TOOL_DEPS_core_T_x86_64-pc-windows-msvc += llvm-ar.exe -INSTALLED_BINS_x86_64-pc-windows-msvc += llvm-ar.exe - -# When working with MSVC on windows, each DLL needs to explicitly declare its -# interface to the outside world through some means. The options for doing so -# include: -# -# 1. A custom attribute on each function itself -# 2. A linker argument saying what to export -# 3. A file which lists all symbols that need to be exported -# -# The Rust compiler takes care (1) for us for all Rust code by annotating all -# public-facing functions with dllexport, but we have a few native dependencies -# which need to cross the DLL boundary. The most important of these dependencies -# is LLVM which is linked into `rustc_llvm.dll` but primarily used from -# `rustc_trans.dll`. This means that many of LLVM's C API functions need to be -# exposed from `rustc_llvm.dll` to be forwarded over the boundary. -# -# Unfortunately, at this time, LLVM does not handle this sort of exportation on -# Windows for us, so we're forced to do it ourselves if we want it (which seems -# like the path of least resistance right now). To do this we generate a `.DEF` -# file [1] which we then custom-pass to the linker when building the rustc_llvm -# crate. This DEF file list all symbols that are exported from -# `src/librustc_llvm/lib.rs` and is generated by a small python script. -# -# Fun times! -# -# [1]: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx -RUSTFLAGS_rustc_llvm_T_x86_64-pc-windows-msvc += \ - -C link-args="-DEF:x86_64-pc-windows-msvc/rt/rustc_llvm.def" -CUSTOM_DEPS_rustc_llvm_T_x86_64-pc-windows-msvc += \ - x86_64-pc-windows-msvc/rt/rustc_llvm.def - -x86_64-pc-windows-msvc/rt/rustc_llvm.def: $(S)src/etc/mklldef.py \ - $(S)src/librustc_llvm/lib.rs - $(CFG_PYTHON) $^ $@ rustc_llvm-$(CFG_FILENAME_EXTRA) - # All windows nightiles are currently a GNU triple, so this MSVC triple is not # bootstrapping from itself. This is relevant during stage0, and other parts of # the build system take this into account. diff --git a/mk/platform.mk b/mk/platform.mk index 8a5e58c46f676..abc9cc038d022 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -238,3 +238,72 @@ endef $(foreach target,$(CFG_TARGET), \ $(eval $(call CFG_MAKE_TOOLCHAIN,$(target)))) + +# These two environment variables are scraped by the `./configure` script and +# are necessary for `cl.exe` to find standard headers (the INCLUDE variable) and +# for `link.exe` to find standard libraries (the LIB variable). +ifdef CFG_MSVC_INCLUDE_PATH +export INCLUDE := $(CFG_MSVC_INCLUDE_PATH) +endif +ifdef CFG_MSVC_LIB_PATH +export LIB := $(CFG_MSVC_LIB_PATH) +endif + +# Unfortunately `link.exe` is also a program in `/usr/bin` on MinGW installs, +# but it's not the one that we want. As a result we make sure that our detected +# `link.exe` shows up in PATH first. +ifdef CFG_MSVC_LINK +export PATH := $(CFG_MSVC_ROOT)/VC/bin/amd64:$(PATH) +endif + +# There are more comments about this available in the target specification for +# Windows MSVC in the compiler, but the gist of it is that we use `llvm-ar.exe` +# instead of `lib.exe` for assembling archives, so we need to inject this custom +# dependency here. +define ADD_LLVM_AR_TO_MSVC_DEPS +ifeq ($$(findstring msvc,$(1)),msvc) +NATIVE_TOOL_DEPS_core_T_$(1) += llvm-ar.exe +INSTALLED_BINS_$(1) += llvm-ar.exe +endif +endef + +$(foreach target,$(CFG_TARGET), \ + $(eval $(call ADD_LLVM_AR_TO_MSVC_DEPS,$(target)))) + +# When working with MSVC on windows, each DLL needs to explicitly declare its +# interface to the outside world through some means. The options for doing so +# include: +# +# 1. A custom attribute on each function itself +# 2. A linker argument saying what to export +# 3. A file which lists all symbols that need to be exported +# +# The Rust compiler takes care (1) for us for all Rust code by annotating all +# public-facing functions with dllexport, but we have a few native dependencies +# which need to cross the DLL boundary. The most important of these dependencies +# is LLVM which is linked into `rustc_llvm.dll` but primarily used from +# `rustc_trans.dll`. This means that many of LLVM's C API functions need to be +# exposed from `rustc_llvm.dll` to be forwarded over the boundary. +# +# Unfortunately, at this time, LLVM does not handle this sort of exportation on +# Windows for us, so we're forced to do it ourselves if we want it (which seems +# like the path of least resistance right now). To do this we generate a `.DEF` +# file [1] which we then custom-pass to the linker when building the rustc_llvm +# crate. This DEF file list all symbols that are exported from +# `src/librustc_llvm/lib.rs` and is generated by a small python script. +# +# Fun times! +# +# [1]: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx +define ADD_RUSTC_LLVM_DEF_TO_MSVC +ifeq ($$(findstring msvc,$(1)),msvc) +RUSTFLAGS_rustc_llvm_T_$(1) += -C link-args="-DEF:$(1)/rt/rustc_llvm.def" +CUSTOM_DEPS_rustc_llvm_T_$(1) += $(1)/rt/rustc_llvm.def + +$(1)/rt/rustc_llvm.def: $$(S)src/etc/mklldef.py $$(S)src/librustc_llvm/lib.rs + $$(CFG_PYTHON) $$^ $$@ rustc_llvm-$$(CFG_FILENAME_EXTRA) +endif +endef + +$(foreach target,$(CFG_TARGET), \ + $(eval $(call ADD_RUSTC_LLVM_DEF_TO_MSVC,$(target)))) From 91d799eab0d7f6784fb4366182b5007cf055519d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Jun 2015 14:57:06 -0700 Subject: [PATCH 02/36] msvc: Implement runtime support for unwinding Now that LLVM has been updated, the only remaining roadblock to implementing unwinding for MSVC is to fill out the runtime support in `std::rt::unwind::seh`. This commit does precisely that, fixing up some other bits and pieces along the way: * The `seh` unwinding module now uses `RaiseException` to initiate a panic. * The `rust_try.ll` file was rewritten for MSVC (as it's quite different) and is located at `rust_try_msvc_64.ll`, only included on MSVC builds for now. * The personality function for all landing pads generated by LLVM is hard-wired to `__C_specific_handler` instead of the standard `rust_eh_personality` lang item. This is required to get LLVM to emit SEH unwinding information instead of DWARF unwinding information. This also means that on MSVC the `rust_eh_personality` function is entirely unused (but is defined as it's a lang item). More details about how panicking works on SEH can be found in the `rust_try_msvc_64.ll` or `seh.rs` files, but I'm always open to adding more comments! A key aspect of this PR is missing, however, which is that **unwinding is still turned off by default for MSVC**. There is a [bug in llvm][llvm-bug] which causes optimizations to inline enough landing pads that LLVM chokes. If the compiler is optimized at `-O1` (where inlining isn't enabled) then it can bootstrap with unwinding enabled, but when optimized at `-O2` (inlining is enabled) then it hits a fatal LLVM error. [llvm-bug]: https://llvm.org/bugs/show_bug.cgi?id=23884 --- mk/rt.mk | 9 +- src/librustc_trans/trans/cleanup.rs | 24 ++++- src/libstd/rt/unwind/seh.rs | 131 ++++++++++++++++++++++++++-- src/rt/rust_try_msvc_64.ll | 78 +++++++++++++++++ 4 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 src/rt/rust_try_msvc_64.ll diff --git a/mk/rt.mk b/mk/rt.mk index 777a2a0fd3b4b..6513cf107726a 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -53,9 +53,12 @@ NATIVE_DEPS_hoedown_$(1) := hoedown/src/autolink.c \ NATIVE_DEPS_miniz_$(1) = miniz.c NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \ rust_android_dummy.c -NATIVE_DEPS_rustrt_native_$(1) := \ - rust_try.ll \ - arch/$$(HOST_$(1))/record_sp.S +NATIVE_DEPS_rustrt_native_$(1) := arch/$$(HOST_$(1))/record_sp.S +ifeq ($$(findstring msvc,$(1)),msvc) +NATIVE_DEPS_rustrt_native_$(1) += rust_try_msvc_64.ll +else +NATIVE_DEPS_rustrt_native_$(1) += rust_try.ll +endif NATIVE_DEPS_rust_test_helpers_$(1) := rust_test_helpers.c NATIVE_DEPS_morestack_$(1) := arch/$$(HOST_$(1))/morestack.S diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 6355a713a2ce6..b7e761fa4b991 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -856,18 +856,36 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx // this function, so we just codegen a generic reference to it. We don't // specify any of the types for the function, we just make it a symbol // that LLVM can later use. + // + // Note that MSVC is a little special here in that we don't use the + // `eh_personality` lang item at all. Currently LLVM has support for + // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the + // *name of the personality function* to decide what kind of unwind side + // tables/landing pads to emit. It looks like Dwarf is used by default, + // injecting a dependency on the `_Unwind_Resume` symbol for resuming + // an "exception", but for MSVC we want to force SEH. This means that we + // can't actually have the personality function be our standard + // `rust_eh_personality` function, but rather we wired it up to the + // CRT's custom `__C_specific_handler` personality funciton, which + // forces LLVM to consider landing pads as "landing pads for SEH". + let target = &self.ccx.sess().target.target; let llpersonality = match pad_bcx.tcx().lang_items.eh_personality() { - Some(def_id) => { + Some(def_id) if !target.options.is_like_msvc => { callee::trans_fn_ref(pad_bcx.ccx(), def_id, ExprId(0), pad_bcx.fcx.param_substs).val } - None => { + _ => { let mut personality = self.ccx.eh_personality().borrow_mut(); match *personality { Some(llpersonality) => llpersonality, None => { + let name = if target.options.is_like_msvc { + "__C_specific_handler" + } else { + "rust_eh_personality" + }; let fty = Type::variadic_func(&[], &Type::i32(self.ccx)); - let f = declare::declare_cfn(self.ccx, "rust_eh_personality", fty, + let f = declare::declare_cfn(self.ccx, name, fty, self.ccx.tcx().types.i32); *personality = Some(f); f diff --git a/src/libstd/rt/unwind/seh.rs b/src/libstd/rt/unwind/seh.rs index a72c1debe14e0..632ab4f8e2537 100644 --- a/src/libstd/rt/unwind/seh.rs +++ b/src/libstd/rt/unwind/seh.rs @@ -8,23 +8,136 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Win64 SEH (see http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx) +//! +//! On Windows (currently only on MSVC), the default exception handling +//! mechanism is Structured Exception Handling (SEH). This is quite different +//! than Dwarf-based exception handling (e.g. what other unix platforms use) in +//! terms of compiler internals, so LLVM is required to have a good deal of +//! extra support for SEH. Currently this support is somewhat lacking, so what's +//! here is the bare bones of SEH support. +//! +//! In a nutshell, what happens here is: +//! +//! 1. The `panic` function calls the standard Windows function `RaiseException` +//! with a Rust-specific code, triggering the unwinding process. +//! 2. All landing pads generated by the compiler (just "cleanup" landing pads) +//! use the personality function `__C_specific_handler`, a function in the +//! CRT, and the unwinding code in Windows will use this personality function +//! to execute all cleanup code on the stack. +//! 3. Eventually the "catch" code in `rust_try` (located in +//! src/rt/rust_try_msvc_64.ll) is executed, which will ensure that the +//! exception being caught is indeed a Rust exception, returning control back +//! into Rust. +//! +//! Some specific differences from the gcc-based exception handling are: +//! +//! * Rust has no custom personality function, it is instead *always* +//! __C_specific_handler, so the filtering is done in a C++-like manner +//! instead of in the personality function itself. Note that the specific +//! syntax for this (found in the rust_try_msvc_64.ll) is taken from an LLVM +//! test case for SEH. +//! * We've got some data to transmit across the unwinding boundary, +//! specifically a `Box`. In Dwarf-based unwinding this +//! data is part of the payload of the exception, but I have not currently +//! figured out how to do this with LLVM's bindings. Judging by some comments +//! in the LLVM test cases this may not even be possible currently with LLVM, +//! so this is just abandoned entirely. Instead the data is stored in a +//! thread-local in `panic` and retrieved during `cleanup`. +//! +//! So given all that, the bindings here are pretty small, + +#![allow(bad_style)] + use prelude::v1::*; use any::Any; -use intrinsics; -use libc::c_void; +use libc::{c_ulong, DWORD, c_void}; +use sys_common::thread_local::StaticKey; + +// 0x R U S T +const RUST_PANIC: DWORD = 0x52555354; +static PANIC_DATA: StaticKey = StaticKey::new(None); + +// This function is provided by kernel32.dll +extern "system" { + fn RaiseException(dwExceptionCode: DWORD, + dwExceptionFlags: DWORD, + nNumberOfArguments: DWORD, + lpArguments: *const c_ulong); +} + +#[repr(C)] +pub struct EXCEPTION_POINTERS { + ExceptionRecord: *mut EXCEPTION_RECORD, + ContextRecord: *mut CONTEXT, +} + +enum CONTEXT {} + +#[repr(C)] +struct EXCEPTION_RECORD { + ExceptionCode: DWORD, + ExceptionFlags: DWORD, + ExceptionRecord: *mut _EXCEPTION_RECORD, + ExceptionAddress: *mut c_void, + NumberParameters: DWORD, + ExceptionInformation: [*mut c_ulong; EXCEPTION_MAXIMUM_PARAMETERS], +} -pub unsafe fn panic(_data: Box) -> ! { - intrinsics::abort(); +enum _EXCEPTION_RECORD {} + +const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15; + +pub unsafe fn panic(data: Box) -> ! { + // See module docs above for an explanation of why `data` is stored in a + // thread local instead of being passed as an argument to the + // `RaiseException` function (which can in theory carry along arbitrary + // data). + let exception = Box::new(data); + rtassert!(PANIC_DATA.get().is_null()); + PANIC_DATA.set(Box::into_raw(exception) as *mut u8); + + RaiseException(RUST_PANIC, 0, 0, 0 as *const _); + rtabort!("could not unwind stack"); } -pub unsafe fn cleanup(_ptr: *mut c_void) -> Box { - intrinsics::abort(); +pub unsafe fn cleanup(ptr: *mut c_void) -> Box { + // The `ptr` here actually corresponds to the code of the exception, and our + // real data is stored in our thread local. + rtassert!(ptr as DWORD == RUST_PANIC); + + let data = PANIC_DATA.get() as *mut Box; + PANIC_DATA.set(0 as *mut u8); + rtassert!(!data.is_null()); + + *Box::from_raw(data) } +// This is required by the compiler to exist (e.g. it's a lang item), but it's +// never actually called by the compiler because __C_specific_handler is the +// personality function that is always used. Hence this is just an aborting +// stub. #[lang = "eh_personality"] -#[no_mangle] -pub extern fn rust_eh_personality() {} +fn rust_eh_personality() { + unsafe { ::intrinsics::abort() } +} +// This is a function referenced from `rust_try_msvc_64.ll` which is used to +// filter the exceptions being caught by that function. +// +// In theory local variables can be accessed through the `rbp` parameter of this +// function, but a comment in an LLVM test case indicates that this is not +// implemented in LLVM, so this is just an idempotent function which doesn't +// ferry along any other information. +// +// This function just takes a look at the current EXCEPTION_RECORD being thrown +// to ensure that it's code is RUST_PANIC, which was set by the call to +// `RaiseException` above in the `panic` function. #[no_mangle] -pub extern fn rust_eh_personality_catch() {} +pub extern fn __rust_try_filter(eh_ptrs: *mut EXCEPTION_POINTERS, + _rbp: *mut c_void) -> i32 { + unsafe { + ((*(*eh_ptrs).ExceptionRecord).ExceptionCode == RUST_PANIC) as i32 + } +} diff --git a/src/rt/rust_try_msvc_64.ll b/src/rt/rust_try_msvc_64.ll new file mode 100644 index 0000000000000..bda136d84780b --- /dev/null +++ b/src/rt/rust_try_msvc_64.ll @@ -0,0 +1,78 @@ +; Copyright 2015 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. + +; 64-bit MSVC's definition of the `rust_try` function. This function can't be +; defined in Rust as it's a "try-catch" block that's not expressible in Rust's +; syntax, so we're using LLVM to produce an object file with the associated +; handler. +; +; To use the correct system implementation details, this file is separate from +; the standard rust_try.ll as we need specifically use the __C_specific_handler +; personality function or otherwise LLVM doesn't emit SEH handling tables. +; There's also a few fiddly bits about SEH right now in LLVM that require us to +; structure this a fairly particular way! +; +; See also: src/libstd/rt/unwind/seh.rs + +define i8* @rust_try(void (i8*)* %f, i8* %env) { + invoke void %f(i8* %env) + to label %normal + unwind label %catch + +normal: + ret i8* null + +; Here's where most of the magic happens, this is the only landing pad in rust +; tagged with "catch" to indicate that we're catching an exception. The other +; catch handlers in rust_try.ll just catch *all* exceptions, but that's because +; most exceptions are already filtered out by their personality function. +; +; For MSVC we're just using a standard personality function that we can't +; customize, so we need to do the exception filtering ourselves, and this is +; currently performed by the `__rust_try_filter` function. This function, +; specified in the landingpad instruction, will be invoked by Windows SEH +; routines and will return whether the exception in question can be caught (aka +; the Rust runtime is the one that threw the exception). +; +; To get this to compile (currently LLVM segfaults if it's not in this +; particular structure), when the landingpad is executing we test to make sure +; that the ID of the exception being thrown is indeed the one that we were +; expecting. If it's not, we resume the exception, and otherwise we return the +; pointer that we got +; +; Full disclosure: It's not clear to me what this `llvm.eh.typeid` stuff is +; doing *other* then just allowing LLVM to compile this file without +; segfaulting. I would expect the entire landing pad to just be: +; +; %vals = landingpad ... +; %ehptr = extractvalue { i8*, i32 } %vals, 0 +; ret i8* %ehptr +; +; but apparently LLVM chokes on this, so we do the more complicated thing to +; placate it. +catch: + %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) + catch i8* bitcast (i32 (i8*, i8*)* @__rust_try_filter to i8*) + %ehptr = extractvalue { i8*, i32 } %vals, 0 + %sel = extractvalue { i8*, i32 } %vals, 1 + %filter_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @__rust_try_filter to i8*)) + %is_filter = icmp eq i32 %sel, %filter_sel + br i1 %is_filter, label %catch-return, label %catch-resume + +catch-return: + ret i8* %ehptr + +catch-resume: + resume { i8*, i32 } %vals +} + +declare i32 @__C_specific_handler(...) +declare i32 @__rust_try_filter(i8*, i8*) +declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind From 9e3cb6447596049464292c0afa8c4b9a0cb8c806 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 00:33:52 -0700 Subject: [PATCH 03/36] rustc_trans: Handle empty dlls on MSVC If a dylib doesn't actually export any symbols then link.exe won't emit a `foo.lib` file to link against (as one isn't necessary). Detect this case in the backend by omitting the `foo.lib` argument to the linker if it doesn't actually exist. --- src/librustc_trans/back/link.rs | 6 ++++-- src/librustc_trans/back/linker.rs | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 6b8b59de3c253..cf5feabcc57e2 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1214,11 +1214,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session, // Just need to tell the linker about where the library lives and // what its name is - if let Some(dir) = cratepath.parent() { + let parent = cratepath.parent(); + if let Some(dir) = parent { cmd.include_path(&fix_windows_verbatim_for_gcc(dir)); } let filestem = cratepath.file_stem().unwrap().to_str().unwrap(); - cmd.link_dylib(&unlib(&sess.target, filestem)); + cmd.link_rust_dylib(&unlib(&sess.target, filestem), + parent.unwrap_or(Path::new(""))); } } diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 1eacec46c87bb..7253334d69989 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -11,6 +11,7 @@ use std::ffi::OsString; use std::path::{Path, PathBuf}; use std::process::Command; +use std::fs; use rustc_back::archive; use session::Session; @@ -25,6 +26,7 @@ use session::config; /// MSVC linker (e.g. `link.exe`) is being used. pub trait Linker { fn link_dylib(&mut self, lib: &str); + fn link_rust_dylib(&mut self, lib: &str, path: &Path); fn link_framework(&mut self, framework: &str); fn link_staticlib(&mut self, lib: &str); fn link_rlib(&mut self, lib: &Path); @@ -67,6 +69,10 @@ impl<'a> Linker for GnuLinker<'a> { fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); } fn args(&mut self, args: &[String]) { self.cmd.args(args); } + fn link_rust_dylib(&mut self, lib: &str, _path: &Path) { + self.cmd.arg("-l").arg(lib); + } + fn link_framework(&mut self, framework: &str) { self.cmd.arg("-framework").arg(framework); } @@ -189,6 +195,18 @@ impl<'a> Linker for MsvcLinker<'a> { fn link_dylib(&mut self, lib: &str) { self.cmd.arg(&format!("{}.lib", lib)); } + + fn link_rust_dylib(&mut self, lib: &str, path: &Path) { + // When producing a dll, the MSVC linker may not actually emit a + // `foo.lib` file if the dll doesn't actually export any symbols, so we + // check to see if the file is there and just omit linking to it if it's + // not present. + let name = format!("{}.lib", lib); + if fs::metadata(&path.join(&name)).is_ok() { + self.cmd.arg(name); + } + } + fn link_staticlib(&mut self, lib: &str) { self.cmd.arg(&format!("{}.lib", lib)); } From 759a7f1f66490191a6f809c9709151d6d27cea87 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 09:13:30 -0700 Subject: [PATCH 04/36] test: Use liblibc in lang-item-public Makes this test case more robust by using standard libraries to ensure the binary can be built. --- src/test/auxiliary/lang-item-public.rs | 35 ++++++-------------------- src/test/run-pass/lang-item-public.rs | 30 +--------------------- 2 files changed, 8 insertions(+), 57 deletions(-) diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index d195bd7e77bd8..4b60a370187af 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -8,15 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(no_std)] +#![feature(no_std, core, libc)] #![no_std] #![feature(lang_items)] -#[lang="sized"] -pub trait Sized { } - -#[lang="panic"] -fn panic(_: &(&'static str, &'static str, usize)) -> ! { loop {} } +extern crate core; +extern crate libc; #[lang = "stack_exhausted"] extern fn stack_exhausted() {} @@ -24,26 +21,8 @@ extern fn stack_exhausted() {} #[lang = "eh_personality"] extern fn eh_personality() {} -#[lang="copy"] -pub trait Copy { - // Empty. -} - -#[lang="rem"] -pub trait Rem { - type Output = Self; - fn rem(self, rhs: RHS) -> Self::Output; -} - -impl Rem for isize { - type Output = isize; - - #[inline] - fn rem(self, other: isize) -> isize { - // if you use `self % other` here, as one would expect, you - // get back an error because of potential failure/overflow, - // which tries to invoke error fns that don't have the - // appropriate signatures anymore. So...just return 0. - 0 - } +#[lang = "panic_fmt"] +extern fn rust_begin_unwind(msg: core::fmt::Arguments, file: &'static str, + line: u32) -> ! { + loop {} } diff --git a/src/test/run-pass/lang-item-public.rs b/src/test/run-pass/lang-item-public.rs index f5b9bd4fbaa69..57a32ba599f93 100644 --- a/src/test/run-pass/lang-item-public.rs +++ b/src/test/run-pass/lang-item-public.rs @@ -11,39 +11,11 @@ // aux-build:lang-item-public.rs // ignore-android -#![feature(lang_items, start, no_std)] +#![feature(start, no_std)] #![no_std] extern crate lang_item_public as lang_lib; -#[cfg(target_os = "linux")] -#[link(name = "c")] -extern {} - -#[cfg(target_os = "android")] -#[link(name = "c")] -extern {} - -#[cfg(target_os = "freebsd")] -#[link(name = "execinfo")] -extern {} - -#[cfg(target_os = "freebsd")] -#[link(name = "c")] -extern {} - -#[cfg(target_os = "dragonfly")] -#[link(name = "c")] -extern {} - -#[cfg(any(target_os = "bitrig", target_os = "openbsd"))] -#[link(name = "c")] -extern {} - -#[cfg(target_os = "macos")] -#[link(name = "System")] -extern {} - #[start] fn main(_: isize, _: *const *const u8) -> isize { 1_isize % 1_isize From 3f178b8653f7de239240103b7a8b07e8f6d8b14f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 25 Jun 2015 12:31:06 -0700 Subject: [PATCH 05/36] Fix links in release notes. My bad! --- RELEASES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 9932684a34cc4..32319f3b7c566 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Version 1.1.0 (June 2015) Highlights ---------- -* The [`std::fs` module has been expanded][fs-expand] to expand the set of +* The [`std::fs` module has been expanded][fs] to expand the set of functionality exposed: * `DirEntry` now supports optimizations like `file_type` and `metadata` which don't incur a syscall on some platforms. @@ -28,7 +28,7 @@ Libraries whitespace boundaries. * On both Windows and Unix, new extension traits provide conversion of I/O types to and from the underlying system handles. On Unix, these - traits are [`FrowRawFd`] and [`AsRawFd`], on Windows `FromRawHandle` + traits are [`FromRawFd`] and [`AsRawFd`], on Windows `FromRawHandle` and `AsRawHandle`. These are implemented for `File`, `TcpStream`, `TcpListener`, and `UpdSocket`. Further implementations for `std::process` will be stabilized later. From 74fbe3e088f1c6c2a1492505578e116ad554f508 Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Fri, 26 Jun 2015 00:41:48 +0900 Subject: [PATCH 06/36] Correct typos and remove unused references from RELEASES.md I found some typos in the upcoming 1.1 release note. I corrected them, but I wanted to go further. So I wrote a script that checks the integrity of the Markdown references, and ran it against `RELEASES.md`. This commit fixes some trivial cases, but also removes the following "unused" references: - [`Iterator::cloned`](http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.cloned) - [`thread::scoped`](http://static.rust-lang.org/doc/master/std/thread/fn.scoped.html) - [`Debug` improvements](https://github.com/rust-lang/rfcs/blob/master/text/0640-debug-improvements.md) - [Rebalancing coherence.](https://github.com/rust-lang/rfcs/pull/1023) However, I think there's a possibility that these features might need to get descriptions as well. How do you feel about it? --- RELEASES.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 9932684a34cc4..3980c56db56e0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Version 1.1.0 (June 2015) Highlights ---------- -* The [`std::fs` module has been expanded][fs-expand] to expand the set of +* The [`std::fs` module has been expanded][fs] to expand the set of functionality exposed: * `DirEntry` now supports optimizations like `file_type` and `metadata` which don't incur a syscall on some platforms. @@ -24,11 +24,11 @@ Highlights Libraries --------- -* The `str::split_whitespace` method splits a string on unicode +* The [`str::split_whitespace`] method splits a string on unicode whitespace boundaries. * On both Windows and Unix, new extension traits provide conversion of I/O types to and from the underlying system handles. On Unix, these - traits are [`FrowRawFd`] and [`AsRawFd`], on Windows `FromRawHandle` + traits are [`FromRawFd`] and [`AsRawFd`], on Windows `FromRawHandle` and `AsRawHandle`. These are implemented for `File`, `TcpStream`, `TcpListener`, and `UpdSocket`. Further implementations for `std::process` will be stabilized later. @@ -80,8 +80,7 @@ Misc * [The `drop_with_repr_extern` lint warns about mixing `repr(C)` with `Drop`][drop]. -[`split_whitespace`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_whitespace -[`Iterator::cloned`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.cloned +[`str::split_whitespace`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_whitespace [`FromRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.FromRawFd.html [`AsRawFd`]: http://doc.rust-lang.org/nightly/std/os/unix/io/trait.AsRawFd.html [`std::os::unix::symlink`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/fn.symlink.html @@ -251,7 +250,6 @@ Misc [sw]: https://github.com/rust-lang/rfcs/blob/master/text/1054-str-words.md [th]: https://github.com/rust-lang/rfcs/blob/master/text/0909-move-thread-local-to-std-thread.md [send-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0458-send-improvements.md -[scoped]: http://static.rust-lang.org/doc/master/std/thread/fn.scoped.html [moar-ufcs]: https://github.com/rust-lang/rust/pull/22172 [prim-inherent]: https://github.com/rust-lang/rust/pull/23104 [overflow]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md @@ -261,12 +259,10 @@ Misc [string-pattern]: https://github.com/rust-lang/rust/pull/22466 [oibit-final]: https://github.com/rust-lang/rust/pull/21689 [reflect]: https://github.com/rust-lang/rust/pull/23712 -[debug-builder]: https://github.com/rust-lang/rfcs/blob/master/text/0640-debug-improvements.md [conversion]: https://github.com/rust-lang/rfcs/pull/529 [num-traits]: https://github.com/rust-lang/rust/pull/23549 [index-value]: https://github.com/rust-lang/rust/pull/23601 [dropck]: https://github.com/rust-lang/rfcs/pull/769 -[fundamental]: https://github.com/rust-lang/rfcs/pull/1023 [ci-compare]: https://gist.github.com/brson/a30a77836fbec057cbee [fn-inherit]: https://github.com/rust-lang/rust/pull/23282 [fn-blanket]: https://github.com/rust-lang/rust/pull/23895 @@ -369,7 +365,6 @@ Version 1.0.0-alpha.2 (February 2015) [osstr]: https://github.com/rust-lang/rust/pull/21488 [osstr-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0517-io-os-reform.md [Self]: https://github.com/rust-lang/rust/pull/22158 -[ufcs]: https://github.com/rust-lang/rust/pull/21077 [ufcs-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0132-ufcs.md [un]: https://github.com/rust-lang/rust/pull/22256 From 8e3ea5d5014de1a590a79d05d0a64a0f618c3afa Mon Sep 17 00:00:00 2001 From: Cruz Julian Bishop Date: Thu, 25 Jun 2015 23:26:05 +0000 Subject: [PATCH 07/36] Ignore KDevelop 4 (and 5 pre-release) project files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5d5da135a8272..572111bf96158 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ *.exe *.fn *.html +*.kdev4 *.ky *.ll *.llvm From fd9b2caa5f6792a87a4c99bbbd6abed303a8ab5c Mon Sep 17 00:00:00 2001 From: OGINO Masanori Date: Fri, 26 Jun 2015 11:09:15 +0900 Subject: [PATCH 08/36] Correct a missing reference in the release note. Fix #26537. Signed-off-by: OGINO Masanori --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 203da02c373ef..913b83a0f61f8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Version 1.1.0 (June 2015) Highlights ---------- -* The [`std::fs` module has been expanded][fs-expand] to expand the set of +* The [`std::fs` module has been expanded][fs] to expand the set of functionality exposed: * `DirEntry` now supports optimizations like `file_type` and `metadata` which don't incur a syscall on some platforms. From aa03871a6efd240c16eacf6f8e9a56d708a71b62 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 24 Jun 2015 02:54:32 +0300 Subject: [PATCH 09/36] rustc: combine type-flag-checking traits and fns and into one trait. --- src/librustc/metadata/tydecode.rs | 4 +- src/librustc/middle/implicator.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 21 +- src/librustc/middle/infer/freshen.rs | 4 +- src/librustc/middle/infer/mod.rs | 25 +- src/librustc/middle/infer/resolve.rs | 6 +- src/librustc/middle/intrinsicck.rs | 6 +- src/librustc/middle/subst.rs | 21 +- src/librustc/middle/traits/error_reporting.rs | 8 +- src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/traits/mod.rs | 4 +- src/librustc/middle/traits/project.rs | 11 +- src/librustc/middle/traits/select.rs | 8 +- src/librustc/middle/ty.rs | 416 +++++++----------- src/librustc/middle/ty_fold.rs | 6 +- src/librustc/util/ppaux.rs | 5 +- src/librustc_driver/test.rs | 14 +- src/librustc_trans/trans/base.rs | 4 +- src/librustc_trans/trans/callee.rs | 6 +- src/librustc_trans/trans/common.rs | 10 +- src/librustc_trans/trans/intrinsic.rs | 6 +- src/librustc_trans/trans/meth.rs | 4 +- src/librustc_trans/trans/monomorphize.rs | 10 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/_match.rs | 4 +- src/librustc_typeck/check/assoc.rs | 4 +- src/librustc_typeck/check/cast.rs | 5 +- src/librustc_typeck/check/method/probe.rs | 7 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 80 ++-- src/librustc_typeck/check/op.rs | 14 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/lib.rs | 6 +- 33 files changed, 306 insertions(+), 431 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 63afdc8b0fcf1..57814fbe8f89e 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -21,7 +21,7 @@ pub use self::DefIdSource::*; use middle::region; use middle::subst; use middle::subst::VecPerParamSpace; -use middle::ty::{self, ToPredicate, Ty}; +use middle::ty::{self, ToPredicate, Ty, HasTypeFlags}; use std::str; use syntax::abi; @@ -534,7 +534,7 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w // If there is a closure buried in the type some where, then we // need to re-convert any def ids (see case 'k', below). That means // we can't reuse the cached version. - if !ty::type_has_ty_closure(tt) { + if !tt.has_closure_types() { return tt; } } diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index f87b121eb224d..5e720125aa00b 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -400,7 +400,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { } fn fully_normalize(&self, value: &T) -> Result - where T : TypeFoldable<'tcx> + ty::HasProjectionTypes + where T : TypeFoldable<'tcx> + ty::HasTypeFlags { let value = traits::fully_normalize(self.infcx, diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 4ae618d45b728..8839e68e767f2 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -77,7 +77,7 @@ use middle::def; use middle::infer; use middle::region; use middle::subst; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty::{Region, ReFree}; use std::cell::{Cell, RefCell}; @@ -226,7 +226,7 @@ pub trait ErrorReporting<'tcx> { fn values_str(&self, values: &ValuePairs<'tcx>) -> Option; - fn expected_found_str>( + fn expected_found_str + HasTypeFlags>( &self, exp_found: &ty::expected_found) -> Option; @@ -504,18 +504,18 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } } - fn expected_found_str>( + fn expected_found_str + HasTypeFlags>( &self, exp_found: &ty::expected_found) -> Option { let expected = exp_found.expected.resolve(self); - if expected.contains_error() { + if expected.references_error() { return None; } let found = exp_found.found.resolve(self); - if found.contains_error() { + if found.references_error() { return None; } @@ -1793,16 +1793,12 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { pub trait Resolvable<'tcx> { fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) -> Self; - fn contains_error(&self) -> bool; } impl<'tcx> Resolvable<'tcx> for Ty<'tcx> { fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) -> Ty<'tcx> { infcx.resolve_type_vars_if_possible(self) } - fn contains_error(&self) -> bool { - ty::type_is_error(*self) - } } impl<'tcx> Resolvable<'tcx> for ty::TraitRef<'tcx> { @@ -1810,9 +1806,6 @@ impl<'tcx> Resolvable<'tcx> for ty::TraitRef<'tcx> { -> ty::TraitRef<'tcx> { infcx.resolve_type_vars_if_possible(self) } - fn contains_error(&self) -> bool { - ty::trait_ref_contains_error(self) - } } impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> { @@ -1822,10 +1815,6 @@ impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> { { infcx.resolve_type_vars_if_possible(self) } - - fn contains_error(&self) -> bool { - ty::trait_ref_contains_error(&self.0) - } } fn lifetimes_in_scope(tcx: &ty::ctxt, diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index 1aa54863c203a..26655a24c324b 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -30,7 +30,7 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold; use middle::ty_fold::TypeFoldable; use middle::ty_fold::TypeFolder; @@ -104,7 +104,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_needs_infer(t) && !ty::type_has_erasable_regions(t) { + if !t.needs_infer() && !t.has_erasable_regions() { return t; } diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 2df335b5c3c0a..0c38b655b34ad 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -26,7 +26,7 @@ use middle::free_region::FreeRegionMap; use middle::subst; use middle::subst::Substs; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; use middle::ty_relate::{Relate, RelateResult, TypeRelation}; use rustc_data_structures::unify::{self, UnificationTable}; @@ -973,20 +973,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let resolved_expected = expected_ty.map(|e_ty| self.resolve_type_vars_if_possible(&e_ty)); - match resolved_expected { - Some(t) if ty::type_is_error(t) => (), - _ => { - let error_str = err.map_or("".to_string(), |t_err| { - format!(" ({})", t_err) - }); + if !resolved_expected.references_error() { + let error_str = err.map_or("".to_string(), |t_err| { + format!(" ({})", t_err) + }); - self.tcx.sess.span_err(sp, &format!("{}{}", - mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty), - error_str)); + self.tcx.sess.span_err(sp, &format!("{}{}", + mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty), + error_str)); - if let Some(err) = err { - ty::note_and_explain_type_err(self.tcx, err, sp) - } + if let Some(err) = err { + ty::note_and_explain_type_err(self.tcx, err, sp) } } } @@ -1001,7 +998,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let actual_ty = self.resolve_type_vars_if_possible(&actual_ty); // Don't report an error if actual type is TyError. - if ty::type_is_error(actual_ty) { + if actual_ty.references_error() { return; } diff --git a/src/librustc/middle/infer/resolve.rs b/src/librustc/middle/infer/resolve.rs index b67437fd12781..41a0d373fba43 100644 --- a/src/librustc/middle/infer/resolve.rs +++ b/src/librustc/middle/infer/resolve.rs @@ -9,7 +9,7 @@ // except according to those terms. use super::{InferCtxt, fixup_err, fres, unresolved_ty, unresolved_int_ty, unresolved_float_ty}; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFoldable}; /////////////////////////////////////////////////////////////////////////// @@ -36,7 +36,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for OpportunisticTypeResolver<'a, 'tcx> } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_has_ty_infer(t) { + if !t.has_infer_types() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t0 = self.infcx.shallow_resolve(t); @@ -75,7 +75,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_needs_infer(t) { + if !t.needs_infer() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t = self.infcx.shallow_resolve(t); diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index c4d924d676c89..cf70d63106c70 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -13,7 +13,7 @@ use metadata::csearch; use middle::def::DefFn; use middle::subst::{Subst, Substs, EnumeratedItems}; use middle::ty::{TransmuteRestriction, ctxt, TyBareFn}; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use std::fmt; @@ -92,8 +92,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> { // Simple case: no type parameters involved. if - !ty::type_has_params(from) && !ty::type_has_self(from) && - !ty::type_has_params(to) && !ty::type_has_self(to) + !from.has_param_types() && !from.has_self_ty() && + !to.has_param_types() && !to.has_self_ty() { let restriction = TransmuteRestriction { span: span, diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index c3c29d0ade8df..56798ae6848a5 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -13,7 +13,7 @@ pub use self::ParamSpace::*; pub use self::RegionSubsts::*; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags, RegionEscape}; use middle::ty_fold::{self, TypeFoldable, TypeFolder}; use std::fmt; @@ -100,17 +100,6 @@ impl<'tcx> Substs<'tcx> { *self.types.get(ty_param_def.space, ty_param_def.index as usize) } - pub fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.types.iter().any(|&t| ty::type_escapes_depth(t, depth)) || { - match self.regions { - ErasedRegions => - false, - NonerasedRegions(ref regions) => - regions.iter().any(|r| r.escapes_depth(depth)), - } - } - } - pub fn self_ty(&self) -> Option> { self.types.get_self().cloned() } @@ -632,7 +621,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_needs_subst(t) { + if !t.needs_subst() { return t; } @@ -729,10 +718,10 @@ impl<'a,'tcx> SubstFolder<'a,'tcx> { /// first case we do not increase the Debruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. fn shift_regions_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> { - debug!("shift_regions(ty={:?}, region_binders_passed={:?}, type_has_escaping_regions={:?})", - ty, self.region_binders_passed, ty::type_has_escaping_regions(ty)); + debug!("shift_regions(ty={:?}, region_binders_passed={:?}, has_escaping_regions={:?})", + ty, self.region_binders_passed, ty.has_escaping_regions()); - if self.region_binders_passed == 0 || !ty::type_has_escaping_regions(ty) { + if self.region_binders_passed == 0 || !ty.has_escaping_regions() { return ty; } diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index dc7e4f9c57114..7b86e1b4539e6 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -25,7 +25,7 @@ use super::{ use fmt_macros::{Parser, Piece, Position}; use middle::infer::InferCtxt; -use middle::ty::{self, ToPredicate, ReferencesError, ToPolyTraitRef, TraitRef}; +use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef}; use middle::ty_fold::TypeFoldable; use std::collections::HashMap; use std::fmt; @@ -245,7 +245,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, ref e) => { let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref); let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref); - if !ty::type_is_error(actual_trait_ref.self_ty()) { + if !actual_trait_ref.self_ty().references_error() { span_err!(infcx.tcx.sess, obligation.cause.span, E0281, "type mismatch: the type `{}` implements the trait `{}`, \ but the trait `{}` is required ({})", @@ -325,8 +325,8 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let trait_ref = data.to_poly_trait_ref(); let self_ty = trait_ref.self_ty(); let all_types = &trait_ref.substs().types; - if all_types.iter().any(|&t| ty::type_is_error(t)) { - } else if all_types.iter().any(|&t| ty::type_needs_infer(t)) { + if all_types.references_error() { + } else if all_types.needs_infer() { // This is kind of a hack: it frequently happens that some earlier // error prevents types from being fully inferred, and then we get // a bunch of uninteresting errors saying something like "(infcx: &InferCtxt<'a,'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Result>> - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("normalize_param_env(value={:?})", value); diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index cb5440fbf9000..0203a860beb42 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -23,8 +23,7 @@ use super::util; use middle::infer; use middle::subst::Subst; -use middle::ty::{self, ToPredicate, ReferencesError, RegionEscape, - HasProjectionTypes, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPredicate, RegionEscape, HasTypeFlags, ToPolyTraitRef, Ty}; use middle::ty_fold::{self, TypeFoldable, TypeFolder}; use syntax::parse::token; use util::common::FN_OUTPUT_NAME; @@ -195,7 +194,7 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { normalize_with_depth(selcx, cause, 0, value) } @@ -206,7 +205,7 @@ pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tc depth: usize, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); let result = normalizer.fold(value); @@ -238,7 +237,7 @@ impl<'a,'b,'tcx> AssociatedTypeNormalizer<'a,'b,'tcx> { } } - fn fold + HasProjectionTypes>(&mut self, value: &T) -> T { + fn fold + HasTypeFlags>(&mut self, value: &T) -> T { let value = self.selcx.infcx().resolve_type_vars_if_possible(value); if !value.has_projection_types() { @@ -374,7 +373,7 @@ fn opt_normalize_projection_type<'a,'b,'tcx>( depth, obligations); - if ty::type_has_projection(projected_ty) { + if projected_ty.has_projection_types() { let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); let normalized_ty = normalizer.fold(&projected_ty); diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 4246d5f0e83f8..fcc6365dab5a7 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -38,7 +38,7 @@ use super::util; use middle::fast_reject; use middle::subst::{Subst, Substs, TypeSpace}; -use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty, HasTypeFlags}; use middle::infer; use middle::infer::{InferCtxt, TypeFreshener}; use middle::ty_fold::TypeFoldable; @@ -675,7 +675,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { stack: &TraitObligationStack<'o, 'tcx>) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if ty::type_is_error(stack.obligation.predicate.0.self_ty()) { + if stack.obligation.predicate.0.self_ty().references_error() { return Ok(Some(ErrorCandidate)); } @@ -886,7 +886,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match *candidate { Ok(Some(_)) | Err(_) => true, Ok(None) => { - cache_fresh_trait_pred.0.input_types().iter().any(|&t| ty::type_has_ty_infer(t)) + cache_fresh_trait_pred.0.input_types().has_infer_types() } } } @@ -2558,7 +2558,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err; } for &ty in fields.init() { - if ty::type_is_error(ty.subst(tcx, &new_substs)) { + if ty.subst(tcx, &new_substs).references_error() { return Err(Unimplemented); } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 3f84d433e9cb5..47d66db88b04a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1180,64 +1180,6 @@ impl<'tcx> Borrow> for InternedTy<'tcx> { } } -pub fn type_has_params(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_PARAMS) -} -pub fn type_has_self(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_SELF) -} -pub fn type_has_ty_infer(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_TY_INFER) -} -pub fn type_needs_infer(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) -} -pub fn type_is_global(ty: Ty) -> bool { - !ty.flags.get().intersects(TypeFlags::HAS_LOCAL_NAMES) -} -pub fn type_has_projection(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_PROJECTION) -} -pub fn type_has_ty_closure(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE) -} - -pub fn type_has_erasable_regions(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_RE_EARLY_BOUND | - TypeFlags::HAS_RE_INFER | - TypeFlags::HAS_FREE_REGIONS) -} - -/// An "escaping region" is a bound region whose binder is not part of `t`. -/// -/// So, for example, consider a type like the following, which has two binders: -/// -/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope -/// -/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the -/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner -/// fn type*, that type has an escaping region: `'a`. -/// -/// Note that what I'm calling an "escaping region" is often just called a "free region". However, -/// we already use the term "free region". It refers to the regions that we use to represent bound -/// regions on a fn definition while we are typechecking its body. -/// -/// To clarify, conceptually there is no particular difference between an "escaping" region and a -/// "free" region. However, there is a big difference in practice. Basically, when "entering" a -/// binding level, one is generally required to do some sort of processing to a bound region, such -/// as replacing it with a fresh/skolemized region, or making an entry in the environment to -/// represent the scope to which it is attached, etc. An escaping region represents a bound region -/// for which this processing has not yet been done. -pub fn type_has_escaping_regions(ty: Ty) -> bool { - type_escapes_depth(ty, 0) -} - -pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool { - ty.region_depth > depth -} - #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct BareFnTy<'tcx> { pub unsafety: ast::Unsafety, @@ -1497,15 +1439,6 @@ pub struct UpvarBorrow { pub type UpvarCaptureMap = FnvHashMap; impl Region { - pub fn is_global(&self) -> bool { - // does this represent a region that can be named in a global - // way? used in fulfillment caching. - match *self { - ty::ReStatic | ty::ReEmpty => true, - _ => false, - } - } - pub fn is_bound(&self) -> bool { match *self { ty::ReEarlyBound(..) => true, @@ -2254,29 +2187,6 @@ impl<'tcx> Predicate<'tcx> { Predicate::Projection(ty::Binder(data.subst(tcx, substs))), } } - - // Indicates whether this predicate references only 'global' - // types/lifetimes that are the same regardless of what fn we are - // in. This is used for caching. Errs on the side of returning - // false. - pub fn is_global(&self) -> bool { - match *self { - ty::Predicate::Trait(ref data) => { - let substs = data.skip_binder().trait_ref.substs; - - substs.types.iter().all(|t| ty::type_is_global(t)) && { - match substs.regions { - subst::ErasedRegions => true, - subst::NonerasedRegions(ref r) => r.iter().all(|r| r.is_global()), - } - } - } - - _ => { - false - } - } - } } #[derive(Clone, PartialEq, Eq, Hash)] @@ -3711,18 +3621,6 @@ pub fn type_is_nil(ty: Ty) -> bool { } } -pub fn type_is_error(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::HAS_TY_ERR) -} - -pub fn type_needs_subst(ty: Ty) -> bool { - ty.flags.get().intersects(TypeFlags::NEEDS_SUBST) -} - -pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool { - tref.substs.types.any(|&ty| type_is_error(ty)) -} - pub fn type_is_ty_var(ty: Ty) -> bool { match ty.sty { TyInfer(TyVar(_)) => true, @@ -4255,7 +4153,7 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>, return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT); } - assert!(!ty::type_needs_infer(ty)); + assert!(!ty.needs_infer()); // Fast-path for primitive types let result = match ty.sty { @@ -4277,7 +4175,7 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>, ty::BoundCopy, span)); - if !type_has_params(ty) && !type_has_self(ty) { + if !ty.has_param_types() && !ty.has_self_ty() { ty.flags.set(ty.flags.get() | if result { TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT } else { @@ -4307,7 +4205,7 @@ fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'t tcx: &ty::ctxt<'tcx>, span: Span, ty: Ty<'tcx>) -> bool { - assert!(!ty::type_needs_infer(ty)); + assert!(!ty.needs_infer()); // Fast-path for primitive types let result = match ty.sty { @@ -4321,7 +4219,7 @@ fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'t TyInfer(..) | TyError => None }.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span)); - if !type_has_params(ty) && !type_has_self(ty) { + if !ty.has_param_types() && !ty.has_self_ty() { ty.flags.set(ty.flags.get() | if result { TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED } else { @@ -5028,7 +4926,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>, AdjustDerefRef(ref adj) => { let mut adjusted_ty = unadjusted_ty; - if !ty::type_is_error(adjusted_ty) { + if !adjusted_ty.references_error() { for i in 0..adj.autoderefs { let method_call = MethodCall::autoderef(expr_id, i as u32); match method_type(method_call) { @@ -7362,11 +7260,33 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc Ok(()) } -// FIXME(#20298) -- all of these types basically walk various +// FIXME(#20298) -- all of these traits basically walk various // structures to test whether types/regions are reachable with various // properties. It should be possible to express them in terms of one // common "walker" trait or something. +/// An "escaping region" is a bound region whose binder is not part of `t`. +/// +/// So, for example, consider a type like the following, which has two binders: +/// +/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope +/// +/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the +/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner +/// fn type*, that type has an escaping region: `'a`. +/// +/// Note that what I'm calling an "escaping region" is often just called a "free region". However, +/// we already use the term "free region". It refers to the regions that we use to represent bound +/// regions on a fn definition while we are typechecking its body. +/// +/// To clarify, conceptually there is no particular difference between an "escaping" region and a +/// "free" region. However, there is a big difference in practice. Basically, when "entering" a +/// binding level, one is generally required to do some sort of processing to a bound region, such +/// as replacing it with a fresh/skolemized region, or making an entry in the environment to +/// represent the scope to which it is attached, etc. An escaping region represents a bound region +/// for which this processing has not yet been done. pub trait RegionEscape { fn has_escaping_regions(&self) -> bool { self.has_regions_escaping_depth(0) @@ -7377,7 +7297,7 @@ pub trait RegionEscape { impl<'tcx> RegionEscape for Ty<'tcx> { fn has_regions_escaping_depth(&self, depth: u32) -> bool { - ty::type_escapes_depth(*self, depth) + self.region_depth > depth } } @@ -7491,237 +7411,221 @@ impl<'tcx> RegionEscape for ProjectionTy<'tcx> { } } -pub trait HasProjectionTypes { - fn has_projection_types(&self) -> bool; -} - -impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec { +pub trait HasTypeFlags { + fn has_type_flags(&self, flags: TypeFlags) -> bool; fn has_projection_types(&self) -> bool { - self.iter().any(|p| p.has_projection_types()) + self.has_type_flags(TypeFlags::HAS_PROJECTION) } -} - -impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace { - fn has_projection_types(&self) -> bool { - self.iter().any(|p| p.has_projection_types()) + fn references_error(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_ERR) } -} - -impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> { - fn has_projection_types(&self) -> bool { - self.sig.has_projection_types() + fn has_param_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PARAMS) } -} - -impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> { - fn has_projection_types(&self) -> bool { - self.ty.has_projection_types() + fn has_self_ty(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_SELF) } -} - -impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> { - fn has_projection_types(&self) -> bool { - self.predicates.has_projection_types() + fn has_infer_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER) } -} - -impl<'tcx> HasProjectionTypes for Predicate<'tcx> { - fn has_projection_types(&self) -> bool { - match *self { - Predicate::Trait(ref data) => data.has_projection_types(), - Predicate::Equate(ref data) => data.has_projection_types(), - Predicate::RegionOutlives(ref data) => data.has_projection_types(), - Predicate::TypeOutlives(ref data) => data.has_projection_types(), - Predicate::Projection(ref data) => data.has_projection_types(), - } + fn needs_infer(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) } -} - -impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> { - fn has_projection_types(&self) -> bool { - self.trait_ref.has_projection_types() + fn needs_subst(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST) } -} - -impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> { - fn has_projection_types(&self) -> bool { - self.0.has_projection_types() || self.1.has_projection_types() + fn has_closure_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_CLOSURE) } -} - -impl HasProjectionTypes for Region { - fn has_projection_types(&self) -> bool { - false + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND | + TypeFlags::HAS_RE_INFER | + TypeFlags::HAS_FREE_REGIONS) } -} - -impl HasProjectionTypes for OutlivesPredicate { - fn has_projection_types(&self) -> bool { - self.0.has_projection_types() || self.1.has_projection_types() + /// Indicates whether this value references only 'global' + /// types/lifetimes that are the same regardless of what fn we are + /// in. This is used for caching. Errs on the side of returning + /// false. + fn is_global(&self) -> bool { + !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) } } -impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> { - fn has_projection_types(&self) -> bool { - self.projection_ty.has_projection_types() || self.ty.has_projection_types() +impl<'tcx,T:HasTypeFlags> HasTypeFlags for Vec { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self[..].has_type_flags(flags) } } -impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> { - fn has_projection_types(&self) -> bool { - self.trait_ref.has_projection_types() +impl<'tcx,T:HasTypeFlags> HasTypeFlags for [T] { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.iter().any(|p| p.has_type_flags(flags)) } } -impl<'tcx> HasProjectionTypes for Ty<'tcx> { - fn has_projection_types(&self) -> bool { - ty::type_has_projection(*self) +impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.iter().any(|p| p.has_type_flags(flags)) } } -impl<'tcx> HasProjectionTypes for TraitRef<'tcx> { - fn has_projection_types(&self) -> bool { - self.substs.has_projection_types() +impl<'tcx> HasTypeFlags for ClosureTy<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.sig.has_type_flags(flags) } } -impl<'tcx> HasProjectionTypes for subst::Substs<'tcx> { - fn has_projection_types(&self) -> bool { - self.types.iter().any(|t| t.has_projection_types()) +impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.ty.has_type_flags(flags) } } -impl<'tcx,T> HasProjectionTypes for Option - where T : HasProjectionTypes -{ - fn has_projection_types(&self) -> bool { - self.iter().any(|t| t.has_projection_types()) +impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.predicates.has_type_flags(flags) } } -impl<'tcx,T> HasProjectionTypes for Rc - where T : HasProjectionTypes -{ - fn has_projection_types(&self) -> bool { - (**self).has_projection_types() +impl<'tcx> HasTypeFlags for Predicate<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + match *self { + Predicate::Trait(ref data) => data.has_type_flags(flags), + Predicate::Equate(ref data) => data.has_type_flags(flags), + Predicate::RegionOutlives(ref data) => data.has_type_flags(flags), + Predicate::TypeOutlives(ref data) => data.has_type_flags(flags), + Predicate::Projection(ref data) => data.has_type_flags(flags), + } } } -impl<'tcx,T> HasProjectionTypes for Box - where T : HasProjectionTypes -{ - fn has_projection_types(&self) -> bool { - (**self).has_projection_types() +impl<'tcx> HasTypeFlags for TraitPredicate<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.trait_ref.has_type_flags(flags) } } -impl HasProjectionTypes for Binder - where T : HasProjectionTypes -{ - fn has_projection_types(&self) -> bool { - self.0.has_projection_types() +impl<'tcx> HasTypeFlags for EquatePredicate<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.0.has_type_flags(flags) || self.1.has_type_flags(flags) } } -impl<'tcx> HasProjectionTypes for FnOutput<'tcx> { - fn has_projection_types(&self) -> bool { - match *self { - FnConverging(t) => t.has_projection_types(), - FnDiverging => false, +impl HasTypeFlags for Region { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + if flags.intersects(TypeFlags::HAS_LOCAL_NAMES) { + // does this represent a region that cannot be named in a global + // way? used in fulfillment caching. + match *self { + ty::ReStatic | ty::ReEmpty => {} + _ => return true + } } + if flags.intersects(TypeFlags::HAS_RE_INFER) { + if let ty::ReInfer(_) = *self { + return true; + } + } + false } } -impl<'tcx> HasProjectionTypes for FnSig<'tcx> { - fn has_projection_types(&self) -> bool { - self.inputs.iter().any(|t| t.has_projection_types()) || - self.output.has_projection_types() +impl HasTypeFlags for OutlivesPredicate { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.0.has_type_flags(flags) || self.1.has_type_flags(flags) } } -impl<'tcx> HasProjectionTypes for field<'tcx> { - fn has_projection_types(&self) -> bool { - self.mt.ty.has_projection_types() +impl<'tcx> HasTypeFlags for ProjectionPredicate<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.projection_ty.has_type_flags(flags) || self.ty.has_type_flags(flags) } } -impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> { - fn has_projection_types(&self) -> bool { - self.sig.has_projection_types() +impl<'tcx> HasTypeFlags for ProjectionTy<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.trait_ref.has_type_flags(flags) } } -pub trait ReferencesError { - fn references_error(&self) -> bool; +impl<'tcx> HasTypeFlags for Ty<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.flags.get().intersects(flags) + } } -impl ReferencesError for Binder { - fn references_error(&self) -> bool { - self.0.references_error() +impl<'tcx> HasTypeFlags for TraitRef<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.substs.has_type_flags(flags) } } -impl ReferencesError for Rc { - fn references_error(&self) -> bool { - (&**self).references_error() +impl<'tcx> HasTypeFlags for subst::Substs<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.types.has_type_flags(flags) || match self.regions { + subst::ErasedRegions => false, + subst::NonerasedRegions(ref r) => r.has_type_flags(flags) + } } } -impl<'tcx> ReferencesError for TraitPredicate<'tcx> { - fn references_error(&self) -> bool { - self.trait_ref.references_error() +impl<'tcx,T> HasTypeFlags for Option + where T : HasTypeFlags +{ + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.iter().any(|t| t.has_type_flags(flags)) } } -impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> { - fn references_error(&self) -> bool { - self.projection_ty.trait_ref.references_error() || self.ty.references_error() +impl<'tcx,T> HasTypeFlags for Rc + where T : HasTypeFlags +{ + fn has_type_flags(&self, flags: TypeFlags) -> bool { + (**self).has_type_flags(flags) } } -impl<'tcx> ReferencesError for TraitRef<'tcx> { - fn references_error(&self) -> bool { - self.input_types().iter().any(|t| t.references_error()) +impl<'tcx,T> HasTypeFlags for Box + where T : HasTypeFlags +{ + fn has_type_flags(&self, flags: TypeFlags) -> bool { + (**self).has_type_flags(flags) } } -impl<'tcx> ReferencesError for Ty<'tcx> { - fn references_error(&self) -> bool { - type_is_error(*self) +impl HasTypeFlags for Binder + where T : HasTypeFlags +{ + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.0.has_type_flags(flags) } } -impl<'tcx> ReferencesError for Predicate<'tcx> { - fn references_error(&self) -> bool { +impl<'tcx> HasTypeFlags for FnOutput<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { match *self { - Predicate::Trait(ref data) => data.references_error(), - Predicate::Equate(ref data) => data.references_error(), - Predicate::RegionOutlives(ref data) => data.references_error(), - Predicate::TypeOutlives(ref data) => data.references_error(), - Predicate::Projection(ref data) => data.references_error(), + FnConverging(t) => t.has_type_flags(flags), + FnDiverging => false, } } } -impl ReferencesError for OutlivesPredicate - where A : ReferencesError, B : ReferencesError -{ - fn references_error(&self) -> bool { - self.0.references_error() || self.1.references_error() +impl<'tcx> HasTypeFlags for FnSig<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.inputs.iter().any(|t| t.has_type_flags(flags)) || + self.output.has_type_flags(flags) } } -impl<'tcx> ReferencesError for EquatePredicate<'tcx> -{ - fn references_error(&self) -> bool { - self.0.references_error() || self.1.references_error() +impl<'tcx> HasTypeFlags for field<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.mt.ty.has_type_flags(flags) } } -impl ReferencesError for Region -{ - fn references_error(&self) -> bool { - false +impl<'tcx> HasTypeFlags for BareFnTy<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.sig.has_type_flags(flags) } } diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index fe89ca751e7ce..ea52b1da36168 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -36,7 +36,7 @@ use middle::subst; use middle::subst::VecPerParamSpace; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags, RegionEscape}; use middle::traits; use std::fmt; @@ -896,7 +896,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_escapes_depth(t, self.current_depth-1) { + if !t.has_regions_escaping_depth(self.current_depth-1) { return t; } @@ -946,7 +946,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !ty::type_has_erasable_regions(t) { + if !t.has_erasable_regions() { return t; } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0ae089df50dd2..fcff4363fd603 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -14,13 +14,12 @@ use middle::ty::{BoundRegion, BrAnon, BrNamed}; use middle::ty::{ReEarlyBound, BrFresh, ctxt}; use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty}; use middle::ty::{ReSkolemized, ReVar, BrEnv}; -use middle::ty::{mt, Ty}; use middle::ty::{TyBool, TyChar, TyStruct, TyEnum}; use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn}; use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple}; use middle::ty::TyClosure; use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer}; -use middle::ty; +use middle::ty::{self, mt, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFoldable}; use std::fmt; @@ -155,7 +154,7 @@ fn parameterized(f: &mut fmt::Formatter, ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| { match def.default { Some(default) => { - if !has_self && ty::type_has_self(default) { + if !has_self && default.has_self_ty() { // In an object type, there is no `Self`, and // thus if the default value references Self, // the user will be required to give an diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 62c8e0368d906..9ceaf748af7b1 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -22,7 +22,7 @@ use rustc_typeck::middle::resolve_lifetime; use rustc_typeck::middle::stability; use rustc_typeck::middle::subst; use rustc_typeck::middle::subst::Subst; -use rustc_typeck::middle::ty::{self, Ty}; +use rustc_typeck::middle::ty::{self, Ty, RegionEscape}; use rustc_typeck::middle::ty_relate::TypeRelation; use rustc_typeck::middle::infer; use rustc_typeck::middle::infer::lub::Lub; @@ -745,22 +745,22 @@ fn escaping() { // Situation: // Theta = [A -> &'a foo] - assert!(!ty::type_has_escaping_regions(env.t_nil())); + assert!(!env.t_nil().has_escaping_regions()); let t_rptr_free1 = env.t_rptr_free(0, 1); - assert!(!ty::type_has_escaping_regions(t_rptr_free1)); + assert!(!t_rptr_free1.has_escaping_regions()); let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1)); - assert!(ty::type_has_escaping_regions(t_rptr_bound1)); + assert!(t_rptr_bound1.has_escaping_regions()); let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(2)); - assert!(ty::type_has_escaping_regions(t_rptr_bound2)); + assert!(t_rptr_bound2.has_escaping_regions()); // t_fn = fn(A) let t_param = env.t_param(subst::TypeSpace, 0); - assert!(!ty::type_has_escaping_regions(t_param)); + assert!(!t_param.has_escaping_regions()); let t_fn = env.t_fn(&[t_param], env.t_nil()); - assert!(!ty::type_has_escaping_regions(t_fn)); + assert!(!t_fn.has_escaping_regions()); }) } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 461739a362d30..c7288bb1eef80 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -40,7 +40,7 @@ use middle::cfg; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; -use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size}; +use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size, HasTypeFlags}; use rustc::ast_map; use session::config::{self, NoDebugInfo}; use session::Session; @@ -1007,7 +1007,7 @@ pub fn alloc_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, name: &str) -> let _icx = push_ctxt("alloc_ty"); let ccx = bcx.ccx(); let ty = type_of::type_of(ccx, t); - assert!(!ty::type_has_params(t)); + assert!(!t.has_param_types()); let val = alloca(bcx, ty, name); return val; } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 093b824701fa4..c036078f42f55 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -49,7 +49,7 @@ use trans::meth; use trans::monomorphize; use trans::type_::Type; use trans::type_of; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags, RegionEscape}; use middle::ty::MethodCall; use rustc::ast_map; @@ -402,8 +402,8 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( param_substs, substs); - assert!(substs.types.all(|t| !ty::type_needs_infer(*t))); - assert!(substs.types.all(|t| !ty::type_has_escaping_regions(*t))); + assert!(!substs.types.needs_infer()); + assert!(!substs.types.has_escaping_regions()); let substs = substs.erase_regions(); // Load the info for the appropriate trait if necessary. diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 403755c536d75..0127c57d9cf34 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -37,7 +37,7 @@ use trans::monomorphize; use trans::type_::Type; use trans::type_of; use middle::traits; -use middle::ty::{self, HasProjectionTypes, Ty}; +use middle::ty::{self, HasTypeFlags, Ty}; use middle::ty_fold; use middle::ty_fold::{TypeFolder, TypeFoldable}; use rustc::ast_map::{PathElem, PathName}; @@ -336,7 +336,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res { pub type ExternMap = FnvHashMap; pub fn validate_substs(substs: &Substs) { - assert!(substs.types.all(|t| !ty::type_needs_infer(*t))); + assert!(!substs.types.needs_infer()); } // work around bizarre resolve errors @@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { } pub fn monomorphize(&self, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { monomorphize::apply_param_substs(self.ccx.tcx(), self.param_substs, @@ -610,7 +610,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { } pub fn monomorphize(&self, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { monomorphize::apply_param_substs(self.tcx(), self.fcx.param_substs, @@ -1194,7 +1194,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } }; - if substs.types.any(|t| ty::type_needs_infer(*t)) { + if substs.types.needs_infer() { tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}", node, substs)); } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index dd97265e428ed..a90b462b98572 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -30,7 +30,7 @@ use trans::type_of; use trans::machine; use trans::machine::llsize_of; use trans::type_::Type; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use syntax::abi::RustIntrinsic; use syntax::ast; use syntax::parse::token; @@ -103,8 +103,8 @@ pub fn check_intrinsics(ccx: &CrateContext) { debug!("transmute_restriction: {:?}", transmute_restriction); - assert!(!ty::type_has_params(transmute_restriction.substituted_from)); - assert!(!ty::type_has_params(transmute_restriction.substituted_to)); + assert!(!transmute_restriction.substituted_from.has_param_types()); + assert!(!transmute_restriction.substituted_to.has_param_types()); let llfromtype = type_of::sizing_type_of(ccx, transmute_restriction.substituted_from); diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index e61770768db22..f78d1c44f5f42 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -37,7 +37,7 @@ use trans::machine; use trans::monomorphize; use trans::type_::Type; use trans::type_of::*; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty::MethodCall; use syntax::abi::{Rust, RustCall}; @@ -248,7 +248,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, substs: impl_substs, nested: _ }) => { - assert!(impl_substs.types.all(|t| !ty::type_needs_infer(*t))); + assert!(!impl_substs.types.needs_infer()); // Create the substitutions that are in scope. This combines // the type parameters from the impl with those declared earlier. diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index f4bad313bafb1..4d64b1c03b800 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -25,7 +25,7 @@ use trans::base; use trans::common::*; use trans::declare; use trans::foreign; -use middle::ty::{self, HasProjectionTypes, Ty}; +use middle::ty::{self, HasTypeFlags, Ty}; use syntax::abi; use syntax::ast; @@ -47,9 +47,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, psubsts, ref_id); - assert!(psubsts.types.all(|t| { - !ty::type_needs_infer(*t) && !ty::type_has_params(*t) - })); + assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types()); let _icx = push_ctxt("monomorphic_fn"); @@ -302,7 +300,7 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>, param_substs: &Substs<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { let substituted = value.subst(tcx, param_substs); normalize_associated_type(tcx, &substituted) @@ -313,7 +311,7 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>, /// and hence we can be sure that all associated types will be /// completely normalized away. pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("normalize_associated_type(t={:?})", value); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d4ecdc65eadb0..ec5b543cfcd18 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -56,7 +56,7 @@ use middle::resolve_lifetime as rl; use middle::privacy::{AllPublic, LastMod}; use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs}; use middle::traits; -use middle::ty::{self, RegionEscape, Ty, ToPredicate}; +use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags}; use middle::ty_fold; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope}; @@ -439,7 +439,7 @@ fn create_substs_for_ast_path<'tcx>( // other type parameters may reference `Self` in their // defaults. This will lead to an ICE if we are not // careful! - if self_ty.is_none() && ty::type_has_self(default) { + if self_ty.is_none() && default.has_self_ty() { span_err!(tcx.sess, span, E0393, "the type parameter `{}` must be explicitly specified \ in an object type because its default value `{}` references \ diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cf086a32ae599..95814370900c4 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -15,7 +15,7 @@ use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding}; use middle::pat_util::pat_is_resolved_const; use middle::privacy::{AllPublic, LastMod}; use middle::subst::Substs; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use check::{check_expr, check_expr_has_type, check_expr_with_expectation}; use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation}; use check::{check_expr_with_lvalue_pref, LvaluePreference}; @@ -499,7 +499,7 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_expr_has_type(fcx, &**e, tcx.types.bool); } - if ty::type_is_error(result_ty) || ty::type_is_error(bty) { + if result_ty.references_error() || bty.references_error() { tcx.types.err } else { let (origin, expected, found) = match match_src { diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index df9fe6b002efb..4eafbaaf794d2 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -11,7 +11,7 @@ use middle::infer::InferCtxt; use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, SelectionContext, ObligationCause}; -use middle::ty::{self, HasProjectionTypes}; +use middle::ty::{self, HasTypeFlags}; use middle::ty_fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; @@ -23,7 +23,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, body_id: ast::NodeId, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("normalize_associated_types_in(value={:?})", value); let mut selcx = SelectionContext::new(infcx, typer); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index c46a033c13f95..5bf1ef346113c 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -45,8 +45,7 @@ use super::structurally_resolved_type; use lint; use middle::cast::{CastKind, CastTy}; -use middle::ty; -use middle::ty::Ty; +use middle::ty::{self, Ty, HasTypeFlags}; use syntax::ast; use syntax::ast::UintTy::{TyU8}; use syntax::codemap::Span; @@ -199,7 +198,7 @@ impl<'tcx> CastCheck<'tcx> { debug!("check_cast({}, {:?} as {:?})", self.expr.id, self.expr_ty, self.cast_ty); - if ty::type_is_error(self.expr_ty) || ty::type_is_error(self.cast_ty) { + if self.expr_ty.references_error() || self.cast_ty.references_error() { // No sense in giving duplicate error messages } else if self.try_coercion_cast(fcx) { self.trivial_cast_lint(fcx); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 46bffa8ccabda..f8ce387969458 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -21,6 +21,7 @@ use middle::subst; use middle::subst::Subst; use middle::traits; use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef, TraitRef}; +use middle::ty::HasTypeFlags; use middle::ty_fold::TypeFoldable; use middle::infer; use middle::infer::InferCtxt; @@ -528,7 +529,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // artifacts. This means it is safe to put into the // `WhereClauseCandidate` and (eventually) into the // `WhereClausePick`. - assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t))); + assert!(!trait_ref.substs.types.needs_infer()); this.inherent_candidates.push(Candidate { xform_self_ty: xform_self_ty, @@ -928,7 +929,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option> { debug!("pick_step: step={:?}", step); - if ty::type_is_error(step.self_ty) { + if step.self_ty.references_error() { return None; } @@ -1357,7 +1358,7 @@ impl<'tcx> Candidate<'tcx> { // inference variables or other artifacts. This // means they are safe to put into the // `WhereClausePick`. - assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t))); + assert!(!trait_ref.substs().types.needs_infer()); WhereClausePick((*trait_ref).clone(), index) } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index a1d1ddff45aae..de8629da3cade 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -15,7 +15,7 @@ use CrateCtxt; use astconv::AstConv; use check::{self, FnCtxt}; -use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate}; +use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, HasTypeFlags}; use middle::def; use middle::lang_items::FnOnceTraitLangItem; use middle::subst::Substs; @@ -40,7 +40,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, error: MethodError<'tcx>) { // avoid suggestions when we don't know what's going on. - if ty::type_is_error(rcvr_ty) { + if rcvr_ty.references_error() { return } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 34df349b7a3db..fa768cb9adbb8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -96,7 +96,7 @@ use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace use middle::traits::{self, report_fulfillment_errors}; use middle::ty::{FnSig, GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; -use middle::ty::{self, HasProjectionTypes, RegionEscape, ToPolyTraitRef, Ty}; +use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; use middle::ty::liberate_late_bound_regions; use middle::ty::{MethodCall, MethodCallee, MethodMap}; use middle::ty_fold::{TypeFolder, TypeFoldable}; @@ -397,7 +397,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { body_id: ast::NodeId, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { let mut fulfillment_cx = self.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, @@ -1296,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { debug!("resolve_type_vars_if_possible(ty={:?})", ty); - // No ty::infer()? Nothing needs doing. - if !ty::type_has_ty_infer(ty) { + // No TyInfer()? Nothing needs doing. + if !ty.has_infer_types() { debug!("resolve_type_vars_if_possible: ty={:?}", ty); return ty; } // If `ty` is a type variable, see whether we already know what it is. ty = self.infcx().resolve_type_vars_if_possible(&ty); - if !ty::type_has_ty_infer(ty) { + if !ty.has_infer_types() { debug!("resolve_type_vars_if_possible: ty={:?}", ty); return ty; } @@ -1312,7 +1312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If not, try resolving any new fcx obligations that have cropped up. self.select_new_obligations(); ty = self.infcx().resolve_type_vars_if_possible(&ty); - if !ty::type_has_ty_infer(ty) { + if !ty.has_infer_types() { debug!("resolve_type_vars_if_possible: ty={:?}", ty); return ty; } @@ -1333,9 +1333,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// main checking when doing a second pass before writeback. The /// justification is that writeback will produce an error for /// these unconstrained type variables. - fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult> { - let t = self.infcx().resolve_type_vars_if_possible(t); - if ty::type_has_ty_infer(t) || ty::type_is_error(t) { Err(()) } else { Ok(t) } + fn resolve_type_vars_or_error(&self, ty: &Ty<'tcx>) -> mc::McResult> { + let ty = self.infcx().resolve_type_vars_if_possible(ty); + if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } } fn record_deferred_call_resolution(&self, @@ -1443,7 +1443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { substs: &Substs<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { let value = value.subst(self.tcx(), substs); let result = self.normalize_associated_types_in(span, &value); @@ -1469,7 +1469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn normalize_associated_types_in(&self, span: Span, value: &T) -> T - where T : TypeFoldable<'tcx> + HasProjectionTypes + where T : TypeFoldable<'tcx> + HasTypeFlags { self.inh.normalize_associated_types_in(self, span, self.body_id, value) } @@ -1954,7 +1954,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.resolve_type_vars_if_possible(t) } }; - if ty::type_is_error(resolved_t) { + if resolved_t.references_error() { return (resolved_t, autoderefs, None); } @@ -2186,7 +2186,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, tuple_arguments: TupleArgumentsFlag, expected: Expectation<'tcx>) -> ty::FnOutput<'tcx> { - if ty::type_is_error(method_fn_ty) { + if method_fn_ty.references_error() { let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len()); let err_inputs = match tuple_arguments { @@ -2607,7 +2607,7 @@ fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, /// Invariant: /// If an expression has any sub-expressions that result in a type error, -/// inspecting that expression's type with `ty::type_is_error` will return +/// inspecting that expression's type with `ty.references_error()` will return /// true. Likewise, if an expression is known to diverge, inspecting its /// type with `ty::type_is_bot` will return true (n.b.: since Rust is /// strict, _|_ can appear in the type of an expression that does not, @@ -2710,7 +2710,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }; let cond_ty = fcx.expr_ty(cond_expr); - let if_ty = if ty::type_is_error(cond_ty) { + let if_ty = if cond_ty.references_error() { fcx.tcx().types.err } else { branches_ty @@ -3022,7 +3022,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fields, base_expr.is_none(), None); - if ty::type_is_error(fcx.node_ty(id)) { + if fcx.node_ty(id).references_error() { struct_type = tcx.types.err; } @@ -3153,7 +3153,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx, &**oprnd, expected_inner, lvalue_pref); let mut oprnd_t = fcx.expr_ty(&**oprnd); - if !ty::type_is_error(oprnd_t) { + if !oprnd_t.references_error() { match unop { ast::UnUniq => { oprnd_t = ty::mk_uniq(tcx, oprnd_t); @@ -3232,7 +3232,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, lvalue_pref); let tm = ty::mt { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl }; - let oprnd_t = if ty::type_is_error(tm.ty) { + let oprnd_t = if tm.ty.references_error() { tcx.types.err } else { // Note: at this point, we cannot say what the best lifetime @@ -3352,7 +3352,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized); - if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { + if lhs_ty.references_error() || rhs_ty.references_error() { fcx.write_error(id); } else { fcx.write_nil(id); @@ -3370,7 +3370,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, check_block_no_value(fcx, &**body); let cond_ty = fcx.expr_ty(&**cond); let body_ty = fcx.node_ty(body.id); - if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) { + if cond_ty.references_error() || body_ty.references_error() { fcx.write_error(id); } else { @@ -3409,7 +3409,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a)); let args_err = arg_tys.fold(false, |rest_err, a| { - rest_err || ty::type_is_error(a)}); + rest_err || a.references_error()}); if args_err { fcx.write_error(id); } @@ -3427,7 +3427,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let t_expr = fcx.expr_ty(e); // Eagerly check for some obvious errors. - if ty::type_is_error(t_expr) { + if t_expr.references_error() { fcx.write_error(id); } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) { report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id); @@ -3504,7 +3504,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ty::BoundCopy); } - if ty::type_is_error(element_ty) { + if element_ty.references_error() { fcx.write_error(id); } else { let t = ty::mk_vec(tcx, t, Some(count)); @@ -3532,7 +3532,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.expr_ty(&**e) } }; - err_field = err_field || ty::type_is_error(t); + err_field = err_field || t.references_error(); t }).collect(); if err_field { @@ -3592,7 +3592,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, // the resulting structure type. This is needed to handle type // parameters correctly. let actual_structure_type = fcx.expr_ty(&*expr); - if !ty::type_is_error(actual_structure_type) { + if !actual_structure_type.references_error() { let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path); match fcx.mk_subty(false, infer::Misc(path.span), @@ -3630,9 +3630,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let base_t = fcx.expr_ty(&**base); let idx_t = fcx.expr_ty(&**idx); - if ty::type_is_error(base_t) { + if base_t.references_error() { fcx.write_ty(id, base_t); - } else if ty::type_is_error(idx_t) { + } else if idx_t.references_error() { fcx.write_ty(id, idx_t); } else { let base_t = structurally_resolved_type(fcx, expr.span, base_t); @@ -3671,8 +3671,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, (Some(ty), None) | (None, Some(ty)) => { Some(ty) } - (Some(t_start), Some(t_end)) if (ty::type_is_error(t_start) || - ty::type_is_error(t_end)) => { + (Some(t_start), Some(t_end)) if (t_start.references_error() || + t_end.references_error()) => { Some(fcx.tcx().types.err) } (Some(t_start), Some(t_end)) => { @@ -3690,7 +3690,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, // some bounds, then we'll need to check `t_start` against them here. let range_type = match idx_type { - Some(idx_type) if ty::type_is_error(idx_type) => { + Some(idx_type) if idx_type.references_error() => { fcx.tcx().types.err } Some(idx_type) => { @@ -3765,7 +3765,7 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>, node_id: ast::NodeId) -> bool { match def { def::DefAssociatedConst(..) => { - if ty::type_has_params(ty) || ty::type_has_self(ty) { + if ty.has_param_types() || ty.has_self_ty() { span_err!(fcx.sess(), span, E0329, "Associated consts cannot depend \ on type parameters or Self."); @@ -3933,7 +3933,7 @@ pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) if let Some(ref init) = local.init { check_decl_initializer(fcx, local, &**init); let init_ty = fcx.expr_ty(&**init); - if ty::type_is_error(init_ty) { + if init_ty.references_error() { fcx.write_ty(local.id, init_ty); } } @@ -3944,7 +3944,7 @@ pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local) }; _match::check_pat(&pcx, &*local.pat, t); let pat_ty = fcx.node_ty(local.pat.id); - if ty::type_is_error(pat_ty) { + if pat_ty.references_error() { fcx.write_ty(local.id, pat_ty); } } @@ -3961,7 +3961,7 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) { check_decl_local(fcx, &**l); let l_t = fcx.node_ty(l.id); saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t); - saw_err = saw_err || ty::type_is_error(l_t); + saw_err = saw_err || l_t.references_error(); } ast::DeclItem(_) => {/* ignore for now */ } } @@ -3972,14 +3972,14 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) { check_expr_has_type(fcx, &**expr, ty::mk_nil(fcx.tcx())); let expr_ty = fcx.expr_ty(&**expr); saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty); - saw_err = saw_err || ty::type_is_error(expr_ty); + saw_err = saw_err || expr_ty.references_error(); } ast::StmtSemi(ref expr, id) => { node_id = id; check_expr(fcx, &**expr); let expr_ty = fcx.expr_ty(&**expr); saw_bot |= fcx.infcx().type_var_diverges(expr_ty); - saw_err |= ty::type_is_error(expr_ty); + saw_err |= expr_ty.references_error(); } ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro") } @@ -3997,7 +3997,7 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) { pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) { check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil(fcx.tcx()))); let blkty = fcx.node_ty(blk.id); - if ty::type_is_error(blkty) { + if blkty.references_error() { fcx.write_error(blk.id); } else { let nilty = ty::mk_nil(fcx.tcx()); @@ -4041,7 +4041,7 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, warned = true; } any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty); - any_err = any_err || ty::type_is_error(s_ty); + any_err = any_err || s_ty.references_error(); } match blk.expr { None => if any_err { @@ -4184,7 +4184,7 @@ pub fn check_instantiable(tcx: &ty::ctxt, pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) { let t = ty::node_id_to_type(tcx, id); - if ty::type_needs_subst(t) { + if t.needs_subst() { span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic"); return; } @@ -4874,7 +4874,7 @@ fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let alternative = f(); // If not, error. - if ty::type_is_ty_var(alternative) || ty::type_is_error(alternative) { + if ty::type_is_ty_var(alternative) || alternative.references_error() { fcx.type_error_message(sp, |_actual| { "the type of this value must be known in this context".to_string() }, ty, None); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index a5e4e0fab5963..8aeef7f03b4e8 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -21,7 +21,7 @@ use super::{ structurally_resolved_type, }; use middle::traits; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use syntax::ast; use syntax::ast_util; use syntax::parse::token; @@ -46,7 +46,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, fcx.write_nil(expr.id); } else { // error types are considered "builtin" - assert!(!ty::type_is_error(lhs_ty) || !ty::type_is_error(rhs_ty)); + assert!(!lhs_ty.references_error() || !rhs_ty.references_error()); span_err!(tcx.sess, lhs_expr.span, E0368, "binary assignment operation `{}=` cannot be applied to types `{}` and `{}`", ast_util::binop_to_string(op.node), @@ -228,7 +228,7 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, Ok(return_ty) => return_ty, Err(()) => { // error types are considered "builtin" - if !ty::type_is_error(lhs_ty) { + if !lhs_ty.references_error() { span_err!(fcx.tcx().sess, lhs_expr.span, E0369, "binary operation `{}` cannot be applied to type `{}`", ast_util::binop_to_string(op.node), @@ -428,20 +428,20 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, } BinOpCategory::Shift => { - ty::type_is_error(lhs) || ty::type_is_error(rhs) || + lhs.references_error() || rhs.references_error() || ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) } BinOpCategory::Math => { - ty::type_is_error(lhs) || ty::type_is_error(rhs) || + lhs.references_error() || rhs.references_error() || ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) || ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) } BinOpCategory::Bitwise => { - ty::type_is_error(lhs) || ty::type_is_error(rhs) || + lhs.references_error() || rhs.references_error() || ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) || ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) || @@ -449,7 +449,7 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, } BinOpCategory::Comparison => { - ty::type_is_error(lhs) || ty::type_is_error(rhs) || + lhs.references_error() || rhs.references_error() || ty::type_is_scalar(lhs) && ty::type_is_scalar(rhs) || ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a96e7864fe679..4441afcec5f29 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -91,7 +91,7 @@ use middle::mem_categorization as mc; use middle::region::CodeExtent; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall}; +use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall, HasTypeFlags}; use middle::infer::{self, GenericKind}; use middle::pat_util; @@ -262,7 +262,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { /// Try to resolve the type for the given node. pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> Ty<'tcx> { let ty_unadjusted = self.resolve_node_type(expr.id); - if ty::type_is_error(ty_unadjusted) { + if ty_unadjusted.references_error() { ty_unadjusted } else { let tcx = self.fcx.tcx(); @@ -1172,7 +1172,7 @@ fn link_region_from_node_type<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, id, mutbl, cmt_borrowed); let rptr_ty = rcx.resolve_node_type(id); - if !ty::type_is_error(rptr_ty) { + if !rptr_ty.references_error() { let tcx = rcx.fcx.ccx.tcx; debug!("rptr_ty={}", rptr_ty); let r = ty::ty_region(tcx, span, rptr_ty); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 8feecd1561311..d968d854bb365 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -105,7 +105,7 @@ pub use rustc::util; use middle::def; use middle::infer; use middle::subst; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, HasTypeFlags}; use rustc::ast_map; use session::config; use util::common::time; @@ -148,7 +148,7 @@ pub struct CrateCtxt<'a, 'tcx: 'a> { // Functions that write types into the node type table fn write_ty_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) { debug!("write_ty_to_tcx({}, {:?})", node_id, ty); - assert!(!ty::type_needs_infer(ty)); + assert!(!ty.needs_infer()); tcx.node_type_insert(node_id, ty); } @@ -160,7 +160,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id, item_substs); - assert!(item_substs.substs.types.all(|t| !ty::type_needs_infer(*t))); + assert!(!item_substs.substs.types.needs_infer()); tcx.item_substs.borrow_mut().insert(node_id, item_substs); } From 59935f70e01b854bd1f43baa1915af38c37bcef2 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 24 Jun 2015 08:24:13 +0300 Subject: [PATCH 10/36] rustc: move some functions in middle::ty working on Ty to methods. --- src/librustc/middle/cast.rs | 4 +- src/librustc/middle/cfg/construct.rs | 6 +- src/librustc/middle/check_match.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 2 +- src/librustc/middle/liveness.rs | 13 +- src/librustc/middle/mem_categorization.rs | 14 +- src/librustc/middle/traits/object_safety.rs | 2 +- src/librustc/middle/traits/project.rs | 2 +- src/librustc/middle/traits/select.rs | 8 +- src/librustc/middle/ty.rs | 483 ++++++++---------- src/librustc/util/ppaux.rs | 2 +- src/librustc_trans/trans/_match.rs | 11 +- src/librustc_trans/trans/attributes.rs | 4 +- src/librustc_trans/trans/base.rs | 30 +- src/librustc_trans/trans/callee.rs | 8 +- src/librustc_trans/trans/common.rs | 10 +- src/librustc_trans/trans/consts.rs | 30 +- src/librustc_trans/trans/datum.rs | 2 +- .../trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/debuginfo/mod.rs | 2 +- .../trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/trans/expr.rs | 36 +- src/librustc_trans/trans/foreign.rs | 8 +- src/librustc_trans/trans/glue.rs | 4 +- src/librustc_trans/trans/tvec.rs | 2 +- src/librustc_trans/trans/type_of.rs | 18 +- src/librustc_typeck/check/_match.rs | 14 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 4 +- src/librustc_typeck/check/mod.rs | 43 +- src/librustc_typeck/check/op.rs | 37 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/check/wf.rs | 2 +- src/librustc_typeck/check/writeback.rs | 2 +- src/librustc_typeck/collect.rs | 11 +- .../constrained_type_params.rs | 2 +- 37 files changed, 395 insertions(+), 439 deletions(-) diff --git a/src/librustc/middle/cast.rs b/src/librustc/middle/cast.rs index 34088d5f13ee7..ec1fd67616b81 100644 --- a/src/librustc/middle/cast.rs +++ b/src/librustc/middle/cast.rs @@ -66,8 +66,8 @@ impl<'tcx> CastTy<'tcx> { ty::TyInt(_) => Some(CastTy::Int(IntTy::I)), ty::TyUint(u) => Some(CastTy::Int(IntTy::U(u))), ty::TyFloat(_) => Some(CastTy::Float), - ty::TyEnum(..) if ty::type_is_c_like_enum( - tcx, t) => Some(CastTy::Int(IntTy::CEnum)), + ty::TyEnum(..) if t.is_c_like_enum(tcx) => + Some(CastTy::Int(IntTy::CEnum)), ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)), ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)), ty::TyBareFn(..) => Some(CastTy::FnPtr), diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index e782a03176d67..71c3ffb862840 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -411,14 +411,14 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { func_or_rcvr: &ast::Expr, args: I) -> CFGIndex { let method_call = ty::MethodCall::expr(call_expr.id); - let return_ty = ty::ty_fn_ret(match self.tcx.method_map.borrow().get(&method_call) { + let fn_ty = match self.tcx.method_map.borrow().get(&method_call) { Some(method) => method.ty, None => ty::expr_ty_adjusted(self.tcx, func_or_rcvr) - }); + }; let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); let ret = self.straightline(call_expr, func_or_rcvr_exit, args); - if return_ty.diverges() { + if fn_ty.fn_ret().diverges() { self.add_unreachable_node() } else { ret diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 1ec6e0d6d80d0..1f137a22b1d2c 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -656,7 +656,9 @@ fn is_useful(cx: &MatchCheckCtxt, let left_ty = ty::pat_ty(cx.tcx, &*real_pat); match real_pat.node { - ast::PatIdent(ast::BindByRef(..), _, _) => ty::deref(left_ty, false).unwrap().ty, + ast::PatIdent(ast::BindByRef(..), _, _) => { + left_ty.builtin_deref(false).unwrap().ty + } _ => left_ty, } }; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index ab67c68be124b..2b685f801d7f7 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -821,7 +821,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // the method call infrastructure should have // replaced all late-bound regions with variables: - let self_ty = ty::ty_fn_sig(method_ty).input(0); + let self_ty = method_ty.fn_sig().input(0); let self_ty = ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap(); let (m, r) = match self_ty.sty { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 9bcc251725c00..aa329d1fab6ca 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1137,9 +1137,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } ast::ExprCall(ref f, ref args) => { - let diverges = !self.ir.tcx.is_method_call(expr.id) && { - ty::ty_fn_ret(ty::expr_ty_adjusted(self.ir.tcx, &**f)).diverges() - }; + let diverges = !self.ir.tcx.is_method_call(expr.id) && + ty::expr_ty_adjusted(self.ir.tcx, &**f).fn_ret().diverges(); let succ = if diverges { self.s.exit_ln } else { @@ -1152,8 +1151,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ast::ExprMethodCall(_, _, ref args) => { let method_call = ty::MethodCall::expr(expr.id); let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty; - let diverges = ty::ty_fn_ret(method_ty).diverges(); - let succ = if diverges { + let succ = if method_ty.fn_ret().diverges() { self.s.exit_ln } else { succ @@ -1500,8 +1498,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match fn_ty.sty { ty::TyClosure(closure_def_id, substs) => self.ir.tcx.closure_type(closure_def_id, substs).sig.output(), - _ => - ty::ty_fn_ret(fn_ty), + _ => fn_ty.fn_ret() } } @@ -1523,7 +1520,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ty::FnConverging(t_ret) if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() => { - if ty::type_is_nil(t_ret) { + if t_ret.is_nil() { // for nil return types, it is ok to not return a value expl. } else { let ends_with_stmt = match body.expr { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ca8de74b35bda..6e3a36d85c6ae 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -426,7 +426,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // a bind-by-ref means that the base_ty will be the type of the ident itself, // but what we want here is the type of the underlying value being borrowed. // So peel off one-level, turning the &T into T. - match ty::deref(base_ty, false) { + match base_ty.builtin_deref(false) { Some(t) => t.ty, None => { return Err(()); } } @@ -928,13 +928,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Some(method_ty) => { let ref_ty = ty::no_late_bound_regions( - self.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap(); + self.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); self.cat_rvalue_node(node.id(), node.span(), ref_ty) } None => base_cmt }; let base_cmt_ty = base_cmt.ty; - match ty::deref(base_cmt_ty, true) { + match base_cmt_ty.builtin_deref(true) { Some(mt) => { let ret = self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty, @@ -1023,11 +1023,11 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty); // FIXME(#20649) -- why are we using the `self_ty` as the element type...? - let self_ty = ty::ty_fn_sig(method_ty).input(0); + let self_ty = method_ty.fn_sig().input(0); ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap() } None => { - match ty::array_element_ty(self.tcx(), base_cmt.ty) { + match base_cmt.ty.builtin_index() { Some(ty) => ty, None => { return Err(()); @@ -1081,7 +1081,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { span:elt.span(), cat:cat_deref(base_cmt.clone(), 0, ptr), mutbl:m, - ty: match ty::deref(base_cmt.ty, false) { + ty: match base_cmt.ty.builtin_deref(false) { Some(mt) => mt.ty, None => self.tcx().sess.bug("Found non-derefable type") }, @@ -1375,7 +1375,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // types are generated by method resolution and always have // all late-bound regions fully instantiated, so we just want // to skip past the binder. - ty::no_late_bound_regions(self.tcx(), &ty::ty_fn_ret(method_ty)) + ty::no_late_bound_regions(self.tcx(), &method_ty.fn_ret()) .unwrap() .unwrap() // overloaded ops do not diverge, either } diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index afb30716c3669..db7b91952a885 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -306,7 +306,7 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &ty::ctxt<'tcx>, let mut supertraits: Option>> = None; let mut error = false; - ty::maybe_walk_ty(ty, |ty| { + ty.maybe_walk(|ty| { match ty.sty { ty::TyParam(ref param_ty) => { if param_ty.space == SelfSpace { diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 0203a860beb42..6af10f06a8015 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -773,7 +773,7 @@ fn confirm_fn_pointer_candidate<'cx,'tcx>( -> (Ty<'tcx>, Vec>) { let fn_type = selcx.infcx().shallow_resolve(fn_type); - let sig = ty::ty_fn_sig(fn_type); + let sig = fn_type.fn_sig(); confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes) } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index fcc6365dab5a7..5bac1811ee130 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -540,7 +540,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // terms of `Fn` etc, but we could probably make this more // precise still. let input_types = stack.fresh_trait_ref.0.input_types(); - let unbound_input_types = input_types.iter().any(|&t| ty::type_is_fresh(t)); + let unbound_input_types = input_types.iter().any(|ty| ty.is_fresh()); if unbound_input_types && (self.intercrate || @@ -2334,7 +2334,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // ok to skip binder; it is reintroduced below let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); - let sig = ty::ty_fn_sig(self_ty); + let sig = self_ty.fn_sig(); let trait_ref = util::closure_trait_ref_and_return_type(self.tcx(), obligation.predicate.def_id(), @@ -2536,7 +2536,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(Unimplemented); }; let mut ty_params = vec![]; - ty::walk_ty(field, |ty| { + for ty in field.walk() { if let ty::TyParam(p) = ty.sty { assert!(p.space == TypeSpace); let idx = p.idx as usize; @@ -2544,7 +2544,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty_params.push(idx); } } - }); + } if ty_params.is_empty() { return Err(Unimplemented); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 47d66db88b04a..8470d9d5f819e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3541,28 +3541,20 @@ impl<'tcx> TyS<'tcx> { _ => false, } } -} - -pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) - where F: FnMut(Ty<'tcx>), -{ - for ty in ty_root.walk() { - f(ty); - } -} -/// Walks `ty` and any types appearing within `ty`, invoking the -/// callback `f` on each type. If the callback returns false, then the -/// children of the current type are ignored. -/// -/// Note: prefer `ty.walk()` where possible. -pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F) - where F : FnMut(Ty<'tcx>) -> bool -{ - let mut walker = ty_root.walk(); - while let Some(ty) = walker.next() { - if !f(ty) { - walker.skip_current_subtree(); + /// Walks `ty` and any types appearing within `ty`, invoking the + /// callback `f` on each type. If the callback returns false, then the + /// children of the current type are ignored. + /// + /// Note: prefer `ty.walk()` where possible. + pub fn maybe_walk(&'tcx self, mut f: F) + where F : FnMut(Ty<'tcx>) -> bool + { + let mut walker = self.walk(); + while let Some(ty) = walker.next() { + if !f(ty) { + walker.skip_current_subtree(); + } } } } @@ -3613,128 +3605,126 @@ impl<'tcx> ItemSubsts<'tcx> { } // Type utilities - -pub fn type_is_nil(ty: Ty) -> bool { - match ty.sty { - TyTuple(ref tys) => tys.is_empty(), - _ => false +impl<'tcx> TyS<'tcx> { + pub fn is_nil(&self) -> bool { + match self.sty { + TyTuple(ref tys) => tys.is_empty(), + _ => false + } } -} -pub fn type_is_ty_var(ty: Ty) -> bool { - match ty.sty { - TyInfer(TyVar(_)) => true, - _ => false + pub fn is_ty_var(&self) -> bool { + match self.sty { + TyInfer(TyVar(_)) => true, + _ => false + } } -} -pub fn type_is_bool(ty: Ty) -> bool { ty.sty == TyBool } + pub fn is_bool(&self) -> bool { self.sty == TyBool } -pub fn type_is_self(ty: Ty) -> bool { - match ty.sty { - TyParam(ref p) => p.space == subst::SelfSpace, - _ => false + pub fn is_self(&self) -> bool { + match self.sty { + TyParam(ref p) => p.space == subst::SelfSpace, + _ => false + } } -} -fn type_is_slice(ty: Ty) -> bool { - match ty.sty { - TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty { - TySlice(_) | TyStr => true, - _ => false, - }, - _ => false + fn is_slice(&self) -> bool { + match self.sty { + TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty { + TySlice(_) | TyStr => true, + _ => false, + }, + _ => false + } } -} -pub fn type_is_structural(ty: Ty) -> bool { - match ty.sty { - TyStruct(..) | TyTuple(_) | TyEnum(..) | - TyArray(..) | TyClosure(..) => true, - _ => type_is_slice(ty) | type_is_trait(ty) + pub fn is_structural(&self) -> bool { + match self.sty { + TyStruct(..) | TyTuple(_) | TyEnum(..) | + TyArray(..) | TyClosure(..) => true, + _ => self.is_slice() | self.is_trait() + } } -} -pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool { - match ty.sty { - TyStruct(did, _) => lookup_simd(cx, did), - _ => false + pub fn is_simd(&self, cx: &ctxt) -> bool { + match self.sty { + TyStruct(did, _) => lookup_simd(cx, did), + _ => false + } } -} -pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.sty { - TyArray(ty, _) | TySlice(ty) => ty, - TyStr => mk_mach_uint(cx, ast::TyU8), - _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}", - ty)), + pub fn sequence_element_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { + match self.sty { + TyArray(ty, _) | TySlice(ty) => ty, + TyStr => mk_mach_uint(cx, ast::TyU8), + _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}", + self)), + } } -} -pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.sty { - TyStruct(did, substs) => { - let fields = lookup_struct_fields(cx, did); - lookup_field_type(cx, did, fields[0].id, substs) + pub fn simd_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { + match self.sty { + TyStruct(did, substs) => { + let fields = lookup_struct_fields(cx, did); + lookup_field_type(cx, did, fields[0].id, substs) + } + _ => panic!("simd_type called on invalid type") } - _ => panic!("simd_type called on invalid type") } -} -pub fn simd_size(cx: &ctxt, ty: Ty) -> usize { - match ty.sty { - TyStruct(did, _) => { - let fields = lookup_struct_fields(cx, did); - fields.len() + pub fn simd_size(&self, cx: &ctxt) -> usize { + match self.sty { + TyStruct(did, _) => { + let fields = lookup_struct_fields(cx, did); + fields.len() + } + _ => panic!("simd_size called on invalid type") } - _ => panic!("simd_size called on invalid type") } -} -pub fn type_is_region_ptr(ty: Ty) -> bool { - match ty.sty { - TyRef(..) => true, - _ => false + pub fn is_region_ptr(&self) -> bool { + match self.sty { + TyRef(..) => true, + _ => false + } } -} -pub fn type_is_unsafe_ptr(ty: Ty) -> bool { - match ty.sty { - TyRawPtr(_) => return true, - _ => return false + pub fn is_unsafe_ptr(&self) -> bool { + match self.sty { + TyRawPtr(_) => return true, + _ => return false + } } -} -pub fn type_is_unique(ty: Ty) -> bool { - match ty.sty { - TyBox(_) => true, - _ => false + pub fn is_unique(&self) -> bool { + match self.sty { + TyBox(_) => true, + _ => false + } } -} -/* - A scalar type is one that denotes an atomic datum, with no sub-components. - (A TyRawPtr is scalar because it represents a non-managed pointer, so its - contents are abstract to rustc.) -*/ -pub fn type_is_scalar(ty: Ty) -> bool { - match ty.sty { - TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) | - TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) | - TyBareFn(..) | TyRawPtr(_) => true, - _ => false + /* + A scalar type is one that denotes an atomic datum, with no sub-components. + (A TyRawPtr is scalar because it represents a non-managed pointer, so its + contents are abstract to rustc.) + */ + pub fn is_scalar(&self) -> bool { + match self.sty { + TyBool | TyChar | TyInt(_) | TyFloat(_) | TyUint(_) | + TyInfer(IntVar(_)) | TyInfer(FloatVar(_)) | + TyBareFn(..) | TyRawPtr(_) => true, + _ => false + } } -} -/// Returns true if this type is a floating point type and false otherwise. -pub fn type_is_floating_point(ty: Ty) -> bool { - match ty.sty { - TyFloat(_) | - TyInfer(FloatVar(_)) => - true, - - _ => - false, + /// Returns true if this type is a floating point type and false otherwise. + pub fn is_floating_point(&self) -> bool { + match self.sty { + TyFloat(_) | + TyInfer(FloatVar(_)) => true, + _ => false, + } } } @@ -4508,141 +4498,124 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) r } -pub fn type_is_trait(ty: Ty) -> bool { - match ty.sty { - TyTrait(..) => true, - _ => false - } -} - -pub fn type_is_integral(ty: Ty) -> bool { - match ty.sty { - TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true, - _ => false +impl<'tcx> TyS<'tcx> { + pub fn is_trait(&self) -> bool { + match self.sty { + TyTrait(..) => true, + _ => false + } } -} -pub fn type_is_fresh(ty: Ty) -> bool { - match ty.sty { - TyInfer(FreshTy(_)) => true, - TyInfer(FreshIntTy(_)) => true, - TyInfer(FreshFloatTy(_)) => true, - _ => false + pub fn is_integral(&self) -> bool { + match self.sty { + TyInfer(IntVar(_)) | TyInt(_) | TyUint(_) => true, + _ => false + } } -} -pub fn type_is_uint(ty: Ty) -> bool { - match ty.sty { - TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true, - _ => false + pub fn is_fresh(&self) -> bool { + match self.sty { + TyInfer(FreshTy(_)) => true, + TyInfer(FreshIntTy(_)) => true, + TyInfer(FreshFloatTy(_)) => true, + _ => false + } } -} -pub fn type_is_char(ty: Ty) -> bool { - match ty.sty { - TyChar => true, - _ => false + pub fn is_uint(&self) -> bool { + match self.sty { + TyInfer(IntVar(_)) | TyUint(ast::TyUs) => true, + _ => false + } } -} -pub fn type_is_bare_fn(ty: Ty) -> bool { - match ty.sty { - TyBareFn(..) => true, - _ => false + pub fn is_char(&self) -> bool { + match self.sty { + TyChar => true, + _ => false + } } -} -pub fn type_is_bare_fn_item(ty: Ty) -> bool { - match ty.sty { - TyBareFn(Some(_), _) => true, - _ => false + pub fn is_bare_fn(&self) -> bool { + match self.sty { + TyBareFn(..) => true, + _ => false + } } -} -pub fn type_is_fp(ty: Ty) -> bool { - match ty.sty { - TyInfer(FloatVar(_)) | TyFloat(_) => true, - _ => false + pub fn is_bare_fn_item(&self) -> bool { + match self.sty { + TyBareFn(Some(_), _) => true, + _ => false + } } -} - -pub fn type_is_numeric(ty: Ty) -> bool { - return type_is_integral(ty) || type_is_fp(ty); -} -pub fn type_is_signed(ty: Ty) -> bool { - match ty.sty { - TyInt(_) => true, - _ => false + pub fn is_fp(&self) -> bool { + match self.sty { + TyInfer(FloatVar(_)) | TyFloat(_) => true, + _ => false + } } -} -pub fn type_is_machine(ty: Ty) -> bool { - match ty.sty { - TyInt(ast::TyIs) | TyUint(ast::TyUs) => false, - TyInt(..) | TyUint(..) | TyFloat(..) => true, - _ => false + pub fn is_numeric(&self) -> bool { + self.is_integral() || self.is_fp() } -} -// Whether a type is enum like, that is an enum type with only nullary -// constructors -pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool { - match ty.sty { - TyEnum(did, _) => { - let variants = enum_variants(cx, did); - if variants.is_empty() { - false - } else { - variants.iter().all(|v| v.args.is_empty()) - } + pub fn is_signed(&self) -> bool { + match self.sty { + TyInt(_) => true, + _ => false } - _ => false } -} -// Returns the type and mutability of *ty. -// -// The parameter `explicit` indicates if this is an *explicit* dereference. -// Some types---notably unsafe ptrs---can only be dereferenced explicitly. -pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option> { - match ty.sty { - TyBox(ty) => { - Some(mt { - ty: ty, - mutbl: ast::MutImmutable, - }) - }, - TyRef(_, mt) => Some(mt), - TyRawPtr(mt) if explicit => Some(mt), - _ => None + pub fn is_machine(&self) -> bool { + match self.sty { + TyInt(ast::TyIs) | TyUint(ast::TyUs) => false, + TyInt(..) | TyUint(..) | TyFloat(..) => true, + _ => false + } } -} -pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.sty { - TyBox(ty) => ty, - TyRef(_, mt) | TyRawPtr(mt) => mt.ty, - _ => ty + // Whether a type is enum like, that is an enum type with only nullary + // constructors + pub fn is_c_like_enum(&self, cx: &ctxt) -> bool { + match self.sty { + TyEnum(did, _) => { + let variants = enum_variants(cx, did); + if variants.is_empty() { + false + } else { + variants.iter().all(|v| v.args.is_empty()) + } + } + _ => false + } } -} -// Returns the type of ty[i] -pub fn index<'tcx>(ty: Ty<'tcx>) -> Option> { - match ty.sty { - TyArray(ty, _) | TySlice(ty) => Some(ty), - _ => None + // Returns the type and mutability of *ty. + // + // The parameter `explicit` indicates if this is an *explicit* dereference. + // Some types---notably unsafe ptrs---can only be dereferenced explicitly. + pub fn builtin_deref(&self, explicit: bool) -> Option> { + match self.sty { + TyBox(ty) => { + Some(mt { + ty: ty, + mutbl: ast::MutImmutable, + }) + }, + TyRef(_, mt) => Some(mt), + TyRawPtr(mt) if explicit => Some(mt), + _ => None + } } -} -// Returns the type of elements contained within an 'array-like' type. -// This is exactly the same as the above, except it supports strings, -// which can't actually be indexed. -pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option> { - match ty.sty { - TyArray(ty, _) | TySlice(ty) => Some(ty), - TyStr => Some(tcx.types.u8), - _ => None + // Returns the type of ty[i] + pub fn builtin_index(&self) -> Option> { + match self.sty { + TyArray(ty, _) | TySlice(ty) => Some(ty), + _ => None + } } } @@ -4725,50 +4698,36 @@ pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts } } -pub fn fn_is_variadic(fty: Ty) -> bool { - match fty.sty { - TyBareFn(_, ref f) => f.sig.0.variadic, - ref s => { - panic!("fn_is_variadic() called on non-fn type: {:?}", s) +impl<'tcx> TyS<'tcx> { + pub fn fn_sig(&self) -> &'tcx PolyFnSig<'tcx> { + match self.sty { + TyBareFn(_, ref f) => &f.sig, + _ => panic!("Ty::fn_sig() called on non-fn type: {:?}", self) } } -} -pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> { - match fty.sty { - TyBareFn(_, ref f) => &f.sig, - ref s => { - panic!("ty_fn_sig() called on non-fn type: {:?}", s) + /// Returns the ABI of the given function. + pub fn fn_abi(&self) -> abi::Abi { + match self.sty { + TyBareFn(_, ref f) => f.abi, + _ => panic!("Ty::fn_abi() called on non-fn type"), } } -} -/// Returns the ABI of the given function. -pub fn ty_fn_abi(fty: Ty) -> abi::Abi { - match fty.sty { - TyBareFn(_, ref f) => f.abi, - _ => panic!("ty_fn_abi() called on non-fn type"), + // Type accessors for substructures of types + pub fn fn_args(&self) -> ty::Binder>> { + self.fn_sig().inputs() } -} - -// Type accessors for substructures of types -pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder>> { - ty_fn_sig(fty).inputs() -} -pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder> { - match fty.sty { - TyBareFn(_, ref f) => f.sig.output(), - ref s => { - panic!("ty_fn_ret() called on non-fn type: {:?}", s) - } + pub fn fn_ret(&self) -> Binder> { + self.fn_sig().output() } -} -pub fn is_fn_ty(fty: Ty) -> bool { - match fty.sty { - TyBareFn(..) => true, - _ => false + pub fn is_fn(&self) -> bool { + match self.sty { + TyBareFn(..) => true, + _ => false + } } } @@ -4935,12 +4894,12 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>, // regions fully instantiated and coverge. let fn_ret = ty::no_late_bound_regions(cx, - &ty_fn_ret(method_ty)).unwrap(); + &method_ty.fn_ret()).unwrap(); adjusted_ty = fn_ret.unwrap(); } None => {} } - match deref(adjusted_ty, true) { + match adjusted_ty.builtin_deref(true) { Some(mt) => { adjusted_ty = mt.ty; } None => { cx.sess.span_bug( @@ -5578,7 +5537,7 @@ impl<'tcx> VariantInfo<'tcx> { let arg_tys = if !args.is_empty() { // the regions in the argument types come from the // enum def'n, and hence will all be early bound - ty::no_late_bound_regions(cx, &ty_fn_args(ctor_ty)).unwrap() + ty::no_late_bound_regions(cx, &ctor_ty.fn_args()).unwrap() } else { Vec::new() }; @@ -6595,7 +6554,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) - helper(tcx, output, svh, state); } }; - maybe_walk_ty(ty, |ty| { + ty.maybe_walk(|ty| { match ty.sty { TyBool => byte!(2), TyChar => byte!(3), @@ -6939,7 +6898,7 @@ pub enum ExplicitSelfCategory { /// types, nor does it resolve fictitious types. pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, ty: Ty) { - walk_ty(ty, |ty| { + for ty in ty.walk() { match ty.sty { TyRef(region, _) => { accumulator.push(*region) @@ -6972,7 +6931,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, TyError => { } } - }); + } fn accum_substs(accumulator: &mut Vec, substs: &Substs) { match substs.regions { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fcff4363fd603..71f3675aecee1 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -51,7 +51,7 @@ fn fn_sig(f: &mut fmt::Formatter, match output { ty::FnConverging(ty) => { - if !ty::type_is_nil(ty) { + if !ty.is_nil() { try!(write!(f, " -> {}", ty)); } Ok(()) diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 4df10ee3d098e..dd47a3a871842 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -662,7 +662,12 @@ fn bind_subslice_pat(bcx: Block, offset_right: usize) -> ValueRef { let _icx = push_ctxt("match::bind_subslice_pat"); let vec_ty = node_id_type(bcx, pat_id); - let unit_ty = ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty)); + let vec_ty_contents = match vec_ty.sty { + ty::TyBox(ty) => ty, + ty::TyRef(_, mt) | ty::TyRawPtr(mt) => mt.ty, + _ => vec_ty + }; + let unit_ty = vec_ty_contents.sequence_element_type(bcx.tcx()); let vec_datum = match_datum(val, vec_ty); let (base, len) = vec_datum.get_vec_base_and_len(bcx); @@ -836,7 +841,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, } let _icx = push_ctxt("compare_values"); - if ty::type_is_scalar(rhs_t) { + if rhs_t.is_scalar() { let cmp = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq, debug_loc); return Result::new(cx, cmp); } @@ -1140,7 +1145,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, match opts[0] { ConstantValue(..) | ConstantRange(..) => { test_val = load_if_immediate(bcx, val, left_ty); - kind = if ty::type_is_integral(left_ty) { + kind = if left_ty.is_integral() { Switch } else { Compare diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index 39e5670c975e0..db29a43afce77 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -262,7 +262,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx attrs.arg(idx, llvm::DereferenceableAttribute(llsz)); } else { attrs.arg(idx, llvm::NonNullAttribute); - if ty::type_is_trait(inner) { + if inner.is_trait() { attrs.arg(idx + 1, llvm::NonNullAttribute); } } @@ -291,7 +291,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx attrs.arg(idx, llvm::DereferenceableAttribute(llsz)); } else { attrs.arg(idx, llvm::NonNullAttribute); - if ty::type_is_trait(mt.ty) { + if mt.ty.is_trait() { attrs.arg(idx + 1, llvm::NonNullAttribute); } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index c7288bb1eef80..81951600a3a33 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -40,7 +40,7 @@ use middle::cfg; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; -use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size, HasTypeFlags}; +use middle::ty::{self, Ty, ClosureTyper, HasTypeFlags}; use rustc::ast_map; use session::config::{self, NoDebugInfo}; use session::Session; @@ -443,11 +443,11 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, } ty::TyArray(_, n) => { let (base, len) = tvec::get_fixed_base_and_len(cx, data_ptr, n); - let unit_ty = ty::sequence_element_type(cx.tcx(), t); + let unit_ty = t.sequence_element_type(cx.tcx()); cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f); } ty::TySlice(_) | ty::TyStr => { - let unit_ty = ty::sequence_element_type(cx.tcx(), t); + let unit_ty = t.sequence_element_type(cx.tcx()); cx = tvec::iter_vec_raw(cx, data_ptr, unit_ty, info.unwrap(), f); } ty::TyTuple(ref args) => { @@ -626,9 +626,9 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>( let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false); (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false) } - ty::TyStruct(_, _) if type_is_simd(cx.tcx(), rhs_t) => { + ty::TyStruct(_, _) if rhs_t.is_simd(cx.tcx()) => { let mut res = C_bool(cx.ccx(), false); - for i in 0 .. simd_size(cx.tcx(), rhs_t) { + for i in 0 .. rhs_t.simd_size(cx.tcx()) { res = Or(cx, res, IsNull(cx, ExtractElement(cx, rhs, C_int(cx.ccx(), i as i64))), debug_loc); @@ -805,13 +805,13 @@ pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, } } - let val = if ty::type_is_bool(t) { + let val = if t.is_bool() { LoadRangeAssert(cx, ptr, 0, 2, llvm::False) - } else if ty::type_is_char(t) { + } else if t.is_char() { // a char is a Unicode codepoint, and so takes values from 0 // to 0x10FFFF inclusive only. LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False) - } else if (ty::type_is_region_ptr(t) || ty::type_is_unique(t)) + } else if (t.is_region_ptr() || t.is_unique()) && !common::type_is_fat_ptr(cx.tcx(), t) { LoadNonNull(cx, ptr) } else { @@ -839,7 +839,7 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t } pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef { - if ty::type_is_bool(ty) { + if ty.is_bool() { ZExt(bcx, val, Type::i8(bcx.ccx())) } else { val @@ -847,7 +847,7 @@ pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef { } pub fn to_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef { - if ty::type_is_bool(ty) { + if ty.is_bool() { Trunc(bcx, val, Type::i1(bcx.ccx())) } else { val @@ -953,7 +953,7 @@ pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>) { let _icx = push_ctxt("memcpy_ty"); let ccx = bcx.ccx(); - if ty::type_is_structural(t) { + if t.is_structural() { let llty = type_of::type_of(ccx, t); let llsz = llsize_of(ccx, llty); let llalign = type_of::align_of(ccx, t); @@ -1669,8 +1669,8 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("trans_fn(param_substs={:?})", param_substs); let _icx = push_ctxt("trans_fn"); let fn_ty = ty::node_id_to_type(ccx.tcx(), id); - let output_type = ty::erase_late_bound_regions(ccx.tcx(), &ty::ty_fn_ret(fn_ty)); - let abi = ty::ty_fn_abi(fn_ty); + let output_type = ty::erase_late_bound_regions(ccx.tcx(), &fn_ty.fn_ret()); + let abi = fn_ty.fn_abi(); trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi, closure::ClosureEnv::NotClosure); } @@ -1800,7 +1800,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx let arg_tys = ty::erase_late_bound_regions( - ccx.tcx(), &ty::ty_fn_args(ctor_ty)); + ccx.tcx(), &ctor_ty.fn_args()); let arg_datums = create_datums_for_fn_args(bcx, &arg_tys[..]); @@ -2334,7 +2334,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { unsafe { // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected - let llty = if ty::type_is_bool(ty) { + let llty = if ty.is_bool() { llvm::LLVMInt8TypeInContext(ccx.llcx()) } else { llvm::LLVMTypeOf(v) diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index c036078f42f55..3b7a92c09ec3f 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -917,7 +917,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>( { let args = ty::erase_late_bound_regions( - bcx.tcx(), &ty::ty_fn_args(fn_ty)); + bcx.tcx(), &fn_ty.fn_args()); // Translate the `self` argument first. if !ignore_self { @@ -978,7 +978,7 @@ fn trans_overloaded_call_args<'blk, 'tcx>( ignore_self: bool) -> Block<'blk, 'tcx> { // Translate the `self` argument first. - let arg_tys = ty::erase_late_bound_regions(bcx.tcx(), &ty::ty_fn_args(fn_ty)); + let arg_tys = ty::erase_late_bound_regions(bcx.tcx(), &fn_ty.fn_args()); if !ignore_self { let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0])); bcx = trans_arg_datum(bcx, @@ -1024,8 +1024,8 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, debug!("trans_args(abi={})", abi); let _icx = push_ctxt("trans_args"); - let arg_tys = ty::erase_late_bound_regions(cx.tcx(), &ty::ty_fn_args(fn_ty)); - let variadic = ty::fn_is_variadic(fn_ty); + let arg_tys = ty::erase_late_bound_regions(cx.tcx(), &fn_ty.fn_args()); + let variadic = fn_ty.fn_sig().0.variadic; let mut bcx = cx; diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 0127c57d9cf34..2aa12e088aa12 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -155,7 +155,7 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty< } let mut needs_unwind_cleanup = false; - ty::maybe_walk_ty(ty, |ty| { + ty.maybe_walk(|ty| { needs_unwind_cleanup |= match ty.sty { ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyTuple(_) | ty::TyRawPtr(_) => false, @@ -234,10 +234,10 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) - use trans::type_of::sizing_type_of; let tcx = ccx.tcx(); - let simple = ty::type_is_scalar(ty) || - ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) || + let simple = ty.is_scalar() || + ty.is_unique() || ty.is_region_ptr() || type_is_newtype_immediate(ccx, ty) || - ty::type_is_simd(tcx, ty); + ty.is_simd(tcx); if simple && !type_is_fat_ptr(tcx, ty) { return true; } @@ -267,7 +267,7 @@ pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) - /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI /// compatibility). pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool { - ty::type_is_nil(ty) || ty::type_is_empty(ccx.tcx(), ty) + ty.is_nil() || ty::type_is_empty(ccx.tcx(), ty) } /// Generates a unique symbol based off the name given. This is used to create diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 7fbc86d7a8a3e..30cb0680b6997 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -149,7 +149,7 @@ fn const_deref<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, v: ValueRef, ty: Ty<'tcx>) -> (ValueRef, Ty<'tcx>) { - match ty::deref(ty, true) { + match ty.builtin_deref(true) { Some(mt) => { if type_is_sized(cx.tcx(), mt.ty) { (const_deref_ptr(cx, v), mt.ty) @@ -323,7 +323,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, param_substs, &target); - let pointee_ty = ty::deref(ty, true) + let pointee_ty = ty.builtin_deref(true) .expect("consts: unsizing got non-pointer type").ty; let (base, old_info) = if !type_is_sized(cx.tcx(), pointee_ty) { // Normally, the source is a thin pointer and we are @@ -338,7 +338,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, (llconst, None) }; - let unsized_ty = ty::deref(target, true) + let unsized_ty = target.builtin_deref(true) .expect("consts: unsizing got non-pointer target type").ty; let ptr_ty = type_of::in_memory_type_of(cx, unsized_ty).ptr_to(); let base = ptrcast(base, ptr_ty); @@ -499,14 +499,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug!("const_expr_unadjusted: te1={}, ty={:?}", cx.tn().val_to_string(te1), ty); - let is_simd = ty::type_is_simd(cx.tcx(), ty); + let is_simd = ty.is_simd(cx.tcx()); let intype = if is_simd { - ty::simd_type(cx.tcx(), ty) + ty.simd_type(cx.tcx()) } else { ty }; - let is_float = ty::type_is_fp(intype); - let signed = ty::type_is_signed(intype); + let is_float = intype.is_fp(); + let signed = intype.is_signed(); let (te2, _) = const_expr(cx, &**e2, param_substs, fn_args); @@ -572,7 +572,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, check_unary_expr_validity(cx, e, ty, te); - let is_float = ty::type_is_fp(ty); + let is_float = ty.is_fp(); match u { ast::UnUniq | ast::UnDeref => { const_deref(cx, te, ty).0 @@ -660,7 +660,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } if type_is_fat_ptr(cx.tcx(), t_expr) { // Fat pointer casts. - let t_cast_inner = ty::deref(t_cast, true).expect("cast to non-pointer").ty; + let t_cast_inner = t_cast.builtin_deref(true).expect("cast to non-pointer").ty; let ptr_ty = type_of::in_memory_type_of(cx, t_cast_inner).ptr_to(); let addr = ptrcast(const_get_elt(cx, v, &[abi::FAT_PTR_ADDR as u32]), ptr_ty); @@ -681,11 +681,11 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, llvm::LLVMConstIntCast(iv, llty.to_ref(), s) } (CastTy::Int(_), CastTy::Int(_)) => { - let s = ty::type_is_signed(t_expr) as Bool; + let s = t_expr.is_signed() as Bool; llvm::LLVMConstIntCast(v, llty.to_ref(), s) } (CastTy::Int(_), CastTy::Float) => { - if ty::type_is_signed(t_expr) { + if t_expr.is_signed() { llvm::LLVMConstSIToFP(v, llty.to_ref()) } else { llvm::LLVMConstUIToFP(v, llty.to_ref()) @@ -781,7 +781,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } }).collect::>(); - if ty::type_is_simd(cx.tcx(), ety) { + if ety.is_simd(cx.tcx()) { C_vector(&cs[..]) } else { adt::trans_const(cx, &*repr, discr, &cs[..]) @@ -789,7 +789,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }) } ast::ExprVec(ref es) => { - let unit_ty = ty::sequence_element_type(cx.tcx(), ety); + let unit_ty = ety.sequence_element_type(cx.tcx()); let llunitty = type_of::type_of(cx, unit_ty); let vs = es.iter().map(|e| const_expr(cx, &**e, param_substs, fn_args).0) .collect::>(); @@ -801,7 +801,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } ast::ExprRepeat(ref elem, ref count) => { - let unit_ty = ty::sequence_element_type(cx.tcx(), ety); + let unit_ty = ety.sequence_element_type(cx.tcx()); let llunitty = type_of::type_of(cx, unit_ty); let n = ty::eval_repeat_count(cx.tcx(), count); let unit_val = const_expr(cx, &**elem, param_substs, fn_args).0; @@ -875,7 +875,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs) } def::DefStruct(_) => { - if ty::type_is_simd(cx.tcx(), ety) { + if ety.is_simd(cx.tcx()) { C_vector(&arg_vals[..]) } else { let repr = adt::represent_type(cx, ety); diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index e60e4e4abe053..d7083eb2d3336 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -640,7 +640,7 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> { } pub fn to_llbool<'blk>(self, bcx: Block<'blk, 'tcx>) -> ValueRef { - assert!(ty::type_is_bool(self.ty)); + assert!(self.ty.is_bool()); self.to_llscalarish(bcx) } } diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 7660f59e1d08b..95c18e6006384 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -1192,7 +1192,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, struct_llvm_type, StructMDF(StructMemberDescriptionFactory { fields: fields, - is_simd: ty::type_is_simd(cx.tcx(), struct_type), + is_simd: struct_type.is_simd(cx.tcx()), span: span, }) ) diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 06f1a56c6ef1f..3c63f0fa30c1a 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -416,7 +416,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let return_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &return_type); - if ty::type_is_nil(return_type) { + if return_type.is_nil() { signature.push(ptr::null_mut()) } else { signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP)); diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index 5ba5ecb02c024..4092ba8bfa55a 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -144,7 +144,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(')'); match sig.output { - ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {} + ty::FnConverging(result_type) if result_type.is_nil() => {} ty::FnConverging(result_type) => { output.push_str(" -> "); push_debuginfo_type_name(cx, result_type, true, output); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 5ee7159493534..9d30023cd189a 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -252,7 +252,7 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llty = type_of::type_of(bcx.ccx(), const_ty); // HACK(eddyb) get around issues with lifetime intrinsics. let scratch = alloca_no_lifetime(bcx, llty, "const"); - let lldest = if !ty::type_is_structural(const_ty) { + let lldest = if !const_ty.is_structural() { // Cast pointer to slot, because constants have different types. PointerCast(bcx, scratch, val_ty(global)) } else { @@ -790,8 +790,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let ref_ty = // invoked methods have LB regions instantiated: ty::no_late_bound_regions( - bcx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap(); - let elt_ty = match ty::deref(ref_ty, true) { + bcx.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); + let elt_ty = match ref_ty.builtin_deref(true) { None => { bcx.tcx().sess.span_bug(index_expr.span, "index method didn't return a \ @@ -835,7 +835,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ccx.int_type()); let ix_val = { if ix_size < int_size { - if ty::type_is_signed(expr_ty(bcx, idx)) { + if expr_ty(bcx, idx).is_signed() { SExt(bcx, ix_val, ccx.int_type()) } else { ZExt(bcx, ix_val, ccx.int_type()) } } else if ix_size > int_size { @@ -845,7 +845,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } }; - let unit_ty = ty::sequence_element_type(bcx.tcx(), base_datum.ty); + let unit_ty = base_datum.ty.sequence_element_type(bcx.tcx()); let (base, len) = base_datum.get_vec_base_and_len(bcx); @@ -1490,7 +1490,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // panic occur before the ADT as a whole is ready. let custom_cleanup_scope = fcx.push_custom_cleanup_scope(); - if ty::type_is_simd(bcx.tcx(), ty) { + if ty.is_simd(bcx.tcx()) { // Issue 23112: The original logic appeared vulnerable to same // order-of-eval bug. But, SIMD values are tuple-structs; // i.e. functional record update (FRU) syntax is unavailable. @@ -1626,11 +1626,11 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let datum = unpack_datum!(bcx, trans(bcx, sub_expr)); let val = datum.to_llscalarish(bcx); let (bcx, llneg) = { - if ty::type_is_fp(un_ty) { + if un_ty.is_fp() { let result = FNeg(bcx, val, debug_loc); (bcx, result) } else { - let is_signed = ty::type_is_signed(un_ty); + let is_signed = un_ty.is_signed(); let result = Neg(bcx, val, debug_loc); let bcx = if bcx.ccx().check_overflow() && is_signed { let (llty, min) = base::llty_and_min_for_signed_ty(bcx, un_ty); @@ -1735,14 +1735,14 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_eager_binop"); let tcx = bcx.tcx(); - let is_simd = ty::type_is_simd(tcx, lhs_t); + let is_simd = lhs_t.is_simd(tcx); let intype = if is_simd { - ty::simd_type(tcx, lhs_t) + lhs_t.simd_type(tcx) } else { lhs_t }; - let is_float = ty::type_is_fp(intype); - let is_signed = ty::type_is_signed(intype); + let is_float = intype.is_fp(); + let is_signed = intype.is_signed(); let info = expr_info(binop_expr); let binop_debug_loc = binop_expr.debug_loc(); @@ -1999,7 +1999,7 @@ pub fn cast_is_noop<'tcx>(tcx: &ty::ctxt<'tcx>, return true; } - match (ty::deref(t_in, true), ty::deref(t_out, true)) { + match (t_in.builtin_deref(true), t_out.builtin_deref(true)) { (Some(ty::mt{ ty: t_in, .. }), Some(ty::mt{ ty: t_out, .. })) => { t_in == t_out } @@ -2108,7 +2108,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ll_t_in = val_ty(discr); (discr, adt::is_discr_signed(&*repr)) } else { - (datum.to_llscalarish(bcx), ty::type_is_signed(t_in)) + (datum.to_llscalarish(bcx), t_in.is_signed()) }; let newval = match (r_t_in, r_t_out) { @@ -2242,7 +2242,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let ref_ty = // invoked methods have their LB regions instantiated ty::no_late_bound_regions( - ccx.tcx(), &ty::ty_fn_ret(method_ty)).unwrap().unwrap(); + ccx.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref"); unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call, @@ -2545,13 +2545,13 @@ fn build_unchecked_rshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // #1877, #10183: Ensure that input is always valid let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc); let tcx = bcx.tcx(); - let is_simd = ty::type_is_simd(tcx, lhs_t); + let is_simd = lhs_t.is_simd(tcx); let intype = if is_simd { - ty::simd_type(tcx, lhs_t) + lhs_t.simd_type(tcx) } else { lhs_t }; - let is_signed = ty::type_is_signed(intype); + let is_signed = intype.is_signed(); if is_signed { AShr(bcx, lhs, rhs, binop_debug_loc) } else { diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 4f3f13e4bed24..2ac6b02445cce 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -324,7 +324,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let llarg_foreign = if foreign_indirect { llarg_rust } else { - if ty::type_is_bool(passed_arg_tys[i]) { + if passed_arg_tys[i].is_bool() { let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False); Trunc(bcx, val, Type::i1(bcx.ccx())) } else { @@ -450,7 +450,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) { if !tcx.sess.features.borrow().simd_ffi { let check = |ast_ty: &ast::Ty, ty: ty::Ty| { - if ty::type_is_simd(tcx, ty) { + if ty.is_simd(tcx) { tcx.sess.span_err(ast_ty.span, &format!("use of SIMD type `{}` in FFI is highly experimental and \ may result in invalid code", @@ -777,7 +777,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // pointer). It makes adapting types easier, since we can // always just bitcast pointers. if !foreign_indirect { - llforeign_arg = if ty::type_is_bool(rust_ty) { + llforeign_arg = if rust_ty.is_bool() { let lltemp = builder.alloca(Type::bool(ccx), ""); builder.store(builder.zext(llforeign_arg, Type::bool(ccx)), lltemp); lltemp @@ -799,7 +799,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let llrust_arg = if rust_indirect || type_is_fat_ptr(ccx.tcx(), rust_ty) { llforeign_arg } else { - if ty::type_is_bool(rust_ty) { + if rust_ty.is_bool() { let tmp = builder.load_range_assert(llforeign_arg, 0, 2, llvm::False); builder.trunc(tmp, Type::i1(ccx)) } else if type_of::type_of(ccx, rust_ty).is_aggregate() { diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index b84475d915a4f..5e7f067a4b3b8 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -392,7 +392,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in let ccx = bcx.ccx(); // First get the size of all statically known fields. // Don't use type_of::sizing_type_of because that expects t to be sized. - assert!(!ty::type_is_simd(bcx.tcx(), t)); + assert!(!t.is_simd(bcx.tcx())); let repr = adt::represent_type(ccx, t); let sizing_type = adt::sizing_type_of(ccx, &*repr, true); let sized_size = C_uint(ccx, llsize_of_alloc(ccx, sizing_type)); @@ -426,7 +426,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in (Load(bcx, size_ptr), Load(bcx, align_ptr)) } ty::TySlice(_) | ty::TyStr => { - let unit_ty = ty::sequence_element_type(bcx.tcx(), t); + let unit_ty = t.sequence_element_type(bcx.tcx()); // The info in this case is the length of the str, so the size is that // times the unit size. let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty); diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index bba0f6d26083a..8b28d9c1250e7 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -253,7 +253,7 @@ fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn vec_types_from_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, vec_expr: &ast::Expr) -> VecTypes<'tcx> { let vec_ty = node_id_type(bcx, vec_expr.id); - vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty)) + vec_types(bcx, vec_ty.sequence_element_type(bcx.tcx())) } fn vec_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, unit_ty: Ty<'tcx>) diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 49601ac6fe94d..a27166844806c 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -222,9 +222,9 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ } ty::TyStruct(..) => { - if ty::type_is_simd(cx.tcx(), t) { - let llet = type_of(cx, ty::simd_type(cx.tcx(), t)); - let n = ty::simd_size(cx.tcx(), t) as u64; + if t.is_simd(cx.tcx()) { + let llet = type_of(cx, t.simd_type(cx.tcx())); + let n = t.simd_size(cx.tcx()) as u64; ensure_array_fits_in_address_space(cx, llet, n, t); Type::vector(&llet, n) } else { @@ -245,7 +245,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ } pub fn foreign_arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { - if ty::type_is_bool(t) { + if t.is_bool() { Type::i1(cx) } else { type_of(cx, t) @@ -253,7 +253,7 @@ pub fn foreign_arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) - } pub fn arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { - if ty::type_is_bool(t) { + if t.is_bool() { Type::i1(cx) } else if type_is_immediate(cx, t) && type_of(cx, t).is_aggregate() { // We want to pass small aggregates as immediate values, but using an aggregate LLVM type @@ -402,9 +402,9 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> adt::type_of(cx, &*repr) } ty::TyStruct(did, ref substs) => { - if ty::type_is_simd(cx.tcx(), t) { - let llet = in_memory_type_of(cx, ty::simd_type(cx.tcx(), t)); - let n = ty::simd_size(cx.tcx(), t) as u64; + if t.is_simd(cx.tcx()) { + let llet = in_memory_type_of(cx, t.simd_type(cx.tcx())); + let n = t.simd_size(cx.tcx()) as u64; ensure_array_fits_in_address_space(cx, llet, n, t); Type::vector(&llet, n) } else { @@ -434,7 +434,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // If this was an enum or struct, fill in the type now. match t.sty { ty::TyEnum(..) | ty::TyStruct(..) | ty::TyClosure(..) - if !ty::type_is_simd(cx.tcx(), t) => { + if !t.is_simd(cx.tcx()) => { let repr = adt::represent_type(cx, t); adt::finish_type_of(cx, &*repr, &mut llty); } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 95814370900c4..6b11efb478287 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -90,7 +90,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let rhs_ty = fcx.expr_ty(end); // Check that both end-points are of numeric or char type. - let numeric_or_char = |t| ty::type_is_numeric(t) || ty::type_is_char(t); + let numeric_or_char = |ty: Ty| ty.is_numeric() || ty.is_char(); let lhs_compat = numeric_or_char(lhs_ty); let rhs_compat = numeric_or_char(rhs_ty); @@ -303,8 +303,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); ty::mk_slice(tcx, tcx.mk_region(region), ty::mt { ty: inner_ty, - mutbl: ty::deref(expected_ty, true).map(|mt| mt.mutbl) - .unwrap_or(ast::MutImmutable) + mutbl: expected_ty.builtin_deref(true).map(|mt| mt.mutbl) + .unwrap_or(ast::MutImmutable) }) } }; @@ -321,7 +321,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, } if let Some(ref slice) = *slice { let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); - let mutbl = ty::deref(expected_ty, true) + let mutbl = expected_ty.builtin_deref(true) .map_or(ast::MutImmutable, |mt| mt.mutbl); let slice_ty = ty::mk_slice(tcx, tcx.mk_region(region), ty::mt { @@ -411,7 +411,7 @@ pub fn check_dereferencable<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let tcx = pcx.fcx.ccx.tcx; if pat_is_binding(&tcx.def_map, inner) { let expected = fcx.infcx().shallow_resolve(expected); - ty::deref(expected, true).map_or(true, |mt| match mt.ty.sty { + expected.builtin_deref(true).map_or(true, |mt| match mt.ty.sty { ty::TyTrait(_) => { // This is "x = SomeTrait" being reduced from // "let &x = &SomeTrait" or "let box x = Box", an error. @@ -633,8 +633,8 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let ctor_scheme = ty::lookup_item_type(tcx, enum_def); let ctor_predicates = ty::lookup_predicates(tcx, enum_def); - let path_scheme = if ty::is_fn_ty(ctor_scheme.ty) { - let fn_ret = ty::no_late_bound_regions(tcx, &ty::ty_fn_ret(ctor_scheme.ty)).unwrap(); + let path_scheme = if ctor_scheme.ty.is_fn() { + let fn_ret = ty::no_late_bound_regions(tcx, &ctor_scheme.ty.fn_ret()).unwrap(); ty::TypeScheme { ty: fn_ret.unwrap(), generics: ctor_scheme.generics, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index e7271d2fa88cf..4951a9a6f2f16 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -360,7 +360,7 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { // refactor it.) let method_sig = ty::no_late_bound_regions(fcx.tcx(), - ty::ty_fn_sig(method_callee.ty)).unwrap(); + method_callee.ty.fn_sig()).unwrap(); debug!("attempt_resolution: method_callee={:?}", method_callee); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 5bf1ef346113c..1ff4c4eb0f455 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -169,7 +169,7 @@ impl<'tcx> CastCheck<'tcx> { fn trivial_cast_lint<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) { let t_cast = self.cast_ty; let t_expr = self.expr_ty; - if ty::type_is_numeric(t_cast) && ty::type_is_numeric(t_expr) { + if t_cast.is_numeric() && t_expr.is_numeric() { fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS, self.expr.id, self.span, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index fd93a2493db5a..a5b812ee80ee8 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -536,8 +536,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } Some(ty::AutoPtr(_, _)) => { (adr.autoderefs, adr.unsize.map(|target| { - ty::deref(target, false) - .expect("fixup: AutoPtr is not &T").ty + target.builtin_deref(false) + .expect("fixup: AutoPtr is not &T").ty })) } Some(_) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fa768cb9adbb8..de09a98b89e52 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -229,7 +229,7 @@ impl<'tcx> Expectation<'tcx> { match *self { ExpectHasType(ety) => { let ety = fcx.infcx().shallow_resolve(ety); - if !ty::type_is_ty_var(ety) { + if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation @@ -1146,7 +1146,7 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ast::MutMutable => "mut ", ast::MutImmutable => "" }; - if ty::type_is_trait(t_cast) { + if t_cast.is_trait() { match fcx.tcx().sess.codemap().span_to_snippet(t_span) { Ok(s) => { fcx.tcx().sess.span_suggestion(t_span, @@ -1948,7 +1948,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, } UnresolvedTypeAction::Ignore => { // We can continue even when the type cannot be resolved - // (i.e. it is an inference variable) because `ty::deref` + // (i.e. it is an inference variable) because `Ty::builtin_deref` // and `try_overloaded_deref` both simply return `None` // in such a case without producing spurious errors. fcx.resolve_type_vars_if_possible(t) @@ -1964,7 +1964,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, } // Otherwise, deref if type is derefable: - let mt = match ty::deref(resolved_t, false) { + let mt = match resolved_t.builtin_deref(false) { Some(mt) => Some(mt), None => { let method_call = @@ -2045,7 +2045,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, Some(method) => { // extract method method return type, which will be &T; // all LB regions should have been instantiated during method lookup - let ret_ty = ty::ty_fn_ret(method.ty); + let ret_ty = method.ty.fn_ret(); let ret_ty = ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap(); if let Some(method_call) = method_call { @@ -2053,7 +2053,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } // method returns &T, but the type as visible to user is T, so deref - ty::deref(ret_ty, true) + ret_ty.builtin_deref(true) } None => None, } @@ -2125,7 +2125,7 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let input_ty = fcx.infcx().next_ty_var(); // First, try built-in indexing. - match (ty::index(adjusted_ty), &index_ty.sty) { + match (adjusted_ty.builtin_index(), &index_ty.sty) { (Some(ty), &ty::TyUint(ast::TyUs)) | (Some(ty), &ty::TyInfer(ty::IntVar(_))) => { debug!("try_index_step: success, using built-in indexing"); // If we had `[T; N]`, we should've caught it before unsizing to `[T]`. @@ -3160,7 +3160,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::UnDeref => { oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t); - oprnd_t = match ty::deref(oprnd_t, true) { + oprnd_t = match oprnd_t.builtin_deref(true) { Some(mt) => mt.ty, None => match try_overloaded_deref(fcx, expr.span, Some(MethodCall::expr(expr.id)), @@ -3179,8 +3179,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ast::UnNot => { oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t); - if !(ty::type_is_integral(oprnd_t) || - oprnd_t.sty == ty::TyBool) { + if !(oprnd_t.is_integral() || oprnd_t.sty == ty::TyBool) { oprnd_t = op::check_user_unop(fcx, "!", "not", tcx.lang_items.not_trait(), expr, &**oprnd, oprnd_t, unop); @@ -3189,8 +3188,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ast::UnNeg => { oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t); - if !(ty::type_is_integral(oprnd_t) || - ty::type_is_fp(oprnd_t)) { + if !(oprnd_t.is_integral() || oprnd_t.is_fp()) { oprnd_t = op::check_user_unop(fcx, "-", "neg", tcx.lang_items.neg_trait(), expr, &**oprnd, oprnd_t, unop); @@ -4201,7 +4199,7 @@ pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) { span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous"); return; } - if !ty::type_is_machine(e) { + if !e.is_machine() { span_err!(tcx.sess, sp, E0077, "SIMD vector element type should be machine type"); return; @@ -4870,11 +4868,11 @@ fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, { let mut ty = fcx.resolve_type_vars_if_possible(ty); - if ty::type_is_ty_var(ty) { + if ty.is_ty_var() { let alternative = f(); // If not, error. - if ty::type_is_ty_var(alternative) || alternative.references_error() { + if alternative.is_ty_var() || alternative.references_error() { fcx.type_error_message(sp, |_actual| { "the type of this value must be known in this context".to_string() }, ty, None); @@ -4933,15 +4931,12 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, if tps.is_empty() { return; } let mut tps_used: Vec<_> = repeat(false).take(tps.len()).collect(); - ty::walk_ty(ty, |t| { - match t.sty { - ty::TyParam(ParamTy {idx, ..}) => { - debug!("Found use of ty param num {}", idx); - tps_used[idx as usize] = true; - } - _ => () - } - }); + for leaf_ty in ty.walk() { + if let ty::TyParam(ParamTy {idx, ..}) = leaf_ty.sty { + debug!("Found use of ty param num {}", idx); + tps_used[idx as usize] = true; + } + } for (i, b) in tps_used.iter().enumerate() { if !*b { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 8aeef7f03b4e8..48dc64e8c8b49 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -86,7 +86,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // traits, because their return type is not bool. Perhaps this // should change, but for now if LHS is SIMD we go down a // different path that bypassess all traits. - if ty::type_is_simd(fcx.tcx(), lhs_ty) { + if lhs_ty.is_simd(fcx.tcx()) { check_expr_coercable_to_type(fcx, rhs_expr, lhs_ty); let rhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr)); let return_ty = enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op); @@ -122,8 +122,7 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // can't pin this down to a specific impl. let rhs_ty = fcx.resolve_type_vars_if_possible(rhs_ty); if - !ty::type_is_ty_var(lhs_ty) && - !ty::type_is_ty_var(rhs_ty) && + !lhs_ty.is_ty_var() && !rhs_ty.is_ty_var() && is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op) { let builtin_return_ty = @@ -157,7 +156,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, BinOpCategory::Shift => { // For integers, the shift amount can be of any integral // type. For simd, the type must match exactly. - if ty::type_is_simd(tcx, lhs_ty) { + if lhs_ty.is_simd(tcx) { demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty); } @@ -177,12 +176,12 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty); // if this is simd, result is same as lhs, else bool - if ty::type_is_simd(tcx, lhs_ty) { - let unit_ty = ty::simd_type(tcx, lhs_ty); + if lhs_ty.is_simd(tcx) { + let unit_ty = lhs_ty.simd_type(tcx); debug!("enforce_builtin_binop_types: lhs_ty={:?} unit_ty={:?}", lhs_ty, unit_ty); - if !ty::type_is_integral(unit_ty) { + if !unit_ty.is_integral() { tcx.sess.span_err( lhs_expr.span, &format!("binary comparison operation `{}` not supported \ @@ -335,7 +334,7 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, // extract return type for method; all late bound regions // should have been instantiated by now - let ret_ty = ty::ty_fn_ret(method_ty); + let ret_ty = method_ty.fn_ret(); Ok(ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap()) } None => { @@ -429,29 +428,29 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, BinOpCategory::Shift => { lhs.references_error() || rhs.references_error() || - ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || - ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) + lhs.is_integral() && rhs.is_integral() || + lhs.is_simd(cx) && rhs.is_simd(cx) } BinOpCategory::Math => { lhs.references_error() || rhs.references_error() || - ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || - ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) || - ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) + lhs.is_integral() && rhs.is_integral() || + lhs.is_floating_point() && rhs.is_floating_point() || + lhs.is_simd(cx) && rhs.is_simd(cx) } BinOpCategory::Bitwise => { lhs.references_error() || rhs.references_error() || - ty::type_is_integral(lhs) && ty::type_is_integral(rhs) || - ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) || - ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) || - ty::type_is_bool(lhs) && ty::type_is_bool(rhs) + lhs.is_integral() && rhs.is_integral() || + lhs.is_floating_point() && rhs.is_floating_point() || + lhs.is_simd(cx) && rhs.is_simd(cx) || + lhs.is_bool() && rhs.is_bool() } BinOpCategory::Comparison => { lhs.references_error() || rhs.references_error() || - ty::type_is_scalar(lhs) && ty::type_is_scalar(rhs) || - ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) + lhs.is_scalar() && rhs.is_scalar() || + lhs.is_simd(cx) && rhs.is_simd(cx) } } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 4441afcec5f29..e06ebd0276ffd 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -662,7 +662,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { constrain_call(rcx, expr, Some(&**base), None::.iter(), true); let fn_ret = // late-bound regions in overloaded method calls are instantiated - ty::no_late_bound_regions(rcx.tcx(), &ty::ty_fn_ret(method.ty)).unwrap(); + ty::no_late_bound_regions(rcx.tcx(), &method.ty.fn_ret()).unwrap(); fn_ret.unwrap() } None => rcx.resolve_node_type(base.id) @@ -891,7 +891,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, // Treat overloaded autoderefs as if an AutoRef adjustment // was applied on the base type, as that is always the case. - let fn_sig = ty::ty_fn_sig(method.ty); + let fn_sig = method.ty.fn_sig(); let fn_sig = // late-bound regions should have been instantiated ty::no_late_bound_regions(rcx.tcx(), fn_sig).unwrap(); let self_ty = fn_sig.inputs[0]; @@ -937,7 +937,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, r_deref_expr, *r_ptr); } - match ty::deref(derefd_ty, true) { + match derefd_ty.builtin_deref(true) { Some(mt) => derefd_ty = mt.ty, /* if this type can't be dereferenced, then there's already an error in the session saying so. Just bail out for now */ diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index c048845892c4b..aa6f533401dd6 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -661,7 +661,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // enum def'n, and hence will all be early bound let arg_tys = ty::no_late_bound_regions( - fcx.tcx(), &ty::ty_fn_args(ctor_ty)).unwrap(); + fcx.tcx(), &ctor_ty.fn_args()).unwrap(); AdtVariant { fields: args.iter().enumerate().map(|(index, arg)| { let arg_ty = arg_tys[index]; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 05cc3077fc9fb..2bf8c5b5fafd3 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -95,7 +95,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let rhs_ty = self.fcx.node_ty(rhs.id); let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty); - if ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) { + if lhs_ty.is_scalar() && rhs_ty.is_scalar() { self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id)); // weird but true: the by-ref binops put an diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a873900b5fc60..6c1235e5a7569 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1882,16 +1882,15 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &**path); let cur_idx = index; - ty::walk_ty(ty, |t| { - match t.sty { - ty::TyParam(p) => if p.idx > cur_idx { + for leaf_ty in ty.walk() { + if let ty::TyParam(p) = leaf_ty.sty { + if p.idx > cur_idx { span_err!(tcx.sess, path.span, E0128, "type parameters with a default cannot use \ forward declared identifiers"); - }, - _ => {} } - }); + } + } Some(ty) } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index b1580a74876c1..7844d71462cfc 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -24,7 +24,7 @@ pub enum Parameter { /// by `ty` (see RFC 447). pub fn parameters_for_type<'tcx>(ty: Ty<'tcx>) -> Vec { let mut result = vec![]; - ty::maybe_walk_ty(ty, |t| { + ty.maybe_walk(|t| { if let ty::TyProjection(..) = t.sty { false // projections are not injective. } else { From 2332765cbc5d58fe03356a6adefc83ff6412c1c2 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 24 Jun 2015 08:44:10 +0300 Subject: [PATCH 11/36] rustc: prefer unqualified `ctxt` to `ty::ctxt` in middle::ty. --- src/librustc/middle/ty.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8470d9d5f819e..e66deb08290f8 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2063,7 +2063,7 @@ impl<'tcx> GenericPredicates<'tcx> { } } - pub fn instantiate(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>) + pub fn instantiate(&self, tcx: &ctxt<'tcx>, substs: &Substs<'tcx>) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { predicates: self.predicates.subst(tcx, substs), @@ -2071,7 +2071,7 @@ impl<'tcx> GenericPredicates<'tcx> { } pub fn instantiate_supertrait(&self, - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, poly_trait_ref: &ty::PolyTraitRef<'tcx>) -> InstantiatedPredicates<'tcx> { @@ -2109,7 +2109,7 @@ impl<'tcx> Predicate<'tcx> { /// substitution in terms of what happens with bound regions. See /// lengthy comment below for details. pub fn subst_supertrait(&self, - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, trait_ref: &ty::PolyTraitRef<'tcx>) -> ty::Predicate<'tcx> { @@ -2876,7 +2876,7 @@ impl ClosureKind { } pub trait ClosureTyper<'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { + fn tcx(&self) -> &ctxt<'tcx> { self.param_env().tcx } @@ -3585,7 +3585,7 @@ impl ParamTy { ParamTy::new(def.space, def.index, def.name) } - pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> { + pub fn to_ty<'tcx>(self, tcx: &ctxt<'tcx>) -> Ty<'tcx> { ty::mk_param(tcx, self.space, self.idx, self.name) } @@ -4108,7 +4108,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, ty: Ty<'tcx>, bound: ty::BuiltinBound, span: Span) @@ -4178,7 +4178,7 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>, #[inline] pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, span: Span, ty: Ty<'tcx>) -> bool @@ -4192,7 +4192,7 @@ pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, } fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, span: Span, ty: Ty<'tcx>) -> bool { assert!(!ty.needs_infer()); @@ -6703,7 +6703,7 @@ pub fn construct_free_substs<'a,'tcx>( } } - fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>, + fn push_types_from_defs<'tcx>(tcx: &ctxt<'tcx>, types: &mut VecPerParamSpace>, defs: &[TypeParameterDef<'tcx>]) { for def in defs { @@ -6966,7 +6966,7 @@ pub type TraitMap = NodeMap>; // imported. pub type GlobMap = HashMap>; -pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: F) -> T where +pub fn with_freevars(tcx: &ctxt, fid: ast::NodeId, f: F) -> T where F: FnOnce(&[Freevar]) -> T, { match tcx.freevars.borrow().get(&fid) { @@ -6994,7 +6994,7 @@ impl<'tcx> AutoDerefRef<'tcx> { /// Replace any late-bound regions bound in `value` with free variants attached to scope-id /// `scope_id`. pub fn liberate_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, all_outlive_scope: region::DestructionScopeData, value: &Binder) -> T @@ -7006,7 +7006,7 @@ pub fn liberate_late_bound_regions<'tcx, T>( } pub fn count_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, value: &Binder) -> usize where T : TypeFoldable<'tcx> @@ -7016,7 +7016,7 @@ pub fn count_late_bound_regions<'tcx, T>( } pub fn binds_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, value: &Binder) -> bool where T : TypeFoldable<'tcx> @@ -7027,7 +7027,7 @@ pub fn binds_late_bound_regions<'tcx, T>( /// Flattens two binding levels into one. So `for<'a> for<'b> Foo` /// becomes `for<'a,'b> Foo`. pub fn flatten_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, bound2_value: &Binder>) -> Binder where T: TypeFoldable<'tcx> @@ -7049,7 +7049,7 @@ pub fn flatten_late_bound_regions<'tcx, T>( } pub fn no_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, value: &Binder) -> Option where T : TypeFoldable<'tcx> @@ -7064,7 +7064,7 @@ pub fn no_late_bound_regions<'tcx, T>( /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also /// method lookup and a few other places where precise region relationships are not required. pub fn erase_late_bound_regions<'tcx, T>( - tcx: &ty::ctxt<'tcx>, + tcx: &ctxt<'tcx>, value: &Binder) -> T where T : TypeFoldable<'tcx> @@ -7147,7 +7147,7 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { } } -pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>, +pub fn make_substs_for_receiver_types<'tcx>(tcx: &ctxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>, method: &ty::Method<'tcx>) -> subst::Substs<'tcx> From 6db5126240b6420630553b930417fca10986d75d Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 25 Jun 2015 04:09:46 +0300 Subject: [PATCH 12/36] rustc: make ty::mk_* constructors into methods on ty::ctxt. --- src/librustc/metadata/tydecode.rs | 34 +- src/librustc/middle/astconv_util.rs | 8 +- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/implicator.rs | 4 +- src/librustc/middle/infer/combine.rs | 6 +- src/librustc/middle/infer/freshen.rs | 2 +- .../middle/infer/higher_ranked/mod.rs | 2 +- src/librustc/middle/infer/mod.rs | 4 +- .../middle/infer/region_inference/mod.rs | 2 +- src/librustc/middle/infer/unify_key.rs | 6 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/traits/project.rs | 6 +- src/librustc/middle/traits/select.rs | 4 +- src/librustc/middle/traits/util.rs | 4 +- src/librustc/middle/ty.rs | 369 +++++++++--------- src/librustc/middle/ty_fold.rs | 2 +- src/librustc/middle/ty_relate/mod.rs | 24 +- src/librustc_driver/test.rs | 68 ++-- src/librustc_lint/builtin.rs | 8 +- src/librustc_trans/trans/_match.rs | 11 +- src/librustc_trans/trans/adt.rs | 6 +- src/librustc_trans/trans/base.rs | 10 +- src/librustc_trans/trans/callee.rs | 29 +- src/librustc_trans/trans/closure.rs | 8 +- src/librustc_trans/trans/consts.rs | 2 +- src/librustc_trans/trans/context.rs | 8 +- .../trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/expr.rs | 6 +- src/librustc_trans/trans/foreign.rs | 2 +- src/librustc_trans/trans/glue.rs | 21 +- src/librustc_trans/trans/meth.rs | 6 +- src/librustc_trans/trans/tvec.rs | 4 +- src/librustc_trans/trans/type_of.rs | 2 +- src/librustc_typeck/astconv.rs | 38 +- src/librustc_typeck/check/_match.rs | 26 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/closure.rs | 8 +- src/librustc_typeck/check/coercion.rs | 8 +- src/librustc_typeck/check/compare_method.rs | 26 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 5 +- src/librustc_typeck/check/mod.rs | 140 ++++--- src/librustc_typeck/check/op.rs | 14 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 8 +- src/librustc_typeck/collect.rs | 44 +-- src/librustc_typeck/lib.rs | 8 +- 48 files changed, 481 insertions(+), 526 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 57814fbe8f89e..a5b9e40593a83 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -471,14 +471,14 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w let def = parse_def_(st, NominalType, conv); let substs = parse_substs_(st, conv); assert_eq!(next(st), ']'); - return ty::mk_enum(tcx, def, st.tcx.mk_substs(substs)); + return tcx.mk_enum(def, st.tcx.mk_substs(substs)); } 'x' => { assert_eq!(next(st), '['); let trait_ref = ty::Binder(parse_trait_ref_(st, conv)); let bounds = parse_existential_bounds_(st, conv); assert_eq!(next(st), ']'); - return ty::mk_trait(tcx, trait_ref, bounds); + return tcx.mk_trait(trait_ref, bounds); } 'p' => { assert_eq!(next(st), '['); @@ -487,38 +487,38 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w let space = parse_param_space(st); assert_eq!(next(st), '|'); let name = token::intern(&parse_str(st, ']')); - return ty::mk_param(tcx, space, index, name); + return tcx.mk_param(space, index, name); } - '~' => return ty::mk_uniq(tcx, parse_ty_(st, conv)), - '*' => return ty::mk_ptr(tcx, parse_mt_(st, conv)), + '~' => return tcx.mk_box(parse_ty_(st, conv)), + '*' => return tcx.mk_ptr(parse_mt_(st, conv)), '&' => { let r = parse_region_(st, conv); let mt = parse_mt_(st, conv); - return ty::mk_rptr(tcx, tcx.mk_region(r), mt); + return tcx.mk_ref(tcx.mk_region(r), mt); } 'V' => { let t = parse_ty_(st, conv); - let sz = parse_size(st); - return ty::mk_vec(tcx, t, sz); + return match parse_size(st) { + Some(n) => tcx.mk_array(t, n), + None => tcx.mk_slice(t) + }; } 'v' => { - return ty::mk_str(tcx); + return tcx.mk_str(); } 'T' => { assert_eq!(next(st), '['); let mut params = Vec::new(); while peek(st) != ']' { params.push(parse_ty_(st, conv)); } st.pos = st.pos + 1; - return ty::mk_tup(tcx, params); + return tcx.mk_tup(params); } 'F' => { let def_id = parse_def_(st, NominalType, conv); - return ty::mk_bare_fn(tcx, Some(def_id), - tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); + return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); } 'G' => { - return ty::mk_bare_fn(tcx, None, - tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); + return tcx.mk_fn(None, tcx.mk_bare_fn(parse_bare_fn_ty_(st, conv))); } '#' => { let pos = parse_hex(st); @@ -558,20 +558,20 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w let did = parse_def_(st, NominalType, conv); let substs = parse_substs_(st, conv); assert_eq!(next(st), ']'); - return ty::mk_struct(st.tcx, did, st.tcx.mk_substs(substs)); + return st.tcx.mk_struct(did, st.tcx.mk_substs(substs)); } 'k' => { assert_eq!(next(st), '['); let did = parse_def_(st, ClosureSource, conv); let substs = parse_substs_(st, conv); assert_eq!(next(st), ']'); - return ty::mk_closure(st.tcx, did, st.tcx.mk_substs(substs)); + return st.tcx.mk_closure(did, st.tcx.mk_substs(substs)); } 'P' => { assert_eq!(next(st), '['); let trait_ref = parse_trait_ref_(st, conv); let name = token::intern(&parse_str(st, ']')); - return ty::mk_projection(tcx, trait_ref, name); + return tcx.mk_projection(trait_ref, name); } 'e' => { return tcx.types.err; diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 33d37b285890a..fb0131f258d43 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -49,10 +49,10 @@ pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>, match nty { ast::TyBool => tcx.types.bool, ast::TyChar => tcx.types.char, - ast::TyInt(it) => ty::mk_mach_int(tcx, it), - ast::TyUint(uit) => ty::mk_mach_uint(tcx, uit), - ast::TyFloat(ft) => ty::mk_mach_float(tcx, ft), - ast::TyStr => ty::mk_str(tcx) + ast::TyInt(it) => tcx.mk_mach_int(it), + ast::TyUint(uit) => tcx.mk_mach_uint(uit), + ast::TyFloat(ft) => tcx.mk_mach_float(ft), + ast::TyStr => tcx.mk_str() } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 1f137a22b1d2c..dd708cf8f3ae6 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -651,7 +651,7 @@ fn is_useful(cx: &MatchCheckCtxt, None => v[0] }; let left_ty = if real_pat.id == DUMMY_NODE_ID { - ty::mk_nil(cx.tcx) + cx.tcx.mk_nil() } else { let left_ty = ty::pat_ty(cx.tcx, &*real_pat); diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index 5e720125aa00b..3cdf53e6b0acd 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -334,7 +334,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { let assoc_type_projections: Vec<_> = trait_def.associated_type_names .iter() - .map(|&name| ty::mk_projection(self.tcx(), trait_ref.clone(), name)) + .map(|&name| self.tcx().mk_projection(trait_ref.clone(), name)) .collect(); debug!("accumulate_from_assoc_types: assoc_type_projections={:?}", assoc_type_projections); @@ -437,7 +437,7 @@ pub fn object_region_bounds<'tcx>( // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically // a skolemized type. - let open_ty = ty::mk_infer(tcx, ty::FreshTy(0)); + let open_ty = tcx.mk_infer(ty::FreshTy(0)); // Note that we preserve the overall binding levels here. assert!(!open_ty.has_escaping_regions()); diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 17d545212c281..13b2214d35328 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -129,8 +129,8 @@ fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, .unify_var_value(vid, val) .map_err(|e| int_unification_error(vid_is_expected, e))); match val { - IntType(v) => Ok(ty::mk_mach_int(infcx.tcx, v)), - UintType(v) => Ok(ty::mk_mach_uint(infcx.tcx, v)), + IntType(v) => Ok(infcx.tcx.mk_mach_int(v)), + UintType(v) => Ok(infcx.tcx.mk_mach_uint(v)), } } @@ -145,7 +145,7 @@ fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, .borrow_mut() .unify_var_value(vid, val) .map_err(|e| float_unification_error(vid_is_expected, e))); - Ok(ty::mk_mach_float(infcx.tcx, val)) + Ok(infcx.tcx.mk_mach_float(val)) } impl<'a, 'tcx> CombineFields<'a, 'tcx> { diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index 26655a24c324b..d65c4061f11eb 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -71,7 +71,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { Entry::Vacant(entry) => { let index = self.freshen_count; self.freshen_count += 1; - let t = ty::mk_infer(self.infcx.tcx, freshener(index)); + let t = self.infcx.tcx.mk_infer(freshener(index)); entry.insert(t); t } diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 7b26f6b153733..9005e1b8c53a5 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -507,7 +507,7 @@ pub fn construct_skolemized_substs<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, types: &mut subst::VecPerParamSpace>, defs: &[ty::TypeParameterDef<'tcx>]) { for def in defs { - let ty = ty::mk_param_from_def(tcx, def); + let ty = tcx.mk_param_from_def(def); types.push(def.space, ty); } } diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 0c38b655b34ad..2873a59ae8b1a 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -772,11 +772,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn next_ty_var(&self) -> Ty<'tcx> { - ty::mk_var(self.tcx, self.next_ty_var_id(false)) + self.tcx.mk_var(self.next_ty_var_id(false)) } pub fn next_diverging_ty_var(&self) -> Ty<'tcx> { - ty::mk_var(self.tcx, self.next_ty_var_id(true)) + self.tcx.mk_var(self.next_ty_var_id(true)) } pub fn next_ty_vars(&self, n: usize) -> Vec> { diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index e397f35685559..fac7b53ca76aa 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -1672,7 +1672,7 @@ impl<'tcx> GenericKind<'tcx> { GenericKind::Param(ref p) => p.to_ty(tcx), GenericKind::Projection(ref p) => - ty::mk_projection(tcx, p.trait_ref.clone(), p.item_name), + tcx.mk_projection(p.trait_ref.clone(), p.item_name), } } } diff --git a/src/librustc/middle/infer/unify_key.rs b/src/librustc/middle/infer/unify_key.rs index 6b23e2c5029b8..c13cec45dc44a 100644 --- a/src/librustc/middle/infer/unify_key.rs +++ b/src/librustc/middle/infer/unify_key.rs @@ -26,8 +26,8 @@ impl UnifyKey for ty::IntVid { impl<'tcx> ToType<'tcx> for IntVarValue { fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> { match *self { - ty::IntType(i) => ty::mk_mach_int(tcx, i), - ty::UintType(i) => ty::mk_mach_uint(tcx, i), + ty::IntType(i) => tcx.mk_mach_int(i), + ty::UintType(i) => tcx.mk_mach_uint(i), } } } @@ -43,6 +43,6 @@ impl UnifyKey for ty::FloatVid { impl<'tcx> ToType<'tcx> for ast::FloatTy { fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> { - ty::mk_mach_float(tcx, *self) + tcx.mk_mach_float(*self) } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index cf70d63106c70..900dbb444e4e6 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -30,7 +30,7 @@ pub fn check_crate(tcx: &ctxt) { tcx: tcx, param_envs: Vec::new(), dummy_sized_ty: tcx.types.isize, - dummy_unsized_ty: ty::mk_vec(tcx, tcx.types.isize, None), + dummy_unsized_ty: tcx.mk_slice(tcx.types.isize), }; visit::walk_crate(&mut visitor, tcx.map.krate()); } diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 6af10f06a8015..e0709f51ab1b0 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -524,9 +524,9 @@ fn project_type<'cx,'tcx>( Ok(ProjectedTy::Progress(ty, obligations)) } None => { - Ok(ProjectedTy::NoProgress(ty::mk_projection(selcx.tcx(), - obligation.predicate.trait_ref.clone(), - obligation.predicate.item_name))) + Ok(ProjectedTy::NoProgress(selcx.tcx().mk_projection( + obligation.predicate.trait_ref.clone(), + obligation.predicate.item_name))) } } } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 5bac1811ee130..86d4e8c753375 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -2451,7 +2451,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { projection_bounds: data_a.bounds.projection_bounds.clone(), }; - let new_trait = ty::mk_trait(tcx, data_a.principal.clone(), bounds); + let new_trait = tcx.mk_trait(data_a.principal.clone(), bounds); let origin = infer::Misc(obligation.cause.span); if self.infcx.sub_types(false, origin, new_trait, target).is_err() { return Err(Unimplemented); @@ -2573,7 +2573,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let param_b = *substs_b.types.get(TypeSpace, i); new_substs.types.get_mut_slice(TypeSpace)[i] = param_b; } - let new_struct = ty::mk_struct(tcx, def_id, tcx.mk_substs(new_substs)); + let new_struct = tcx.mk_struct(def_id, tcx.mk_substs(new_substs)); let origin = infer::Misc(obligation.cause.span); if self.infcx.sub_types(false, origin, new_struct, target).is_err() { return Err(Unimplemented); diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 7b4a59b5427c1..79b9ae22e4b5c 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -456,14 +456,14 @@ pub fn closure_trait_ref_and_return_type<'tcx>( { let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.0.inputs[0], - TupleArgumentsFlag::Yes => ty::mk_tup(tcx, sig.0.inputs.to_vec()), + TupleArgumentsFlag::Yes => tcx.mk_tup(sig.0.inputs.to_vec()), }; let trait_substs = Substs::new_trait(vec![arguments_tuple], vec![], self_ty); let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, substs: tcx.mk_substs(trait_substs), }; - ty::Binder((trait_ref, sig.0.output.unwrap_or(ty::mk_nil(tcx)))) + ty::Binder((trait_ref, sig.0.output.unwrap_or(tcx.mk_nil()))) } impl<'tcx,O:fmt::Debug> fmt::Debug for super::Obligation<'tcx, O> { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e66deb08290f8..51fb11f7452f4 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3034,7 +3034,7 @@ impl<'tcx> ctxt<'tcx> { abi: bare_fn.abi, sig: bare_fn.sig.clone() }); - ty::mk_bare_fn(self, None, unsafe_fn_ty_a) + self.mk_fn(None, unsafe_fn_ty_a) } pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> { @@ -3085,13 +3085,6 @@ impl<'tcx> ctxt<'tcx> { } } -// Interns a type/name combination, stores the resulting box in cx.interner, -// and returns the box as cast to an unsafe ptr (see comments for Ty above). -pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: TypeVariants<'tcx>) -> Ty<'tcx> { - let mut interner = cx.interner.borrow_mut(); - intern_ty(&cx.arenas.type_, &mut *interner, st) -} - fn intern_ty<'tcx>(type_arena: &'tcx TypedArena>, interner: &mut FnvHashMap, Ty<'tcx>>, st: TypeVariants<'tcx>) @@ -3309,201 +3302,202 @@ impl FlagComputation { } } -pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> { - match tm { - ast::TyIs => tcx.types.isize, - ast::TyI8 => tcx.types.i8, - ast::TyI16 => tcx.types.i16, - ast::TyI32 => tcx.types.i32, - ast::TyI64 => tcx.types.i64, +impl<'tcx> ctxt<'tcx> { + // Interns a type/name combination, stores the resulting box in cx.interner, + // and returns the box as cast to an unsafe ptr (see comments for Ty above). + pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> { + let mut interner = self.interner.borrow_mut(); + intern_ty(&self.arenas.type_, &mut *interner, st) } -} -pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> { - match tm { - ast::TyUs => tcx.types.usize, - ast::TyU8 => tcx.types.u8, - ast::TyU16 => tcx.types.u16, - ast::TyU32 => tcx.types.u32, - ast::TyU64 => tcx.types.u64, + pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> { + match tm { + ast::TyIs => self.types.isize, + ast::TyI8 => self.types.i8, + ast::TyI16 => self.types.i16, + ast::TyI32 => self.types.i32, + ast::TyI64 => self.types.i64, + } } -} -pub fn mk_mach_float<'tcx>(tcx: &ctxt<'tcx>, tm: ast::FloatTy) -> Ty<'tcx> { - match tm { - ast::TyF32 => tcx.types.f32, - ast::TyF64 => tcx.types.f64, + pub fn mk_mach_uint(&self, tm: ast::UintTy) -> Ty<'tcx> { + match tm { + ast::TyUs => self.types.usize, + ast::TyU8 => self.types.u8, + ast::TyU16 => self.types.u16, + ast::TyU32 => self.types.u32, + ast::TyU64 => self.types.u64, + } } -} -pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_t(cx, TyStr) -} + pub fn mk_mach_float(&self, tm: ast::FloatTy) -> Ty<'tcx> { + match tm { + ast::TyF32 => self.types.f32, + ast::TyF64 => self.types.f64, + } + } -pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, m: ast::Mutability) -> Ty<'tcx> { - mk_rptr(cx, r, - mt { - ty: mk_t(cx, TyStr), - mutbl: m - }) -} + pub fn mk_str(&self) -> Ty<'tcx> { + self.mk_ty(TyStr) + } -pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> { - // take a copy of substs so that we own the vectors inside - mk_t(cx, TyEnum(did, substs)) -} + pub fn mk_static_str(&self) -> Ty<'tcx> { + self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str()) + } -pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, TyBox(ty)) } + pub fn mk_enum(&self, did: ast::DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> { + // take a copy of substs so that we own the vectors inside + self.mk_ty(TyEnum(did, substs)) + } -pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> { mk_t(cx, TyRawPtr(tm)) } + pub fn mk_box(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ty(TyBox(ty)) + } -pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> { - mk_t(cx, TyRef(r, tm)) -} + pub fn mk_ptr(&self, tm: mt<'tcx>) -> Ty<'tcx> { + self.mk_ty(TyRawPtr(tm)) + } -pub fn mk_mut_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { - mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutMutable}) -} -pub fn mk_imm_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { - mk_rptr(cx, r, mt {ty: ty, mutbl: ast::MutImmutable}) -} + pub fn mk_ref(&self, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> { + self.mk_ty(TyRef(r, tm)) + } -pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - mk_ptr(cx, mt {ty: ty, mutbl: ast::MutMutable}) -} + pub fn mk_mut_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ref(r, mt {ty: ty, mutbl: ast::MutMutable}) + } -pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - mk_ptr(cx, mt {ty: ty, mutbl: ast::MutImmutable}) -} + pub fn mk_imm_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ref(r, mt {ty: ty, mutbl: ast::MutImmutable}) + } -pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable}) -} + pub fn mk_mut_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ptr(mt {ty: ty, mutbl: ast::MutMutable}) + } -pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option) -> Ty<'tcx> { - match sz { - Some(n) => mk_t(cx, TyArray(ty, n)), - None => mk_t(cx, TySlice(ty)) + pub fn mk_imm_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ptr(mt {ty: ty, mutbl: ast::MutImmutable}) } -} -pub fn mk_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> { - mk_rptr(cx, r, - mt { - ty: mk_vec(cx, tm.ty, None), - mutbl: tm.mutbl - }) -} + pub fn mk_nil_ptr(&self) -> Ty<'tcx> { + self.mk_imm_ptr(self.mk_nil()) + } -pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec>) -> Ty<'tcx> { - mk_t(cx, TyTuple(ts)) -} + pub fn mk_array(&self, ty: Ty<'tcx>, n: usize) -> Ty<'tcx> { + self.mk_ty(TyArray(ty, n)) + } -pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_tup(cx, Vec::new()) -} + pub fn mk_slice(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.mk_ty(TySlice(ty)) + } -pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_t(cx, TyBool) -} + pub fn mk_tup(&self, ts: Vec>) -> Ty<'tcx> { + self.mk_ty(TyTuple(ts)) + } -pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>, - opt_def_id: Option, - fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> { - mk_t(cx, TyBareFn(opt_def_id, fty)) -} + pub fn mk_nil(&self) -> Ty<'tcx> { + self.mk_tup(Vec::new()) + } -pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>, - def_id: ast::DefId, - input_tys: &[Ty<'tcx>], - output: Ty<'tcx>) -> Ty<'tcx> { - let input_args = input_tys.iter().cloned().collect(); - mk_bare_fn(cx, - Some(def_id), - cx.mk_bare_fn(BareFnTy { - unsafety: ast::Unsafety::Normal, - abi: abi::Rust, - sig: ty::Binder(FnSig { - inputs: input_args, - output: ty::FnConverging(output), - variadic: false - }) - })) -} - -pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>, - principal: ty::PolyTraitRef<'tcx>, - bounds: ExistentialBounds<'tcx>) - -> Ty<'tcx> -{ - assert!(bound_list_is_sorted(&bounds.projection_bounds)); + pub fn mk_bool(&self) -> Ty<'tcx> { + self.mk_ty(TyBool) + } - let inner = box TraitTy { - principal: principal, - bounds: bounds - }; - mk_t(cx, TyTrait(inner)) -} + pub fn mk_fn(&self, + opt_def_id: Option, + fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> { + self.mk_ty(TyBareFn(opt_def_id, fty)) + } -fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool { - bounds.is_empty() || - bounds[1..].iter().enumerate().all( - |(index, bound)| bounds[index].sort_key() <= bound.sort_key()) -} + pub fn mk_ctor_fn(&self, + def_id: ast::DefId, + input_tys: &[Ty<'tcx>], + output: Ty<'tcx>) -> Ty<'tcx> { + let input_args = input_tys.iter().cloned().collect(); + self.mk_fn(Some(def_id), self.mk_bare_fn(BareFnTy { + unsafety: ast::Unsafety::Normal, + abi: abi::Rust, + sig: ty::Binder(FnSig { + inputs: input_args, + output: ty::FnConverging(output), + variadic: false + }) + })) + } -pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) { - bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key())) -} + pub fn mk_trait(&self, + principal: ty::PolyTraitRef<'tcx>, + bounds: ExistentialBounds<'tcx>) + -> Ty<'tcx> + { + assert!(bound_list_is_sorted(&bounds.projection_bounds)); -pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>, - trait_ref: TraitRef<'tcx>, - item_name: ast::Name) - -> Ty<'tcx> { - // take a copy of substs so that we own the vectors inside - let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name }; - mk_t(cx, TyProjection(inner)) -} + let inner = box TraitTy { + principal: principal, + bounds: bounds + }; + self.mk_ty(TyTrait(inner)) + } -pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId, - substs: &'tcx Substs<'tcx>) -> Ty<'tcx> { - // take a copy of substs so that we own the vectors inside - mk_t(cx, TyStruct(struct_id, substs)) -} + pub fn mk_projection(&self, + trait_ref: TraitRef<'tcx>, + item_name: ast::Name) + -> Ty<'tcx> { + // take a copy of substs so that we own the vectors inside + let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name }; + self.mk_ty(TyProjection(inner)) + } -pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>) - -> Ty<'tcx> { - mk_t(cx, TyClosure(closure_id, substs)) -} + pub fn mk_struct(&self, struct_id: ast::DefId, + substs: &'tcx Substs<'tcx>) -> Ty<'tcx> { + // take a copy of substs so that we own the vectors inside + self.mk_ty(TyStruct(struct_id, substs)) + } -pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> { - mk_infer(cx, TyVar(v)) -} + pub fn mk_closure(&self, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>) + -> Ty<'tcx> { + self.mk_ty(TyClosure(closure_id, substs)) + } -pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> { - mk_infer(cx, IntVar(v)) -} + pub fn mk_var(&self, v: TyVid) -> Ty<'tcx> { + self.mk_infer(TyVar(v)) + } -pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> { - mk_infer(cx, FloatVar(v)) -} + pub fn mk_int_var(&self, v: IntVid) -> Ty<'tcx> { + self.mk_infer(IntVar(v)) + } -pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> { - mk_t(cx, TyInfer(it)) -} + pub fn mk_float_var(&self, v: FloatVid) -> Ty<'tcx> { + self.mk_infer(FloatVar(v)) + } + + pub fn mk_infer(&self, it: InferTy) -> Ty<'tcx> { + self.mk_ty(TyInfer(it)) + } + + pub fn mk_param(&self, + space: subst::ParamSpace, + index: u32, + name: ast::Name) -> Ty<'tcx> { + self.mk_ty(TyParam(ParamTy { space: space, idx: index, name: name })) + } + + pub fn mk_self_type(&self) -> Ty<'tcx> { + self.mk_param(subst::SelfSpace, 0, special_idents::type_self.name) + } -pub fn mk_param<'tcx>(cx: &ctxt<'tcx>, - space: subst::ParamSpace, - index: u32, - name: ast::Name) -> Ty<'tcx> { - mk_t(cx, TyParam(ParamTy { space: space, idx: index, name: name })) + pub fn mk_param_from_def(&self, def: &TypeParameterDef) -> Ty<'tcx> { + self.mk_param(def.space, def.index, def.name) + } } -pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { - mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name) +fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate]) -> bool { + bounds.is_empty() || + bounds[1..].iter().enumerate().all( + |(index, bound)| bounds[index].sort_key() <= bound.sort_key()) } -pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> { - mk_param(cx, def.space, def.index, def.name) +pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) { + bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key())) } impl<'tcx> TyS<'tcx> { @@ -3586,7 +3580,7 @@ impl ParamTy { } pub fn to_ty<'tcx>(self, tcx: &ctxt<'tcx>) -> Ty<'tcx> { - ty::mk_param(tcx, self.space, self.idx, self.name) + tcx.mk_param(self.space, self.idx, self.name) } pub fn is_self(&self) -> bool { @@ -3657,7 +3651,7 @@ impl<'tcx> TyS<'tcx> { pub fn sequence_element_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { match self.sty { TyArray(ty, _) | TySlice(ty) => ty, - TyStr => mk_mach_uint(cx, ast::TyU8), + TyStr => cx.mk_mach_uint(ast::TyU8), _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}", self)), } @@ -4745,18 +4739,6 @@ pub fn ty_region(tcx: &ctxt, } } -pub fn free_region_from_def(outlives_extent: region::DestructionScopeData, - def: &RegionParameterDef) - -> ty::Region -{ - let ret = - ty::ReFree(ty::FreeRegion { scope: outlives_extent, - bound_region: ty::BrNamed(def.def_id, - def.name) }); - debug!("free_region_from_def returns {:?}", ret); - ret -} - // Returns the type of a pattern as a monotype. Like @expr_ty, this function // doesn't provide type parameter substitutions. pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> { @@ -4860,7 +4842,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>, AdjustReifyFnPointer => { match unadjusted_ty.sty { ty::TyBareFn(Some(_), b) => { - ty::mk_bare_fn(cx, None, b) + cx.mk_fn(None, b) } _ => { cx.sess.bug( @@ -4932,10 +4914,10 @@ pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>, match autoref { None => ty, Some(AutoPtr(r, m)) => { - mk_rptr(cx, r, mt { ty: ty, mutbl: m }) + cx.mk_ref(r, mt { ty: ty, mutbl: m }) } Some(AutoUnsafe(m)) => { - mk_ptr(cx, mt { ty: ty, mutbl: m }) + cx.mk_ptr(mt { ty: ty, mutbl: m }) } } } @@ -6185,12 +6167,11 @@ pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>, freevar_ty } UpvarCapture::ByRef(borrow) => { - mk_rptr(tcx, - tcx.mk_region(borrow.region), - ty::mt { - ty: freevar_ty, - mutbl: borrow.kind.to_mutbl_lossy(), - }) + tcx.mk_ref(tcx.mk_region(borrow.region), + ty::mt { + ty: freevar_ty, + mutbl: borrow.kind.to_mutbl_lossy(), + }) } }; @@ -6698,8 +6679,12 @@ pub fn construct_free_substs<'a,'tcx>( all_outlive_extent: region::DestructionScopeData, region_params: &[RegionParameterDef]) { - for r in region_params { - regions.push(r.space, ty::free_region_from_def(all_outlive_extent, r)); + for def in region_params { + let region = + ReFree(FreeRegion { scope: all_outlive_extent, + bound_region: BrNamed(def.def_id, def.name) }); + debug!("push_region_params {:?}", region); + regions.push(def.space, region); } } @@ -6709,7 +6694,7 @@ pub fn construct_free_substs<'a,'tcx>( for def in defs { debug!("construct_parameter_environment(): push_types_from_defs: def={:?}", def); - let ty = ty::mk_param_from_def(tcx, def); + let ty = tcx.mk_param_from_def(def); types.push(def.space, ty); } } @@ -7161,7 +7146,7 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ctxt<'tcx>, let meth_tps: Vec = method.generics.types.get_slice(subst::FnSpace) .iter() - .map(|def| ty::mk_param_from_def(tcx, def)) + .map(|def| tcx.mk_param_from_def(def)) .collect(); let meth_regions: Vec = method.generics.regions.get_slice(subst::FnSpace) diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index ea52b1da36168..012f5216ed7e3 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -641,7 +641,7 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, ty.sty.clone() } }; - ty::mk_t(this.tcx(), sty) + this.tcx().mk_ty(sty) } pub fn super_fold_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T, diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs index b8c212fe3f20b..422498624a9d3 100644 --- a/src/librustc/middle/ty_relate/mod.rs +++ b/src/librustc/middle/ty_relate/mod.rs @@ -469,21 +469,21 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, if a_id == b_id => { let substs = try!(relate_item_substs(relation, a_id, a_substs, b_substs)); - Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs))) + Ok(tcx.mk_enum(a_id, tcx.mk_substs(substs))) } (&ty::TyTrait(ref a_), &ty::TyTrait(ref b_)) => { let principal = try!(relation.relate(&a_.principal, &b_.principal)); let bounds = try!(relation.relate(&a_.bounds, &b_.bounds)); - Ok(ty::mk_trait(tcx, principal, bounds)) + Ok(tcx.mk_trait(principal, bounds)) } (&ty::TyStruct(a_id, a_substs), &ty::TyStruct(b_id, b_substs)) if a_id == b_id => { let substs = try!(relate_item_substs(relation, a_id, a_substs, b_substs)); - Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs))) + Ok(tcx.mk_struct(a_id, tcx.mk_substs(substs))) } (&ty::TyClosure(a_id, a_substs), @@ -494,33 +494,33 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, // the (anonymous) type of the same closure expression. So // all of their regions should be equated. let substs = try!(relate_substs(relation, None, a_substs, b_substs)); - Ok(ty::mk_closure(tcx, a_id, tcx.mk_substs(substs))) + Ok(tcx.mk_closure(a_id, tcx.mk_substs(substs))) } (&ty::TyBox(a_inner), &ty::TyBox(b_inner)) => { let typ = try!(relation.relate(&a_inner, &b_inner)); - Ok(ty::mk_uniq(tcx, typ)) + Ok(tcx.mk_box(typ)) } (&ty::TyRawPtr(ref a_mt), &ty::TyRawPtr(ref b_mt)) => { let mt = try!(relation.relate(a_mt, b_mt)); - Ok(ty::mk_ptr(tcx, mt)) + Ok(tcx.mk_ptr(mt)) } (&ty::TyRef(a_r, ref a_mt), &ty::TyRef(b_r, ref b_mt)) => { let r = try!(relation.relate_with_variance(ty::Contravariant, a_r, b_r)); let mt = try!(relation.relate(a_mt, b_mt)); - Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt)) + Ok(tcx.mk_ref(tcx.mk_region(r), mt)) } (&ty::TyArray(a_t, sz_a), &ty::TyArray(b_t, sz_b)) => { let t = try!(relation.relate(&a_t, &b_t)); if sz_a == sz_b { - Ok(ty::mk_vec(tcx, t, Some(sz_a))) + Ok(tcx.mk_array(t, sz_a)) } else { Err(ty::terr_fixed_array_size(expected_found(relation, &sz_a, &sz_b))) } @@ -529,7 +529,7 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, (&ty::TySlice(a_t), &ty::TySlice(b_t)) => { let t = try!(relation.relate(&a_t, &b_t)); - Ok(ty::mk_vec(tcx, t, None)) + Ok(tcx.mk_slice(t)) } (&ty::TyTuple(ref as_), &ty::TyTuple(ref bs)) => @@ -538,7 +538,7 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, let ts = try!(as_.iter().zip(bs) .map(|(a, b)| relation.relate(a, b)) .collect::>()); - Ok(ty::mk_tup(tcx, ts)) + Ok(tcx.mk_tup(ts)) } else if !(as_.is_empty() || bs.is_empty()) { Err(ty::terr_tuple_size( expected_found(relation, &as_.len(), &bs.len()))) @@ -551,13 +551,13 @@ pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R, if a_opt_def_id == b_opt_def_id => { let fty = try!(relation.relate(a_fty, b_fty)); - Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty))) + Ok(tcx.mk_fn(a_opt_def_id, tcx.mk_bare_fn(fty))) } (&ty::TyProjection(ref a_data), &ty::TyProjection(ref b_data)) => { let projection_ty = try!(relation.relate(a_data, b_data)); - Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name)) + Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name)) } _ => diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 9ceaf748af7b1..02ea8859b5c75 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -256,30 +256,29 @@ impl<'a, 'tcx> Env<'a, 'tcx> { -> Ty<'tcx> { let input_args = input_tys.iter().cloned().collect(); - ty::mk_bare_fn(self.infcx.tcx, - None, - self.infcx.tcx.mk_bare_fn(ty::BareFnTy { - unsafety: ast::Unsafety::Normal, - abi: abi::Rust, - sig: ty::Binder(ty::FnSig { - inputs: input_args, - output: ty::FnConverging(output_ty), - variadic: false - }) - })) + self.infcx.tcx.mk_fn(None, + self.infcx.tcx.mk_bare_fn(ty::BareFnTy { + unsafety: ast::Unsafety::Normal, + abi: abi::Rust, + sig: ty::Binder(ty::FnSig { + inputs: input_args, + output: ty::FnConverging(output_ty), + variadic: false + }) + })) } pub fn t_nil(&self) -> Ty<'tcx> { - ty::mk_nil(self.infcx.tcx) + self.infcx.tcx.mk_nil() } pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> { - ty::mk_tup(self.infcx.tcx, vec![ty1, ty2]) + self.infcx.tcx.mk_tup(vec![ty1, ty2]) } pub fn t_param(&self, space: subst::ParamSpace, index: u32) -> Ty<'tcx> { let name = format!("T{}", index); - ty::mk_param(self.infcx.tcx, space, index, token::intern(&name[..])) + self.infcx.tcx.mk_param(space, index, token::intern(&name[..])) } pub fn re_early_bound(&self, @@ -302,16 +301,14 @@ impl<'a, 'tcx> Env<'a, 'tcx> { } pub fn t_rptr(&self, r: ty::Region) -> Ty<'tcx> { - ty::mk_imm_rptr(self.infcx.tcx, - self.infcx.tcx.mk_region(r), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), + self.tcx().types.isize) } pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> { let r = self.re_late_bound_with_debruijn(id, ty::DebruijnIndex::new(1)); - ty::mk_imm_rptr(self.infcx.tcx, - self.infcx.tcx.mk_region(r), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), + self.tcx().types.isize) } pub fn t_rptr_late_bound_with_debruijn(&self, @@ -319,15 +316,14 @@ impl<'a, 'tcx> Env<'a, 'tcx> { debruijn: ty::DebruijnIndex) -> Ty<'tcx> { let r = self.re_late_bound_with_debruijn(id, debruijn); - ty::mk_imm_rptr(self.infcx.tcx, - self.infcx.tcx.mk_region(r), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), + self.tcx().types.isize) } pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> { let r = ty::ReScope(CodeExtent::from_node_id(id)); - ty::mk_imm_rptr(self.infcx.tcx, self.infcx.tcx.mk_region(r), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), + self.tcx().types.isize) } pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region { @@ -337,15 +333,13 @@ impl<'a, 'tcx> Env<'a, 'tcx> { pub fn t_rptr_free(&self, nid: ast::NodeId, id: u32) -> Ty<'tcx> { let r = self.re_free(nid, id); - ty::mk_imm_rptr(self.infcx.tcx, - self.infcx.tcx.mk_region(r), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r), + self.tcx().types.isize) } pub fn t_rptr_static(&self) -> Ty<'tcx> { - ty::mk_imm_rptr(self.infcx.tcx, - self.infcx.tcx.mk_region(ty::ReStatic), - self.tcx().types.isize) + self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(ty::ReStatic), + self.tcx().types.isize) } pub fn dummy_type_trace(&self) -> infer::TypeTrace<'tcx> { @@ -804,9 +798,9 @@ fn walk_ty() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let uint_ty = tcx.types.usize; - let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty)); - let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); - let uniq_ty = ty::mk_uniq(tcx, tup2_ty); + let tup1_ty = tcx.mk_tup(vec!(int_ty, uint_ty, int_ty, uint_ty)); + let tup2_ty = tcx.mk_tup(vec!(tup1_ty, tup1_ty, uint_ty)); + let uniq_ty = tcx.mk_box(tup2_ty); let walked: Vec<_> = uniq_ty.walk().collect(); assert_eq!(walked, [uniq_ty, tup2_ty, @@ -822,9 +816,9 @@ fn walk_ty_skip_subtree() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let uint_ty = tcx.types.usize; - let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty)); - let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); - let uniq_ty = ty::mk_uniq(tcx, tup2_ty); + let tup1_ty = tcx.mk_tup(vec!(int_ty, uint_ty, int_ty, uint_ty)); + let tup2_ty = tcx.mk_tup(vec!(tup1_ty, tup1_ty, uint_ty)); + let uniq_ty = tcx.mk_box(tup2_ty); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index ffb860283dd7e..29799d34ee583 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1699,15 +1699,15 @@ impl LintPass for MissingCopyImplementations { if ast_generics.is_parameterized() { return; } - ty::mk_struct(cx.tcx, local_def(item.id), - cx.tcx.mk_substs(Substs::empty())) + cx.tcx.mk_struct(local_def(item.id), + cx.tcx.mk_substs(Substs::empty())) } ast::ItemEnum(_, ref ast_generics) => { if ast_generics.is_parameterized() { return; } - ty::mk_enum(cx.tcx, local_def(item.id), - cx.tcx.mk_substs(Substs::empty())) + cx.tcx.mk_enum(local_def(item.id), + cx.tcx.mk_substs(Substs::empty())) } _ => return, }; diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index dd47a3a871842..4667e36c64a9a 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -674,9 +674,8 @@ fn bind_subslice_pat(bcx: Block, let slice_begin = InBoundsGEP(bcx, base, &[C_uint(bcx.ccx(), offset_left)]); let slice_len_offset = C_uint(bcx.ccx(), offset_left + offset_right); let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None); - let slice_ty = ty::mk_slice(bcx.tcx(), - bcx.tcx().mk_region(ty::ReStatic), - ty::mt {ty: unit_ty, mutbl: ast::MutImmutable}); + let slice_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), + bcx.tcx().mk_slice(unit_ty)); let scratch = rvalue_scratch_datum(bcx, slice_ty, ""); Store(bcx, slice_begin, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR])); @@ -854,9 +853,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>, // NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item, // which calls memcmp(). let pat_len = val_ty(rhs).element_type().array_length(); - let ty_str_slice = ty::mk_str_slice(cx.tcx(), - cx.tcx().mk_region(ty::ReStatic), - ast::MutImmutable); + let ty_str_slice = cx.tcx().mk_static_str(); let rhs_str = alloc_ty(cx, ty_str_slice, "rhs_str"); Store(cx, GEPi(cx, rhs, &[0, 0]), expr::get_dataptr(cx, rhs_str)); @@ -1063,7 +1060,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, .unwrap_or(DUMMY_NODE_ID); let left_ty = if pat_id == DUMMY_NODE_ID { - ty::mk_nil(tcx) + tcx.mk_nil() } else { node_id_type(bcx, pat_id) }; diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 2a1c2457b9d32..255920aa96d54 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -623,8 +623,8 @@ fn bounds_usable(cx: &CrateContext, ity: IntType, bounds: &IntBounds) -> bool { pub fn ty_of_inttype<'tcx>(tcx: &ty::ctxt<'tcx>, ity: IntType) -> Ty<'tcx> { match ity { - attr::SignedInt(t) => ty::mk_mach_int(tcx, t), - attr::UnsignedInt(t) => ty::mk_mach_uint(tcx, t) + attr::SignedInt(t) => tcx.mk_mach_int(t), + attr::UnsignedInt(t) => tcx.mk_mach_uint(t) } } @@ -1078,7 +1078,7 @@ pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, -> datum::DatumBlock<'blk, 'tcx, datum::Expr> { let tcx = bcx.tcx(); - let ptr_ty = ty::mk_imm_ptr(bcx.tcx(), tcx.dtor_type()); + let ptr_ty = bcx.tcx().mk_imm_ptr(tcx.dtor_type()); match *r { Univariant(ref st, dtor) if dtor_active(dtor) => { let flag_ptr = GEPi(bcx, val, &[0, st.fields.len() - 1]); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 81951600a3a33..b86bf67869d77 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -202,10 +202,10 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let closure_kind = ccx.tcx().closure_kind(closure_id); match closure_kind { ty::FnClosureKind => { - ty::mk_imm_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty) + ccx.tcx().mk_imm_ref(ccx.tcx().mk_region(ty::ReStatic), fn_ty) } ty::FnMutClosureKind => { - ty::mk_mut_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty) + ccx.tcx().mk_mut_ref(ccx.tcx().mk_region(ty::ReStatic), fn_ty) } ty::FnOnceClosureKind => fn_ty } @@ -1579,7 +1579,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Tuple up closure argument types for the "rust-call" ABI. closure::ClosureEnv::Closure(_) => { - vec![ty::mk_tup(ccx.tcx(), monomorphized_arg_types)] + vec![ccx.tcx().mk_tup(monomorphized_arg_types)] } }; for monomorphized_arg_type in &monomorphized_arg_types { @@ -2115,7 +2115,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, debug!("register_fn_llvmty id={} sym={}", node_id, sym); let llfn = declare::define_fn(ccx, &sym[..], cc, llfty, - ty::FnConverging(ty::mk_nil(ccx.tcx()))).unwrap_or_else(||{ + ty::FnConverging(ccx.tcx().mk_nil())).unwrap_or_else(||{ ccx.sess().span_fatal(sp, &format!("symbol `{}` is already defined", sym)); }); finish_register_fn(ccx, sym, node_id, llfn); @@ -2197,7 +2197,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, &ccx.int_type()); let llfn = declare::define_cfn(ccx, "main", llfty, - ty::mk_nil(ccx.tcx())).unwrap_or_else(||{ + ccx.tcx().mk_nil()).unwrap_or_else(||{ ccx.sess().span_err(sp, "entry symbol `main` defined multiple times"); // FIXME: We should be smart and show a better diagnostic here. ccx.sess().help("did you use #[no_mangle] on `fn main`? Use #[start] instead"); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 3b7a92c09ec3f..a7c01036f845e 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -277,7 +277,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( ty::FnOnceClosureKind => false, }; let bare_fn_ty_maybe_ref = if is_by_ref { - ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), bare_fn_ty) + tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), bare_fn_ty) } else { bare_fn_ty }; @@ -308,18 +308,17 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( } }; let sig = ty::erase_late_bound_regions(tcx, sig); - let tuple_input_ty = ty::mk_tup(tcx, sig.inputs.to_vec()); - let tuple_fn_ty = ty::mk_bare_fn(tcx, - opt_def_id, - tcx.mk_bare_fn(ty::BareFnTy { - unsafety: ast::Unsafety::Normal, - abi: synabi::RustCall, - sig: ty::Binder(ty::FnSig { - inputs: vec![bare_fn_ty_maybe_ref, - tuple_input_ty], - output: sig.output, - variadic: false - })})); + let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec()); + let tuple_fn_ty = tcx.mk_fn(opt_def_id, + tcx.mk_bare_fn(ty::BareFnTy { + unsafety: ast::Unsafety::Normal, + abi: synabi::RustCall, + sig: ty::Binder(ty::FnSig { + inputs: vec![bare_fn_ty_maybe_ref, + tuple_input_ty], + output: sig.output, + variadic: false + })})); debug!("tuple_fn_ty: {:?}", tuple_fn_ty); // @@ -615,7 +614,7 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, Some(method) => match method.origin { ty::MethodTraitObject(_) => match method.ty.sty { ty::TyBareFn(_, ref fty) => { - ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty)) + bcx.tcx().mk_fn(None, meth::opaque_method_ty(bcx.tcx(), fty)) } _ => method.ty }, @@ -749,7 +748,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, expr::Ignore => { let ret_ty = match ret_ty { ty::FnConverging(ret_ty) => ret_ty, - ty::FnDiverging => ty::mk_nil(ccx.tcx()) + ty::FnDiverging => ccx.tcx().mk_nil() }; if !is_rust_fn || type_of::return_uses_outptr(ccx, ret_ty) || diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 61351847a830c..b1c8671383767 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -363,8 +363,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( // Find a version of the closure type. Substitute static for the // region since it doesn't really matter. let substs = tcx.mk_substs(substs); - let closure_ty = ty::mk_closure(tcx, closure_def_id, substs); - let ref_closure_ty = ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), closure_ty); + let closure_ty = tcx.mk_closure(closure_def_id, substs); + let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), closure_ty); // Make a version with the type of by-ref closure. let ty::ClosureTy { unsafety, abi, mut sig } = typer.closure_type(closure_def_id, substs); @@ -372,7 +372,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig.clone() }); - let llref_fn_ty = ty::mk_bare_fn(tcx, None, llref_bare_fn_ty); + let llref_fn_ty = tcx.mk_fn(None, llref_bare_fn_ty); debug!("trans_fn_once_adapter_shim: llref_fn_ty={:?}", llref_fn_ty); @@ -383,7 +383,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let llonce_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, sig: sig }); - let llonce_fn_ty = ty::mk_bare_fn(tcx, None, llonce_bare_fn_ty); + let llonce_fn_ty = tcx.mk_fn(None, llonce_bare_fn_ty); // Create the by-value helper. let function_name = link::mangle_internal_name_by_type_and_seq(ccx, llonce_fn_ty, "once_shim"); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 30cb0680b6997..a12c07c975017 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -306,7 +306,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Don't copy data to do a deref+ref // (i.e., skip the last auto-deref). llconst = addr_of(cx, llconst, "autoref"); - ty = ty::mk_imm_rptr(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ty); + ty = cx.tcx().mk_imm_ref(cx.tcx().mk_region(ty::ReStatic), ty); } } else { let (dv, dt) = const_deref(cx, llconst, ty); diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 0ae69682f914a..cf9d70cc65727 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -791,7 +791,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $ret:expr) => ( if *key == $name { let f = declare::declare_cfn(ccx, $name, Type::func(&[], &$ret), - ty::mk_nil(ccx.tcx())); + ccx.tcx().mk_nil()); ccx.intrinsics().borrow_mut().insert($name, f.clone()); return Some(f); } @@ -799,7 +799,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $ret:expr) => ( if *key == $name { let f = declare::declare_cfn(ccx, $name, Type::func(&[$($arg),*], &$ret), - ty::mk_nil(ccx.tcx())); + ccx.tcx().mk_nil()); ccx.intrinsics().borrow_mut().insert($name, f.clone()); return Some(f); } @@ -939,7 +939,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option Option(cx: &CrateContext<'a, 'tcx>, unique_type_id: UniqueTypeId, span: Span) -> MetadataCreationResult { - let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt { + let data_ptr_type = cx.tcx().mk_ptr(ty::mt { ty: element_type, mutbl: ast::MutImmutable }); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 9d30023cd189a..2187b7f6ae1c6 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1110,7 +1110,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, None, expr.span, expr.id, - ty::mk_struct(tcx, did, tcx.mk_substs(substs)), + tcx.mk_struct(did, tcx.mk_substs(substs)), dest) } else { tcx.sess.span_bug(expr.span, @@ -1697,7 +1697,7 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, lval: Datum<'tcx, Lvalue>) -> DatumBlock<'blk, 'tcx, Expr> { - let dest_ty = ty::mk_imm_rptr(bcx.tcx(), bcx.tcx().mk_region(ty::ReStatic), lval.ty); + let dest_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), lval.ty); let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr"); memcpy_ty(bcx, scratch.val, lval.val, scratch.ty); @@ -2180,7 +2180,7 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Compute final type. Note that we are loose with the region and // mutability, since those things don't matter in trans. let referent_ty = lv_datum.ty; - let ptr_ty = ty::mk_imm_rptr(bcx.tcx(), bcx.tcx().mk_region(ty::ReStatic), referent_ty); + let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), referent_ty); // Get the pointer. let llref = lv_datum.to_llref(); diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 2ac6b02445cce..6f3346b9329a2 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -538,7 +538,7 @@ pub fn decl_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => panic!("expected bare fn in decl_rust_fn_with_foreign_abi") }; let llfn = declare::declare_fn(ccx, name, cconv, llfn_ty, - ty::FnConverging(ty::mk_nil(ccx.tcx()))); + ty::FnConverging(ccx.tcx().mk_nil())); add_argument_attributes(&tys, llfn); debug!("decl_rust_fn_with_foreign_abi(llfn_ty={}, llfn={})", ccx.tn().type_to_string(llfn_ty), ccx.tn().val_to_string(llfn)); diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 5e7f067a4b3b8..7a5ccd5b9c617 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -218,7 +218,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let llty = if type_is_sized(ccx.tcx(), t) { type_of(ccx, t).ptr_to() } else { - type_of(ccx, ty::mk_uniq(ccx.tcx(), t)).ptr_to() + type_of(ccx, ccx.tcx().mk_box(t)).ptr_to() }; let llfnty = Type::glue_fn(ccx, llty); @@ -226,13 +226,13 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // To avoid infinite recursion, don't `make_drop_glue` until after we've // added the entry to the `drop_glues` cache. if let Some(old_sym) = ccx.available_drop_glues().borrow().get(&g) { - let llfn = declare::declare_cfn(ccx, &old_sym, llfnty, ty::mk_nil(ccx.tcx())); + let llfn = declare::declare_cfn(ccx, &old_sym, llfnty, ccx.tcx().mk_nil()); ccx.drop_glues().borrow_mut().insert(g, llfn); return llfn; }; let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, "drop"); - let llfn = declare::define_cfn(ccx, &fn_nm, llfnty, ty::mk_nil(ccx.tcx())).unwrap_or_else(||{ + let llfn = declare::define_cfn(ccx, &fn_nm, llfnty, ccx.tcx().mk_nil()).unwrap_or_else(||{ ccx.sess().bug(&format!("symbol `{}` already defined", fn_nm)); }); ccx.available_drop_glues().borrow_mut().insert(g, fn_nm); @@ -243,10 +243,10 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let (arena, fcx): (TypedArena<_>, FunctionContext); arena = TypedArena::new(); fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, - ty::FnConverging(ty::mk_nil(ccx.tcx())), + ty::FnConverging(ccx.tcx().mk_nil()), empty_substs, None, &arena); - let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx()))); + let bcx = init_function(&fcx, false, ty::FnConverging(ccx.tcx().mk_nil())); update_linkage(ccx, llfn, None, OriginalTranslation); @@ -261,7 +261,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let llrawptr0 = get_param(llfn, fcx.arg_offset() as c_uint); let bcx = make_drop_glue(bcx, llrawptr0, g); - finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None); + finish_fn(&fcx, bcx, ty::FnConverging(ccx.tcx().mk_nil()), DebugLoc::None); llfn } @@ -328,10 +328,9 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let name = csearch::get_symbol(&ccx.sess().cstore, did); let class_ty = ty::lookup_item_type(tcx, parent_id).ty.subst(tcx, substs); let llty = type_of_dtor(ccx, class_ty); - let dtor_ty = ty::mk_ctor_fn(ccx.tcx(), - did, - &[get_drop_glue_type(ccx, t)], - ty::mk_nil(ccx.tcx())); + let dtor_ty = ccx.tcx().mk_ctor_fn(did, + &[get_drop_glue_type(ccx, t)], + ccx.tcx().mk_nil()); foreign::get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), &name[..], llvm::CCallConv, llty, dtor_ty) } @@ -371,7 +370,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx.fcx.schedule_drop_adt_contents(cleanup::CustomScope(contents_scope), v0, t); let glue_type = get_drop_glue_type(bcx.ccx(), t); - let dtor_ty = ty::mk_ctor_fn(bcx.tcx(), class_did, &[glue_type], ty::mk_nil(bcx.tcx())); + let dtor_ty = bcx.tcx().mk_ctor_fn(class_did, &[glue_type], bcx.tcx().mk_nil()); let (_, bcx) = invoke(bcx, dtor_addr, &[v0], dtor_ty, DebugLoc::None); bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, contents_scope) diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index f78d1c44f5f42..c6107f7d268af 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -584,8 +584,8 @@ pub fn trans_object_shim<'a, 'tcx>( debug!("trans_object_shim: fty={:?} method_ty={:?}", fty, method_ty); // - let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty); - let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty); + let shim_fn_ty = tcx.mk_fn(None, fty); + let method_bare_fn_ty = tcx.mk_fn(None, method_ty); let function_name = link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim"); let llfn = declare::define_internal_rust_fn(ccx, &function_name, shim_fn_ty).unwrap_or_else(||{ ccx.sess().bug(&format!("symbol `{}` already defined", function_name)); @@ -827,7 +827,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>) -> &'tcx ty::BareFnTy<'tcx> { let mut inputs = method_ty.sig.0.inputs.clone(); - inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8)); + inputs[0] = tcx.mk_mut_ptr(tcx.mk_mach_int(ast::TyI8)); tcx.mk_bare_fn(ty::BareFnTy { unsafety: method_ty.unsafety, diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 8b28d9c1250e7..3c6770caef8d1 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -106,9 +106,7 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let count = elements_required(bcx, content_expr); debug!(" vt={}, count={}", vt.to_string(ccx), count); - let fixed_ty = ty::mk_vec(bcx.tcx(), - vt.unit_ty, - Some(count)); + let fixed_ty = bcx.tcx().mk_array(vt.unit_ty, count); let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty); // Always create an alloca even if zero-sized, to preserve diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index a27166844806c..96eae5fd184ab 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -278,7 +278,7 @@ pub fn arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type { /// For the raw type without far pointer indirection, see `in_memory_type_of`. pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type { let ty = if !type_is_sized(cx.tcx(), ty) { - ty::mk_imm_ptr(cx.tcx(), ty) + cx.tcx().mk_imm_ptr(ty) } else { ty }; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ec5b543cfcd18..d5e57e163029d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -579,7 +579,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>, let (implied_output_region, params_lifetimes) = find_implied_output_region(&*inputs, input_params); - let input_ty = ty::mk_tup(this.tcx(), inputs); + let input_ty = this.tcx().mk_tup(inputs); let (output, output_span) = match data.output { Some(ref output_ty) => { @@ -590,7 +590,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>, output_ty.span) } None => { - (ty::mk_nil(this.tcx()), data.span) + (this.tcx().mk_nil(), data.span) } }; @@ -852,7 +852,7 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>( // this, we currently insert a dummy type and then remove it // later. Yuck. - let dummy_self_ty = ty::mk_infer(tcx, ty::FreshTy(0)); + let dummy_self_ty = tcx.mk_infer(ty::FreshTy(0)); if self_ty.is_none() { // if converting for an object type let mut dummy_substs = trait_ref.skip_binder().substs.clone(); // binder moved here -+ assert!(dummy_substs.self_ty().is_none()); // | @@ -924,7 +924,7 @@ fn ast_path_to_ty<'tcx>( // FIXME(#12938): This is a hack until we have full support for DST. if Some(did) == this.tcx().lang_items.owned_box() { assert_eq!(substs.types.len(TypeSpace), 1); - return ty::mk_uniq(this.tcx(), *substs.types.get(TypeSpace, 0)); + return this.tcx().mk_box(*substs.types.get(TypeSpace, 0)); } decl_ty.subst(this.tcx(), &substs) @@ -1081,7 +1081,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>, ty::item_path_str(tcx, trait_def_id)); } - ty::mk_trait(tcx, object.principal, object.bounds) + tcx.mk_trait(object.principal, object.bounds) } fn report_ambiguous_associated_type(tcx: &ty::ctxt, @@ -1393,7 +1393,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, } def::DefTyParam(space, index, _, name) => { check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS); - ty::mk_param(tcx, space, index, name) + tcx.mk_param(space, index, name) } def::DefSelfTy(_, Some((_, self_ty_id))) => { // Self in impl (we know the concrete type). @@ -1411,7 +1411,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>, def::DefSelfTy(Some(_), None) => { // Self in trait. check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS); - ty::mk_self_type(tcx) + tcx.mk_self_type() } def::DefAssociatedTy(trait_did, _) => { check_path_args(tcx, &base_segments[..base_segments.len()-2], NO_TPS | NO_REGIONS); @@ -1509,7 +1509,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, let typ = match ast_ty.node { ast::TyVec(ref ty) => { - ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None) + tcx.mk_slice(ast_ty_to_ty(this, rscope, &**ty)) } ast::TyObjectSum(ref ty, ref bounds) => { match ast_ty_to_trait_ref(this, rscope, &**ty, bounds) { @@ -1527,7 +1527,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, } } ast::TyPtr(ref mt) => { - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: ast_ty_to_ty(this, rscope, &*mt.ty), mutbl: mt.mutbl }) @@ -1540,13 +1540,13 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, rscope, Some(ty::ObjectLifetimeDefault::Specific(r))); let t = ast_ty_to_ty(this, rscope1, &*mt.ty); - ty::mk_rptr(tcx, tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl}) + tcx.mk_ref(tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl}) } ast::TyTup(ref fields) => { let flds = fields.iter() .map(|t| ast_ty_to_ty(this, rscope, &**t)) .collect(); - ty::mk_tup(tcx, flds) + tcx.mk_tup(flds) } ast::TyParen(ref typ) => ast_ty_to_ty(this, rscope, &**typ), ast::TyBareFn(ref bf) => { @@ -1555,7 +1555,7 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, "variadic function must have C calling convention"); } let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl); - ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn)) + tcx.mk_fn(None, tcx.mk_bare_fn(bare_fn)) } ast::TyPolyTraitRef(ref bounds) => { conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds) @@ -1603,11 +1603,11 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>, Ok(r) => { match r { ConstVal::Int(i) => - ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), - Some(i as usize)), + tcx.mk_array(ast_ty_to_ty(this, rscope, &**ty), + i as usize), ConstVal::Uint(i) => - ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), - Some(i as usize)), + tcx.mk_array(ast_ty_to_ty(this, rscope, &**ty), + i as usize), _ => { span_err!(tcx.sess, ast_ty.span, E0249, "expected constant integer expression \ @@ -1724,7 +1724,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, (Some(self_info.untransformed_self_ty), None) } ty::ByReferenceExplicitSelfCategory(region, mutability) => { - (Some(ty::mk_rptr(this.tcx(), + (Some(this.tcx().mk_ref( this.tcx().mk_region(region), ty::mt { ty: self_info.untransformed_self_ty, @@ -1733,7 +1733,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, Some(region)) } ty::ByBoxExplicitSelfCategory => { - (Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty)), None) + (Some(this.tcx().mk_box(self_info.untransformed_self_ty)), None) } } } @@ -1779,7 +1779,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, implied_output_region, lifetimes_for_params, &**output)), - ast::DefaultReturn(..) => ty::FnConverging(ty::mk_nil(this.tcx())), + ast::DefaultReturn(..) => ty::FnConverging(this.tcx().mk_nil()), ast::NoReturn(..) => ty::FnDiverging }; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 6b11efb478287..c223809b8c80e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -59,8 +59,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let expected_ty = structurally_resolved_type(fcx, pat.span, expected); if let ty::TyRef(_, mt) = expected_ty.sty { if let ty::TySlice(_) = mt.ty.sty { - pat_ty = ty::mk_slice(tcx, tcx.mk_region(ty::ReStatic), - ty::mt{ ty: tcx.types.u8, mutbl: ast::MutImmutable }) + pat_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), + tcx.mk_slice(tcx.types.u8)) } } } @@ -171,7 +171,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, // and T is the expected type. let region_var = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); let mt = ty::mt { ty: expected, mutbl: mutbl }; - let region_ty = ty::mk_rptr(tcx, tcx.mk_region(region_var), mt); + let region_ty = tcx.mk_ref(tcx.mk_region(region_var), mt); // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is // required. However, we use equality, which is stronger. See (*) for @@ -246,7 +246,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let element_tys: Vec<_> = (0..elements.len()).map(|_| fcx.infcx().next_ty_var()) .collect(); - let pat_ty = ty::mk_tup(tcx, element_tys.clone()); + let pat_ty = tcx.mk_tup(element_tys.clone()); fcx.write_ty(pat.id, pat_ty); demand::eqtype(fcx, pat.span, expected, pat_ty); for (element_pat, element_ty) in elements.iter().zip(element_tys) { @@ -255,7 +255,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, } ast::PatBox(ref inner) => { let inner_ty = fcx.infcx().next_ty_var(); - let uniq_ty = ty::mk_uniq(tcx, inner_ty); + let uniq_ty = tcx.mk_box(inner_ty); if check_dereferencable(pcx, pat.span, expected, &**inner) { // Here, `demand::subtype` is good enough, but I don't @@ -274,7 +274,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let mt = ty::mt { ty: inner_ty, mutbl: mutbl }; let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); - let rptr_ty = ty::mk_rptr(tcx, tcx.mk_region(region), mt); + let rptr_ty = tcx.mk_ref(tcx.mk_region(region), mt); if check_dereferencable(pcx, pat.span, expected, &**inner) { // `demand::subtype` would be good enough, but using @@ -292,17 +292,17 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let expected_ty = structurally_resolved_type(fcx, pat.span, expected); let inner_ty = fcx.infcx().next_ty_var(); let pat_ty = match expected_ty.sty { - ty::TyArray(_, size) => ty::mk_vec(tcx, inner_ty, Some({ + ty::TyArray(_, size) => tcx.mk_array(inner_ty, { let min_len = before.len() + after.len(); match *slice { Some(_) => cmp::max(min_len, size), None => min_len } - })), + }), _ => { let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span)); - ty::mk_slice(tcx, tcx.mk_region(region), ty::mt { - ty: inner_ty, + tcx.mk_ref(tcx.mk_region(region), ty::mt { + ty: tcx.mk_slice(inner_ty), mutbl: expected_ty.builtin_deref(true).map(|mt| mt.mutbl) .unwrap_or(ast::MutImmutable) }) @@ -324,8 +324,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let mutbl = expected_ty.builtin_deref(true) .map_or(ast::MutImmutable, |mt| mt.mutbl); - let slice_ty = ty::mk_slice(tcx, tcx.mk_region(region), ty::mt { - ty: inner_ty, + let slice_ty = tcx.mk_ref(tcx.mk_region(region), ty::mt { + ty: tcx.mk_slice(inner_ty), mutbl: mutbl }); check_pat(pcx, &**slice, slice_ty); @@ -485,7 +485,7 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // us to give better error messages (pointing to a usually better // arm for inconsistent arms or to the whole match when a `()` type // is required). - Expectation::ExpectHasType(ety) if ety != ty::mk_nil(fcx.tcx()) => { + Expectation::ExpectHasType(ety) if ety != fcx.tcx().mk_nil() => { check_expr_coercable_to_type(fcx, &*arm.body, ety); ety } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 4951a9a6f2f16..30ed9d9eb2f24 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -371,7 +371,7 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { demand::eqtype(fcx, self.call_expr.span, self_arg_ty, method_arg_ty); } - let nilty = ty::mk_nil(fcx.tcx()); + let nilty = fcx.tcx().mk_nil(); demand::eqtype(fcx, self.call_expr.span, method_sig.output.unwrap_or(nilty), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 10b2459b220f2..ec4c4a3271433 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -60,10 +60,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, abi::RustCall, expected_sig); - let closure_type = ty::mk_closure(fcx.ccx.tcx, - expr_def_id, - fcx.ccx.tcx.mk_substs( - fcx.inh.param_env.free_substs.clone())); + let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id, + fcx.ccx.tcx.mk_substs(fcx.inh.param_env.free_substs.clone())); fcx.write_ty(expr.id, closure_type); @@ -83,7 +81,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, // Tuple up the arguments and insert the resulting function type into // the `closures` table. - fn_ty.sig.0.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.0.inputs)]; + fn_ty.sig.0.inputs = vec![fcx.tcx().mk_tup(fn_ty.sig.0.inputs)]; debug!("closure for {:?} --> sig={:?} opt_kind={:?}", expr_def_id, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 785202de92159..612b574dfa7c6 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -201,8 +201,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // &T to autoref to &&T. return None; } - let ty = ty::mk_rptr(self.tcx(), r_borrow, - mt {ty: inner_ty, mutbl: mutbl_b}); + let ty = self.tcx().mk_ref(r_borrow, + mt {ty: inner_ty, mutbl: mutbl_b}); if let Err(err) = self.subtype(ty, b) { if first_error.is_none() { first_error = Some(err); @@ -384,7 +384,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.sty { ty::TyBareFn(None, _) => { - let a_fn_pointer = ty::mk_bare_fn(self.tcx(), None, fn_ty_a); + let a_fn_pointer = self.tcx().mk_fn(None, fn_ty_a); try!(self.subtype(a_fn_pointer, b)); Ok(Some(ty::AdjustReifyFnPointer)) } @@ -411,7 +411,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }; // Check that the types which they point at are compatible. - let a_unsafe = ty::mk_ptr(self.tcx(), ty::mt{ mutbl: mutbl_b, ty: mt_a.ty }); + let a_unsafe = self.tcx().mk_ptr(ty::mt{ mutbl: mutbl_b, ty: mt_a.ty }); try!(self.subtype(a_unsafe, b)); try!(coerce_mutbls(mt_a.mutbl, mutbl_b)); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 7cd5e4548ec2b..44768990d68c4 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -275,9 +275,9 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // type. // Compute skolemized form of impl and trait method tys. - let impl_fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(impl_m.fty.clone())); + let impl_fty = tcx.mk_fn(None, tcx.mk_bare_fn(impl_m.fty.clone())); let impl_fty = impl_fty.subst(tcx, impl_to_skol_substs); - let trait_fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(trait_m.fty.clone())); + let trait_fty = tcx.mk_fn(None, tcx.mk_bare_fn(trait_m.fty.clone())); let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs); let err = infcx.commit_if_ok(|snapshot| { @@ -296,12 +296,11 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_m_span, impl_m_body_id, &impl_sig); - let impl_fty = - ty::mk_bare_fn(tcx, - None, - tcx.mk_bare_fn(ty::BareFnTy { unsafety: impl_m.fty.unsafety, - abi: impl_m.fty.abi, - sig: ty::Binder(impl_sig) })); + let impl_fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy { + unsafety: impl_m.fty.unsafety, + abi: impl_m.fty.abi, + sig: ty::Binder(impl_sig) + })); debug!("compare_impl_method: impl_fty={:?}", impl_fty); @@ -316,12 +315,11 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_m_span, impl_m_body_id, &trait_sig); - let trait_fty = - ty::mk_bare_fn(tcx, - None, - tcx.mk_bare_fn(ty::BareFnTy { unsafety: trait_m.fty.unsafety, - abi: trait_m.fty.abi, - sig: ty::Binder(trait_sig) })); + let trait_fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy { + unsafety: trait_m.fty.unsafety, + abi: trait_m.fty.abi, + sig: ty::Binder(trait_sig) + })); debug!("compare_impl_method: trait_fty={:?}", trait_fty); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index a5b812ee80ee8..2104ebaec45c9 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -108,7 +108,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // Create the final `MethodCallee`. let method_ty = pick.item.as_opt_method().unwrap(); - let fty = ty::mk_bare_fn(self.tcx(), None, self.tcx().mk_bare_fn(ty::BareFnTy { + let fty = self.tcx().mk_fn(None, self.tcx().mk_bare_fn(ty::BareFnTy { sig: ty::Binder(method_sig), unsafety: method_ty.fty.unsafety, abi: method_ty.fty.abi.clone(), diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 30fb830495e77..6ba9704aa987f 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -224,7 +224,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, &method_ty.fty.sig).0; let fn_sig = fcx.instantiate_type_scheme(span, trait_ref.substs, &fn_sig); let transformed_self_ty = fn_sig.inputs[0]; - let fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(ty::BareFnTy { + let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy { sig: ty::Binder(fn_sig), unsafety: method_ty.fty.unsafety, abi: method_ty.fty.abi.clone(), diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index f8ce387969458..a8fc411410567 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -218,9 +218,8 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, match final_ty.sty { ty::TyArray(elem_ty, _) => { - let slice_ty = ty::mk_vec(fcx.tcx(), elem_ty, None); steps.push(CandidateStep { - self_ty: slice_ty, + self_ty: fcx.tcx().mk_slice(elem_ty), autoderefs: dereferences, unsize: true }); @@ -984,7 +983,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // Search through mutabilities in order to find one where pick works: [ast::MutImmutable, ast::MutMutable].iter().filter_map(|&m| { - let autoref_ty = ty::mk_rptr(tcx, region, ty::mt { + let autoref_ty = tcx.mk_ref(region, ty::mt { ty: step.self_ty, mutbl: m }); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index de09a98b89e52..6826c33359aee 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1377,7 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (_, &mut ref ty) in &mut *self.inh.node_types.borrow_mut() { let resolved = self.infcx().resolve_type_vars_if_possible(ty); if self.infcx().type_var_diverges(resolved) { - demand::eqtype(self, codemap::DUMMY_SP, *ty, ty::mk_nil(self.tcx())); + demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil()); } else { match self.infcx().type_is_unconstrained_numeric(resolved) { UnconstrainedInt => { @@ -1557,7 +1557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn write_nil(&self, node_id: ast::NodeId) { - self.write_ty(node_id, ty::mk_nil(self.tcx())); + self.write_ty(node_id, self.tcx().mk_nil()); } pub fn write_error(&self, node_id: ast::NodeId) { self.write_ty(node_id, self.tcx().types.err); @@ -2089,7 +2089,7 @@ fn lookup_indexing<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // After we have fully autoderef'd, if the resulting type is [T; n], then // do a final unsized coercion to yield [T]. if let ty::TyArray(element_ty, _) = ty.sty { - let adjusted_ty = ty::mk_vec(fcx.tcx(), element_ty, None); + let adjusted_ty = fcx.tcx().mk_slice(element_ty); try_index_step(fcx, MethodCall::expr(expr.id), expr, base_expr, adjusted_ty, autoderefs, true, lvalue_pref, idx_ty) } else { @@ -2191,7 +2191,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, - TupleArguments => vec![ty::mk_tup(fcx.tcx(), err_inputs)], + TupleArguments => vec![fcx.tcx().mk_tup(err_inputs)], }; check_argument_types(fcx, @@ -2433,17 +2433,15 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let tcx = fcx.ccx.tcx; match lit.node { - ast::LitStr(..) => ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), ast::MutImmutable), + ast::LitStr(..) => tcx.mk_static_str(), ast::LitBinary(ref v) => { - ty::mk_rptr(tcx, tcx.mk_region(ty::ReStatic), ty::mt { - ty: ty::mk_vec(tcx, tcx.types.u8, Some(v.len())), - mutbl: ast::MutImmutable, - }) + tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), + tcx.mk_array(tcx.types.u8, v.len())) } ast::LitByte(_) => tcx.types.u8, ast::LitChar(_) => tcx.types.char, - ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(tcx, t), - ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(tcx, t), + ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t), + ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t), ast::LitInt(_, ast::UnsuffixedIntLit(_)) => { let opt_ty = expected.to_option(fcx).and_then(|ty| { match ty.sty { @@ -2455,9 +2453,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } }); opt_ty.unwrap_or_else( - || ty::mk_int_var(tcx, fcx.infcx().next_int_var_id())) + || tcx.mk_int_var(fcx.infcx().next_int_var_id())) } - ast::LitFloat(_, t) => ty::mk_mach_float(tcx, t), + ast::LitFloat(_, t) => tcx.mk_mach_float(t), ast::LitFloatUnsuffixed(_) => { let opt_ty = expected.to_option(fcx).and_then(|ty| { match ty.sty { @@ -2466,7 +2464,7 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } }); opt_ty.unwrap_or_else( - || ty::mk_float_var(tcx, fcx.infcx().next_float_var_id())) + || tcx.mk_float_var(fcx.infcx().next_float_var_id())) } ast::LitBool(_) => tcx.types.bool } @@ -2705,7 +2703,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, infer::IfExpressionWithNoElse(sp), false, then_ty, - ty::mk_nil(fcx.tcx())) + fcx.tcx().mk_nil()) } }; @@ -2991,8 +2989,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } if !error_happened { - fcx.write_ty(node_id, ty::mk_struct(fcx.ccx.tcx, - class_id, substitutions)); + fcx.write_ty(node_id, fcx.ccx.tcx.mk_struct(class_id, substitutions)); } } @@ -3102,7 +3099,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let def_id = definition.def_id(); let referent_ty = fcx.expr_ty(&**subexpr); if tcx.lang_items.exchange_heap() == Some(def_id) { - fcx.write_ty(id, ty::mk_uniq(tcx, referent_ty)); + fcx.write_ty(id, tcx.mk_box(referent_ty)); checked = true } } @@ -3156,7 +3153,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if !oprnd_t.references_error() { match unop { ast::UnUniq => { - oprnd_t = ty::mk_uniq(tcx, oprnd_t); + oprnd_t = tcx.mk_box(oprnd_t); } ast::UnDeref => { oprnd_t = structurally_resolved_type(fcx, expr.span, oprnd_t); @@ -3247,7 +3244,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, // value whose address was taken can actually be made to live // as long as it needs to live. let region = fcx.infcx().next_region_var(infer::AddrOfRegion(expr.span)); - ty::mk_rptr(tcx, tcx.mk_region(region), tm) + tcx.mk_ref(tcx.mk_region(region), tm) }; fcx.write_ty(id, oprnd_t); } @@ -3308,7 +3305,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, match *expr_opt { None => if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span), - result_type, ty::mk_nil(fcx.tcx())) { + result_type, fcx.tcx().mk_nil()) { span_err!(tcx.sess, expr.span, E0069, "`return;` in a function whose return type is \ not `()`"); @@ -3463,7 +3460,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, t } }; - let typ = ty::mk_vec(tcx, typ, Some(args.len())); + let typ = tcx.mk_array(typ, args.len()); fcx.write_ty(id, typ); } ast::ExprRepeat(ref element, ref count_expr) => { @@ -3505,7 +3502,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if element_ty.references_error() { fcx.write_error(id); } else { - let t = ty::mk_vec(tcx, t, Some(count)); + let t = tcx.mk_array(t, count); fcx.write_ty(id, t); } } @@ -3536,7 +3533,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if err_field { fcx.write_error(id); } else { - let typ = ty::mk_tup(tcx, elt_ts); + let typ = tcx.mk_tup(elt_ts); fcx.write_ty(id, typ); } } @@ -3712,7 +3709,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, traits::ItemObligation(did)), &bounds); - ty::mk_struct(tcx, did, tcx.mk_substs(substs)) + tcx.mk_struct(did, tcx.mk_substs(substs)) } else { span_err!(tcx.sess, expr.span, E0236, "no lang item for range syntax"); fcx.tcx().types.err @@ -3722,7 +3719,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, // Neither start nor end => RangeFull if let Some(did) = tcx.lang_items.range_full_struct() { let substs = Substs::new_type(vec![], vec![]); - ty::mk_struct(tcx, did, tcx.mk_substs(substs)) + tcx.mk_struct(did, tcx.mk_substs(substs)) } else { span_err!(tcx.sess, expr.span, E0237, "no lang item for range syntax"); fcx.tcx().types.err @@ -3967,7 +3964,7 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) { ast::StmtExpr(ref expr, id) => { node_id = id; // Check with expected type of () - check_expr_has_type(fcx, &**expr, ty::mk_nil(fcx.tcx())); + check_expr_has_type(fcx, &**expr, fcx.tcx().mk_nil()); let expr_ty = fcx.expr_ty(&**expr); saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty); saw_err = saw_err || expr_ty.references_error(); @@ -3993,12 +3990,12 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) { } pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) { - check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil(fcx.tcx()))); + check_block_with_expected(fcx, blk, ExpectHasType(fcx.tcx().mk_nil())); let blkty = fcx.node_ty(blk.id); if blkty.references_error() { fcx.write_error(blk.id); } else { - let nilty = ty::mk_nil(fcx.tcx()); + let nilty = fcx.tcx().mk_nil(); demand::suptype(fcx, blk.span, nilty, blkty); } } @@ -4734,8 +4731,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let input_tys: Vec = data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect(); - let tuple_ty = - ty::mk_tup(fcx.tcx(), input_tys); + let tuple_ty = fcx.tcx().mk_tup(input_tys); if type_count >= 1 { substs.types.push(space, tuple_ty); @@ -4745,7 +4741,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, data.output.as_ref().map(|ty| fcx.to_ty(&**ty)); let output_ty = - output_ty.unwrap_or(ty::mk_nil(fcx.tcx())); + output_ty.unwrap_or(fcx.tcx().mk_nil()); if type_count >= 2 { substs.types.push(space, output_ty); @@ -4952,7 +4948,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> { let name = token::intern(&format!("P{}", n)); - ty::mk_param(ccx.tcx, subst::FnSpace, n, name) + ccx.tcx.mk_param(subst::FnSpace, n, name) } let tcx = ccx.tcx; @@ -4963,22 +4959,22 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { //We only care about the operation here let (n_tps, inputs, output) = match split[1] { - "cxchg" => (1, vec!(ty::mk_mut_ptr(tcx, param(ccx, 0)), + "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0), param(ccx, 0)), param(ccx, 0)), - "load" => (1, vec!(ty::mk_imm_ptr(tcx, param(ccx, 0))), + "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))), param(ccx, 0)), - "store" => (1, vec!(ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0)), - ty::mk_nil(tcx)), + "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)), + tcx.mk_nil()), "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" | "umin" => { - (1, vec!(ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0)), + (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)), param(ccx, 0)) } "fence" | "singlethreadfence" => { - (0, Vec::new(), ty::mk_nil(tcx)) + (0, Vec::new(), tcx.mk_nil()) } op => { span_err!(tcx.sess, it.span, E0092, @@ -4991,50 +4987,47 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { (0, Vec::new(), ty::FnDiverging) } else { let (n_tps, inputs, output) = match &name[..] { - "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)), + "breakpoint" => (0, Vec::new(), tcx.mk_nil()), "size_of" | "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize), "size_of_val" | "min_align_of_val" => { (1, vec![ - ty::mk_imm_rptr(tcx, - tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), + tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(0))), param(ccx, 0)) ], ccx.tcx.types.usize) } "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)), "uninit" => (1, Vec::new(), param(ccx, 0)), - "forget" => (1, vec!( param(ccx, 0) ), ty::mk_nil(tcx)), + "forget" => (1, vec!( param(ccx, 0) ), tcx.mk_nil()), "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)), "move_val_init" => { (1, vec!( - ty::mk_mut_rptr(tcx, - tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), + tcx.mk_mut_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(0))), param(ccx, 0)), param(ccx, 0) ), - ty::mk_nil(tcx)) + tcx.mk_nil()) } "drop_in_place" => { - (1, vec![ty::mk_mut_ptr(tcx, param(ccx, 0))], ty::mk_nil(tcx)) + (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil()) } "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool), - "type_name" => (1, Vec::new(), ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), - ast::MutImmutable)), + "type_name" => (1, Vec::new(), tcx.mk_static_str()), "type_id" => (1, Vec::new(), ccx.tcx.types.u64), "offset" | "arith_offset" => { (1, vec!( - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutImmutable }), ccx.tcx.types.isize ), - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutImmutable })) @@ -5042,44 +5035,44 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "copy" | "copy_nonoverlapping" => { (1, vec!( - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutImmutable }), - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutMutable }), tcx.types.usize, ), - ty::mk_nil(tcx)) + tcx.mk_nil()) } "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => { (1, vec!( - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutMutable }), - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutImmutable }), tcx.types.usize, ), - ty::mk_nil(tcx)) + tcx.mk_nil()) } "write_bytes" | "volatile_set_memory" => { (1, vec!( - ty::mk_ptr(tcx, ty::mt { + tcx.mk_ptr(ty::mt { ty: param(ccx, 0), mutbl: ast::MutMutable }), tcx.types.u8, tcx.types.usize, ), - ty::mk_nil(tcx)) + tcx.mk_nil()) } "sqrtf32" => (0, vec!( tcx.types.f32 ), tcx.types.f32), "sqrtf64" => (0, vec!( tcx.types.f64 ), tcx.types.f64), @@ -5160,41 +5153,41 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "bswap64" => (0, vec!( tcx.types.u64 ), tcx.types.u64), "volatile_load" => - (1, vec!( ty::mk_imm_ptr(tcx, param(ccx, 0)) ), param(ccx, 0)), + (1, vec!( tcx.mk_imm_ptr(param(ccx, 0)) ), param(ccx, 0)), "volatile_store" => - (1, vec!( ty::mk_mut_ptr(tcx, param(ccx, 0)), param(ccx, 0) ), ty::mk_nil(tcx)), + (1, vec!( tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()), "i8_add_with_overflow" | "i8_sub_with_overflow" | "i8_mul_with_overflow" => (0, vec!(tcx.types.i8, tcx.types.i8), - ty::mk_tup(tcx, vec!(tcx.types.i8, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.i8, tcx.types.bool))), "i16_add_with_overflow" | "i16_sub_with_overflow" | "i16_mul_with_overflow" => (0, vec!(tcx.types.i16, tcx.types.i16), - ty::mk_tup(tcx, vec!(tcx.types.i16, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.i16, tcx.types.bool))), "i32_add_with_overflow" | "i32_sub_with_overflow" | "i32_mul_with_overflow" => (0, vec!(tcx.types.i32, tcx.types.i32), - ty::mk_tup(tcx, vec!(tcx.types.i32, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.i32, tcx.types.bool))), "i64_add_with_overflow" | "i64_sub_with_overflow" | "i64_mul_with_overflow" => (0, vec!(tcx.types.i64, tcx.types.i64), - ty::mk_tup(tcx, vec!(tcx.types.i64, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.i64, tcx.types.bool))), "u8_add_with_overflow" | "u8_sub_with_overflow" | "u8_mul_with_overflow" => (0, vec!(tcx.types.u8, tcx.types.u8), - ty::mk_tup(tcx, vec!(tcx.types.u8, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.u8, tcx.types.bool))), "u16_add_with_overflow" | "u16_sub_with_overflow" | "u16_mul_with_overflow" => (0, vec!(tcx.types.u16, tcx.types.u16), - ty::mk_tup(tcx, vec!(tcx.types.u16, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.u16, tcx.types.bool))), "u32_add_with_overflow" | "u32_sub_with_overflow" | "u32_mul_with_overflow"=> (0, vec!(tcx.types.u32, tcx.types.u32), - ty::mk_tup(tcx, vec!(tcx.types.u32, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.u32, tcx.types.bool))), "u64_add_with_overflow" | "u64_sub_with_overflow" | "u64_mul_with_overflow" => (0, vec!(tcx.types.u64, tcx.types.u64), - ty::mk_tup(tcx, vec!(tcx.types.u64, tcx.types.bool))), + tcx.mk_tup(vec!(tcx.types.u64, tcx.types.bool))), "unchecked_udiv" | "unchecked_sdiv" | "unchecked_urem" | "unchecked_srem" => (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), @@ -5202,13 +5195,12 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "overflowing_add" | "overflowing_sub" | "overflowing_mul" => (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), - "return_address" => (0, vec![], ty::mk_imm_ptr(tcx, tcx.types.u8)), + "return_address" => (0, vec![], tcx.mk_imm_ptr(tcx.types.u8)), - "assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)), + "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()), "discriminant_value" => (1, vec![ - ty::mk_imm_rptr(tcx, - tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), + tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(0))), param(ccx, 0))], tcx.types.u64), @@ -5220,7 +5212,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { }; (n_tps, inputs, ty::FnConverging(output)) }; - let fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(ty::BareFnTy { + let fty = tcx.mk_fn(None, tcx.mk_bare_fn(ty::BareFnTy { unsafety: ast::Unsafety::Unsafe, abi: abi::RustIntrinsic, sig: ty::Binder(FnSig { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 48dc64e8c8b49..b41bb9feb5212 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -97,9 +97,9 @@ pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, match BinOpCategory::from(op) { BinOpCategory::Shortcircuit => { // && and || are a simple case. - demand::suptype(fcx, lhs_expr.span, ty::mk_bool(tcx), lhs_ty); - check_expr_coercable_to_type(fcx, rhs_expr, ty::mk_bool(tcx)); - fcx.write_ty(expr.id, ty::mk_bool(tcx)); + demand::suptype(fcx, lhs_expr.span, tcx.mk_bool(), lhs_ty); + check_expr_coercable_to_type(fcx, rhs_expr, tcx.mk_bool()); + fcx.write_ty(expr.id, tcx.mk_bool()); } _ => { // Otherwise, we always treat operators as if they are @@ -148,9 +148,9 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let tcx = fcx.tcx(); match BinOpCategory::from(op) { BinOpCategory::Shortcircuit => { - demand::suptype(fcx, lhs_expr.span, ty::mk_bool(tcx), lhs_ty); - demand::suptype(fcx, rhs_expr.span, ty::mk_bool(tcx), rhs_ty); - ty::mk_bool(tcx) + demand::suptype(fcx, lhs_expr.span, tcx.mk_bool(), lhs_ty); + demand::suptype(fcx, rhs_expr.span, tcx.mk_bool(), rhs_ty); + tcx.mk_bool() } BinOpCategory::Shift => { @@ -193,7 +193,7 @@ fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, lhs_ty } } else { - ty::mk_bool(tcx) + tcx.mk_bool() } } } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index e06ebd0276ffd..c659357dd0305 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1520,7 +1520,7 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>, debug!("projection_bounds(projection_ty={:?})", projection_ty); - let ty = ty::mk_projection(tcx, projection_ty.trait_ref.clone(), projection_ty.item_name); + let ty = tcx.mk_projection(projection_ty.trait_ref.clone(), projection_ty.item_name); // Say we have a projection `>::SomeType`. We are interested // in looking for a trait definition like: diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index b66c76048c639..266babda57824 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -210,8 +210,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // impl, plus its own. let new_polytype = ty::TypeScheme { generics: new_method_ty.generics.clone(), - ty: ty::mk_bare_fn(tcx, Some(new_did), - tcx.mk_bare_fn(new_method_ty.fty.clone())) + ty: tcx.mk_fn(Some(new_did), + tcx.mk_bare_fn(new_method_ty.fty.clone())) }; debug!("new_polytype={:?}", new_polytype); @@ -468,12 +468,12 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => { infer::mk_subr(&infcx, infer::RelateObjectBound(span), *r_b, *r_a); - check_mutbl(mt_a, mt_b, &|ty| ty::mk_imm_rptr(tcx, r_b, ty)) + check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty)) } (&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) | (&ty::TyRawPtr(mt_a), &ty::TyRawPtr(mt_b)) => { - check_mutbl(mt_a, mt_b, &|ty| ty::mk_imm_ptr(tcx, ty)) + check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ptr(ty)) } (&ty::TyStruct(def_id_a, substs_a), &ty::TyStruct(def_id_b, substs_b)) => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 6c1235e5a7569..4c550e5d44ae4 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -416,7 +416,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { item_name: ast::Name) -> Ty<'tcx> { - ty::mk_projection(self.tcx(), trait_ref, item_name) + self.tcx().mk_projection(trait_ref, item_name) } } @@ -508,7 +508,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ast::Generics { // `where T:Foo`. let def = astconv.tcx().type_parameter_def(node_id); - let ty = ty::mk_param_from_def(astconv.tcx(), &def); + let ty = astconv.tcx().mk_param_from_def(&def); let from_ty_params = self.ty_params @@ -577,7 +577,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ast::TupleVariantKind(ref args) if !args.is_empty() => { let rs = ExplicitRscope; let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect(); - ty::mk_ctor_fn(tcx, variant_def_id, &input_tys, enum_scheme.ty) + tcx.mk_ctor_fn(variant_def_id, &input_tys, enum_scheme.ty) } ast::TupleVariantKind(_) => { @@ -631,8 +631,8 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, container, None); - let fty = ty::mk_bare_fn(ccx.tcx, Some(def_id), - ccx.tcx.mk_bare_fn(ty_method.fty.clone())); + let fty = ccx.tcx.mk_fn(Some(def_id), + ccx.tcx.mk_bare_fn(ty_method.fty.clone())); debug!("method {} (id {}) has type {:?}", ident, id, fty); ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme { @@ -995,7 +995,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { convert_methods(ccx, TraitContainer(local_def(it.id)), methods, - ty::mk_self_type(tcx), + tcx.mk_self_type(), &trait_def.generics, &trait_predicates); @@ -1026,7 +1026,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { check_method_self_type(ccx, &BindingRscope::new(), ccx.method_ty(trait_item.id), - ty::mk_self_type(tcx), + tcx.mk_self_type(), &sig.explicit_self, it.id) } @@ -1088,7 +1088,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys)); let substs = mk_item_substs(ccx, &scheme.generics); - let selfty = ty::mk_struct(tcx, local_def(id), tcx.mk_substs(substs)); + let selfty = tcx.mk_struct(local_def(id), tcx.mk_substs(substs)); // If this struct is enum-like or tuple-like, create the type of its // constructor. @@ -1110,8 +1110,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, .unwrap() .ty) .collect(); - let ctor_fn_ty = ty::mk_ctor_fn(tcx, - local_def(ctor_id), + let ctor_fn_ty = tcx.mk_ctor_fn(local_def(ctor_id), &inputs[..], selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); @@ -1177,7 +1176,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, let scope = &(generics, &self_predicate); // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`. - let self_param_ty = ty::mk_self_type(tcx); + let self_param_ty = tcx.mk_self_type(); let superbounds1 = compute_bounds(&ccx.icx(scope), self_param_ty, bounds, @@ -1295,12 +1294,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics.ty_params .iter() .enumerate() - .map(|(i, def)| ty::mk_param(tcx, TypeSpace, + .map(|(i, def)| tcx.mk_param(TypeSpace, i as u32, def.ident.name)) .collect(); // ...and also create the `Self` parameter. - let self_ty = ty::mk_self_type(tcx); + let self_ty = tcx.mk_self_type(); Substs::new_trait(types, regions, self_ty) } @@ -1389,9 +1388,8 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) } }; - let assoc_ty = ty::mk_projection(ccx.tcx, - self_trait_ref, - trait_item.ident.name); + let assoc_ty = ccx.tcx.mk_projection(self_trait_ref, + trait_item.ident.name); let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)), assoc_ty, @@ -1450,7 +1448,7 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ast::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => { let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty()); let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl); - let ty = ty::mk_bare_fn(tcx, Some(local_def(it.id)), tcx.mk_bare_fn(tofd)); + let ty = tcx.mk_fn(Some(local_def(it.id)), tcx.mk_bare_fn(tofd)); ty::TypeScheme { ty: ty, generics: ty_generics } } ast::ItemTy(ref t, ref generics) => { @@ -1462,13 +1460,13 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, // Create a new generic polytype. let ty_generics = ty_generics_for_type_or_impl(ccx, generics); let substs = mk_item_substs(ccx, &ty_generics); - let t = ty::mk_enum(tcx, local_def(it.id), tcx.mk_substs(substs)); + let t = tcx.mk_enum(local_def(it.id), tcx.mk_substs(substs)); ty::TypeScheme { ty: t, generics: ty_generics } } ast::ItemStruct(_, ref generics) => { let ty_generics = ty_generics_for_type_or_impl(ccx, generics); let substs = mk_item_substs(ccx, &ty_generics); - let t = ty::mk_struct(tcx, local_def(it.id), tcx.mk_substs(substs)); + let t = tcx.mk_struct(local_def(it.id), tcx.mk_substs(substs)); ty::TypeScheme { ty: t, generics: ty_generics } } ast::ItemDefaultImpl(..) | @@ -2121,14 +2119,12 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>( ast::Return(ref ty) => ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)), ast::DefaultReturn(..) => - ty::FnConverging(ty::mk_nil(ccx.tcx)), + ty::FnConverging(ccx.tcx.mk_nil()), ast::NoReturn(..) => ty::FnDiverging }; - let t_fn = ty::mk_bare_fn( - ccx.tcx, - None, + let t_fn = ccx.tcx.mk_fn(None, ccx.tcx.mk_bare_fn(ty::BareFnTy { abi: abi, unsafety: ast::Unsafety::Unsafe, @@ -2149,7 +2145,7 @@ fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, { let types = ty_generics.types.map( - |def| ty::mk_param_from_def(ccx.tcx, def)); + |def| ccx.tcx.mk_param_from_def(def)); let regions = ty_generics.regions.map( diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index d968d854bb365..34f166e0e0dfb 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -226,12 +226,12 @@ fn check_main_fn_ty(ccx: &CrateCtxt, } _ => () } - let se_ty = ty::mk_bare_fn(tcx, Some(local_def(main_id)), tcx.mk_bare_fn(ty::BareFnTy { + let se_ty = tcx.mk_fn(Some(local_def(main_id)), tcx.mk_bare_fn(ty::BareFnTy { unsafety: ast::Unsafety::Normal, abi: abi::Rust, sig: ty::Binder(ty::FnSig { inputs: Vec::new(), - output: ty::FnConverging(ty::mk_nil(tcx)), + output: ty::FnConverging(tcx.mk_nil()), variadic: false }) })); @@ -272,13 +272,13 @@ fn check_start_fn_ty(ccx: &CrateCtxt, _ => () } - let se_ty = ty::mk_bare_fn(tcx, Some(local_def(start_id)), tcx.mk_bare_fn(ty::BareFnTy { + let se_ty = tcx.mk_fn(Some(local_def(start_id)), tcx.mk_bare_fn(ty::BareFnTy { unsafety: ast::Unsafety::Normal, abi: abi::Rust, sig: ty::Binder(ty::FnSig { inputs: vec!( tcx.types.isize, - ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, tcx.types.u8)) + tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8)) ), output: ty::FnConverging(tcx.types.isize), variadic: false, From 5cedd66a6c37ed04377aeea92db092f343bfe152 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 25 Jun 2015 04:10:11 +0300 Subject: [PATCH 13/36] rustc: remove 3 dead functions in middle::ty. --- src/librustc/middle/ty.rs | 23 +---------------------- src/librustc_typeck/check/writeback.rs | 2 +- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 51fb11f7452f4..185a04bc5215c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -85,7 +85,7 @@ use std::collections::{HashMap, HashSet}; use syntax::abi; use syntax::ast::{CrateNum, DefId, ItemImpl, ItemTrait, LOCAL_CRATE}; use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId}; -use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility}; +use syntax::ast::{StructField, UnnamedField, Visibility}; use syntax::ast_util::{self, is_local, local_def}; use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt}; use syntax::codemap::Span; @@ -1840,13 +1840,6 @@ pub enum BuiltinBound { Sync, } -/// An existential bound that does not implement any traits. -pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx> { - ty::ExistentialBounds { region_bound: r, - builtin_bounds: BuiltinBounds::empty(), - projection_bounds: Vec::new() } -} - impl CLike for BuiltinBound { fn to_usize(&self) -> usize { *self as usize @@ -5004,15 +4997,6 @@ pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool { } } -pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId { - match s.node { - ast::StmtDecl(_, id) | StmtExpr(_, id) | StmtSemi(_, id) => { - return id; - } - ast::StmtMac(..) => panic!("unexpanded macro in trans") - } -} - pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field]) -> usize { let mut i = 0; @@ -5025,11 +5009,6 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field]) .collect::>())); } -pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem]) - -> Option { - trait_items.iter().position(|m| m.name() == id) -} - pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String { match ty.sty { TyBool | TyChar | TyInt(_) | diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 2bf8c5b5fafd3..9abee1a3aaab6 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -128,7 +128,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { return; } - self.visit_node_id(ResolvingExpr(s.span), ty::stmt_node_id(s)); + self.visit_node_id(ResolvingExpr(s.span), ast_util::stmt_id(s)); visit::walk_stmt(self, s); } From ad66c215aa2b20cf42968915571886e6ce8e9dd4 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 25 Jun 2015 23:42:17 +0300 Subject: [PATCH 14/36] rustc: switch most remaining middle::ty functions to methods. --- src/librustc/metadata/encoder.rs | 51 +- src/librustc/middle/cfg/construct.rs | 2 +- src/librustc/middle/check_const.rs | 24 +- src/librustc/middle/check_match.rs | 34 +- src/librustc/middle/check_rvalues.rs | 2 +- src/librustc/middle/const_eval.rs | 18 +- src/librustc/middle/dead.rs | 23 +- src/librustc/middle/effect.rs | 8 +- src/librustc/middle/expr_use_visitor.rs | 37 +- src/librustc/middle/implicator.rs | 16 +- src/librustc/middle/infer/bivariate.rs | 4 +- src/librustc/middle/infer/error_reporting.rs | 337 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc/middle/intrinsicck.rs | 12 +- src/librustc/middle/liveness.rs | 11 +- src/librustc/middle/mem_categorization.rs | 20 +- src/librustc/middle/pat_util.rs | 2 +- src/librustc/middle/stability.rs | 28 +- src/librustc/middle/traits/coherence.rs | 14 +- src/librustc/middle/traits/error_reporting.rs | 12 +- src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/traits/object_safety.rs | 16 +- src/librustc/middle/traits/project.rs | 4 +- src/librustc/middle/traits/select.rs | 36 +- src/librustc/middle/traits/util.rs | 20 +- src/librustc/middle/ty.rs | 5324 ++++++++--------- src/librustc/middle/ty_relate/mod.rs | 2 +- src/librustc/util/ppaux.rs | 12 +- src/librustc_borrowck/borrowck/check_loans.rs | 2 +- src/librustc_borrowck/borrowck/fragments.rs | 8 +- .../borrowck/gather_loans/gather_moves.rs | 4 +- .../borrowck/gather_loans/mod.rs | 2 +- .../borrowck/gather_loans/move_error.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 32 +- src/librustc_driver/driver.rs | 20 +- src/librustc_driver/pretty.rs | 2 +- src/librustc_driver/test.rs | 20 +- src/librustc_lint/builtin.rs | 74 +- src/librustc_privacy/lib.rs | 34 +- src/librustc_trans/save/dump_csv.rs | 46 +- src/librustc_trans/save/mod.rs | 8 +- src/librustc_trans/trans/_match.rs | 27 +- src/librustc_trans/trans/adt.rs | 27 +- src/librustc_trans/trans/attributes.rs | 4 +- src/librustc_trans/trans/base.rs | 34 +- src/librustc_trans/trans/callee.rs | 34 +- src/librustc_trans/trans/closure.rs | 8 +- src/librustc_trans/trans/common.rs | 35 +- src/librustc_trans/trans/consts.rs | 26 +- src/librustc_trans/trans/datum.rs | 8 +- .../trans/debuginfo/metadata.rs | 16 +- src/librustc_trans/trans/debuginfo/mod.rs | 6 +- .../trans/debuginfo/namespace.rs | 4 +- .../trans/debuginfo/type_names.rs | 6 +- src/librustc_trans/trans/declare.rs | 2 +- src/librustc_trans/trans/expr.rs | 38 +- src/librustc_trans/trans/foreign.rs | 16 +- src/librustc_trans/trans/glue.rs | 6 +- src/librustc_trans/trans/inline.rs | 11 +- src/librustc_trans/trans/intrinsic.rs | 8 +- src/librustc_trans/trans/meth.rs | 26 +- src/librustc_trans/trans/monomorphize.rs | 8 +- src/librustc_trans/trans/tvec.rs | 4 +- src/librustc_trans/trans/type_of.rs | 6 +- src/librustc_typeck/astconv.rs | 15 +- src/librustc_typeck/check/_match.rs | 26 +- src/librustc_typeck/check/callee.rs | 5 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/closure.rs | 6 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 2 +- src/librustc_typeck/check/dropck.rs | 36 +- src/librustc_typeck/check/method/confirm.rs | 10 +- src/librustc_typeck/check/method/mod.rs | 6 +- src/librustc_typeck/check/method/probe.rs | 29 +- src/librustc_typeck/check/method/suggest.rs | 21 +- src/librustc_typeck/check/mod.rs | 146 +- src/librustc_typeck/check/op.rs | 4 +- src/librustc_typeck/check/regionck.rs | 30 +- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/wf.rs | 61 +- src/librustc_typeck/check/writeback.rs | 8 +- src/librustc_typeck/coherence/mod.rs | 51 +- src/librustc_typeck/coherence/orphan.rs | 14 +- src/librustc_typeck/coherence/overlap.rs | 14 +- src/librustc_typeck/coherence/unsafety.rs | 4 +- src/librustc_typeck/collect.rs | 48 +- src/librustc_typeck/lib.rs | 6 +- src/librustc_typeck/variance.rs | 22 +- src/librustdoc/clean/inline.rs | 36 +- src/librustdoc/clean/mod.rs | 8 +- src/librustdoc/clean/simplify.rs | 5 +- 92 files changed, 3516 insertions(+), 3790 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index b217eabec6e6a..b844717e61388 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -23,7 +23,6 @@ use metadata::cstore; use metadata::decoder; use metadata::tyencode; use middle::def; -use middle::ty::lookup_item_type; use middle::ty::{self, Ty}; use middle::stability; use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; @@ -133,7 +132,7 @@ pub fn def_to_string(did: DefId) -> String { fn encode_item_variances(rbml_w: &mut Encoder, ecx: &EncodeContext, id: NodeId) { - let v = ty::item_variances(ecx.tcx, ast_util::local_def(id)); + let v = ecx.tcx.item_variances(ast_util::local_def(id)); rbml_w.start_tag(tag_item_variances); v.encode(rbml_w); rbml_w.end_tag(); @@ -144,8 +143,8 @@ fn encode_bounds_and_type_for_item<'a, 'tcx>(rbml_w: &mut Encoder, id: ast::NodeId) { encode_bounds_and_type(rbml_w, ecx, - &ty::lookup_item_type(ecx.tcx, local_def(id)), - &ty::lookup_predicates(ecx.tcx, local_def(id))); + &ecx.tcx.lookup_item_type(local_def(id)), + &ecx.tcx.lookup_predicates(local_def(id))); } fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder, @@ -293,8 +292,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let mut disr_val = 0; let mut i = 0; - let vi = ty::enum_variants(ecx.tcx, - DefId { krate: ast::LOCAL_CRATE, node: id }); + let vi = ecx.tcx.enum_variants(local_def(id)); for variant in variants { let def_id = local_def(variant.node.id); index.push(entry { @@ -319,7 +317,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, match variant.node.kind { ast::TupleVariantKind(_) => {}, ast::StructVariantKind(_) => { - let fields = ty::lookup_struct_fields(ecx.tcx, def_id); + let fields = ecx.tcx.lookup_struct_fields(def_id); let idx = encode_info_for_struct(ecx, rbml_w, &fields[..], @@ -328,9 +326,10 @@ fn encode_enum_variant_info(ecx: &EncodeContext, encode_index(rbml_w, idx, write_i64); } } - if (*vi)[i].disr_val != disr_val { - encode_disr_val(ecx, rbml_w, (*vi)[i].disr_val); - disr_val = (*vi)[i].disr_val; + let specified_disr_val = vi[i].disr_val; + if specified_disr_val != disr_val { + encode_disr_val(ecx, rbml_w, specified_disr_val); + disr_val = specified_disr_val; } encode_bounds_and_type_for_item(rbml_w, ecx, def_id.local_id()); @@ -379,9 +378,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext, Some(implementations) => { for base_impl_did in implementations.iter() { for &method_did in impl_items.get(base_impl_did).unwrap() { - let impl_item = ty::impl_or_trait_item( - ecx.tcx, - method_did.def_id()); + let impl_item = ecx.tcx.impl_or_trait_item(method_did.def_id()); if let ty::MethodTraitItem(ref m) = impl_item { encode_reexported_static_method(rbml_w, exp, @@ -875,7 +872,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if let Some(impl_item) = impl_item_opt { if let ast::MethodImplItem(ref sig, _) = impl_item.node { encode_attributes(rbml_w, &impl_item.attrs); - let scheme = ty::lookup_item_type(ecx.tcx, m.def_id); + let scheme = ecx.tcx.lookup_item_type(m.def_id); let any_types = !scheme.generics.types.is_empty(); let needs_inline = any_types || is_default_impl || attr::requests_inline(&impl_item.attrs); @@ -923,7 +920,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_attributes(rbml_w, &ii.attrs); } else { encode_predicates(rbml_w, ecx, - &ty::lookup_predicates(ecx.tcx, associated_type.def_id), + &ecx.tcx.lookup_predicates(associated_type.def_id), tag_item_generics); } @@ -995,7 +992,7 @@ fn encode_extension_implementations(ecx: &EncodeContext, rbml_w: &mut Encoder, trait_def_id: DefId) { assert!(ast_util::is_local(trait_def_id)); - let def = ty::lookup_trait_def(ecx.tcx, trait_def_id); + let def = ecx.tcx.lookup_trait_def(trait_def_id); def.for_each_impl(ecx.tcx, |impl_def_id| { rbml_w.start_tag(tag_items_data_item_extension_impl); @@ -1161,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index); } ast::ItemStruct(ref struct_def, _) => { - let fields = ty::lookup_struct_fields(tcx, def_id); + let fields = tcx.lookup_struct_fields(def_id); /* First, encode the fields These come first because we need to write them to make @@ -1220,7 +1217,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(rbml_w, item.ident.name); encode_unsafety(rbml_w, unsafety); - let trait_ref = ty::impl_trait_ref(tcx, local_def(item.id)).unwrap(); + let trait_ref = tcx.impl_trait_ref(local_def(item.id)).unwrap(); encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); rbml_w.end_tag(); } @@ -1274,7 +1271,7 @@ fn encode_info_for_item(ecx: &EncodeContext, } rbml_w.end_tag(); } - if let Some(trait_ref) = ty::impl_trait_ref(tcx, local_def(item.id)) { + if let Some(trait_ref) = tcx.impl_trait_ref(local_def(item.id)) { encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref); } encode_path(rbml_w, path.clone()); @@ -1298,7 +1295,7 @@ fn encode_info_for_item(ecx: &EncodeContext, pos: rbml_w.mark_stable_position(), }); - match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) { + match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { ty::ConstTraitItem(ref associated_const) => { encode_info_for_associated_const(ecx, rbml_w, @@ -1333,22 +1330,22 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_def_id(rbml_w, def_id); encode_family(rbml_w, 'I'); encode_item_variances(rbml_w, ecx, item.id); - let trait_def = ty::lookup_trait_def(tcx, def_id); - let trait_predicates = ty::lookup_predicates(tcx, def_id); + let trait_def = tcx.lookup_trait_def(def_id); + let trait_predicates = tcx.lookup_predicates(def_id); encode_unsafety(rbml_w, trait_def.unsafety); encode_paren_sugar(rbml_w, trait_def.paren_sugar); - encode_defaulted(rbml_w, ty::trait_has_default_impl(tcx, def_id)); + encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id)); encode_associated_type_names(rbml_w, &trait_def.associated_type_names); encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics); - encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id), + encode_predicates(rbml_w, ecx, &tcx.lookup_super_predicates(def_id), tag_item_super_predicates); encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); encode_name(rbml_w, item.ident.name); encode_attributes(rbml_w, &item.attrs); encode_visibility(rbml_w, vis); encode_stability(rbml_w, stab); - for &method_def_id in ty::trait_item_def_ids(tcx, def_id).iter() { + for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { rbml_w.start_tag(tag_item_trait_item); match method_def_id { ty::ConstTraitItemId(const_def_id) => { @@ -1380,7 +1377,7 @@ fn encode_info_for_item(ecx: &EncodeContext, rbml_w.end_tag(); // Now output the trait item info for each trait item. - let r = ty::trait_item_def_ids(tcx, def_id); + let r = tcx.trait_item_def_ids(def_id); for (i, &item_def_id) in r.iter().enumerate() { assert_eq!(item_def_id.def_id().krate, ast::LOCAL_CRATE); @@ -1397,7 +1394,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_stability(rbml_w, stab); let trait_item_type = - ty::impl_or_trait_item(tcx, item_def_id.def_id()); + tcx.impl_or_trait_item(item_def_id.def_id()); let is_nonstatic_method; match trait_item_type { ty::ConstTraitItem(associated_const) => { diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 71c3ffb862840..801b3a721e40d 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -413,7 +413,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { let method_call = ty::MethodCall::expr(call_expr.id); let fn_ty = match self.tcx.method_map.borrow().get(&method_call) { Some(method) => method.ty, - None => ty::expr_ty_adjusted(self.tcx, func_or_rcvr) + None => self.tcx.expr_ty_adjusted(func_or_rcvr) }; let func_or_rcvr_exit = self.expr(func_or_rcvr, pred); diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 8af6946d3c3b1..62bf1648725cd 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -115,7 +115,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { { let param_env = match item_id { Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id), - None => ty::empty_parameter_environment(self.tcx) + None => self.tcx.empty_parameter_environment() }; f(&mut euv::ExprUseVisitor::new(self, ¶m_env)) } @@ -231,7 +231,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn_like.id()); self.add_qualif(qualif); - if ty::type_contents(self.tcx, ret_ty).interior_unsafe() { + if ret_ty.type_contents(self.tcx).interior_unsafe() { self.add_qualif(ConstQualif::MUTABLE_MEM); } @@ -266,8 +266,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } fn check_static_mut_type(&self, e: &ast::Expr) { - let node_ty = ty::node_id_to_type(self.tcx, e.id); - let tcontents = ty::type_contents(self.tcx, node_ty); + let node_ty = self.tcx.node_id_to_type(e.id); + let tcontents = node_ty.type_contents(self.tcx); let suffix = if tcontents.has_dtor() { "destructors" @@ -282,12 +282,12 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } fn check_static_type(&self, e: &ast::Expr) { - let ty = ty::node_id_to_type(self.tcx, e.id); + let ty = self.tcx.node_id_to_type(e.id); let infcx = infer::new_infer_ctxt(self.tcx); let mut fulfill_cx = traits::FulfillmentContext::new(false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - let env = ty::empty_parameter_environment(self.tcx); + let env = self.tcx.empty_parameter_environment(); match fulfill_cx.select_all_or_error(&infcx, &env) { Ok(()) => { }, Err(ref errors) => { @@ -402,7 +402,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { let mut outer = self.qualif; self.qualif = ConstQualif::empty(); - let node_ty = ty::node_id_to_type(self.tcx, ex.id); + let node_ty = self.tcx.node_id_to_type(ex.id); check_expr(self, ex, node_ty); // Special-case some expressions to avoid certain flags bubbling up. @@ -479,7 +479,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> { // initializer values (very bad). // If the type doesn't have interior mutability, then `ConstQualif::MUTABLE_MEM` has // propagated from another error, so erroring again would be just noise. - let tc = ty::type_contents(self.tcx, node_ty); + let tc = node_ty.type_contents(self.tcx); if self.qualif.intersects(ConstQualif::MUTABLE_MEM) && tc.interior_unsafe() { outer = outer | ConstQualif::NOT_CONST; if self.mode != Mode::Var { @@ -529,7 +529,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &ast::Expr, node_ty: Ty<'tcx>) { match node_ty.sty { ty::TyStruct(did, _) | - ty::TyEnum(did, _) if ty::has_dtor(v.tcx, did) => { + ty::TyEnum(did, _) if v.tcx.has_dtor(did) => { v.add_qualif(ConstQualif::NEEDS_DROP); if v.mode != Mode::Var { v.tcx.sess.span_err(e.span, @@ -560,7 +560,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } } ast::ExprUnary(op, ref inner) => { - match ty::node_id_to_type(v.tcx, inner.id).sty { + match v.tcx.node_id_to_type(inner.id).sty { ty::TyRawPtr(_) => { assert!(op == ast::UnDeref); @@ -574,7 +574,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } } ast::ExprBinary(op, ref lhs, _) => { - match ty::node_id_to_type(v.tcx, lhs.id).sty { + match v.tcx.node_id_to_type(lhs.id).sty { ty::TyRawPtr(_) => { assert!(op.node == ast::BiEq || op.node == ast::BiNe || op.node == ast::BiLe || op.node == ast::BiLt || @@ -731,7 +731,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, ast::ExprClosure(..) => { // Paths in constant contexts cannot refer to local variables, // as there are none, and thus closures can't have upvars there. - if ty::with_freevars(v.tcx, e.id, |fv| !fv.is_empty()) { + if v.tcx.with_freevars(e.id, |fv| !fv.is_empty()) { assert!(v.mode == Mode::Var, "global closures can't capture anything"); v.add_qualif(ConstQualif::NOT_CONST); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index dd708cf8f3ae6..d2b3b83e4f42f 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -20,7 +20,7 @@ use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init}; use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode}; use middle::expr_use_visitor::WriteAndRead; use middle::expr_use_visitor as euv; -use middle::mem_categorization::cmt; +use middle::mem_categorization::{cmt, Typer}; use middle::pat_util::*; use middle::ty::*; use middle::ty; @@ -149,7 +149,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> { pub fn check_crate(tcx: &ty::ctxt) { visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx, - param_env: ty::empty_parameter_environment(tcx), + param_env: tcx.empty_parameter_environment(), }, tcx.map.krate()); tcx.sess.abort_if_errors(); } @@ -203,9 +203,9 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) { // Finally, check if the whole match expression is exhaustive. // Check for empty enum, because is_useful only works on inhabited types. - let pat_ty = node_id_to_type(cx.tcx, scrut.id); + let pat_ty = cx.tcx.node_id_to_type(scrut.id); if inlined_arms.is_empty() { - if !type_is_empty(cx.tcx, pat_ty) { + if !pat_ty.is_empty(cx.tcx) { // We know the type is inhabited, so this must be wrong span_err!(cx.tcx.sess, ex.span, E0002, "non-exhaustive patterns: type {} is non-empty", @@ -231,11 +231,11 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) ast_util::walk_pat(pat, |p| { match p.node { ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => { - let pat_ty = ty::pat_ty(cx.tcx, p); + let pat_ty = cx.tcx.pat_ty(p); if let ty::TyEnum(def_id, _) = pat_ty.sty { let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()); if let Some(DefLocal(_)) = def { - if ty::enum_variants(cx.tcx, def_id).iter().any(|variant| + if cx.tcx.enum_variants(def_id).iter().any(|variant| token::get_name(variant.name) == token::get_name(ident.node.name) && variant.args.is_empty() ) { @@ -509,12 +509,12 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor, ty::TyEnum(cid, _) | ty::TyStruct(cid, _) => { let (vid, is_structure) = match ctor { &Variant(vid) => - (vid, ty::enum_variant_with_id(cx.tcx, cid, vid).arg_names.is_some()), + (vid, cx.tcx.enum_variant_with_id(cid, vid).arg_names.is_some()), _ => - (cid, !ty::is_tuple_struct(cx.tcx, cid)) + (cid, !cx.tcx.is_tuple_struct(cid)) }; if is_structure { - let fields = ty::lookup_struct_fields(cx.tcx, vid); + let fields = cx.tcx.lookup_struct_fields(vid); let field_pats: Vec<_> = fields.into_iter() .zip(pats) .filter(|&(_, ref pat)| pat.node != ast::PatWild(ast::PatWildSingle)) @@ -605,7 +605,7 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty, }, ty::TyEnum(eid, _) => - ty::enum_variants(cx.tcx, eid) + cx.tcx.enum_variants(eid) .iter() .map(|va| Variant(va.id)) .collect(), @@ -653,7 +653,7 @@ fn is_useful(cx: &MatchCheckCtxt, let left_ty = if real_pat.id == DUMMY_NODE_ID { cx.tcx.mk_nil() } else { - let left_ty = ty::pat_ty(cx.tcx, &*real_pat); + let left_ty = cx.tcx.pat_ty(&*real_pat); match real_pat.node { ast::PatIdent(ast::BindByRef(..), _, _) => { @@ -817,11 +817,11 @@ pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usi }, ty::TyEnum(eid, _) => { match *ctor { - Variant(id) => enum_variant_with_id(cx.tcx, eid, id).args.len(), + Variant(id) => cx.tcx.enum_variant_with_id(eid, id).args.len(), _ => unreachable!() } } - ty::TyStruct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(), + ty::TyStruct(cid, _) => cx.tcx.lookup_struct_fields(cid).len(), ty::TyArray(_, n) => n, _ => 0 } @@ -913,7 +913,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], }, _ => { // Assume this is a struct. - match ty::ty_to_def_id(node_id_to_type(cx.tcx, pat_id)) { + match cx.tcx.node_id_to_type(pat_id).ty_to_def_id() { None => { cx.tcx.sess.span_bug(pat_span, "struct pattern wasn't of a \ @@ -924,7 +924,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } }; class_id.map(|variant_id| { - let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id); + let struct_fields = cx.tcx.lookup_struct_fields(variant_id); let args = struct_fields.iter().map(|sf| { match pattern_fields.iter().find(|f| f.node.ident.name == sf.name) { Some(ref f) => &*f.node.pat, @@ -1109,8 +1109,8 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, if pat_is_binding(def_map, &*p) { match p.node { ast::PatIdent(ast::BindByValue(_), _, ref sub) => { - let pat_ty = ty::node_id_to_type(tcx, p.id); - if ty::type_moves_by_default(&cx.param_env, pat.span, pat_ty) { + let pat_ty = tcx.node_id_to_type(p.id); + if cx.param_env.type_moves_by_default(pat_ty, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index f5934751c58b2..1489e946fe2ce 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -59,7 +59,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> { cmt: mc::cmt<'tcx>, _: euv::ConsumeMode) { debug!("consume; cmt: {:?}; type: {:?}", *cmt, cmt.ty); - if !ty::type_is_sized(Some(self.param_env), self.tcx, span, cmt.ty) { + if !cmt.ty.is_sized(self.param_env, span) { span_err!(self.tcx.sess, span, E0161, "cannot move a value of type {0}: the size of {0} cannot be statically determined", cmt.ty); diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index ed06ccf1ec649..1b1725dd15c85 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -126,9 +126,9 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, // `resolve_trait_associated_const` will select an impl // or the default. Some(ref_id) => { - let trait_id = ty::trait_of_item(tcx, def_id) + let trait_id = tcx.trait_of_item(def_id) .unwrap(); - let substs = ty::node_id_item_substs(tcx, ref_id) + let substs = tcx.node_id_item_substs(ref_id) .substs; resolve_trait_associated_const(tcx, ti, trait_id, substs) @@ -176,7 +176,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, // a trait-associated const if the caller gives us // the expression that refers to it. Some(ref_id) => { - let substs = ty::node_id_item_substs(tcx, ref_id) + let substs = tcx.node_id_item_substs(ref_id) .substs; resolve_trait_associated_const(tcx, ti, trait_id, substs).map(|e| e.id) @@ -714,7 +714,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, e: &Expr, ty_hint: Option>) -> EvalResult { eval_const_expr_with_substs(tcx, e, ty_hint, |id| { - ty::node_id_item_substs(tcx, id).substs + tcx.node_id_item_substs(id).substs }) } @@ -725,7 +725,7 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>, where S: Fn(ast::NodeId) -> subst::Substs<'tcx> { fn fromb(b: bool) -> ConstVal { Int(b as i64) } - let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e)); + let ety = ty_hint.or_else(|| tcx.expr_ty_opt(e)); // If type of expression itself is int or uint, normalize in these // bindings so that isize/usize is mapped to a type with an @@ -882,7 +882,7 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>, // FIXME (#23833): the type-hint can cause problems, // e.g. `(i8::MAX + 1_i8) as u32` feeds in `u32` as result // type to the sum, and thus no overflow is signaled. - let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety); + let base_hint = tcx.expr_ty_opt(&**base).unwrap_or(ety); let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint))); match cast_const(tcx, val, ety) { Ok(val) => val, @@ -1030,10 +1030,10 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id, substs: trait_substs }); - ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id()); + tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx); - let param_env = ty::empty_parameter_environment(tcx); + let param_env = tcx.empty_parameter_environment(); let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), trait_ref.to_poly_trait_predicate()); @@ -1056,7 +1056,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, match selection { traits::VtableImpl(ref impl_data) => { - match ty::associated_consts(tcx, impl_data.impl_def_id) + match tcx.associated_consts(impl_data.impl_def_id) .iter().find(|ic| ic.name == ti.ident.name) { Some(ic) => lookup_const_by_id(tcx, ic.def_id, None), None => match ti.node { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index fd810429c86e0..bd8b8afbdfe88 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -100,7 +100,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { Some(method) => { match method.origin { ty::MethodStatic(def_id) => { - match ty::provided_source(self.tcx, def_id) { + match self.tcx.provided_source(def_id) { Some(p_did) => self.check_def_id(p_did), None => self.check_def_id(def_id) } @@ -116,9 +116,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { method_num: index, .. }) => { - let trait_item = ty::trait_item(self.tcx, - trait_ref.def_id, - index); + let trait_item = self.tcx.trait_item(trait_ref.def_id, index); self.check_def_id(trait_item.def_id()); } } @@ -132,9 +130,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) { - match ty::expr_ty_adjusted(self.tcx, lhs).sty { + match self.tcx.expr_ty_adjusted(lhs).sty { ty::TyStruct(id, _) => { - let fields = ty::lookup_struct_fields(self.tcx, id); + let fields = self.tcx.lookup_struct_fields(id); let field_id = fields.iter() .find(|field| field.name == name).unwrap().id; self.live_symbols.insert(field_id.node); @@ -144,9 +142,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) { - match ty::expr_ty_adjusted(self.tcx, lhs).sty { + match self.tcx.expr_ty_adjusted(lhs).sty { ty::TyStruct(id, _) => { - let fields = ty::lookup_struct_fields(self.tcx, id); + let fields = self.tcx.lookup_struct_fields(id); let field_id = fields[idx].id; self.live_symbols.insert(field_id.node); }, @@ -159,8 +157,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { let id = match self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def() { def::DefVariant(_, id, _) => id, _ => { - match ty::ty_to_def_id(ty::node_id_to_type(self.tcx, - lhs.id)) { + match self.tcx.node_id_to_type(lhs.id).ty_to_def_id() { None => { self.tcx.sess.span_bug(lhs.span, "struct pattern wasn't of a \ @@ -170,7 +167,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } }; - let fields = ty::lookup_struct_fields(self.tcx, id); + let fields = self.tcx.lookup_struct_fields(id); for pat in pats { if let ast::PatWild(ast::PatWildSingle) = pat.node.pat.node { continue; @@ -480,8 +477,8 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool { let is_named = node.ident().is_some(); - let field_type = ty::node_id_to_type(self.tcx, node.id); - let is_marker_field = match ty::ty_to_def_id(field_type) { + let field_type = self.tcx.node_id_to_type(node.id); + let is_marker_field = match field_type.ty_to_def_id() { Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)), _ => false }; diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index bb63ec42d8c0c..c48d5d5da4020 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -62,7 +62,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { fn check_str_index(&mut self, e: &ast::Expr) { let base_type = match e.node { - ast::ExprIndex(ref base, _) => ty::node_id_to_type(self.tcx, base.id), + ast::ExprIndex(ref base, _) => self.tcx.node_id_to_type(base.id), _ => return }; debug!("effect: checking index with base type {:?}", @@ -149,7 +149,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { } } ast::ExprCall(ref base, _) => { - let base_type = ty::node_id_to_type(self.tcx, base.id); + let base_type = self.tcx.node_id_to_type(base.id); debug!("effect: call case, base type is {:?}", base_type); if type_is_unsafe_function(base_type) { @@ -157,7 +157,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { } } ast::ExprUnary(ast::UnDeref, ref base) => { - let base_type = ty::node_id_to_type(self.tcx, base.id); + let base_type = self.tcx.node_id_to_type(base.id); debug!("effect: unary case, base type is {:?}", base_type); if let ty::TyRawPtr(_) = base_type.sty { @@ -174,7 +174,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.require_unsafe(expr.span, "use of inline assembly"); } ast::ExprPath(..) => { - if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) { + if let def::DefStatic(_, true) = self.tcx.resolve_expr(expr) { self.require_unsafe(expr.span, "use of mutable static"); } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 2b685f801d7f7..a15d02ea29605 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -229,7 +229,7 @@ impl OverloadedCallType { fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId) -> OverloadedCallType { - let method_descriptor = match ty::impl_or_trait_item(tcx, method_id) { + let method_descriptor = match tcx.impl_or_trait_item(method_id) { ty::MethodTraitItem(ref method_descriptor) => { (*method_descriptor).clone() } @@ -244,7 +244,7 @@ impl OverloadedCallType { } ty::ImplContainer(impl_id) => impl_id, }; - let trait_ref = match ty::impl_trait_ref(tcx, impl_id) { + let trait_ref = match tcx.impl_trait_ref(impl_id) { None => { tcx.sess.bug("statically resolved overloaded call impl \ didn't implement a trait?!") @@ -502,9 +502,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let expr_ty = return_if_err!(self.typer.node_ty(expr.id)); - let r = ty::ty_region(self.tcx(), expr.span, expr_ty); - let bk = ty::BorrowKind::from_mutbl(m); - self.borrow_expr(&**base, r, bk, AddrOf); + if let ty::TyRef(&r, _) = expr_ty.sty { + let bk = ty::BorrowKind::from_mutbl(m); + self.borrow_expr(&**base, r, bk, AddrOf); + } } ast::ExprInlineAsm(ref ia) => { @@ -740,7 +741,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // expression that will actually be used let with_fields = match with_cmt.ty.sty { ty::TyStruct(did, substs) => { - ty::struct_fields(self.tcx(), did, substs) + self.tcx().struct_fields(did, substs) } _ => { // the base expression should always evaluate to a @@ -822,7 +823,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // the method call infrastructure should have // replaced all late-bound regions with variables: let self_ty = method_ty.fn_sig().input(0); - let self_ty = ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap(); + let self_ty = self.tcx().no_late_bound_regions(&self_ty).unwrap(); let (m, r) = match self_ty.sty { ty::TyRef(r, ref m) => (m.mutbl, r), @@ -922,10 +923,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // This is always an rvalue, since we are producing a new // (temporary) indirection. - let adj_ty = - ty::adjust_ty_for_autoref(self.tcx(), - cmt_base_ty, - opt_autoref); + let adj_ty = cmt_base_ty.adjust_for_autoref(self.tcx(), opt_autoref); self.mc.cat_rvalue_node(expr.id, expr.span, adj_ty) } @@ -1074,12 +1072,11 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // It is also a borrow or copy/move of the value being matched. match pat.node { ast::PatIdent(ast::BindByRef(m), _, _) => { - let (r, bk) = { - (ty::ty_region(tcx, pat.span, pat_ty), - ty::BorrowKind::from_mutbl(m)) - }; - delegate.borrow(pat.id, pat.span, cmt_pat, - r, bk, RefBinding); + if let ty::TyRef(&r, _) = pat_ty.sty { + let bk = ty::BorrowKind::from_mutbl(m); + delegate.borrow(pat.id, pat.span, cmt_pat, + r, bk, RefBinding); + } } ast::PatIdent(ast::BindByValue(_), _, _) => { let mode = copy_or_move(typer, &cmt_pat, PatBindingMove); @@ -1152,7 +1149,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { Some(def::DefVariant(enum_did, variant_did, _is_struct)) => { let downcast_cmt = - if ty::enum_is_univariant(tcx, enum_did) { + if tcx.enum_is_univariant(enum_did) { cmt_pat } else { let cmt_pat_ty = cmt_pat.ty; @@ -1238,7 +1235,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { fn walk_captures(&mut self, closure_expr: &ast::Expr) { debug!("walk_captures({:?})", closure_expr); - ty::with_freevars(self.tcx(), closure_expr.id, |freevars| { + self.tcx().with_freevars(closure_expr.id, |freevars| { for freevar in freevars { let id_var = freevar.def.def_id().node; let upvar_id = ty::UpvarId { var_id: id_var, @@ -1283,7 +1280,7 @@ fn copy_or_move<'tcx>(typer: &mc::Typer<'tcx>, move_reason: MoveReason) -> ConsumeMode { - if typer.type_moves_by_default(cmt.span, cmt.ty) { + if typer.type_moves_by_default(cmt.ty, cmt.span) { Move(move_reason) } else { Copy diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index 3cdf53e6b0acd..d5fa885b16ab5 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -112,7 +112,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { ty::TyEnum(def_id, substs) | ty::TyStruct(def_id, substs) => { - let item_scheme = ty::lookup_item_type(self.tcx(), def_id); + let item_scheme = self.tcx().lookup_item_type(def_id); self.accumulate_from_adt(ty, def_id, &item_scheme.generics, substs) } @@ -236,7 +236,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { substs: &Substs<'tcx>) { let predicates = - ty::lookup_predicates(self.tcx(), def_id).instantiate(self.tcx(), substs); + self.tcx().lookup_predicates(def_id).instantiate(self.tcx(), substs); let predicates = match self.fully_normalize(&predicates) { Ok(predicates) => predicates, Err(ErrorReported) => { return; } @@ -250,7 +250,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { ty::Predicate::Equate(..) => { } ty::Predicate::Projection(..) => { } ty::Predicate::RegionOutlives(ref data) => { - match ty::no_late_bound_regions(self.tcx(), data) { + match self.tcx().no_late_bound_regions(data) { None => { } Some(ty::OutlivesPredicate(r_a, r_b)) => { self.push_sub_region_constraint(Some(ty), r_b, r_a); @@ -258,7 +258,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { } } ty::Predicate::TypeOutlives(ref data) => { - match ty::no_late_bound_regions(self.tcx(), data) { + match self.tcx().no_late_bound_regions(data) { None => { } Some(ty::OutlivesPredicate(ty_a, r_b)) => { self.stack.push((r_b, Some(ty))); @@ -275,7 +275,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { .map(|pred| Implication::Predicate(def_id, pred)); self.out.extend(obligations); - let variances = ty::item_variances(self.tcx(), def_id); + let variances = self.tcx().item_variances(def_id); for (®ion, &variance) in substs.regions().iter().zip(&variances.regions) { match variance { @@ -316,7 +316,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { data); for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) { - match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) { + match self.tcx().no_late_bound_regions(&poly_trait_ref) { Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); } None => { } } @@ -330,7 +330,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { trait_ref); let trait_def_id = trait_ref.def_id; - let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + let trait_def = self.tcx().lookup_trait_def(trait_def_id); let assoc_type_projections: Vec<_> = trait_def.associated_type_names .iter() @@ -447,5 +447,5 @@ pub fn object_region_bounds<'tcx>( let mut predicates = others.to_predicates(tcx, open_ty); predicates.extend(trait_refs.iter().map(|t| t.to_predicate())); - ty::required_region_bounds(tcx, open_ty, predicates) + tcx.required_region_bounds(open_ty, predicates) } diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs index 742ad3f29b780..d2268894b20a1 100644 --- a/src/librustc/middle/infer/bivariate.rs +++ b/src/librustc/middle/infer/bivariate.rs @@ -109,8 +109,8 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> { -> RelateResult<'tcx, ty::Binder> where T: Relate<'a,'tcx> { - let a1 = ty::erase_late_bound_regions(self.tcx(), a); - let b1 = ty::erase_late_bound_regions(self.tcx(), b); + let a1 = self.tcx().erase_late_bound_regions(a); + let b1 = self.tcx().erase_late_bound_regions(b); let c = try!(self.relate(&a1, &b1)); Ok(ty::Binder(c)) } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 8839e68e767f2..17075c0cba6ca 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -91,123 +91,125 @@ use syntax::parse::token; use syntax::print::pprust; use syntax::ptr::P; -pub fn note_and_explain_region(tcx: &ty::ctxt, - prefix: &str, - region: ty::Region, - suffix: &str) { - fn item_scope_tag(item: &ast::Item) -> &'static str { - match item.node { - ast::ItemImpl(..) => "impl", - ast::ItemStruct(..) => "struct", - ast::ItemEnum(..) => "enum", - ast::ItemTrait(..) => "trait", - ast::ItemFn(..) => "function body", - _ => "item" +impl<'tcx> ty::ctxt<'tcx> { + pub fn note_and_explain_region(&self, + prefix: &str, + region: ty::Region, + suffix: &str) { + fn item_scope_tag(item: &ast::Item) -> &'static str { + match item.node { + ast::ItemImpl(..) => "impl", + ast::ItemStruct(..) => "struct", + ast::ItemEnum(..) => "enum", + ast::ItemTrait(..) => "trait", + ast::ItemFn(..) => "function body", + _ => "item" + } } - } - - fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span) - -> (String, Option) { - let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo); - (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()), - Some(span)) - } - let (description, span) = match region { - ty::ReScope(scope) => { - let new_string; - let unknown_scope = || { - format!("{}unknown scope: {:?}{}. Please report a bug.", - prefix, scope, suffix) - }; - let span = match scope.span(&tcx.map) { - Some(s) => s, - None => return tcx.sess.note(&unknown_scope()) - }; - let tag = match tcx.map.find(scope.node_id()) { - Some(ast_map::NodeBlock(_)) => "block", - Some(ast_map::NodeExpr(expr)) => match expr.node { - ast::ExprCall(..) => "call", - ast::ExprMethodCall(..) => "method call", - ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let", - ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let", - ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for", - ast::ExprMatch(..) => "match", - _ => "expression", - }, - Some(ast_map::NodeStmt(_)) => "statement", - Some(ast_map::NodeItem(it)) => item_scope_tag(&*it), - Some(_) | None => { - return tcx.sess.span_note(span, &unknown_scope()); - } - }; - let scope_decorated_tag = match scope { - region::CodeExtent::Misc(_) => tag, - region::CodeExtent::ParameterScope { .. } => { - "scope of parameters for function" - } - region::CodeExtent::DestructionScope(_) => { - new_string = format!("destruction scope surrounding {}", tag); - &new_string[..] - } - region::CodeExtent::Remainder(r) => { - new_string = format!("block suffix following statement {}", - r.first_statement_index); - &new_string[..] - } - }; - explain_span(tcx, scope_decorated_tag, span) + fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span) + -> (String, Option) { + let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo); + (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()), + Some(span)) } - ty::ReFree(ref fr) => { - let prefix = match fr.bound_region { - ty::BrAnon(idx) => { - format!("the anonymous lifetime #{} defined on", idx + 1) - } - ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(), - _ => { - format!("the lifetime {} as defined on", - fr.bound_region) - } - }; + let (description, span) = match region { + ty::ReScope(scope) => { + let new_string; + let unknown_scope = || { + format!("{}unknown scope: {:?}{}. Please report a bug.", + prefix, scope, suffix) + }; + let span = match scope.span(&self.map) { + Some(s) => s, + None => return self.sess.note(&unknown_scope()) + }; + let tag = match self.map.find(scope.node_id()) { + Some(ast_map::NodeBlock(_)) => "block", + Some(ast_map::NodeExpr(expr)) => match expr.node { + ast::ExprCall(..) => "call", + ast::ExprMethodCall(..) => "method call", + ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let", + ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let", + ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for", + ast::ExprMatch(..) => "match", + _ => "expression", + }, + Some(ast_map::NodeStmt(_)) => "statement", + Some(ast_map::NodeItem(it)) => item_scope_tag(&*it), + Some(_) | None => { + return self.sess.span_note(span, &unknown_scope()); + } + }; + let scope_decorated_tag = match scope { + region::CodeExtent::Misc(_) => tag, + region::CodeExtent::ParameterScope { .. } => { + "scope of parameters for function" + } + region::CodeExtent::DestructionScope(_) => { + new_string = format!("destruction scope surrounding {}", tag); + &new_string[..] + } + region::CodeExtent::Remainder(r) => { + new_string = format!("block suffix following statement {}", + r.first_statement_index); + &new_string[..] + } + }; + explain_span(self, scope_decorated_tag, span) + } - match tcx.map.find(fr.scope.node_id) { - Some(ast_map::NodeBlock(ref blk)) => { - let (msg, opt_span) = explain_span(tcx, "block", blk.span); - (format!("{} {}", prefix, msg), opt_span) - } - Some(ast_map::NodeItem(it)) => { - let tag = item_scope_tag(&*it); - let (msg, opt_span) = explain_span(tcx, tag, it.span); - (format!("{} {}", prefix, msg), opt_span) - } - Some(_) | None => { - // this really should not happen - (format!("{} unknown free region bounded by scope {:?}", - prefix, fr.scope), None) + ty::ReFree(ref fr) => { + let prefix = match fr.bound_region { + ty::BrAnon(idx) => { + format!("the anonymous lifetime #{} defined on", idx + 1) + } + ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(), + _ => { + format!("the lifetime {} as defined on", + fr.bound_region) + } + }; + + match self.map.find(fr.scope.node_id) { + Some(ast_map::NodeBlock(ref blk)) => { + let (msg, opt_span) = explain_span(self, "block", blk.span); + (format!("{} {}", prefix, msg), opt_span) + } + Some(ast_map::NodeItem(it)) => { + let tag = item_scope_tag(&*it); + let (msg, opt_span) = explain_span(self, tag, it.span); + (format!("{} {}", prefix, msg), opt_span) + } + Some(_) | None => { + // this really should not happen + (format!("{} unknown free region bounded by scope {:?}", + prefix, fr.scope), None) + } } } - } - ty::ReStatic => ("the static lifetime".to_owned(), None), + ty::ReStatic => ("the static lifetime".to_owned(), None), - ty::ReEmpty => ("the empty lifetime".to_owned(), None), + ty::ReEmpty => ("the empty lifetime".to_owned(), None), - ty::ReEarlyBound(ref data) => { - (format!("{}", token::get_name(data.name)), None) - } + ty::ReEarlyBound(ref data) => { + (format!("{}", token::get_name(data.name)), None) + } - // I believe these cases should not occur (except when debugging, - // perhaps) - ty::ReInfer(_) | ty::ReLateBound(..) => { - (format!("lifetime {:?}", region), None) + // I believe these cases should not occur (except when debugging, + // perhaps) + ty::ReInfer(_) | ty::ReLateBound(..) => { + (format!("lifetime {:?}", region), None) + } + }; + let message = format!("{}{}{}", prefix, description, suffix); + if let Some(span) = span { + self.sess.span_note(span, &message); + } else { + self.sess.note(&message); } - }; - let message = format!("{}{}{}", prefix, description, suffix); - if let Some(span) = span { - tcx.sess.span_note(span, &message); - } else { - tcx.sess.note(&message); } } @@ -491,7 +493,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { terr: &ty::type_err<'tcx>) { let span = trace.origin.span(); self.report_type_error(trace, terr); - ty::note_and_explain_type_err(self.tcx, terr, span); + self.tcx.note_and_explain_type_err(terr, span); } /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived @@ -576,8 +578,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { &format!( "consider adding an explicit lifetime bound for `{}`", bound_kind)); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( &format!("{} must be valid for ", labeled_user_string), sub, "..."); @@ -600,13 +601,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span_err!(self.tcx.sess, span, E0312, "lifetime of reference outlines \ lifetime of borrowed content..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "...the reference is valid for ", sub, "..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "...but the borrowed content is only valid for ", sup, ""); @@ -615,33 +614,25 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span_err!(self.tcx.sess, span, E0313, "lifetime of borrowed pointer outlives \ lifetime of captured variable `{}`...", - ty::local_var_name_str(self.tcx, - upvar_id.var_id) - .to_string()); - note_and_explain_region( - self.tcx, + self.tcx.local_var_name_str(upvar_id.var_id)); + self.tcx.note_and_explain_region( "...the borrowed pointer is valid for ", sub, "..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( &format!("...but `{}` is only valid for ", - ty::local_var_name_str(self.tcx, - upvar_id.var_id) - .to_string()), + self.tcx.local_var_name_str(upvar_id.var_id)), sup, ""); } infer::InfStackClosure(span) => { span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "...the closure must be valid for ", sub, "..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "...but the closure's stack frame is only valid for ", sup, ""); @@ -649,8 +640,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { infer::InvokeClosure(span) => { span_err!(self.tcx.sess, span, E0315, "cannot invoke closure outside of its lifetime"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the closure is only valid for ", sup, ""); @@ -659,8 +649,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.sess.span_err( span, "dereference of reference outside its lifetime"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the reference is only valid for ", sup, ""); @@ -669,16 +658,13 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.sess.span_err( span, &format!("captured variable `{}` does not \ - outlive the enclosing closure", - ty::local_var_name_str(self.tcx, - id).to_string())); - note_and_explain_region( - self.tcx, + outlive the enclosing closure", + self.tcx.local_var_name_str(id))); + self.tcx.note_and_explain_region( "captured variable is valid for ", sup, ""); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "closure is valid for ", sub, ""); @@ -686,8 +672,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { infer::IndexSlice(span) => { self.tcx.sess.span_err(span, "index of slice outside its lifetime"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the slice is only valid for ", sup, ""); @@ -697,13 +682,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "lifetime of the source pointer does not outlive \ lifetime bound of the object type"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "object type is valid for ", sub, ""); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "source pointer is only valid for ", sup, ""); @@ -714,7 +697,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { &format!("the type `{}` does not fulfill the \ required lifetime", self.ty_to_string(ty))); - note_and_explain_region(self.tcx, + self.tcx.note_and_explain_region( "type must outlive ", sub, ""); @@ -723,13 +706,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.sess.span_err( span, "lifetime bound not satisfied"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "lifetime parameter instantiated with ", sup, ""); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "but lifetime parameter must outlive ", sub, ""); @@ -740,7 +721,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { &format!("the type `{}` (provided as the value of \ a type parameter) is not valid at this point", self.ty_to_string(ty))); - note_and_explain_region(self.tcx, + self.tcx.note_and_explain_region( "type must outlive ", sub, ""); @@ -750,8 +731,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "lifetime of method receiver does not outlive \ the method call"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the receiver is only valid for ", sup, ""); @@ -761,8 +741,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "lifetime of function argument does not outlive \ the function call"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the function argument is only valid for ", sup, ""); @@ -772,8 +751,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "lifetime of return value does not outlive \ the function call"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the return value is only valid for ", sup, ""); @@ -783,8 +761,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "lifetime of operand does not outlive \ the operation"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the operand is only valid for ", sup, ""); @@ -794,8 +771,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "reference is not valid \ at the time of borrow"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the borrow is only valid for ", sup, ""); @@ -805,8 +781,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { span, "automatically reference is not valid \ at the time of borrow"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the automatic borrow is only valid for ", sup, ""); @@ -817,8 +792,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { &format!("type of expression contains references \ that are not valid during the expression: `{}`", self.ty_to_string(t))); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "type is only valid for ", sup, ""); @@ -829,13 +803,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { "unsafe use of destructor: destructor might be called \ while references are dead"); // FIXME (22171): terms "super/subregion" are suboptimal - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "superregion: ", sup, ""); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "subregion: ", sub, ""); @@ -844,8 +816,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { self.tcx.sess.span_err( span, "lifetime of variable does not enclose its declaration"); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the variable is only valid for ", sup, ""); @@ -856,13 +827,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { &format!("in type `{}`, reference has a longer lifetime \ than the data it references", self.ty_to_string(ty))); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "the pointer is valid for ", sub, ""); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "but the referenced data is only valid for ", sup, ""); @@ -878,16 +847,14 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sup_region: Region) { self.report_inference_failure(var_origin); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "first, the lifetime cannot outlive ", sup_region, "..."); self.note_region_origin(&sup_origin); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "but, the lifetime must be valid for ", sub_region, "..."); @@ -903,16 +870,14 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { region2: Region) { self.report_inference_failure(var_origin); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "first, the lifetime must be contained by ", region1, "..."); self.note_region_origin(&origin1); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "but, the lifetime must also be contained by ", region2, "..."); @@ -1353,7 +1318,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { }; match a_def { def::DefTy(did, _) | def::DefStruct(did) => { - let generics = ty::lookup_item_type(self.tcx, did).generics; + let generics = self.tcx.lookup_item_type(did).generics; let expected = generics.regions.len(subst::TypeSpace) as u32; @@ -1591,7 +1556,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { } infer::UpvarRegion(ref upvar_id, _) => { format!(" for capture of `{}` by closure", - ty::local_var_name_str(self.tcx, upvar_id.var_id).to_string()) + self.tcx.local_var_name_str(upvar_id.var_id).to_string()) } }; @@ -1671,7 +1636,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { span, &format!( "...so that closure can access `{}`", - ty::local_var_name_str(self.tcx, upvar_id.var_id) + self.tcx.local_var_name_str(upvar_id.var_id) .to_string())) } infer::InfStackClosure(span) => { @@ -1695,9 +1660,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { span, &format!("...so that captured variable `{}` \ does not outlive the enclosing closure", - ty::local_var_name_str( - self.tcx, - id).to_string())); + self.tcx.local_var_name_str(id))); } infer::IndexSlice(span) => { self.tcx.sess.span_note( diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 2873a59ae8b1a..f1af2705d4ed8 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -983,7 +983,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { error_str)); if let Some(err) = err { - ty::note_and_explain_type_err(self.tcx, err, sp) + self.tcx.note_and_explain_type_err(err, sp) } } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 900dbb444e4e6..c5f6f0126de37 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -54,7 +54,7 @@ struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> { fn def_id_is_transmute(&self, def_id: DefId) -> bool { - let intrinsic = match ty::lookup_item_type(self.tcx, def_id).ty.sty { + let intrinsic = match self.tcx.lookup_item_type(def_id).ty.sty { ty::TyBareFn(_, ref bfty) => bfty.abi == RustIntrinsic, _ => return false }; @@ -160,8 +160,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> { // In all cases, we keep the original unsubstituted types // around for error reporting. - let from_tc = ty::type_contents(self.tcx, from); - let to_tc = ty::type_contents(self.tcx, to); + let from_tc = from.type_contents(self.tcx); + let to_tc = to.type_contents(self.tcx); if from_tc.interior_param() || to_tc.interior_param() { span_err!(self.tcx.sess, span, E0139, "cannot transmute to or from a type that contains \ @@ -213,7 +213,7 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> { debug!("with_each_combination: space={:?}, index={}, param_ty={:?}", space, index, param_ty); - if !ty::type_is_sized(Some(param_env), self.tcx, span, param_ty) { + if !param_ty.is_sized(param_env, span) { debug!("with_each_combination: param_ty is not known to be sized"); substs.types.get_mut_slice(space)[index] = self.dummy_unsized_ty; @@ -253,9 +253,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &ast::Expr) { if let ast::ExprPath(..) = expr.node { - match ty::resolve_expr(self.tcx, expr) { + match self.tcx.resolve_expr(expr) { DefFn(did, _) if self.def_id_is_transmute(did) => { - let typ = ty::node_id_to_type(self.tcx, expr.id); + let typ = self.tcx.node_id_to_type(expr.id); match typ.sty { TyBareFn(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => { if let ty::FnConverging(to) = bare_fn_ty.sig.0.output { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index aa329d1fab6ca..d354c1667da38 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -465,7 +465,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { // in better error messages than just pointing at the closure // construction site. let mut call_caps = Vec::new(); - ty::with_freevars(ir.tcx, expr.id, |freevars| { + ir.tcx.with_freevars(expr.id, |freevars| { for fv in freevars { if let DefLocal(rv) = fv.def { let fv_ln = ir.add_live_node(FreeVarNode(fv.span)); @@ -1138,7 +1138,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ast::ExprCall(ref f, ref args) => { let diverges = !self.ir.tcx.is_method_call(expr.id) && - ty::expr_ty_adjusted(self.ir.tcx, &**f).fn_ret().diverges(); + self.ir.tcx.expr_ty_adjusted(&**f).fn_ret().diverges(); let succ = if diverges { self.s.exit_ln } else { @@ -1494,7 +1494,7 @@ fn check_fn(_v: &Liveness, impl<'a, 'tcx> Liveness<'a, 'tcx> { fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> { - let fn_ty = ty::node_id_to_type(self.ir.tcx, id); + let fn_ty = self.ir.tcx.node_id_to_type(id); match fn_ty.sty { ty::TyClosure(closure_def_id, substs) => self.ir.tcx.closure_type(closure_def_id, substs).sig.output(), @@ -1511,8 +1511,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { { // within the fn body, late-bound regions are liberated: let fn_ret = - ty::liberate_late_bound_regions( - self.ir.tcx, + self.ir.tcx.liberate_late_bound_regions( region::DestructionScopeData::new(body.id), &self.fn_ret(id)); @@ -1527,7 +1526,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { None if !body.stmts.is_empty() => match body.stmts.first().unwrap().node { ast::StmtSemi(ref e, _) => { - ty::expr_ty(self.ir.tcx, &**e) == t_ret + self.ir.tcx.expr_ty(&**e) == t_ret }, _ => false }, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 6e3a36d85c6ae..969ffaf88a719 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -285,7 +285,7 @@ pub type McResult = Result; pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> { fn node_ty(&self, id: ast::NodeId) -> McResult>; fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult>; - fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool; + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool; fn node_method_ty(&self, method_call: ty::MethodCall) -> Option>; fn node_method_origin(&self, method_call: ty::MethodCall) -> Option>; @@ -406,9 +406,10 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { let unadjusted_ty = try!(self.expr_ty(expr)); - Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty, - self.typer.adjustments().borrow().get(&expr.id), - |method_call| self.typer.node_method_ty(method_call))) + Ok(unadjusted_ty.adjust( + self.tcx(), expr.span, expr.id, + self.typer.adjustments().borrow().get(&expr.id), + |method_call| self.typer.node_method_ty(method_call))) } fn node_ty(&self, id: ast::NodeId) -> McResult> { @@ -927,8 +928,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { let base_cmt = match method_ty { Some(method_ty) => { let ref_ty = - ty::no_late_bound_regions( - self.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); + self.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap(); self.cat_rvalue_node(node.id(), node.span(), ref_ty) } None => base_cmt @@ -1024,7 +1024,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // FIXME(#20649) -- why are we using the `self_ty` as the element type...? let self_ty = method_ty.fn_sig().input(0); - ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap() + self.tcx().no_late_bound_regions(&self_ty).unwrap() } None => { match base_cmt.ty.builtin_index() { @@ -1244,7 +1244,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { let cmt = match opt_def { Some(def::DefVariant(enum_did, variant_did, _)) // univariant enums do not need downcasts - if !ty::enum_is_univariant(self.tcx(), enum_did) => { + if !self.tcx().enum_is_univariant(enum_did) => { self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did) } _ => cmt @@ -1375,7 +1375,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // types are generated by method resolution and always have // all late-bound regions fully instantiated, so we just want // to skip past the binder. - ty::no_late_bound_regions(self.tcx(), &method_ty.fn_ret()) + self.tcx().no_late_bound_regions(&method_ty.fn_ret()) .unwrap() .unwrap() // overloaded ops do not diverge, either } @@ -1583,7 +1583,7 @@ impl<'tcx> fmt::Debug for categorization<'tcx> { cat_static_item => write!(f, "static"), cat_rvalue(r) => write!(f, "rvalue({:?})", r), cat_local(id) => { - let name = ty::tls::with(|tcx| ty::local_var_name_str(tcx, id)); + let name = ty::tls::with(|tcx| tcx.local_var_name_str(id)); write!(f, "local({})", name) } cat_upvar(upvar) => { diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 0cb302d79b866..15a1ba853245b 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -192,7 +192,7 @@ pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> { } pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path { - ty::with_path(tcx, id, |path| ast::Path { + tcx.with_path(id, |path| ast::Path { global: false, segments: path.last().map(|elem| ast::PathSegment { identifier: ast::Ident::new(elem.name()), diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index dad41bdd3a394..4766ae8933d0b 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -382,7 +382,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool, // items. ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => { let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id(); - let trait_items = ty::trait_items(tcx, trait_did); + let trait_items = tcx.trait_items(trait_did); for impl_item in impl_items { let item = trait_items.iter().find(|item| { @@ -425,7 +425,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, method_num: index, .. }) => { - ty::trait_item(tcx, trait_ref.def_id, index).def_id() + tcx.trait_item(trait_ref.def_id, index).def_id() } } } @@ -434,9 +434,9 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, } ast::ExprField(ref base_e, ref field) => { span = field.span; - match ty::expr_ty_adjusted(tcx, base_e).sty { + match tcx.expr_ty_adjusted(base_e).sty { ty::TyStruct(did, _) => { - ty::lookup_struct_fields(tcx, did) + tcx.lookup_struct_fields(did) .iter() .find(|f| f.name == field.node.name) .unwrap_or_else(|| { @@ -451,9 +451,9 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, } ast::ExprTupField(ref base_e, ref field) => { span = field.span; - match ty::expr_ty_adjusted(tcx, base_e).sty { + match tcx.expr_ty_adjusted(base_e).sty { ty::TyStruct(did, _) => { - ty::lookup_struct_fields(tcx, did) + tcx.lookup_struct_fields(did) .get(field.node) .unwrap_or_else(|| { tcx.sess.span_bug(field.span, @@ -468,10 +468,10 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, } } ast::ExprStruct(_, ref expr_fields, _) => { - let type_ = ty::expr_ty(tcx, e); + let type_ = tcx.expr_ty(e); match type_.sty { ty::TyStruct(did, _) => { - let struct_fields = ty::lookup_struct_fields(tcx, did); + let struct_fields = tcx.lookup_struct_fields(did); // check the stability of each field that appears // in the construction expression. for field in expr_fields { @@ -525,11 +525,11 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat, debug!("check_pat(pat = {:?})", pat); if is_internal(tcx, pat.span) { return; } - let did = match ty::pat_ty_opt(tcx, pat) { + let did = match tcx.pat_ty_opt(pat) { Some(&ty::TyS { sty: ty::TyStruct(did, _), .. }) => did, Some(_) | None => return, }; - let struct_fields = ty::lookup_struct_fields(tcx, did); + let struct_fields = tcx.lookup_struct_fields(did); match pat.node { // Foo(a, b, c) ast::PatEnum(_, Some(ref pat_fields)) => { @@ -574,7 +574,7 @@ fn is_internal(tcx: &ty::ctxt, span: Span) -> bool { } fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool { - match ty::trait_item_of_item(tcx, id) { + match tcx.trait_item_of_item(id) { Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => { is_staged_api(tcx, trait_method_id) @@ -602,7 +602,7 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil debug!("lookup(id={:?})", id); // is this definition the implementation of a trait method? - match ty::trait_item_of_item(tcx, id) { + match tcx.trait_item_of_item(id) { Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => { debug!("lookup: trait_method_id={:?}", trait_method_id); return lookup(tcx, trait_method_id) @@ -617,8 +617,8 @@ fn lookup_uncached<'tcx>(tcx: &ty::ctxt<'tcx>, id: DefId) -> Option<&'tcx Stabil }; item_stab.or_else(|| { - if ty::is_impl(tcx, id) { - if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) { + if tcx.is_impl(id) { + if let Some(trait_id) = tcx.trait_id_of_impl(id) { // FIXME (#18969): for the time being, simply use the // stability of the trait to determine the stability of any // unmarked impls for it. See FIXME above for more details. diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index a826836b10c62..371b5c309a850 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -38,7 +38,7 @@ pub fn overlapping_impls(infcx: &InferCtxt, impl1_def_id, impl2_def_id); - let param_env = &ty::empty_parameter_environment(infcx.tcx); + let param_env = &infcx.tcx.empty_parameter_environment(); let selcx = &mut SelectionContext::intercrate(infcx, param_env); infcx.probe(|_| { overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) @@ -111,7 +111,7 @@ pub fn trait_ref_is_knowable<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref: &ty::TraitRe // already if trait_ref.def_id.krate != ast::LOCAL_CRATE && - !ty::has_attr(tcx, trait_ref.def_id, "fundamental") + !tcx.has_attr(trait_ref.def_id, "fundamental") { debug!("trait_ref_is_knowable: trait is neither local nor fundamental"); return false; @@ -142,13 +142,13 @@ fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, let impl_substs = &substs_fn(selcx.infcx(), DUMMY_SP, impl_def_id); let impl_trait_ref = - ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap(); + selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs); let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref); - let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id); + let predicates = selcx.tcx().lookup_predicates(impl_def_id); let predicates = predicates.instantiate(selcx.tcx(), impl_substs); let Normalized { value: predicates, obligations: normalization_obligations2 } = project::normalize(selcx, ObligationCause::dummy(), &predicates); @@ -183,7 +183,7 @@ pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>, // We only except this routine to be invoked on implementations // of a trait, not inherent implementations. - let trait_ref = ty::impl_trait_ref(tcx, impl_def_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); debug!("orphan_check: trait_ref={:?}", trait_ref); // If the *trait* is local to the crate, ok. @@ -280,9 +280,9 @@ fn fundamental_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool ty::TyBox(..) | ty::TyRef(..) => true, ty::TyEnum(def_id, _) | ty::TyStruct(def_id, _) => - ty::has_attr(tcx, def_id, "fundamental"), + tcx.has_attr(def_id, "fundamental"), ty::TyTrait(ref data) => - ty::has_attr(tcx, data.principal_def_id(), "fundamental"), + tcx.has_attr(data.principal_def_id(), "fundamental"), _ => false } diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 7b86e1b4539e6..582873082a68b 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -79,14 +79,14 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, span: Span) -> Option { let def_id = trait_ref.def_id; let mut report = None; - for item in ty::get_attrs(infcx.tcx, def_id).iter() { + for item in infcx.tcx.get_attrs(def_id).iter() { if item.check_name("rustc_on_unimplemented") { let err_sp = if item.meta().span == DUMMY_SP { span } else { item.meta().span }; - let def = ty::lookup_trait_def(infcx.tcx, def_id); + let def = infcx.tcx.lookup_trait_def(def_id); let trait_str = def.trait_ref.to_string(); if let Some(ref istring) = item.value_str() { let mut generic_map = def.generics.types.iter_enumerated() @@ -260,7 +260,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, TraitNotObjectSafe(did) => { span_err!(infcx.tcx.sess, obligation.cause.span, E0038, "cannot convert to a trait object because trait `{}` is not object-safe", - ty::item_path_str(infcx.tcx, did)); + infcx.tcx.item_path_str(did)); for violation in object_safety_violations(infcx.tcx, did) { match violation { @@ -401,7 +401,7 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, match *cause_code { ObligationCauseCode::MiscObligation => { } ObligationCauseCode::ItemObligation(item_def_id) => { - let item_name = ty::item_path_str(tcx, item_def_id); + let item_name = tcx.item_path_str(item_def_id); tcx.sess.span_note( cause_span, &format!("required by `{}`", item_name)); @@ -442,8 +442,8 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, } ObligationCauseCode::ClosureCapture(var_id, closure_span, builtin_bound) => { let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap(); - let trait_name = ty::item_path_str(tcx, def_id); - let name = ty::local_var_name_str(tcx, var_id); + let trait_name = tcx.item_path_str(def_id); + let name = tcx.local_var_name_str(var_id); span_note!(tcx.sess, closure_span, "the closure that captures `{}` requires that all captured variables \ implement the trait `{}`", diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index a26dff4e9fdae..5e274dcec70e4 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -421,7 +421,7 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, // regions. If there are, we will call this obligation an // error. Eventually we should be able to support some // cases here, I imagine (e.g., `for<'a> int : 'a`). - if ty::count_late_bound_regions(selcx.tcx(), binder) != 0 { + if selcx.tcx().count_late_bound_regions(binder) != 0 { errors.push( FulfillmentError::new( obligation.clone(), diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index db7b91952a885..e7f11b06bd132 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -57,7 +57,7 @@ pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>, -> bool { // Because we query yes/no results frequently, we keep a cache: - let def = ty::lookup_trait_def(tcx, trait_def_id); + let def = tcx.lookup_trait_def(trait_def_id); let result = def.object_safety().unwrap_or_else(|| { let result = object_safety_violations(tcx, trait_def_id).is_empty(); @@ -90,7 +90,7 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>, { // Check methods for violations. let mut violations: Vec<_> = - ty::trait_items(tcx, trait_def_id).iter() + tcx.trait_items(trait_def_id).iter() .flat_map(|item| { match *item { ty::MethodTraitItem(ref m) => { @@ -122,10 +122,10 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>, trait_def_id: ast::DefId) -> bool { - let trait_def = ty::lookup_trait_def(tcx, trait_def_id); + let trait_def = tcx.lookup_trait_def(trait_def_id); let trait_ref = trait_def.trait_ref.clone(); let trait_ref = trait_ref.to_poly_trait_ref(); - let predicates = ty::lookup_super_predicates(tcx, trait_def_id); + let predicates = tcx.lookup_super_predicates(trait_def_id); predicates .predicates .into_iter() @@ -153,8 +153,8 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, trait_def_id: ast::DefId) -> bool { - let trait_def = ty::lookup_trait_def(tcx, trait_def_id); - let trait_predicates = ty::lookup_predicates(tcx, trait_def_id); + let trait_def = tcx.lookup_trait_def(trait_def_id); + let trait_predicates = tcx.lookup_predicates(trait_def_id); generics_require_sized_self(tcx, &trait_def.generics, &trait_predicates) } @@ -169,7 +169,7 @@ fn generics_require_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>, }; // Search for a predicate like `Self : Sized` amongst the trait bounds. - let free_substs = ty::construct_free_substs(tcx, generics, ast::DUMMY_NODE_ID); + let free_substs = tcx.construct_free_substs(generics, ast::DUMMY_NODE_ID); let predicates = predicates.instantiate(tcx, &free_substs).predicates.into_vec(); elaborate_predicates(tcx, predicates) .any(|predicate| { @@ -321,7 +321,7 @@ fn contains_illegal_self_type_reference<'tcx>(tcx: &ty::ctxt<'tcx>, // Compute supertraits of current trait lazily. if supertraits.is_none() { - let trait_def = ty::lookup_trait_def(tcx, trait_def_id); + let trait_def = tcx.lookup_trait_def(trait_def_id); let trait_ref = ty::Binder(trait_def.trait_ref.clone()); supertraits = Some(traits::supertraits(tcx, trait_ref).collect()); } diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index e0709f51ab1b0..184de682c67db 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -574,7 +574,7 @@ fn assemble_candidates_from_trait_def<'cx,'tcx>( }; // If so, extract what we know from the trait and try to come up with a good answer. - let trait_predicates = ty::lookup_predicates(selcx.tcx(), trait_ref.def_id); + let trait_predicates = selcx.tcx().lookup_predicates(trait_ref.def_id); let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs); let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates.into_vec()); assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref, @@ -892,7 +892,7 @@ fn confirm_impl_candidate<'cx,'tcx>( // It is not in the impl - get the default from the trait. let trait_ref = obligation.predicate.trait_ref; - for trait_item in ty::trait_items(selcx.tcx(), trait_ref.def_id).iter() { + for trait_item in selcx.tcx().trait_items(trait_ref.def_id).iter() { if let &ty::TypeTraitItem(ref assoc_ty) = trait_item { if assoc_ty.name == obligation.predicate.item_name { if let Some(ty) = assoc_ty.ty { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 86d4e8c753375..01faa6b7cf7b9 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -773,7 +773,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match candidate { ImplCandidate(def_id) => { - match ty::trait_impl_polarity(self.tcx(), def_id) { + match self.tcx().trait_impl_polarity(def_id) { Some(ast::ImplPolarity::Negative) => return Err(Unimplemented), _ => {} } @@ -1024,7 +1024,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { projection_trait_ref={:?}", projection_trait_ref); - let trait_predicates = ty::lookup_predicates(self.tcx(), projection_trait_ref.def_id); + let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id); let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs); debug!("match_projection_obligation_against_bounds_from_trait: \ bounds={:?}", @@ -1224,7 +1224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { debug!("assemble_candidates_from_impls(obligation={:?})", obligation); - let def = ty::lookup_trait_def(self.tcx(), obligation.predicate.def_id()); + let def = self.tcx().lookup_trait_def(obligation.predicate.def_id()); def.for_each_relevant_impl( self.tcx(), @@ -1252,7 +1252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let def_id = obligation.predicate.def_id(); - if ty::trait_has_default_impl(self.tcx(), def_id) { + if self.tcx().trait_has_default_impl(def_id) { match self_ty.sty { ty::TyTrait(..) => { // For object types, we don't know what the closed @@ -1264,7 +1264,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // object types, because it just lets you reflect // onto the object type, not into the object's // interior. - if ty::has_attr(self.tcx(), def_id, "rustc_reflect_like") { + if self.tcx().has_attr(def_id, "rustc_reflect_like") { candidates.vec.push(DefaultImplObjectCandidate(def_id)); } } @@ -1397,7 +1397,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // T: Trait // so it seems ok if we (conservatively) fail to accept that `Unsize` // obligation above. Should be possible to extend this in the future. - let self_ty = match ty::no_late_bound_regions(self.tcx(), &obligation.self_ty()) { + let self_ty = match self.tcx().no_late_bound_regions(&obligation.self_ty()) { Some(t) => t, None => { // Don't add any candidates if there are bound regions. @@ -1736,7 +1736,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::TyStruct(def_id, substs) => { let types: Vec = - ty::struct_fields(self.tcx(), def_id, substs).iter() + self.tcx().struct_fields(def_id, substs).iter() .map(|f| f.mt.ty) .collect(); nominal(bound, types) @@ -1744,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::TyEnum(def_id, substs) => { let types: Vec = - ty::substd_enum_variants(self.tcx(), def_id, substs) + self.tcx().substd_enum_variants(def_id, substs) .iter() .flat_map(|variant| &variant.args) .cloned() @@ -1881,13 +1881,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::TyStruct(def_id, substs) => { - Some(ty::struct_fields(self.tcx(), def_id, substs).iter() + Some(self.tcx().struct_fields(def_id, substs).iter() .map(|f| f.mt.ty) .collect()) } ty::TyEnum(def_id, substs) => { - Some(ty::substd_enum_variants(self.tcx(), def_id, substs) + Some(self.tcx().substd_enum_variants(def_id, substs) .iter() .flat_map(|variant| &variant.args) .map(|&ty| ty) @@ -2161,7 +2161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation, trait_def_id); - assert!(ty::has_attr(self.tcx(), trait_def_id, "rustc_reflect_like")); + assert!(self.tcx().has_attr(trait_def_id, "rustc_reflect_like")); // OK to skip binder, it is reintroduced below let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); @@ -2178,7 +2178,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // reintroduce the two binding levels we skipped, then flatten into one let all_types = ty::Binder(ty::Binder(all_types)); - let all_types = ty::flatten_late_bound_regions(self.tcx(), &all_types); + let all_types = self.tcx().flatten_late_bound_regions(&all_types); self.vtable_default_impl(obligation, trait_def_id, all_types) } @@ -2434,7 +2434,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // assemble_candidates_for_unsizing should ensure there are no late bound // regions here. See the comment there for more details. let source = self.infcx.shallow_resolve( - ty::no_late_bound_regions(tcx, &obligation.self_ty()).unwrap()); + tcx.no_late_bound_regions(&obligation.self_ty()).unwrap()); let target = self.infcx.shallow_resolve(obligation.predicate.0.input_types()[0]); debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})", @@ -2525,8 +2525,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Struct -> Struct. (&ty::TyStruct(def_id, substs_a), &ty::TyStruct(_, substs_b)) => { - let fields = ty::lookup_struct_fields(tcx, def_id).iter().map(|f| { - ty::lookup_field_type_unsubstituted(tcx, def_id, f.id) + let fields = tcx.lookup_struct_fields(def_id).iter().map(|f| { + tcx.lookup_field_type_unsubstituted(def_id, f.id) }).collect::>(); // The last field of the structure has to exist and contain type parameters. @@ -2628,7 +2628,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { -> Result<(Normalized<'tcx, Substs<'tcx>>, infer::SkolemizationMap), ()> { - let impl_trait_ref = ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap(); + let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); // Before we create the substitutions and everything, first // consider a "quick reject". This avoids creating more types @@ -2765,7 +2765,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id); // Find the self type for the impl. - let impl_self_ty = ty::lookup_item_type(self.tcx(), impl_def_id).ty; + let impl_self_ty = self.tcx().lookup_item_type(impl_def_id).ty; let impl_self_ty = impl_self_ty.subst(self.tcx(), &impl_substs); debug!("match_impl_self_types(obligation_self_ty={:?}, impl_self_ty={:?})", @@ -2890,7 +2890,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { debug!("impl_or_trait_obligations(def_id={:?})", def_id); - let predicates = ty::lookup_predicates(self.tcx(), def_id); + let predicates = self.tcx().lookup_predicates(def_id); let predicates = predicates.instantiate(self.tcx(), substs); let predicates = normalize_with_depth(self, cause.clone(), recursion_depth, &predicates); let mut predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates); diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 79b9ae22e4b5c..5c9a8d6c1aa3f 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -43,19 +43,19 @@ impl<'a,'tcx> PredicateSet<'a,'tcx> { // regions before we throw things into the underlying set. let normalized_pred = match *pred { ty::Predicate::Trait(ref data) => - ty::Predicate::Trait(ty::anonymize_late_bound_regions(self.tcx, data)), + ty::Predicate::Trait(self.tcx.anonymize_late_bound_regions(data)), ty::Predicate::Equate(ref data) => - ty::Predicate::Equate(ty::anonymize_late_bound_regions(self.tcx, data)), + ty::Predicate::Equate(self.tcx.anonymize_late_bound_regions(data)), ty::Predicate::RegionOutlives(ref data) => - ty::Predicate::RegionOutlives(ty::anonymize_late_bound_regions(self.tcx, data)), + ty::Predicate::RegionOutlives(self.tcx.anonymize_late_bound_regions(data)), ty::Predicate::TypeOutlives(ref data) => - ty::Predicate::TypeOutlives(ty::anonymize_late_bound_regions(self.tcx, data)), + ty::Predicate::TypeOutlives(self.tcx.anonymize_late_bound_regions(data)), ty::Predicate::Projection(ref data) => - ty::Predicate::Projection(ty::anonymize_late_bound_regions(self.tcx, data)), + ty::Predicate::Projection(self.tcx.anonymize_late_bound_regions(data)), }; self.set.insert(normalized_pred) } @@ -116,7 +116,7 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> { match *predicate { ty::Predicate::Trait(ref data) => { // Predicates declared on the trait. - let predicates = ty::lookup_super_predicates(self.tcx, data.def_id()); + let predicates = self.tcx.lookup_super_predicates(data.def_id()); let mut predicates: Vec<_> = predicates.predicates @@ -236,7 +236,7 @@ impl<'cx, 'tcx> Iterator for SupertraitDefIds<'cx, 'tcx> { None => { return None; } }; - let predicates = ty::lookup_super_predicates(self.tcx, def_id); + let predicates = self.tcx.lookup_super_predicates(def_id); let visited = &mut self.visited; self.stack.extend( predicates.predicates @@ -297,7 +297,7 @@ pub fn fresh_type_vars_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, -> Substs<'tcx> { let tcx = infcx.tcx; - let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics; + let impl_generics = tcx.lookup_item_type(impl_def_id).generics; infcx.fresh_substs_for_generics(span, &impl_generics) } @@ -416,7 +416,7 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>, break; } - let trait_items = ty::trait_items(tcx, bound_ref.def_id()); + let trait_items = tcx.trait_items(bound_ref.def_id()); for trait_item in trait_items.iter() { match *trait_item { ty::MethodTraitItem(_) => method_count += 1, @@ -427,7 +427,7 @@ pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>, // count number of methods preceding the one we are selecting and // add them to the total offset; skip over associated types. - let trait_items = ty::trait_items(tcx, trait_def_id); + let trait_items = tcx.trait_items(trait_def_id); for trait_item in trait_items.iter().take(method_offset_in_trait) { match *trait_item { ty::MethodTraitItem(_) => method_count += 1, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 185a04bc5215c..302ec08db6f26 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -51,9 +51,9 @@ use middle::def::{self, DefMap, ExportMap}; use middle::dependency_format; use middle::fast_reject; use middle::free_region::FreeRegionMap; -use middle::infer::error_reporting::note_and_explain_region; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::mem_categorization as mc; +use middle::mem_categorization::Typer; use middle::region; use middle::resolve_lifetime; use middle::infer; @@ -117,6 +117,221 @@ pub struct field<'tcx> { pub mt: mt<'tcx> } + + +// Enum information +#[derive(Clone)] +pub struct VariantInfo<'tcx> { + pub args: Vec>, + pub arg_names: Option>, + pub ctor_ty: Option>, + pub name: ast::Name, + pub id: ast::DefId, + pub disr_val: Disr, + pub vis: Visibility +} + +impl<'tcx> VariantInfo<'tcx> { + + /// Creates a new VariantInfo from the corresponding ast representation. + /// + /// Does not do any caching of the value in the type context. + pub fn from_ast_variant(cx: &ctxt<'tcx>, + ast_variant: &ast::Variant, + discriminant: Disr) -> VariantInfo<'tcx> { + let ctor_ty = cx.node_id_to_type(ast_variant.node.id); + + match ast_variant.node.kind { + ast::TupleVariantKind(ref args) => { + let arg_tys = if !args.is_empty() { + // the regions in the argument types come from the + // enum def'n, and hence will all be early bound + cx.no_late_bound_regions(&ctor_ty.fn_args()).unwrap() + } else { + Vec::new() + }; + + return VariantInfo { + args: arg_tys, + arg_names: None, + ctor_ty: Some(ctor_ty), + name: ast_variant.node.name.name, + id: ast_util::local_def(ast_variant.node.id), + disr_val: discriminant, + vis: ast_variant.node.vis + }; + }, + ast::StructVariantKind(ref struct_def) => { + let fields: &[StructField] = &struct_def.fields; + + assert!(!fields.is_empty()); + + let arg_tys = struct_def.fields.iter() + .map(|field| cx.node_id_to_type(field.node.id)).collect(); + let arg_names = fields.iter().map(|field| { + match field.node.kind { + NamedField(ident, _) => ident.name, + UnnamedField(..) => cx.sess.bug( + "enum_variants: all fields in struct must have a name") + } + }).collect(); + + return VariantInfo { + args: arg_tys, + arg_names: Some(arg_names), + ctor_ty: None, + name: ast_variant.node.name.name, + id: ast_util::local_def(ast_variant.node.id), + disr_val: discriminant, + vis: ast_variant.node.vis + }; + } + } + } +} + +#[derive(Copy, Clone)] +pub enum DtorKind { + NoDtor, + TraitDtor(DefId, bool) +} + +impl DtorKind { + pub fn is_present(&self) -> bool { + match *self { + TraitDtor(..) => true, + _ => false + } + } + + pub fn has_drop_flag(&self) -> bool { + match self { + &NoDtor => false, + &TraitDtor(_, flag) => flag + } + } +} + +trait IntTypeExt { + fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>; + fn i64_to_disr(&self, val: i64) -> Option; + fn u64_to_disr(&self, val: u64) -> Option; + fn disr_incr(&self, val: Disr) -> Option; + fn disr_string(&self, val: Disr) -> String; + fn disr_wrap_incr(&self, val: Option) -> Disr; +} + +impl IntTypeExt for attr::IntType { + fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { + match *self { + SignedInt(ast::TyI8) => cx.types.i8, + SignedInt(ast::TyI16) => cx.types.i16, + SignedInt(ast::TyI32) => cx.types.i32, + SignedInt(ast::TyI64) => cx.types.i64, + SignedInt(ast::TyIs) => cx.types.isize, + UnsignedInt(ast::TyU8) => cx.types.u8, + UnsignedInt(ast::TyU16) => cx.types.u16, + UnsignedInt(ast::TyU32) => cx.types.u32, + UnsignedInt(ast::TyU64) => cx.types.u64, + UnsignedInt(ast::TyUs) => cx.types.usize, + } + } + + fn i64_to_disr(&self, val: i64) -> Option { + match *self { + SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr), + SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr), + SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr), + SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr), + UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr), + UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr), + UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr), + UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr), + + UnsignedInt(ast::TyUs) | + SignedInt(ast::TyIs) => unreachable!(), + } + } + + fn u64_to_disr(&self, val: u64) -> Option { + match *self { + SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr), + SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr), + SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr), + SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr), + UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr), + UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr), + UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr), + UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr), + + UnsignedInt(ast::TyUs) | + SignedInt(ast::TyIs) => unreachable!(), + } + } + + fn disr_incr(&self, val: Disr) -> Option { + macro_rules! add1 { + ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) } + } + match *self { + // SignedInt repr means we *want* to reinterpret the bits + // treating the highest bit of Disr as a sign-bit, so + // cast to i64 before range-checking. + SignedInt(ast::TyI8) => add1!((val as i64).to_i8()), + SignedInt(ast::TyI16) => add1!((val as i64).to_i16()), + SignedInt(ast::TyI32) => add1!((val as i64).to_i32()), + SignedInt(ast::TyI64) => add1!(Some(val as i64)), + + UnsignedInt(ast::TyU8) => add1!(val.to_u8()), + UnsignedInt(ast::TyU16) => add1!(val.to_u16()), + UnsignedInt(ast::TyU32) => add1!(val.to_u32()), + UnsignedInt(ast::TyU64) => add1!(Some(val)), + + UnsignedInt(ast::TyUs) | + SignedInt(ast::TyIs) => unreachable!(), + } + } + + // This returns a String because (1.) it is only used for + // rendering an error message and (2.) a string can represent the + // full range from `i64::MIN` through `u64::MAX`. + fn disr_string(&self, val: Disr) -> String { + match *self { + SignedInt(ast::TyI8) => format!("{}", val as i8 ), + SignedInt(ast::TyI16) => format!("{}", val as i16), + SignedInt(ast::TyI32) => format!("{}", val as i32), + SignedInt(ast::TyI64) => format!("{}", val as i64), + UnsignedInt(ast::TyU8) => format!("{}", val as u8 ), + UnsignedInt(ast::TyU16) => format!("{}", val as u16), + UnsignedInt(ast::TyU32) => format!("{}", val as u32), + UnsignedInt(ast::TyU64) => format!("{}", val as u64), + + UnsignedInt(ast::TyUs) | + SignedInt(ast::TyIs) => unreachable!(), + } + } + + fn disr_wrap_incr(&self, val: Option) -> Disr { + macro_rules! add1 { + ($e:expr) => { ($e).wrapping_add(1) as Disr } + } + let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE); + match *self { + SignedInt(ast::TyI8) => add1!(val as i8 ), + SignedInt(ast::TyI16) => add1!(val as i16), + SignedInt(ast::TyI32) => add1!(val as i32), + SignedInt(ast::TyI64) => add1!(val as i64), + UnsignedInt(ast::TyU8) => add1!(val as u8 ), + UnsignedInt(ast::TyU16) => add1!(val as u16), + UnsignedInt(ast::TyU32) => add1!(val as u32), + UnsignedInt(ast::TyU64) => add1!(val as u64), + + UnsignedInt(ast::TyUs) | + SignedInt(ast::TyIs) => unreachable!(), + } + } +} + #[derive(Clone, Copy, Debug)] pub enum ImplOrTraitItemContainer { TraitContainer(ast::DefId), @@ -303,6 +518,17 @@ pub enum Variance { Bivariant, // T <: T -- e.g., unused type parameter } +impl fmt::Debug for Variance { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(match *self { + Covariant => "+", + Contravariant => "-", + Invariant => "o", + Bivariant => "*", + }) + } +} + #[derive(Copy, Clone)] pub enum AutoAdjustment<'tcx> { AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type @@ -963,7 +1189,7 @@ pub mod tls { Some(ast_map::NodeTraitItem(..)) | Some(ast_map::NodeVariant(..)) | Some(ast_map::NodeStructCtor(..)) => { - return write!(f, "{}", ty::item_path_str(tcx, def_id)); + return write!(f, "{}", tcx.item_path_str(def_id)); } _ => {} } @@ -1438,6 +1664,13 @@ pub struct UpvarBorrow { pub type UpvarCaptureMap = FnvHashMap; +#[derive(Copy, Clone)] +pub struct ClosureUpvar<'tcx> { + pub def: def::Def, + pub span: Span, + pub ty: Ty<'tcx>, +} + impl Region { pub fn is_bound(&self) -> bool { match *self { @@ -2511,22 +2744,20 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { match impl_item.node { ast::ConstImplItem(_, _) => { let def_id = ast_util::local_def(id); - let scheme = lookup_item_type(cx, def_id); - let predicates = lookup_predicates(cx, def_id); - construct_parameter_environment(cx, - impl_item.span, - &scheme.generics, - &predicates, - id) + let scheme = cx.lookup_item_type(def_id); + let predicates = cx.lookup_predicates(def_id); + cx.construct_parameter_environment(impl_item.span, + &scheme.generics, + &predicates, + id) } ast::MethodImplItem(_, ref body) => { let method_def_id = ast_util::local_def(id); - match ty::impl_or_trait_item(cx, method_def_id) { + match cx.impl_or_trait_item(method_def_id) { MethodTraitItem(ref method_ty) => { let method_generics = &method_ty.generics; let method_bounds = &method_ty.predicates; - construct_parameter_environment( - cx, + cx.construct_parameter_environment( impl_item.span, method_generics, method_bounds, @@ -2553,13 +2784,12 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { match *default { Some(_) => { let def_id = ast_util::local_def(id); - let scheme = lookup_item_type(cx, def_id); - let predicates = lookup_predicates(cx, def_id); - construct_parameter_environment(cx, - trait_item.span, - &scheme.generics, - &predicates, - id) + let scheme = cx.lookup_item_type(def_id); + let predicates = cx.lookup_predicates(def_id); + cx.construct_parameter_environment(trait_item.span, + &scheme.generics, + &predicates, + id) } None => { cx.sess.bug("ParameterEnvironment::from_item(): \ @@ -2577,12 +2807,11 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { } ast::MethodTraitItem(_, Some(ref body)) => { let method_def_id = ast_util::local_def(id); - match ty::impl_or_trait_item(cx, method_def_id) { + match cx.impl_or_trait_item(method_def_id) { MethodTraitItem(ref method_ty) => { let method_generics = &method_ty.generics; let method_bounds = &method_ty.predicates; - construct_parameter_environment( - cx, + cx.construct_parameter_environment( trait_item.span, method_generics, method_bounds, @@ -2608,14 +2837,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { ast::ItemFn(_, _, _, _, _, ref body) => { // We assume this is a function. let fn_def_id = ast_util::local_def(id); - let fn_scheme = lookup_item_type(cx, fn_def_id); - let fn_predicates = lookup_predicates(cx, fn_def_id); - - construct_parameter_environment(cx, - item.span, - &fn_scheme.generics, - &fn_predicates, - body.id) + let fn_scheme = cx.lookup_item_type(fn_def_id); + let fn_predicates = cx.lookup_predicates(fn_def_id); + + cx.construct_parameter_environment(item.span, + &fn_scheme.generics, + &fn_predicates, + body.id) } ast::ItemEnum(..) | ast::ItemStruct(..) | @@ -2623,13 +2851,12 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { ast::ItemConst(..) | ast::ItemStatic(..) => { let def_id = ast_util::local_def(id); - let scheme = lookup_item_type(cx, def_id); - let predicates = lookup_predicates(cx, def_id); - construct_parameter_environment(cx, - item.span, - &scheme.generics, - &predicates, - id) + let scheme = cx.lookup_item_type(def_id); + let predicates = cx.lookup_predicates(def_id); + cx.construct_parameter_environment(item.span, + &scheme.generics, + &predicates, + id) } _ => { cx.sess.span_bug(item.span, @@ -2650,6 +2877,51 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { } } } + + pub fn can_type_implement_copy(&self, self_type: Ty<'tcx>, span: Span) + -> Result<(),CopyImplementationError> { + let tcx = self.tcx; + + let did = match self_type.sty { + ty::TyStruct(struct_did, substs) => { + let fields = tcx.struct_fields(struct_did, substs); + for field in &fields { + if self.type_moves_by_default(field.mt.ty, span) { + return Err(FieldDoesNotImplementCopy(field.name)) + } + } + struct_did + } + ty::TyEnum(enum_did, substs) => { + let enum_variants = tcx.enum_variants(enum_did); + for variant in enum_variants.iter() { + for variant_arg_type in &variant.args { + let substd_arg_type = + variant_arg_type.subst(tcx, substs); + if self.type_moves_by_default(substd_arg_type, span) { + return Err(VariantDoesNotImplementCopy(variant.name)) + } + } + } + enum_did + } + _ => return Err(TypeIsStructural), + }; + + if tcx.has_dtor(did) { + return Err(TypeHasDestructor) + } + + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub enum CopyImplementationError { + FieldDoesNotImplementCopy(ast::Name), + VariantDoesNotImplementCopy(ast::Name), + TypeIsStructural, + TypeHasDestructor, } /// A "type scheme", in ML terminology, is a type combined with some @@ -2777,7 +3049,7 @@ impl<'tcx> TraitDef<'tcx> { pub fn for_each_impl(&self, tcx: &ctxt<'tcx>, mut f: F) { - ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id); + tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id); for &impl_def_id in self.blanket_impls.borrow().iter() { f(impl_def_id); @@ -2795,7 +3067,7 @@ impl<'tcx> TraitDef<'tcx> { self_ty: Ty<'tcx>, mut f: F) { - ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id); + tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id); for &impl_def_id in self.blanket_impls.borrow().iter() { f(impl_def_id); @@ -2902,207 +3174,26 @@ impl<'tcx> CommonTypes<'tcx> { interner: &mut FnvHashMap, Ty<'tcx>>) -> CommonTypes<'tcx> { + let mut mk = |sty| ctxt::intern_ty(arena, interner, sty); CommonTypes { - bool: intern_ty(arena, interner, TyBool), - char: intern_ty(arena, interner, TyChar), - err: intern_ty(arena, interner, TyError), - isize: intern_ty(arena, interner, TyInt(ast::TyIs)), - i8: intern_ty(arena, interner, TyInt(ast::TyI8)), - i16: intern_ty(arena, interner, TyInt(ast::TyI16)), - i32: intern_ty(arena, interner, TyInt(ast::TyI32)), - i64: intern_ty(arena, interner, TyInt(ast::TyI64)), - usize: intern_ty(arena, interner, TyUint(ast::TyUs)), - u8: intern_ty(arena, interner, TyUint(ast::TyU8)), - u16: intern_ty(arena, interner, TyUint(ast::TyU16)), - u32: intern_ty(arena, interner, TyUint(ast::TyU32)), - u64: intern_ty(arena, interner, TyUint(ast::TyU64)), - f32: intern_ty(arena, interner, TyFloat(ast::TyF32)), - f64: intern_ty(arena, interner, TyFloat(ast::TyF64)), - } - } -} - -/// Create a type context and call the closure with a `&ty::ctxt` reference -/// to the context. The closure enforces that the type context and any interned -/// value (types, substs, etc.) can only be used while `ty::tls` has a valid -/// reference to the context, to allow formatting values that need it. -pub fn with_ctxt<'tcx, F, R>(s: Session, - arenas: &'tcx CtxtArenas<'tcx>, - def_map: DefMap, - named_region_map: resolve_lifetime::NamedRegionMap, - map: ast_map::Map<'tcx>, - freevars: RefCell, - region_maps: RegionMaps, - lang_items: middle::lang_items::LanguageItems, - stability: stability::Index<'tcx>, - f: F) -> (Session, R) - where F: FnOnce(&ctxt<'tcx>) -> R -{ - let mut interner = FnvHashMap(); - let common_types = CommonTypes::new(&arenas.type_, &mut interner); - - tls::enter(ctxt { - arenas: arenas, - interner: RefCell::new(interner), - substs_interner: RefCell::new(FnvHashMap()), - bare_fn_interner: RefCell::new(FnvHashMap()), - region_interner: RefCell::new(FnvHashMap()), - stability_interner: RefCell::new(FnvHashMap()), - types: common_types, - named_region_map: named_region_map, - region_maps: region_maps, - free_region_maps: RefCell::new(FnvHashMap()), - item_variance_map: RefCell::new(DefIdMap()), - variance_computed: Cell::new(false), - sess: s, - def_map: def_map, - node_types: RefCell::new(FnvHashMap()), - item_substs: RefCell::new(NodeMap()), - impl_trait_refs: RefCell::new(DefIdMap()), - trait_defs: RefCell::new(DefIdMap()), - predicates: RefCell::new(DefIdMap()), - super_predicates: RefCell::new(DefIdMap()), - fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()), - map: map, - freevars: freevars, - tcache: RefCell::new(DefIdMap()), - rcache: RefCell::new(FnvHashMap()), - tc_cache: RefCell::new(FnvHashMap()), - ast_ty_to_ty_cache: RefCell::new(NodeMap()), - enum_var_cache: RefCell::new(DefIdMap()), - impl_or_trait_items: RefCell::new(DefIdMap()), - trait_item_def_ids: RefCell::new(DefIdMap()), - trait_items_cache: RefCell::new(DefIdMap()), - ty_param_defs: RefCell::new(NodeMap()), - adjustments: RefCell::new(NodeMap()), - normalized_cache: RefCell::new(FnvHashMap()), - lang_items: lang_items, - provided_method_sources: RefCell::new(DefIdMap()), - struct_fields: RefCell::new(DefIdMap()), - destructor_for_type: RefCell::new(DefIdMap()), - destructors: RefCell::new(DefIdSet()), - inherent_impls: RefCell::new(DefIdMap()), - impl_items: RefCell::new(DefIdMap()), - used_unsafe: RefCell::new(NodeSet()), - used_mut_nodes: RefCell::new(NodeSet()), - populated_external_types: RefCell::new(DefIdSet()), - populated_external_primitive_impls: RefCell::new(DefIdSet()), - upvar_capture_map: RefCell::new(FnvHashMap()), - extern_const_statics: RefCell::new(DefIdMap()), - extern_const_variants: RefCell::new(DefIdMap()), - extern_const_fns: RefCell::new(DefIdMap()), - method_map: RefCell::new(FnvHashMap()), - dependency_formats: RefCell::new(FnvHashMap()), - closure_kinds: RefCell::new(DefIdMap()), - closure_tys: RefCell::new(DefIdMap()), - node_lint_levels: RefCell::new(FnvHashMap()), - transmute_restrictions: RefCell::new(Vec::new()), - stability: RefCell::new(stability), - selection_cache: traits::SelectionCache::new(), - repr_hint_cache: RefCell::new(DefIdMap()), - const_qualif_map: RefCell::new(NodeMap()), - custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), - cast_kinds: RefCell::new(NodeMap()), - }, f) -} - -// Type constructors - -impl<'tcx> ctxt<'tcx> { - pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> { - if let Some(substs) = self.substs_interner.borrow().get(&substs) { - return *substs; - } - - let substs = self.arenas.substs.alloc(substs); - self.substs_interner.borrow_mut().insert(substs, substs); - substs - } - - /// Create an unsafe fn ty based on a safe fn ty. - pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> { - assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal); - let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy { - unsafety: ast::Unsafety::Unsafe, - abi: bare_fn.abi, - sig: bare_fn.sig.clone() - }); - self.mk_fn(None, unsafe_fn_ty_a) - } - - pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> { - if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) { - return *bare_fn; - } - - let bare_fn = self.arenas.bare_fn.alloc(bare_fn); - self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn); - bare_fn - } - - pub fn mk_region(&self, region: Region) -> &'tcx Region { - if let Some(region) = self.region_interner.borrow().get(®ion) { - return *region; - } - - let region = self.arenas.region.alloc(region); - self.region_interner.borrow_mut().insert(region, region); - region - } - - pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind { - *self.closure_kinds.borrow().get(&def_id).unwrap() - } - - pub fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs) - } - - pub fn type_parameter_def(&self, - node_id: ast::NodeId) - -> TypeParameterDef<'tcx> - { - self.ty_param_defs.borrow().get(&node_id).unwrap().clone() - } - - pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option { - pat_util::pat_contains_ref_binding(&self.def_map, pat) - } - - pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option { - pat_util::arm_contains_ref_binding(&self.def_map, arm) - } -} - -fn intern_ty<'tcx>(type_arena: &'tcx TypedArena>, - interner: &mut FnvHashMap, Ty<'tcx>>, - st: TypeVariants<'tcx>) - -> Ty<'tcx> -{ - match interner.get(&st) { - Some(ty) => return *ty, - _ => () - } - - let flags = FlagComputation::for_sty(&st); - - let ty = match () { - () => type_arena.alloc(TyS { sty: st, - flags: Cell::new(flags.flags), - region_depth: flags.depth, }), - }; - - debug!("Interned type: {:?} Pointer: {:?}", - ty, ty as *const TyS); - - interner.insert(InternedTy { ty: ty }, ty); - - ty -} + bool: mk(TyBool), + char: mk(TyChar), + err: mk(TyError), + isize: mk(TyInt(ast::TyIs)), + i8: mk(TyInt(ast::TyI8)), + i16: mk(TyInt(ast::TyI16)), + i32: mk(TyInt(ast::TyI32)), + i64: mk(TyInt(ast::TyI64)), + usize: mk(TyUint(ast::TyUs)), + u8: mk(TyUint(ast::TyU8)), + u16: mk(TyUint(ast::TyU16)), + u32: mk(TyUint(ast::TyU32)), + u64: mk(TyUint(ast::TyU64)), + f32: mk(TyFloat(ast::TyF32)), + f64: mk(TyFloat(ast::TyF64)), + } + } +} struct FlagComputation { flags: TypeFlags, @@ -3296,11 +3387,190 @@ impl FlagComputation { } impl<'tcx> ctxt<'tcx> { + /// Create a type context and call the closure with a `&ty::ctxt` reference + /// to the context. The closure enforces that the type context and any interned + /// value (types, substs, etc.) can only be used while `ty::tls` has a valid + /// reference to the context, to allow formatting values that need it. + pub fn create_and_enter(s: Session, + arenas: &'tcx CtxtArenas<'tcx>, + def_map: DefMap, + named_region_map: resolve_lifetime::NamedRegionMap, + map: ast_map::Map<'tcx>, + freevars: RefCell, + region_maps: RegionMaps, + lang_items: middle::lang_items::LanguageItems, + stability: stability::Index<'tcx>, + f: F) -> (Session, R) + where F: FnOnce(&ctxt<'tcx>) -> R + { + let mut interner = FnvHashMap(); + let common_types = CommonTypes::new(&arenas.type_, &mut interner); + + tls::enter(ctxt { + arenas: arenas, + interner: RefCell::new(interner), + substs_interner: RefCell::new(FnvHashMap()), + bare_fn_interner: RefCell::new(FnvHashMap()), + region_interner: RefCell::new(FnvHashMap()), + stability_interner: RefCell::new(FnvHashMap()), + types: common_types, + named_region_map: named_region_map, + region_maps: region_maps, + free_region_maps: RefCell::new(FnvHashMap()), + item_variance_map: RefCell::new(DefIdMap()), + variance_computed: Cell::new(false), + sess: s, + def_map: def_map, + node_types: RefCell::new(FnvHashMap()), + item_substs: RefCell::new(NodeMap()), + impl_trait_refs: RefCell::new(DefIdMap()), + trait_defs: RefCell::new(DefIdMap()), + predicates: RefCell::new(DefIdMap()), + super_predicates: RefCell::new(DefIdMap()), + fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()), + map: map, + freevars: freevars, + tcache: RefCell::new(DefIdMap()), + rcache: RefCell::new(FnvHashMap()), + tc_cache: RefCell::new(FnvHashMap()), + ast_ty_to_ty_cache: RefCell::new(NodeMap()), + enum_var_cache: RefCell::new(DefIdMap()), + impl_or_trait_items: RefCell::new(DefIdMap()), + trait_item_def_ids: RefCell::new(DefIdMap()), + trait_items_cache: RefCell::new(DefIdMap()), + ty_param_defs: RefCell::new(NodeMap()), + adjustments: RefCell::new(NodeMap()), + normalized_cache: RefCell::new(FnvHashMap()), + lang_items: lang_items, + provided_method_sources: RefCell::new(DefIdMap()), + struct_fields: RefCell::new(DefIdMap()), + destructor_for_type: RefCell::new(DefIdMap()), + destructors: RefCell::new(DefIdSet()), + inherent_impls: RefCell::new(DefIdMap()), + impl_items: RefCell::new(DefIdMap()), + used_unsafe: RefCell::new(NodeSet()), + used_mut_nodes: RefCell::new(NodeSet()), + populated_external_types: RefCell::new(DefIdSet()), + populated_external_primitive_impls: RefCell::new(DefIdSet()), + upvar_capture_map: RefCell::new(FnvHashMap()), + extern_const_statics: RefCell::new(DefIdMap()), + extern_const_variants: RefCell::new(DefIdMap()), + extern_const_fns: RefCell::new(DefIdMap()), + method_map: RefCell::new(FnvHashMap()), + dependency_formats: RefCell::new(FnvHashMap()), + closure_kinds: RefCell::new(DefIdMap()), + closure_tys: RefCell::new(DefIdMap()), + node_lint_levels: RefCell::new(FnvHashMap()), + transmute_restrictions: RefCell::new(Vec::new()), + stability: RefCell::new(stability), + selection_cache: traits::SelectionCache::new(), + repr_hint_cache: RefCell::new(DefIdMap()), + const_qualif_map: RefCell::new(NodeMap()), + custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), + cast_kinds: RefCell::new(NodeMap()), + }, f) + } + + // Type constructors + + pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> { + if let Some(substs) = self.substs_interner.borrow().get(&substs) { + return *substs; + } + + let substs = self.arenas.substs.alloc(substs); + self.substs_interner.borrow_mut().insert(substs, substs); + substs + } + + /// Create an unsafe fn ty based on a safe fn ty. + pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> { + assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal); + let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy { + unsafety: ast::Unsafety::Unsafe, + abi: bare_fn.abi, + sig: bare_fn.sig.clone() + }); + self.mk_fn(None, unsafe_fn_ty_a) + } + + pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> { + if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) { + return *bare_fn; + } + + let bare_fn = self.arenas.bare_fn.alloc(bare_fn); + self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn); + bare_fn + } + + pub fn mk_region(&self, region: Region) -> &'tcx Region { + if let Some(region) = self.region_interner.borrow().get(®ion) { + return *region; + } + + let region = self.arenas.region.alloc(region); + self.region_interner.borrow_mut().insert(region, region); + region + } + + pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind { + *self.closure_kinds.borrow().get(&def_id).unwrap() + } + + pub fn closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs) + } + + pub fn type_parameter_def(&self, + node_id: ast::NodeId) + -> TypeParameterDef<'tcx> + { + self.ty_param_defs.borrow().get(&node_id).unwrap().clone() + } + + pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option { + pat_util::pat_contains_ref_binding(&self.def_map, pat) + } + + pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option { + pat_util::arm_contains_ref_binding(&self.def_map, arm) + } + + fn intern_ty(type_arena: &'tcx TypedArena>, + interner: &mut FnvHashMap, Ty<'tcx>>, + st: TypeVariants<'tcx>) + -> Ty<'tcx> { + match interner.get(&st) { + Some(ty) => return *ty, + _ => () + } + + let flags = FlagComputation::for_sty(&st); + + let ty = match () { + () => type_arena.alloc(TyS { sty: st, + flags: Cell::new(flags.flags), + region_depth: flags.depth, }), + }; + + debug!("Interned type: {:?} Pointer: {:?}", + ty, ty as *const TyS); + + interner.insert(InternedTy { ty: ty }, ty); + + ty + } + // Interns a type/name combination, stores the resulting box in cx.interner, // and returns the box as cast to an unsafe ptr (see comments for Ty above). pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> { let mut interner = self.interner.borrow_mut(); - intern_ty(&self.arenas.type_, &mut *interner, st) + ctxt::intern_ty(&self.arenas.type_, &mut *interner, st) } pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> { @@ -3546,16 +3816,6 @@ impl<'tcx> TyS<'tcx> { } } -// Folds types from the bottom up. -pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, - fldop: F) - -> Ty<'tcx> where - F: FnMut(Ty<'tcx>) -> Ty<'tcx>, -{ - let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop}; - f.fold_ty(t0) -} - impl ParamTy { pub fn new(space: subst::ParamSpace, index: u32, @@ -3600,6 +3860,13 @@ impl<'tcx> TyS<'tcx> { } } + pub fn is_empty(&self, cx: &ctxt) -> bool { + match self.sty { + TyEnum(did, _) => cx.enum_variants(did).is_empty(), + _ => false + } + } + pub fn is_ty_var(&self) -> bool { match self.sty { TyInfer(TyVar(_)) => true, @@ -3636,7 +3903,7 @@ impl<'tcx> TyS<'tcx> { pub fn is_simd(&self, cx: &ctxt) -> bool { match self.sty { - TyStruct(did, _) => lookup_simd(cx, did), + TyStruct(did, _) => cx.lookup_simd(did), _ => false } } @@ -3653,8 +3920,8 @@ impl<'tcx> TyS<'tcx> { pub fn simd_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { match self.sty { TyStruct(did, substs) => { - let fields = lookup_struct_fields(cx, did); - lookup_field_type(cx, did, fields[0].id, substs) + let fields = cx.lookup_struct_fields(did); + cx.lookup_field_type(did, fields[0].id, substs) } _ => panic!("simd_type called on invalid type") } @@ -3663,8 +3930,7 @@ impl<'tcx> TyS<'tcx> { pub fn simd_size(&self, cx: &ctxt) -> usize { match self.sty { TyStruct(did, _) => { - let fields = lookup_struct_fields(cx, did); - fields.len() + cx.lookup_struct_fields(did).len() } _ => panic!("simd_size called on invalid type") } @@ -3713,6 +3979,16 @@ impl<'tcx> TyS<'tcx> { _ => false, } } + + pub fn ty_to_def_id(&self) -> Option { + match self.sty { + TyTrait(ref tt) => Some(tt.principal_def_id()), + TyStruct(id, _) | + TyEnum(id, _) | + TyClosure(id, _) => Some(id), + _ => None + } + } } /// Type contents is how the type checker reasons about kinds. @@ -3866,454 +4142,425 @@ impl fmt::Debug for TypeContents { } } -pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { - return memoized(&cx.tc_cache, ty, |ty| { - tc_ty(cx, ty, &mut FnvHashMap()) - }); +impl<'tcx> TyS<'tcx> { + pub fn type_contents(&'tcx self, cx: &ctxt<'tcx>) -> TypeContents { + return memoized(&cx.tc_cache, self, |ty| { + tc_ty(cx, ty, &mut FnvHashMap()) + }); - fn tc_ty<'tcx>(cx: &ctxt<'tcx>, - ty: Ty<'tcx>, - cache: &mut FnvHashMap, TypeContents>) -> TypeContents - { - // Subtle: Note that we are *not* using cx.tc_cache here but rather a - // private cache for this walk. This is needed in the case of cyclic - // types like: - // - // struct List { next: Box>, ... } - // - // When computing the type contents of such a type, we wind up deeply - // recursing as we go. So when we encounter the recursive reference - // to List, we temporarily use TC::None as its contents. Later we'll - // patch up the cache with the correct value, once we've computed it - // (this is basically a co-inductive process, if that helps). So in - // the end we'll compute TC::OwnsOwned, in this case. - // - // The problem is, as we are doing the computation, we will also - // compute an *intermediate* contents for, e.g., Option of - // TC::None. This is ok during the computation of List itself, but if - // we stored this intermediate value into cx.tc_cache, then later - // requests for the contents of Option would also yield TC::None - // which is incorrect. This value was computed based on the crutch - // value for the type contents of list. The correct value is - // TC::OwnsOwned. This manifested as issue #4821. - match cache.get(&ty) { - Some(tc) => { return *tc; } - None => {} - } - match cx.tc_cache.borrow().get(&ty) { // Must check both caches! - Some(tc) => { return *tc; } - None => {} - } - cache.insert(ty, TC::None); - - let result = match ty.sty { - // usize and isize are ffi-unsafe - TyUint(ast::TyUs) | TyInt(ast::TyIs) => { - TC::ReachesFfiUnsafe - } - - // Scalar and unique types are sendable, and durable - TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) | - TyBool | TyInt(_) | TyUint(_) | TyFloat(_) | - TyBareFn(..) | ty::TyChar => { - TC::None - } - - TyBox(typ) => { - TC::ReachesFfiUnsafe | match typ.sty { - TyStr => TC::OwnsOwned, - _ => tc_ty(cx, typ, cache).owned_pointer(), + fn tc_ty<'tcx>(cx: &ctxt<'tcx>, + ty: Ty<'tcx>, + cache: &mut FnvHashMap, TypeContents>) -> TypeContents + { + // Subtle: Note that we are *not* using cx.tc_cache here but rather a + // private cache for this walk. This is needed in the case of cyclic + // types like: + // + // struct List { next: Box>, ... } + // + // When computing the type contents of such a type, we wind up deeply + // recursing as we go. So when we encounter the recursive reference + // to List, we temporarily use TC::None as its contents. Later we'll + // patch up the cache with the correct value, once we've computed it + // (this is basically a co-inductive process, if that helps). So in + // the end we'll compute TC::OwnsOwned, in this case. + // + // The problem is, as we are doing the computation, we will also + // compute an *intermediate* contents for, e.g., Option of + // TC::None. This is ok during the computation of List itself, but if + // we stored this intermediate value into cx.tc_cache, then later + // requests for the contents of Option would also yield TC::None + // which is incorrect. This value was computed based on the crutch + // value for the type contents of list. The correct value is + // TC::OwnsOwned. This manifested as issue #4821. + match cache.get(&ty) { + Some(tc) => { return *tc; } + None => {} + } + match cx.tc_cache.borrow().get(&ty) { // Must check both caches! + Some(tc) => { return *tc; } + None => {} + } + cache.insert(ty, TC::None); + + let result = match ty.sty { + // usize and isize are ffi-unsafe + TyUint(ast::TyUs) | TyInt(ast::TyIs) => { + TC::ReachesFfiUnsafe } - } - - TyTrait(box TraitTy { ref bounds, .. }) => { - object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized - } - TyRawPtr(ref mt) => { - tc_ty(cx, mt.ty, cache).unsafe_pointer() - } + // Scalar and unique types are sendable, and durable + TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) | + TyBool | TyInt(_) | TyUint(_) | TyFloat(_) | + TyBareFn(..) | ty::TyChar => { + TC::None + } - TyRef(r, ref mt) => { - TC::ReachesFfiUnsafe | match mt.ty.sty { - TyStr => borrowed_contents(*r, ast::MutImmutable), - TyArray(..) | - TySlice(_) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, - mt.mutbl)), - _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)), + TyBox(typ) => { + TC::ReachesFfiUnsafe | tc_ty(cx, typ, cache).owned_pointer() } - } - TyArray(ty, _) => { - tc_ty(cx, ty, cache) - } + TyTrait(box TraitTy { ref bounds, .. }) => { + object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized + } - TySlice(ty) => { - tc_ty(cx, ty, cache) | TC::Nonsized - } - TyStr => TC::Nonsized, + TyRawPtr(ref mt) => { + tc_ty(cx, mt.ty, cache).unsafe_pointer() + } - TyStruct(did, substs) => { - let flds = struct_fields(cx, did, substs); - let mut res = - TypeContents::union(&flds[..], - |f| tc_mt(cx, f.mt, cache)); + TyRef(r, ref mt) => { + tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)) | + TC::ReachesFfiUnsafe + } - if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) { - res = res | TC::ReachesFfiUnsafe; + TyArray(ty, _) => { + tc_ty(cx, ty, cache) } - if ty::has_dtor(cx, did) { - res = res | TC::OwnsDtor; + TySlice(ty) => { + tc_ty(cx, ty, cache) | TC::Nonsized } - apply_lang_items(cx, did, res) - } + TyStr => TC::Nonsized, - TyClosure(did, substs) => { - // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure. - let param_env = ty::empty_parameter_environment(cx); - let upvars = closure_upvars(¶m_env, did, substs).unwrap(); - TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache)) - } + TyStruct(did, substs) => { + let flds = cx.struct_fields(did, substs); + let mut res = + TypeContents::union(&flds[..], + |f| tc_mt(cx, f.mt, cache)); - TyTuple(ref tys) => { - TypeContents::union(&tys[..], - |ty| tc_ty(cx, *ty, cache)) - } + if !cx.lookup_repr_hints(did).contains(&attr::ReprExtern) { + res = res | TC::ReachesFfiUnsafe; + } - TyEnum(did, substs) => { - let variants = substd_enum_variants(cx, did, substs); - let mut res = - TypeContents::union(&variants[..], |variant| { - TypeContents::union(&variant.args, - |arg_ty| { - tc_ty(cx, *arg_ty, cache) - }) - }); + if cx.has_dtor(did) { + res = res | TC::OwnsDtor; + } + apply_lang_items(cx, did, res) + } - if ty::has_dtor(cx, did) { - res = res | TC::OwnsDtor; + TyClosure(did, substs) => { + // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure. + let param_env = cx.empty_parameter_environment(); + let upvars = param_env.closure_upvars(did, substs).unwrap(); + TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache)) } - if !variants.is_empty() { - let repr_hints = lookup_repr_hints(cx, did); - if repr_hints.len() > 1 { - // this is an error later on, but this type isn't safe - res = res | TC::ReachesFfiUnsafe; + TyTuple(ref tys) => { + TypeContents::union(&tys[..], + |ty| tc_ty(cx, *ty, cache)) + } + + TyEnum(did, substs) => { + let variants = cx.substd_enum_variants(did, substs); + let mut res = + TypeContents::union(&variants[..], |variant| { + TypeContents::union(&variant.args, + |arg_ty| { + tc_ty(cx, *arg_ty, cache) + }) + }); + + if cx.has_dtor(did) { + res = res | TC::OwnsDtor; } - match repr_hints.get(0) { - Some(h) => if !h.is_ffi_safe() { - res = res | TC::ReachesFfiUnsafe; - }, - // ReprAny - None => { + if !variants.is_empty() { + let repr_hints = cx.lookup_repr_hints(did); + if repr_hints.len() > 1 { + // this is an error later on, but this type isn't safe res = res | TC::ReachesFfiUnsafe; + } - // We allow ReprAny enums if they are eligible for - // the nullable pointer optimization and the - // contained type is an `extern fn` + match repr_hints.get(0) { + Some(h) => if !h.is_ffi_safe() { + res = res | TC::ReachesFfiUnsafe; + }, + // ReprAny + None => { + res = res | TC::ReachesFfiUnsafe; - if variants.len() == 2 { - let mut data_idx = 0; + // We allow ReprAny enums if they are eligible for + // the nullable pointer optimization and the + // contained type is an `extern fn` - if variants[0].args.is_empty() { - data_idx = 1; - } + if variants.len() == 2 { + let mut data_idx = 0; - if variants[data_idx].args.len() == 1 { - match variants[data_idx].args[0].sty { - TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; } - _ => { } + if variants[0].args.is_empty() { + data_idx = 1; + } + + if variants[data_idx].args.len() == 1 { + match variants[data_idx].args[0].sty { + TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; } + _ => { } + } } } } } } + + + apply_lang_items(cx, did, res) } + TyProjection(..) | + TyParam(_) => { + TC::All + } - apply_lang_items(cx, did, res) - } + TyInfer(_) | + TyError => { + cx.sess.bug("asked to compute contents of error type"); + } + }; - TyProjection(..) | - TyParam(_) => { - TC::All - } + cache.insert(ty, result); + result + } + + fn tc_mt<'tcx>(cx: &ctxt<'tcx>, + mt: mt<'tcx>, + cache: &mut FnvHashMap, TypeContents>) -> TypeContents + { + let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable); + mc | tc_ty(cx, mt.ty, cache) + } - TyInfer(_) | - TyError => { - cx.sess.bug("asked to compute contents of error type"); + fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents) + -> TypeContents { + if Some(did) == cx.lang_items.unsafe_cell_type() { + tc | TC::InteriorUnsafe + } else { + tc } - }; + } - cache.insert(ty, result); - result + /// Type contents due to containing a reference with + /// the region `region` and borrow kind `bk`. + fn borrowed_contents(region: ty::Region, + mutbl: ast::Mutability) + -> TypeContents { + let b = match mutbl { + ast::MutMutable => TC::ReachesMutable, + ast::MutImmutable => TC::None, + }; + b | (TC::ReachesBorrowed).when(region != ty::ReStatic) + } + + fn object_contents(bounds: &ExistentialBounds) -> TypeContents { + // These are the type contents of the (opaque) interior. We + // make no assumptions (other than that it cannot have an + // in-scope type parameter within, which makes no sense). + let mut tc = TC::All - TC::InteriorParam; + for bound in &bounds.builtin_bounds { + tc = tc - match bound { + BoundSync | BoundSend | BoundCopy => TC::None, + BoundSized => TC::Nonsized, + }; + } + return tc; + } } - fn tc_mt<'tcx>(cx: &ctxt<'tcx>, - mt: mt<'tcx>, - cache: &mut FnvHashMap, TypeContents>) -> TypeContents + fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + bound: ty::BuiltinBound, + span: Span) + -> bool { - let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable); - mc | tc_ty(cx, mt.ty, cache) - } + let infcx = infer::new_infer_ctxt(param_env.tcx()); - fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents) - -> TypeContents { - if Some(did) == cx.lang_items.unsafe_cell_type() { - tc | TC::InteriorUnsafe - } else { - tc - } - } + let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, + self, bound, span); - /// Type contents due to containing a reference with the region `region` and borrow kind `bk` - fn borrowed_contents(region: ty::Region, - mutbl: ast::Mutability) - -> TypeContents { - let b = match mutbl { - ast::MutMutable => TC::ReachesMutable, - ast::MutImmutable => TC::None, - }; - b | (TC::ReachesBorrowed).when(region != ty::ReStatic) - } - - fn object_contents(bounds: &ExistentialBounds) -> TypeContents { - // These are the type contents of the (opaque) interior. We - // make no assumptions (other than that it cannot have an - // in-scope type parameter within, which makes no sense). - let mut tc = TC::All - TC::InteriorParam; - for bound in &bounds.builtin_bounds { - tc = tc - match bound { - BoundSync | BoundSend | BoundCopy => TC::None, - BoundSized => TC::Nonsized, - }; - } - return tc; + debug!("Ty::impls_bound({:?}, {:?}) = {:?}", + self, bound, is_impld); + + is_impld } -} -fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ctxt<'tcx>, - ty: Ty<'tcx>, - bound: ty::BuiltinBound, - span: Span) - -> bool -{ - let pe; - let param_env = match param_env { - Some(e) => e, - None => { - pe = empty_parameter_environment(tcx); - &pe + fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + span: Span) -> bool { + if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { + return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT); } - }; - let infcx = infer::new_infer_ctxt(tcx); - let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span); + assert!(!self.needs_infer()); - debug!("type_impls_bound({:?}, {:?}) = {:?}", - ty, - bound, - is_impld); + // Fast-path for primitive types + let result = match self.sty { + TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | + TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt { + mutbl: ast::MutImmutable, .. + }) => Some(false), - is_impld -} + TyStr | TyBox(..) | TyRef(_, mt { + mutbl: ast::MutMutable, .. + }) => Some(true), -pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>, - span: Span, - ty: Ty<'tcx>) - -> bool -{ - if ty.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { - return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT); - } - - assert!(!ty.needs_infer()); - - // Fast-path for primitive types - let result = match ty.sty { - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt { - mutbl: ast::MutImmutable, .. - }) => Some(false), - - TyStr | TyBox(..) | TyRef(_, mt { - mutbl: ast::MutMutable, .. - }) => Some(true), - - TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) | - TyClosure(..) | TyEnum(..) | TyStruct(..) | - TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None - }.unwrap_or_else(|| !type_impls_bound(Some(param_env), - param_env.tcx, - ty, - ty::BoundCopy, - span)); - - if !ty.has_param_types() && !ty.has_self_ty() { - ty.flags.set(ty.flags.get() | if result { - TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT - } else { - TypeFlags::MOVENESS_CACHED - }); - } + TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) | + TyClosure(..) | TyEnum(..) | TyStruct(..) | + TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None + }.unwrap_or_else(|| !self.impls_bound(param_env, ty::BoundCopy, span)); - result -} + if !self.has_param_types() && !self.has_self_ty() { + self.flags.set(self.flags.get() | if result { + TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT + } else { + TypeFlags::MOVENESS_CACHED + }); + } -#[inline] -pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ctxt<'tcx>, - span: Span, - ty: Ty<'tcx>) - -> bool -{ - if ty.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) { - let result = ty.flags.get().intersects(TypeFlags::IS_SIZED); - return result; + result } - type_is_sized_uncached(param_env, tcx, span, ty) -} + #[inline] + pub fn is_sized<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + span: Span) -> bool + { + if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) { + return self.flags.get().intersects(TypeFlags::IS_SIZED); + } -fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>, - tcx: &ctxt<'tcx>, - span: Span, - ty: Ty<'tcx>) -> bool { - assert!(!ty.needs_infer()); + self.is_sized_uncached(param_env, span) + } - // Fast-path for primitive types - let result = match ty.sty { - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) | - TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true), + fn is_sized_uncached<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + span: Span) -> bool { + assert!(!self.needs_infer()); - TyStr | TyTrait(..) | TySlice(_) => Some(false), + // Fast-path for primitive types + let result = match self.sty { + TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | + TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) | + TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true), - TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) | - TyInfer(..) | TyError => None - }.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span)); + TyStr | TyTrait(..) | TySlice(_) => Some(false), - if !ty.has_param_types() && !ty.has_self_ty() { - ty.flags.set(ty.flags.get() | if result { - TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED - } else { - TypeFlags::SIZEDNESS_CACHED - }); - } + TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) | + TyInfer(..) | TyError => None + }.unwrap_or_else(|| self.impls_bound(param_env, ty::BoundSized, span)); - result -} + if !self.has_param_types() && !self.has_self_ty() { + self.flags.set(self.flags.get() | if result { + TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED + } else { + TypeFlags::SIZEDNESS_CACHED + }); + } -pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool { - !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe) -} + result + } -// True if instantiating an instance of `r_ty` requires an instance of `r_ty`. -pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool { - fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec, - r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool { - debug!("type_requires({:?}, {:?})?", - r_ty, ty); + pub fn is_ffi_safe(&'tcx self, cx: &ctxt<'tcx>) -> bool { + !self.type_contents(cx).intersects(TC::ReachesFfiUnsafe) + } - let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty); + // True if instantiating an instance of `r_ty` requires an instance of `r_ty`. + pub fn is_instantiable(&'tcx self, cx: &ctxt<'tcx>) -> bool { + fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec, + r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool { + debug!("type_requires({:?}, {:?})?", + r_ty, ty); - debug!("type_requires({:?}, {:?})? {:?}", - r_ty, ty, r); - return r; - } + let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty); - fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec, - r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool { - debug!("subtypes_require({:?}, {:?})?", - r_ty, ty); + debug!("type_requires({:?}, {:?})? {:?}", + r_ty, ty, r); + return r; + } - let r = match ty.sty { - // fixed length vectors need special treatment compared to - // normal vectors, since they don't necessarily have the - // possibility to have length zero. - TyArray(_, 0) => false, // don't need no contents - TyArray(ty, _) => type_requires(cx, seen, r_ty, ty), + fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec, + r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool { + debug!("subtypes_require({:?}, {:?})?", + r_ty, ty); - TyBool | - TyChar | - TyInt(_) | - TyUint(_) | - TyFloat(_) | - TyStr | - TyBareFn(..) | - TyParam(_) | - TyProjection(_) | - TySlice(_) => { - false - } - TyBox(typ) => { - type_requires(cx, seen, r_ty, typ) - } - TyRef(_, ref mt) => { - type_requires(cx, seen, r_ty, mt.ty) - } + let r = match ty.sty { + // fixed length vectors need special treatment compared to + // normal vectors, since they don't necessarily have the + // possibility to have length zero. + TyArray(_, 0) => false, // don't need no contents + TyArray(ty, _) => type_requires(cx, seen, r_ty, ty), - TyRawPtr(..) => { - false // unsafe ptrs can always be NULL - } + TyBool | + TyChar | + TyInt(_) | + TyUint(_) | + TyFloat(_) | + TyStr | + TyBareFn(..) | + TyParam(_) | + TyProjection(_) | + TySlice(_) => { + false + } + TyBox(typ) => { + type_requires(cx, seen, r_ty, typ) + } + TyRef(_, ref mt) => { + type_requires(cx, seen, r_ty, mt.ty) + } - TyTrait(..) => { - false - } + TyRawPtr(..) => { + false // unsafe ptrs can always be NULL + } - TyStruct(ref did, _) if seen.contains(did) => { - false - } + TyTrait(..) => { + false + } - TyStruct(did, substs) => { - seen.push(did); - let fields = struct_fields(cx, did, substs); - let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty)); - seen.pop().unwrap(); - r - } + TyStruct(ref did, _) if seen.contains(did) => { + false + } - TyError | - TyInfer(_) | - TyClosure(..) => { - // this check is run on type definitions, so we don't expect to see - // inference by-products or closure types - cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty)) - } + TyStruct(did, substs) => { + seen.push(did); + let fields = cx.struct_fields(did, substs); + let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty)); + seen.pop().unwrap(); + r + } - TyTuple(ref ts) => { - ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty)) - } + TyError | + TyInfer(_) | + TyClosure(..) => { + // this check is run on type definitions, so we don't expect to see + // inference by-products or closure types + cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty)) + } - TyEnum(ref did, _) if seen.contains(did) => { - false - } + TyTuple(ref ts) => { + ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty)) + } - TyEnum(did, substs) => { - seen.push(did); - let vs = enum_variants(cx, did); - let r = !vs.is_empty() && vs.iter().all(|variant| { - variant.args.iter().any(|aty| { - let sty = aty.subst(cx, substs); - type_requires(cx, seen, r_ty, sty) - }) - }); - seen.pop().unwrap(); - r - } - }; + TyEnum(ref did, _) if seen.contains(did) => { + false + } + + TyEnum(did, substs) => { + seen.push(did); + let vs = cx.enum_variants(did); + let r = !vs.is_empty() && vs.iter().all(|variant| { + variant.args.iter().any(|aty| { + let sty = aty.subst(cx, substs); + type_requires(cx, seen, r_ty, sty) + }) + }); + seen.pop().unwrap(); + r + } + }; - debug!("subtypes_require({:?}, {:?})? {:?}", - r_ty, ty, r); + debug!("subtypes_require({:?}, {:?})? {:?}", + r_ty, ty, r); - return r; - } + return r; + } - let mut seen = Vec::new(); - !subtypes_require(cx, &mut seen, r_ty, r_ty) + let mut seen = Vec::new(); + !subtypes_require(cx, &mut seen, self, self) + } } /// Describes whether a type is representable. For types that are not @@ -4331,161 +4578,161 @@ pub enum Representability { SelfRecursive, } -/// Check whether a type is representable. This means it cannot contain unboxed -/// structural recursion. This check is needed for structs and enums. -pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) - -> Representability { - - // Iterate until something non-representable is found - fn find_nonrepresentable<'tcx, It: Iterator>>(cx: &ctxt<'tcx>, sp: Span, - seen: &mut Vec>, - iter: It) - -> Representability { - iter.fold(Representable, - |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty))) - } - - fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span, - seen: &mut Vec>, ty: Ty<'tcx>) - -> Representability { - match ty.sty { - TyTuple(ref ts) => { - find_nonrepresentable(cx, sp, seen, ts.iter().cloned()) - } - // Fixed-length vectors. - // FIXME(#11924) Behavior undecided for zero-length vectors. - TyArray(ty, _) => { - is_type_structurally_recursive(cx, sp, seen, ty) - } - TyStruct(did, substs) => { - let fields = struct_fields(cx, did, substs); - find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty)) - } - TyEnum(did, substs) => { - let vs = enum_variants(cx, did); - let iter = vs.iter() - .flat_map(|variant| &variant.args) - .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) }); +impl<'tcx> TyS<'tcx> { + /// Check whether a type is representable. This means it cannot contain unboxed + /// structural recursion. This check is needed for structs and enums. + pub fn is_representable(&'tcx self, cx: &ctxt<'tcx>, sp: Span) -> Representability { + + // Iterate until something non-representable is found + fn find_nonrepresentable<'tcx, It: Iterator>>(cx: &ctxt<'tcx>, sp: Span, + seen: &mut Vec>, + iter: It) + -> Representability { + iter.fold(Representable, + |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty))) + } + + fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span, + seen: &mut Vec>, ty: Ty<'tcx>) + -> Representability { + match ty.sty { + TyTuple(ref ts) => { + find_nonrepresentable(cx, sp, seen, ts.iter().cloned()) + } + // Fixed-length vectors. + // FIXME(#11924) Behavior undecided for zero-length vectors. + TyArray(ty, _) => { + is_type_structurally_recursive(cx, sp, seen, ty) + } + TyStruct(did, substs) => { + let fields = cx.struct_fields(did, substs); + find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty)) + } + TyEnum(did, substs) => { + let vs = cx.enum_variants(did); + let iter = vs.iter() + .flat_map(|variant| &variant.args) + .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) }); - find_nonrepresentable(cx, sp, seen, iter) - } - TyClosure(..) => { - // this check is run on type definitions, so we don't expect - // to see closure types - cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty)) + find_nonrepresentable(cx, sp, seen, iter) + } + TyClosure(..) => { + // this check is run on type definitions, so we don't expect + // to see closure types + cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty)) + } + _ => Representable, } - _ => Representable, } - } - fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool { - match ty.sty { - TyStruct(ty_did, _) | TyEnum(ty_did, _) => { - ty_did == did + fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool { + match ty.sty { + TyStruct(ty_did, _) | TyEnum(ty_did, _) => { + ty_did == did + } + _ => false } - _ => false } - } - fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - match (&a.sty, &b.sty) { - (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) | - (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => { - if did_a != did_b { - return false; - } + fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { + match (&a.sty, &b.sty) { + (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) | + (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => { + if did_a != did_b { + return false; + } - let types_a = substs_a.types.get_slice(subst::TypeSpace); - let types_b = substs_b.types.get_slice(subst::TypeSpace); + let types_a = substs_a.types.get_slice(subst::TypeSpace); + let types_b = substs_b.types.get_slice(subst::TypeSpace); - let mut pairs = types_a.iter().zip(types_b); + let mut pairs = types_a.iter().zip(types_b); - pairs.all(|(&a, &b)| same_type(a, b)) - } - _ => { - a == b + pairs.all(|(&a, &b)| same_type(a, b)) + } + _ => { + a == b + } } } - } - // Does the type `ty` directly (without indirection through a pointer) - // contain any types on stack `seen`? - fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span, - seen: &mut Vec>, - ty: Ty<'tcx>) -> Representability { - debug!("is_type_structurally_recursive: {:?}", ty); + // Does the type `ty` directly (without indirection through a pointer) + // contain any types on stack `seen`? + fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span, + seen: &mut Vec>, + ty: Ty<'tcx>) -> Representability { + debug!("is_type_structurally_recursive: {:?}", ty); - match ty.sty { - TyStruct(did, _) | TyEnum(did, _) => { - { - // Iterate through stack of previously seen types. - let mut iter = seen.iter(); - - // The first item in `seen` is the type we are actually curious about. - // We want to return SelfRecursive if this type contains itself. - // It is important that we DON'T take generic parameters into account - // for this check, so that Bar in this example counts as SelfRecursive: - // - // struct Foo; - // struct Bar { x: Bar } + match ty.sty { + TyStruct(did, _) | TyEnum(did, _) => { + { + // Iterate through stack of previously seen types. + let mut iter = seen.iter(); + + // The first item in `seen` is the type we are actually curious about. + // We want to return SelfRecursive if this type contains itself. + // It is important that we DON'T take generic parameters into account + // for this check, so that Bar in this example counts as SelfRecursive: + // + // struct Foo; + // struct Bar { x: Bar } + + match iter.next() { + Some(&seen_type) => { + if same_struct_or_enum_def_id(seen_type, did) { + debug!("SelfRecursive: {:?} contains {:?}", + seen_type, + ty); + return SelfRecursive; + } + } + None => {} + } - match iter.next() { - Some(&seen_type) => { - if same_struct_or_enum_def_id(seen_type, did) { - debug!("SelfRecursive: {:?} contains {:?}", + // We also need to know whether the first item contains other types + // that are structurally recursive. If we don't catch this case, we + // will recurse infinitely for some inputs. + // + // It is important that we DO take generic parameters into account + // here, so that code like this is considered SelfRecursive, not + // ContainsRecursive: + // + // struct Foo { Option> } + + for &seen_type in iter { + if same_type(ty, seen_type) { + debug!("ContainsRecursive: {:?} contains {:?}", seen_type, ty); - return SelfRecursive; + return ContainsRecursive; } } - None => {} } - // We also need to know whether the first item contains other types that - // are structurally recursive. If we don't catch this case, we will recurse - // infinitely for some inputs. - // - // It is important that we DO take generic parameters into account here, - // so that code like this is considered SelfRecursive, not ContainsRecursive: - // - // struct Foo { Option> } - - for &seen_type in iter { - if same_type(ty, seen_type) { - debug!("ContainsRecursive: {:?} contains {:?}", - seen_type, - ty); - return ContainsRecursive; - } - } + // For structs and enums, track all previously seen types by pushing them + // onto the 'seen' stack. + seen.push(ty); + let out = are_inner_types_recursive(cx, sp, seen, ty); + seen.pop(); + out + } + _ => { + // No need to push in other cases. + are_inner_types_recursive(cx, sp, seen, ty) } - - // For structs and enums, track all previously seen types by pushing them - // onto the 'seen' stack. - seen.push(ty); - let out = are_inner_types_recursive(cx, sp, seen, ty); - seen.pop(); - out - } - _ => { - // No need to push in other cases. - are_inner_types_recursive(cx, sp, seen, ty) } } - } - debug!("is_type_representable: {:?}", ty); + debug!("is_type_representable: {:?}", self); - // To avoid a stack overflow when checking an enum variant or struct that - // contains a different, structurally recursive type, maintain a stack - // of seen types and check recursion for each of them (issues #3008, #3779). - let mut seen: Vec = Vec::new(); - let r = is_type_structurally_recursive(cx, sp, &mut seen, ty); - debug!("is_type_representable: {:?} is {:?}", ty, r); - r -} + // To avoid a stack overflow when checking an enum variant or struct that + // contains a different, structurally recursive type, maintain a stack + // of seen types and check recursion for each of them (issues #3008, #3779). + let mut seen: Vec = Vec::new(); + let r = is_type_structurally_recursive(cx, sp, &mut seen, self); + debug!("is_type_representable: {:?} is {:?}", self, r); + r + } -impl<'tcx> TyS<'tcx> { pub fn is_trait(&self) -> bool { match self.sty { TyTrait(..) => true, @@ -4568,7 +4815,7 @@ impl<'tcx> TyS<'tcx> { pub fn is_c_like_enum(&self, cx: &ctxt) -> bool { match self.sty { TyEnum(did, _) => { - let variants = enum_variants(cx, did); + let variants = cx.enum_variants(did); if variants.is_empty() { false } else { @@ -4604,88 +4851,7 @@ impl<'tcx> TyS<'tcx> { _ => None } } -} - -/// Returns the type of element at index `i` in tuple or tuple-like type `t`. -/// For an enum `t`, `variant` is None only if `t` is a univariant enum. -pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>, - ty: Ty<'tcx>, - i: usize, - variant: Option) -> Option> { - - match (&ty.sty, variant) { - (&TyTuple(ref v), None) => v.get(i).cloned(), - - - (&TyStruct(def_id, substs), None) => lookup_struct_fields(cx, def_id) - .get(i) - .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)), - - (&TyEnum(def_id, substs), Some(variant_def_id)) => { - let variant_info = enum_variant_with_id(cx, def_id, variant_def_id); - variant_info.args.get(i).map(|t|t.subst(cx, substs)) - } - - (&TyEnum(def_id, substs), None) => { - assert!(enum_is_univariant(cx, def_id)); - let enum_variants = enum_variants(cx, def_id); - let variant_info = &(*enum_variants)[0]; - variant_info.args.get(i).map(|t|t.subst(cx, substs)) - } - - _ => None - } -} - -/// Returns the type of element at field `n` in struct or struct-like type `t`. -/// For an enum `t`, `variant` must be some def id. -pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>, - ty: Ty<'tcx>, - n: ast::Name, - variant: Option) -> Option> { - - match (&ty.sty, variant) { - (&TyStruct(def_id, substs), None) => { - let r = lookup_struct_fields(cx, def_id); - r.iter().find(|f| f.name == n) - .map(|&f| lookup_field_type(cx, def_id, f.id, substs)) - } - (&TyEnum(def_id, substs), Some(variant_def_id)) => { - let variant_info = enum_variant_with_id(cx, def_id, variant_def_id); - variant_info.arg_names.as_ref() - .expect("must have struct enum variant if accessing a named fields") - .iter().zip(&variant_info.args) - .find(|&(&name, _)| name == n) - .map(|(_name, arg_t)| arg_t.subst(cx, substs)) - } - _ => None - } -} - -pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> { - match node_id_to_type_opt(cx, id) { - Some(ty) => ty, - None => cx.sess.bug( - &format!("node_id_to_type: no type for node `{}`", - cx.map.node_to_string(id))) - } -} - -pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option> { - match cx.node_types.borrow().get(&id) { - Some(&ty) => Some(ty), - None => None - } -} - -pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts<'tcx> { - match cx.item_substs.borrow().get(&id) { - None => ItemSubsts::empty(), - Some(ts) => ts.clone(), - } -} -impl<'tcx> TyS<'tcx> { pub fn fn_sig(&self) -> &'tcx PolyFnSig<'tcx> { match self.sty { TyBareFn(_, ref f) => &f.sig, @@ -4716,339 +4882,144 @@ impl<'tcx> TyS<'tcx> { _ => false } } -} - -pub fn ty_region(tcx: &ctxt, - span: Span, - ty: Ty) -> Region { - match ty.sty { - TyRef(r, _) => *r, - ref s => { - tcx.sess.span_bug( - span, - &format!("ty_region() invoked on an inappropriate ty: {:?}", - s)); - } - } -} - -// Returns the type of a pattern as a monotype. Like @expr_ty, this function -// doesn't provide type parameter substitutions. -pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> { - return node_id_to_type(cx, pat.id); -} -pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option> { - return node_id_to_type_opt(cx, pat.id); -} - - -// Returns the type of an expression as a monotype. -// -// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in -// some cases, we insert `AutoAdjustment` annotations such as auto-deref or -// auto-ref. The type returned by this function does not consider such -// adjustments. See `expr_ty_adjusted()` instead. -// -// NB (2): This type doesn't provide type parameter substitutions; e.g. if you -// ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" -// instead of "fn(ty) -> T with T = isize". -pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> { - return node_id_to_type(cx, expr.id); -} - -pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Option> { - return node_id_to_type_opt(cx, expr.id); -} - -/// Returns the type of `expr`, considering any `AutoAdjustment` -/// entry recorded for that expression. -/// -/// It would almost certainly be better to store the adjusted ty in with -/// the `AutoAdjustment`, but I opted not to do this because it would -/// require serializing and deserializing the type and, although that's not -/// hard to do, I just hate that code so much I didn't want to touch it -/// unless it was to fix it properly, which seemed a distraction from the -/// thread at hand! -nmatsakis -pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> { - adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr), - cx.adjustments.borrow().get(&expr.id), - |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty)) -} - -pub fn expr_span(cx: &ctxt, id: NodeId) -> Span { - match cx.map.find(id) { - Some(ast_map::NodeExpr(e)) => { - e.span - } - Some(f) => { - cx.sess.bug(&format!("Node id {} is not an expr: {:?}", - id, - f)); - } - None => { - cx.sess.bug(&format!("Node id {} is not present \ - in the node map", id)); - } - } -} -pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString { - match cx.map.find(id) { - Some(ast_map::NodeLocal(pat)) => { - match pat.node { - ast::PatIdent(_, ref path1, _) => { - token::get_ident(path1.node) - } - _ => { - cx.sess.bug( - &format!("Variable id {} maps to {:?}, not local", - id, - pat)); - } - } - } - r => { - cx.sess.bug(&format!("Variable id {} maps to {:?}, not local", - id, - r)); + /// See `expr_ty_adjusted` + pub fn adjust(&'tcx self, cx: &ctxt<'tcx>, + span: Span, + expr_id: ast::NodeId, + adjustment: Option<&AutoAdjustment<'tcx>>, + mut method_type: F) + -> Ty<'tcx> where + F: FnMut(MethodCall) -> Option>, + { + if let TyError = self.sty { + return self; } - } -} - -/// See `expr_ty_adjusted` -pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>, - span: Span, - expr_id: ast::NodeId, - unadjusted_ty: Ty<'tcx>, - adjustment: Option<&AutoAdjustment<'tcx>>, - mut method_type: F) - -> Ty<'tcx> where - F: FnMut(MethodCall) -> Option>, -{ - if let TyError = unadjusted_ty.sty { - return unadjusted_ty; - } - return match adjustment { - Some(adjustment) => { - match *adjustment { - AdjustReifyFnPointer => { - match unadjusted_ty.sty { - ty::TyBareFn(Some(_), b) => { - cx.mk_fn(None, b) - } - _ => { - cx.sess.bug( - &format!("AdjustReifyFnPointer adjustment on non-fn-item: \ - {:?}", unadjusted_ty)); + return match adjustment { + Some(adjustment) => { + match *adjustment { + AdjustReifyFnPointer => { + match self.sty { + ty::TyBareFn(Some(_), b) => { + cx.mk_fn(None, b) + } + _ => { + cx.sess.bug( + &format!("AdjustReifyFnPointer adjustment on non-fn-item: \ + {:?}", self)); + } } } - } - AdjustUnsafeFnPointer => { - match unadjusted_ty.sty { - ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b), - ref b => { - cx.sess.bug( - &format!("AdjustReifyFnPointer adjustment on non-fn-item: \ - {:?}", - b)); + AdjustUnsafeFnPointer => { + match self.sty { + ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b), + ref b => { + cx.sess.bug( + &format!("AdjustReifyFnPointer adjustment on non-fn-item: \ + {:?}", + b)); + } } - } - } - - AdjustDerefRef(ref adj) => { - let mut adjusted_ty = unadjusted_ty; - - if !adjusted_ty.references_error() { - for i in 0..adj.autoderefs { - let method_call = MethodCall::autoderef(expr_id, i as u32); - match method_type(method_call) { - Some(method_ty) => { - // Overloaded deref operators have all late-bound - // regions fully instantiated and coverge. - let fn_ret = - ty::no_late_bound_regions(cx, - &method_ty.fn_ret()).unwrap(); - adjusted_ty = fn_ret.unwrap(); + } + + AdjustDerefRef(ref adj) => { + let mut adjusted_ty = self; + + if !adjusted_ty.references_error() { + for i in 0..adj.autoderefs { + let method_call = MethodCall::autoderef(expr_id, i as u32); + match method_type(method_call) { + Some(method_ty) => { + // Overloaded deref operators have all late-bound + // regions fully instantiated and coverge. + let fn_ret = + cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap(); + adjusted_ty = fn_ret.unwrap(); + } + None => {} } - None => {} - } - match adjusted_ty.builtin_deref(true) { - Some(mt) => { adjusted_ty = mt.ty; } - None => { - cx.sess.span_bug( - span, - &format!("the {}th autoderef failed: {}", - i, - adjusted_ty) - ); + match adjusted_ty.builtin_deref(true) { + Some(mt) => { adjusted_ty = mt.ty; } + None => { + cx.sess.span_bug( + span, + &format!("the {}th autoderef failed: {}", + i, + adjusted_ty) + ); + } } } } - } - if let Some(target) = adj.unsize { - target - } else { - adjust_ty_for_autoref(cx, adjusted_ty, adj.autoref) + if let Some(target) = adj.unsize { + target + } else { + adjusted_ty.adjust_for_autoref(cx, adj.autoref) + } } } } - } - None => unadjusted_ty - }; -} - -pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>, - ty: Ty<'tcx>, - autoref: Option>) - -> Ty<'tcx> { - match autoref { - None => ty, - Some(AutoPtr(r, m)) => { - cx.mk_ref(r, mt { ty: ty, mutbl: m }) - } - Some(AutoUnsafe(m)) => { - cx.mk_ptr(mt { ty: ty, mutbl: m }) - } + None => self + }; } -} -pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def { - match tcx.def_map.borrow().get(&expr.id) { - Some(def) => def.full_def(), - None => { - tcx.sess.span_bug(expr.span, &format!( - "no def-map entry for expr {}", expr.id)); + pub fn adjust_for_autoref(&'tcx self, cx: &ctxt<'tcx>, + autoref: Option>) + -> Ty<'tcx> { + match autoref { + None => self, + Some(AutoPtr(r, m)) => { + cx.mk_ref(r, mt { ty: self, mutbl: m }) + } + Some(AutoUnsafe(m)) => { + cx.mk_ptr(mt { ty: self, mutbl: m }) + } } } -} -pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool { - match expr.node { - ast::ExprPath(..) => { - // We can't use resolve_expr here, as this needs to run on broken - // programs. We don't need to through - associated items are all - // rvalues. - match tcx.def_map.borrow().get(&expr.id) { - Some(&def::PathResolution { - base_def: def::DefStatic(..), .. - }) | Some(&def::PathResolution { - base_def: def::DefUpvar(..), .. - }) | Some(&def::PathResolution { - base_def: def::DefLocal(..), .. - }) => { - true + fn sort_string(&self, cx: &ctxt) -> String { + match self.sty { + TyBool | TyChar | TyInt(_) | + TyUint(_) | TyFloat(_) | TyStr => self.to_string(), + TyTuple(ref tys) if tys.is_empty() => self.to_string(), + + TyEnum(id, _) => format!("enum `{}`", cx.item_path_str(id)), + TyBox(_) => "box".to_string(), + TyArray(_, n) => format!("array of {} elements", n), + TySlice(_) => "slice".to_string(), + TyRawPtr(_) => "*-ptr".to_string(), + TyRef(_, _) => "&-ptr".to_string(), + TyBareFn(Some(_), _) => format!("fn item"), + TyBareFn(None, _) => "fn pointer".to_string(), + TyTrait(ref inner) => { + format!("trait {}", cx.item_path_str(inner.principal_def_id())) + } + TyStruct(id, _) => { + format!("struct `{}`", cx.item_path_str(id)) + } + TyClosure(..) => "closure".to_string(), + TyTuple(_) => "tuple".to_string(), + TyInfer(TyVar(_)) => "inferred type".to_string(), + TyInfer(IntVar(_)) => "integral variable".to_string(), + TyInfer(FloatVar(_)) => "floating-point variable".to_string(), + TyInfer(FreshTy(_)) => "skolemized type".to_string(), + TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(), + TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(), + TyProjection(_) => "associated type".to_string(), + TyParam(ref p) => { + if p.space == subst::SelfSpace { + "Self".to_string() + } else { + "type parameter".to_string() } - - Some(..) => false, - - None => tcx.sess.span_bug(expr.span, &format!( - "no def for path {}", expr.id)) - } - } - - ast::ExprUnary(ast::UnDeref, _) | - ast::ExprField(..) | - ast::ExprTupField(..) | - ast::ExprIndex(..) => { - true - } - - ast::ExprCall(..) | - ast::ExprMethodCall(..) | - ast::ExprStruct(..) | - ast::ExprRange(..) | - ast::ExprTup(..) | - ast::ExprIf(..) | - ast::ExprMatch(..) | - ast::ExprClosure(..) | - ast::ExprBlock(..) | - ast::ExprRepeat(..) | - ast::ExprVec(..) | - ast::ExprBreak(..) | - ast::ExprAgain(..) | - ast::ExprRet(..) | - ast::ExprWhile(..) | - ast::ExprLoop(..) | - ast::ExprAssign(..) | - ast::ExprInlineAsm(..) | - ast::ExprAssignOp(..) | - ast::ExprLit(_) | - ast::ExprUnary(..) | - ast::ExprBox(..) | - ast::ExprAddrOf(..) | - ast::ExprBinary(..) | - ast::ExprCast(..) => { - false - } - - ast::ExprParen(ref e) => expr_is_lval(tcx, e), - - ast::ExprIfLet(..) | - ast::ExprWhileLet(..) | - ast::ExprForLoop(..) | - ast::ExprMac(..) => { - tcx.sess.span_bug( - expr.span, - "macro expression remains after expansion"); - } - } -} - -pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field]) - -> usize { - let mut i = 0; - for f in fields { if f.name == name { return i; } i += 1; } - tcx.sess.bug(&format!( - "no field named `{}` found in the list of fields `{:?}`", - token::get_name(name), - fields.iter() - .map(|f| token::get_name(f.name).to_string()) - .collect::>())); -} - -pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String { - match ty.sty { - TyBool | TyChar | TyInt(_) | - TyUint(_) | TyFloat(_) | TyStr => ty.to_string(), - TyTuple(ref tys) if tys.is_empty() => ty.to_string(), - - TyEnum(id, _) => format!("enum `{}`", item_path_str(cx, id)), - TyBox(_) => "box".to_string(), - TyArray(_, n) => format!("array of {} elements", n), - TySlice(_) => "slice".to_string(), - TyRawPtr(_) => "*-ptr".to_string(), - TyRef(_, _) => "&-ptr".to_string(), - TyBareFn(Some(_), _) => format!("fn item"), - TyBareFn(None, _) => "fn pointer".to_string(), - TyTrait(ref inner) => { - format!("trait {}", item_path_str(cx, inner.principal_def_id())) - } - TyStruct(id, _) => { - format!("struct `{}`", item_path_str(cx, id)) - } - TyClosure(..) => "closure".to_string(), - TyTuple(_) => "tuple".to_string(), - TyInfer(TyVar(_)) => "inferred type".to_string(), - TyInfer(IntVar(_)) => "integral variable".to_string(), - TyInfer(FloatVar(_)) => "floating-point variable".to_string(), - TyInfer(FreshTy(_)) => "skolemized type".to_string(), - TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(), - TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(), - TyProjection(_) => "associated type".to_string(), - TyParam(ref p) => { - if p.space == subst::SelfSpace { - "Self".to_string() - } else { - "type parameter".to_string() } + TyError => "type error".to_string(), } - TyError => "type error".to_string(), } } - /// Explains the source of a type err in a short, human readable way. This is meant to be placed /// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()` /// afterwards to present additional details, particularly when it comes to lifetime-related @@ -5116,8 +5087,8 @@ impl<'tcx> fmt::Display for type_err<'tcx> { terr_sorts(values) => tls::with(|tcx| { // A naive approach to making sure that we're not reporting silly errors such as: // (expected closure, found closure). - let expected_str = ty_sort_string(tcx, values.expected); - let found_str = ty_sort_string(tcx, values.found); + let expected_str = values.expected.sort_string(tcx); + let found_str = values.found.sort_string(tcx); if expected_str == found_str { write!(f, "expected {}, found a different {}", expected_str, found_str) } else { @@ -5126,8 +5097,8 @@ impl<'tcx> fmt::Display for type_err<'tcx> { }), terr_traits(values) => tls::with(|tcx| { write!(f, "expected trait `{}`, found trait `{}`", - item_path_str(tcx, values.expected), - item_path_str(tcx, values.found)) + tcx.item_path_str(values.expected), + tcx.item_path_str(values.found)) }), terr_builtin_bounds(values) => { if values.expected.is_empty() { @@ -5179,127 +5150,6 @@ impl<'tcx> fmt::Display for type_err<'tcx> { } } -pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) { - match *err { - terr_regions_does_not_outlive(subregion, superregion) => { - note_and_explain_region(cx, "", subregion, "..."); - note_and_explain_region(cx, "...does not necessarily outlive ", - superregion, ""); - } - terr_regions_not_same(region1, region2) => { - note_and_explain_region(cx, "", region1, "..."); - note_and_explain_region(cx, "...is not the same lifetime as ", - region2, ""); - } - terr_regions_no_overlap(region1, region2) => { - note_and_explain_region(cx, "", region1, "..."); - note_and_explain_region(cx, "...does not overlap ", - region2, ""); - } - terr_regions_insufficiently_polymorphic(_, conc_region) => { - note_and_explain_region(cx, - "concrete lifetime that was found is ", - conc_region, ""); - } - terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => { - // don't bother to print out the message below for - // inference variables, it's not very illuminating. - } - terr_regions_overly_polymorphic(_, conc_region) => { - note_and_explain_region(cx, - "expected concrete lifetime is ", - conc_region, ""); - } - terr_sorts(values) => { - let expected_str = ty_sort_string(cx, values.expected); - let found_str = ty_sort_string(cx, values.found); - if expected_str == found_str && expected_str == "closure" { - cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \ - type")); - cx.sess.span_help(sp, &format!("consider boxing your closure and/or \ - using it as a trait object")); - } - } - _ => {} - } -} - -pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { - cx.provided_method_sources.borrow().get(&id).cloned() -} - -pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Vec>> { - if is_local(id) { - if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node { - ms.iter().filter_map(|ti| { - if let ast::MethodTraitItem(_, Some(_)) = ti.node { - match impl_or_trait_item(cx, ast_util::local_def(ti.id)) { - MethodTraitItem(m) => Some(m), - _ => { - cx.sess.bug("provided_trait_methods(): \ - non-method item found from \ - looking up provided method?!") - } - } - } else { - None - } - }).collect() - } else { - cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id)) - } - } else { - csearch::get_provided_trait_methods(cx, id) - } -} - -pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Vec>> { - if is_local(id) { - match cx.map.expect_item(id.node).node { - ItemTrait(_, _, _, ref tis) => { - tis.iter().filter_map(|ti| { - if let ast::ConstTraitItem(_, _) = ti.node { - match impl_or_trait_item(cx, ast_util::local_def(ti.id)) { - ConstTraitItem(ac) => Some(ac), - _ => { - cx.sess.bug("associated_consts(): \ - non-const item found from \ - looking up a constant?!") - } - } - } else { - None - } - }).collect() - } - ItemImpl(_, _, _, _, _, ref iis) => { - iis.iter().filter_map(|ii| { - if let ast::ConstImplItem(_, _) = ii.node { - match impl_or_trait_item(cx, ast_util::local_def(ii.id)) { - ConstTraitItem(ac) => Some(ac), - _ => { - cx.sess.bug("associated_consts(): \ - non-const item found from \ - looking up a constant?!") - } - } - } else { - None - } - }).collect() - } - _ => { - cx.sess.bug(&format!("associated_consts: `{:?}` is not a trait \ - or impl", id)) - } - } - } else { - csearch::get_associated_consts(cx, id) - } -} - /// Helper for looking things up in the various maps that are populated during /// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of /// these share the pattern that if the id is local, it should have been loaded @@ -5326,1448 +5176,1500 @@ fn lookup_locally_or_in_crate_store(descr: &str, v } -pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize) - -> ImplOrTraitItem<'tcx> { - let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id(); - impl_or_trait_item(cx, method_def_id) -} - -pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId) - -> Rc>> { - let mut trait_items = cx.trait_items_cache.borrow_mut(); - match trait_items.get(&trait_did).cloned() { - Some(trait_items) => trait_items, - None => { - let def_ids = ty::trait_item_def_ids(cx, trait_did); - let items: Rc> = - Rc::new(def_ids.iter() - .map(|d| impl_or_trait_item(cx, d.def_id())) - .collect()); - trait_items.insert(trait_did, items.clone()); - items - } - } -} - -pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Option { - if id.krate == ast::LOCAL_CRATE { - match cx.map.find(id.node) { - Some(ast_map::NodeItem(item)) => { - match item.node { - ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity), - _ => None - } - } - _ => None - } - } else { - csearch::get_impl_polarity(cx, id) - } -} - -pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) - -> CustomCoerceUnsized { - memoized(&cx.custom_coerce_unsized_kinds, did, |did: DefId| { - let (kind, src) = if did.krate != ast::LOCAL_CRATE { - (csearch::get_custom_coerce_unsized_kind(cx, did), "external") - } else { - (None, "local") - }; - - match kind { - Some(kind) => kind, - None => { - cx.sess.bug(&format!("custom_coerce_unsized_kind: \ - {} impl `{}` is missing its kind", - src, item_path_str(cx, did))); - } - } - }) -} - -pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> ImplOrTraitItem<'tcx> { - lookup_locally_or_in_crate_store( - "impl_or_trait_items", id, &cx.impl_or_trait_items, - || csearch::get_impl_or_trait_item(cx, id)) -} - -/// Returns the parameter index that the given associated type corresponds to. -pub fn associated_type_parameter_index(cx: &ctxt, - trait_def: &TraitDef, - associated_type_id: ast::DefId) - -> usize { - for type_parameter_def in &trait_def.generics.types { - if type_parameter_def.def_id == associated_type_id { - return type_parameter_def.index as usize +impl BorrowKind { + pub fn from_mutbl(m: ast::Mutability) -> BorrowKind { + match m { + ast::MutMutable => MutBorrow, + ast::MutImmutable => ImmBorrow, } } - cx.sess.bug("couldn't find associated type parameter index") -} - -pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId) - -> Rc> { - lookup_locally_or_in_crate_store( - "trait_item_def_ids", id, &cx.trait_item_def_ids, - || Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id))) -} -/// Returns the trait-ref corresponding to a given impl, or None if it is -/// an inherent impl. -pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Option> -{ - lookup_locally_or_in_crate_store( - "impl_trait_refs", id, &cx.impl_trait_refs, - || csearch::get_impl_trait(cx, id)) -} - -/// Returns whether this DefId refers to an impl -pub fn is_impl<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> bool { - if id.krate == ast::LOCAL_CRATE { - if let Some(ast_map::NodeItem( - &ast::Item { node: ast::ItemImpl(..), .. })) = cx.map.find(id.node) { - true - } else { - false + /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow + /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a + /// mutability that is stronger than necessary so that it at least *would permit* the borrow in + /// question. + pub fn to_mutbl_lossy(self) -> ast::Mutability { + match self { + MutBorrow => ast::MutMutable, + ImmBorrow => ast::MutImmutable, + + // We have no type corresponding to a unique imm borrow, so + // use `&mut`. It gives all the capabilities of an `&uniq` + // and hence is a safe "over approximation". + UniqueImmBorrow => ast::MutMutable, } - } else { - csearch::is_impl(&cx.sess.cstore, id) } -} -pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId { - tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id() -} - -pub fn try_add_builtin_trait( - tcx: &ctxt, - trait_def_id: ast::DefId, - builtin_bounds: &mut EnumSet) - -> bool -{ - //! Checks whether `trait_ref` refers to one of the builtin - //! traits, like `Send`, and adds the corresponding - //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref` - //! is a builtin trait. - - match tcx.lang_items.to_builtin_kind(trait_def_id) { - Some(bound) => { builtin_bounds.insert(bound); true } - None => false - } -} - -pub fn ty_to_def_id(ty: Ty) -> Option { - match ty.sty { - TyTrait(ref tt) => - Some(tt.principal_def_id()), - TyStruct(id, _) | - TyEnum(id, _) | - TyClosure(id, _) => - Some(id), - _ => - None + pub fn to_user_str(&self) -> &'static str { + match *self { + MutBorrow => "mutable", + ImmBorrow => "immutable", + UniqueImmBorrow => "uniquely immutable", + } } } -// Enum information -#[derive(Clone)] -pub struct VariantInfo<'tcx> { - pub args: Vec>, - pub arg_names: Option>, - pub ctor_ty: Option>, - pub name: ast::Name, - pub id: ast::DefId, - pub disr_val: Disr, - pub vis: Visibility -} +impl<'tcx> ctxt<'tcx> { + /// Returns the type of element at index `i` in tuple or tuple-like type `t`. + /// For an enum `t`, `variant` is None only if `t` is a univariant enum. + pub fn positional_element_ty(&self, + ty: Ty<'tcx>, + i: usize, + variant: Option) -> Option> { -impl<'tcx> VariantInfo<'tcx> { + match (&ty.sty, variant) { + (&TyTuple(ref v), None) => v.get(i).cloned(), - /// Creates a new VariantInfo from the corresponding ast representation. - /// - /// Does not do any caching of the value in the type context. - pub fn from_ast_variant(cx: &ctxt<'tcx>, - ast_variant: &ast::Variant, - discriminant: Disr) -> VariantInfo<'tcx> { - let ctor_ty = node_id_to_type(cx, ast_variant.node.id); - match ast_variant.node.kind { - ast::TupleVariantKind(ref args) => { - let arg_tys = if !args.is_empty() { - // the regions in the argument types come from the - // enum def'n, and hence will all be early bound - ty::no_late_bound_regions(cx, &ctor_ty.fn_args()).unwrap() - } else { - Vec::new() - }; + (&TyStruct(def_id, substs), None) => self.lookup_struct_fields(def_id) + .get(i) + .map(|&t| self.lookup_item_type(t.id).ty.subst(self, substs)), - return VariantInfo { - args: arg_tys, - arg_names: None, - ctor_ty: Some(ctor_ty), - name: ast_variant.node.name.name, - id: ast_util::local_def(ast_variant.node.id), - disr_val: discriminant, - vis: ast_variant.node.vis - }; - }, - ast::StructVariantKind(ref struct_def) => { - let fields: &[StructField] = &struct_def.fields; + (&TyEnum(def_id, substs), Some(variant_def_id)) => { + let variant_info = self.enum_variant_with_id(def_id, variant_def_id); + variant_info.args.get(i).map(|t|t.subst(self, substs)) + } - assert!(!fields.is_empty()); + (&TyEnum(def_id, substs), None) => { + assert!(self.enum_is_univariant(def_id)); + let enum_variants = self.enum_variants(def_id); + let variant_info = &enum_variants[0]; + variant_info.args.get(i).map(|t|t.subst(self, substs)) + } - let arg_tys = struct_def.fields.iter() - .map(|field| node_id_to_type(cx, field.node.id)).collect(); - let arg_names = fields.iter().map(|field| { - match field.node.kind { - NamedField(ident, _) => ident.name, - UnnamedField(..) => cx.sess.bug( - "enum_variants: all fields in struct must have a name") - } - }).collect(); + _ => None + } + } - return VariantInfo { - args: arg_tys, - arg_names: Some(arg_names), - ctor_ty: None, - name: ast_variant.node.name.name, - id: ast_util::local_def(ast_variant.node.id), - disr_val: discriminant, - vis: ast_variant.node.vis - }; + /// Returns the type of element at field `n` in struct or struct-like type `t`. + /// For an enum `t`, `variant` must be some def id. + pub fn named_element_ty(&self, + ty: Ty<'tcx>, + n: ast::Name, + variant: Option) -> Option> { + + match (&ty.sty, variant) { + (&TyStruct(def_id, substs), None) => { + let r = self.lookup_struct_fields(def_id); + r.iter().find(|f| f.name == n) + .map(|&f| self.lookup_field_type(def_id, f.id, substs)) } + (&TyEnum(def_id, substs), Some(variant_def_id)) => { + let variant_info = self.enum_variant_with_id(def_id, variant_def_id); + variant_info.arg_names.as_ref() + .expect("must have struct enum variant if accessing a named fields") + .iter().zip(&variant_info.args) + .find(|&(&name, _)| name == n) + .map(|(_name, arg_t)| arg_t.subst(self, substs)) + } + _ => None } } -} - -pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>, - id: ast::DefId, - substs: &Substs<'tcx>) - -> Vec>> { - enum_variants(cx, id).iter().map(|variant_info| { - let substd_args = variant_info.args.iter() - .map(|aty| aty.subst(cx, substs)).collect::>(); - let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs); + pub fn node_id_to_type(&self, id: ast::NodeId) -> Ty<'tcx> { + match self.node_id_to_type_opt(id) { + Some(ty) => ty, + None => self.sess.bug( + &format!("node_id_to_type: no type for node `{}`", + self.map.node_to_string(id))) + } + } - Rc::new(VariantInfo { - args: substd_args, - ctor_ty: substd_ctor_ty, - ..(**variant_info).clone() - }) - }).collect() -} + pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option> { + self.node_types.borrow().get(&id).cloned() + } -pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String { - with_path(cx, id, |path| ast_map::path_to_string(path)).to_string() -} + pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> { + match self.item_substs.borrow().get(&id) { + None => ItemSubsts::empty(), + Some(ts) => ts.clone(), + } + } -#[derive(Copy, Clone)] -pub enum DtorKind { - NoDtor, - TraitDtor(DefId, bool) -} + // Returns the type of a pattern as a monotype. Like @expr_ty, this function + // doesn't provide type parameter substitutions. + pub fn pat_ty(&self, pat: &ast::Pat) -> Ty<'tcx> { + self.node_id_to_type(pat.id) + } + pub fn pat_ty_opt(&self, pat: &ast::Pat) -> Option> { + self.node_id_to_type_opt(pat.id) + } -impl DtorKind { - pub fn is_present(&self) -> bool { - match *self { - TraitDtor(..) => true, - _ => false - } + // Returns the type of an expression as a monotype. + // + // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in + // some cases, we insert `AutoAdjustment` annotations such as auto-deref or + // auto-ref. The type returned by this function does not consider such + // adjustments. See `expr_ty_adjusted()` instead. + // + // NB (2): This type doesn't provide type parameter substitutions; e.g. if you + // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize" + // instead of "fn(ty) -> T with T = isize". + pub fn expr_ty(&self, expr: &ast::Expr) -> Ty<'tcx> { + self.node_id_to_type(expr.id) } - pub fn has_drop_flag(&self) -> bool { - match self { - &NoDtor => false, - &TraitDtor(_, flag) => flag - } + pub fn expr_ty_opt(&self, expr: &ast::Expr) -> Option> { + self.node_id_to_type_opt(expr.id) } -} -/* If struct_id names a struct with a dtor. */ -pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind { - match cx.destructor_for_type.borrow().get(&struct_id) { - Some(&method_def_id) => { - let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag"); + /// Returns the type of `expr`, considering any `AutoAdjustment` + /// entry recorded for that expression. + /// + /// It would almost certainly be better to store the adjusted ty in with + /// the `AutoAdjustment`, but I opted not to do this because it would + /// require serializing and deserializing the type and, although that's not + /// hard to do, I just hate that code so much I didn't want to touch it + /// unless it was to fix it properly, which seemed a distraction from the + /// thread at hand! -nmatsakis + pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> { + self.expr_ty(expr) + .adjust(self, expr.span, expr.id, + self.adjustments.borrow().get(&expr.id), + |method_call| { + self.method_map.borrow().get(&method_call).map(|method| method.ty) + }) + } - TraitDtor(method_def_id, flag) + pub fn expr_span(&self, id: NodeId) -> Span { + match self.map.find(id) { + Some(ast_map::NodeExpr(e)) => { + e.span + } + Some(f) => { + self.sess.bug(&format!("Node id {} is not an expr: {:?}", + id, f)); + } + None => { + self.sess.bug(&format!("Node id {} is not present \ + in the node map", id)); + } } - None => NoDtor, } -} -pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool { - cx.destructor_for_type.borrow().contains_key(&struct_id) -} - -pub fn with_path(cx: &ctxt, id: ast::DefId, f: F) -> T where - F: FnOnce(ast_map::PathElems) -> T, -{ - if id.krate == ast::LOCAL_CRATE { - cx.map.with_path(id.node, f) - } else { - f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty())) + pub fn local_var_name_str(&self, id: NodeId) -> InternedString { + match self.map.find(id) { + Some(ast_map::NodeLocal(pat)) => { + match pat.node { + ast::PatIdent(_, ref path1, _) => { + token::get_ident(path1.node) + } + _ => { + self.sess.bug(&format!("Variable id {} maps to {:?}, not local", + id, pat)); + } + } + } + r => { + self.sess.bug(&format!("Variable id {} maps to {:?}, not local", + id, r)); + } + } } -} -pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool { - enum_variants(cx, id).len() == 1 -} + pub fn resolve_expr(&self, expr: &ast::Expr) -> def::Def { + match self.def_map.borrow().get(&expr.id) { + Some(def) => def.full_def(), + None => { + self.sess.span_bug(expr.span, &format!( + "no def-map entry for expr {}", expr.id)); + } + } + } + + pub fn expr_is_lval(&self, expr: &ast::Expr) -> bool { + match expr.node { + ast::ExprPath(..) => { + // We can't use resolve_expr here, as this needs to run on broken + // programs. We don't need to through - associated items are all + // rvalues. + match self.def_map.borrow().get(&expr.id) { + Some(&def::PathResolution { + base_def: def::DefStatic(..), .. + }) | Some(&def::PathResolution { + base_def: def::DefUpvar(..), .. + }) | Some(&def::PathResolution { + base_def: def::DefLocal(..), .. + }) => { + true + } -pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool { - match ty.sty { - TyEnum(did, _) => (*enum_variants(cx, did)).is_empty(), - _ => false - } -} + Some(..) => false, -trait IntTypeExt { - fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>; - fn i64_to_disr(&self, val: i64) -> Option; - fn u64_to_disr(&self, val: u64) -> Option; - fn disr_incr(&self, val: Disr) -> Option; - fn disr_string(&self, val: Disr) -> String; - fn disr_wrap_incr(&self, val: Option) -> Disr; -} + None => self.sess.span_bug(expr.span, &format!( + "no def for path {}", expr.id)) + } + } -impl IntTypeExt for attr::IntType { - fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> { - match *self { - SignedInt(ast::TyI8) => cx.types.i8, - SignedInt(ast::TyI16) => cx.types.i16, - SignedInt(ast::TyI32) => cx.types.i32, - SignedInt(ast::TyI64) => cx.types.i64, - SignedInt(ast::TyIs) => cx.types.isize, - UnsignedInt(ast::TyU8) => cx.types.u8, - UnsignedInt(ast::TyU16) => cx.types.u16, - UnsignedInt(ast::TyU32) => cx.types.u32, - UnsignedInt(ast::TyU64) => cx.types.u64, - UnsignedInt(ast::TyUs) => cx.types.usize, + ast::ExprUnary(ast::UnDeref, _) | + ast::ExprField(..) | + ast::ExprTupField(..) | + ast::ExprIndex(..) => { + true + } + + ast::ExprCall(..) | + ast::ExprMethodCall(..) | + ast::ExprStruct(..) | + ast::ExprRange(..) | + ast::ExprTup(..) | + ast::ExprIf(..) | + ast::ExprMatch(..) | + ast::ExprClosure(..) | + ast::ExprBlock(..) | + ast::ExprRepeat(..) | + ast::ExprVec(..) | + ast::ExprBreak(..) | + ast::ExprAgain(..) | + ast::ExprRet(..) | + ast::ExprWhile(..) | + ast::ExprLoop(..) | + ast::ExprAssign(..) | + ast::ExprInlineAsm(..) | + ast::ExprAssignOp(..) | + ast::ExprLit(_) | + ast::ExprUnary(..) | + ast::ExprBox(..) | + ast::ExprAddrOf(..) | + ast::ExprBinary(..) | + ast::ExprCast(..) => { + false + } + + ast::ExprParen(ref e) => self.expr_is_lval(e), + + ast::ExprIfLet(..) | + ast::ExprWhileLet(..) | + ast::ExprForLoop(..) | + ast::ExprMac(..) => { + self.sess.span_bug( + expr.span, + "macro expression remains after expansion"); + } + } + } + + pub fn field_idx_strict(&self, name: ast::Name, fields: &[field]) + -> usize { + let mut i = 0; + for f in fields { if f.name == name { return i; } i += 1; } + self.sess.bug(&format!( + "no field named `{}` found in the list of fields `{:?}`", + token::get_name(name), + fields.iter() + .map(|f| token::get_name(f.name).to_string()) + .collect::>())); + } + + pub fn note_and_explain_type_err(&self, err: &type_err<'tcx>, sp: Span) { + match *err { + terr_regions_does_not_outlive(subregion, superregion) => { + self.note_and_explain_region("", subregion, "..."); + self.note_and_explain_region("...does not necessarily outlive ", + superregion, ""); + } + terr_regions_not_same(region1, region2) => { + self.note_and_explain_region("", region1, "..."); + self.note_and_explain_region("...is not the same lifetime as ", + region2, ""); + } + terr_regions_no_overlap(region1, region2) => { + self.note_and_explain_region("", region1, "..."); + self.note_and_explain_region("...does not overlap ", + region2, ""); + } + terr_regions_insufficiently_polymorphic(_, conc_region) => { + self.note_and_explain_region("concrete lifetime that was found is ", + conc_region, ""); + } + terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => { + // don't bother to print out the message below for + // inference variables, it's not very illuminating. + } + terr_regions_overly_polymorphic(_, conc_region) => { + self.note_and_explain_region("expected concrete lifetime is ", + conc_region, ""); + } + terr_sorts(values) => { + let expected_str = values.expected.sort_string(self); + let found_str = values.found.sort_string(self); + if expected_str == found_str && expected_str == "closure" { + self.sess.span_note(sp, + &format!("no two closures, even if identical, have the same type")); + self.sess.span_help(sp, + &format!("consider boxing your closure and/or \ + using it as a trait object")); + } + } + _ => {} } } - fn i64_to_disr(&self, val: i64) -> Option { - match *self { - SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr), - SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr), - SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr), - SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr), - UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr), - UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr), - UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr), - UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr), + pub fn provided_source(&self, id: ast::DefId) -> Option { + self.provided_method_sources.borrow().get(&id).cloned() + } - UnsignedInt(ast::TyUs) | - SignedInt(ast::TyIs) => unreachable!(), + pub fn provided_trait_methods(&self, id: ast::DefId) -> Vec>> { + if is_local(id) { + if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node { + ms.iter().filter_map(|ti| { + if let ast::MethodTraitItem(_, Some(_)) = ti.node { + match self.impl_or_trait_item(ast_util::local_def(ti.id)) { + MethodTraitItem(m) => Some(m), + _ => { + self.sess.bug("provided_trait_methods(): \ + non-method item found from \ + looking up provided method?!") + } + } + } else { + None + } + }).collect() + } else { + self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id)) + } + } else { + csearch::get_provided_trait_methods(self, id) + } + } + + pub fn associated_consts(&self, id: ast::DefId) -> Vec>> { + if is_local(id) { + match self.map.expect_item(id.node).node { + ItemTrait(_, _, _, ref tis) => { + tis.iter().filter_map(|ti| { + if let ast::ConstTraitItem(_, _) = ti.node { + match self.impl_or_trait_item(ast_util::local_def(ti.id)) { + ConstTraitItem(ac) => Some(ac), + _ => { + self.sess.bug("associated_consts(): \ + non-const item found from \ + looking up a constant?!") + } + } + } else { + None + } + }).collect() + } + ItemImpl(_, _, _, _, _, ref iis) => { + iis.iter().filter_map(|ii| { + if let ast::ConstImplItem(_, _) = ii.node { + match self.impl_or_trait_item(ast_util::local_def(ii.id)) { + ConstTraitItem(ac) => Some(ac), + _ => { + self.sess.bug("associated_consts(): \ + non-const item found from \ + looking up a constant?!") + } + } + } else { + None + } + }).collect() + } + _ => { + self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \ + or impl", id)) + } + } + } else { + csearch::get_associated_consts(self, id) } } - fn u64_to_disr(&self, val: u64) -> Option { - match *self { - SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr), - SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr), - SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr), - SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr), - UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr), - UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr), - UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr), - UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr), + pub fn trait_item(&self, trait_did: ast::DefId, idx: usize) -> ImplOrTraitItem<'tcx> { + let method_def_id = self.trait_item_def_ids(trait_did)[idx].def_id(); + self.impl_or_trait_item(method_def_id) + } - UnsignedInt(ast::TyUs) | - SignedInt(ast::TyIs) => unreachable!(), + pub fn trait_items(&self, trait_did: ast::DefId) -> Rc>> { + let mut trait_items = self.trait_items_cache.borrow_mut(); + match trait_items.get(&trait_did).cloned() { + Some(trait_items) => trait_items, + None => { + let def_ids = self.trait_item_def_ids(trait_did); + let items: Rc> = + Rc::new(def_ids.iter() + .map(|d| self.impl_or_trait_item(d.def_id())) + .collect()); + trait_items.insert(trait_did, items.clone()); + items + } } } - fn disr_incr(&self, val: Disr) -> Option { - macro_rules! add1 { - ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) } + pub fn trait_impl_polarity(&self, id: ast::DefId) -> Option { + if id.krate == ast::LOCAL_CRATE { + match self.map.find(id.node) { + Some(ast_map::NodeItem(item)) => { + match item.node { + ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity), + _ => None + } + } + _ => None + } + } else { + csearch::get_impl_polarity(self, id) } - match *self { - // SignedInt repr means we *want* to reinterpret the bits - // treating the highest bit of Disr as a sign-bit, so - // cast to i64 before range-checking. - SignedInt(ast::TyI8) => add1!((val as i64).to_i8()), - SignedInt(ast::TyI16) => add1!((val as i64).to_i16()), - SignedInt(ast::TyI32) => add1!((val as i64).to_i32()), - SignedInt(ast::TyI64) => add1!(Some(val as i64)), + } - UnsignedInt(ast::TyU8) => add1!(val.to_u8()), - UnsignedInt(ast::TyU16) => add1!(val.to_u16()), - UnsignedInt(ast::TyU32) => add1!(val.to_u32()), - UnsignedInt(ast::TyU64) => add1!(Some(val)), + pub fn custom_coerce_unsized_kind(&self, did: ast::DefId) -> CustomCoerceUnsized { + memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| { + let (kind, src) = if did.krate != ast::LOCAL_CRATE { + (csearch::get_custom_coerce_unsized_kind(self, did), "external") + } else { + (None, "local") + }; - UnsignedInt(ast::TyUs) | - SignedInt(ast::TyIs) => unreachable!(), + match kind { + Some(kind) => kind, + None => { + self.sess.bug(&format!("custom_coerce_unsized_kind: \ + {} impl `{}` is missing its kind", + src, self.item_path_str(did))); + } + } + }) + } + + pub fn impl_or_trait_item(&self, id: ast::DefId) -> ImplOrTraitItem<'tcx> { + lookup_locally_or_in_crate_store( + "impl_or_trait_items", id, &self.impl_or_trait_items, + || csearch::get_impl_or_trait_item(self, id)) + } + + pub fn trait_item_def_ids(&self, id: ast::DefId) -> Rc> { + lookup_locally_or_in_crate_store( + "trait_item_def_ids", id, &self.trait_item_def_ids, + || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id))) + } + + /// Returns the trait-ref corresponding to a given impl, or None if it is + /// an inherent impl. + pub fn impl_trait_ref(&self, id: ast::DefId) -> Option> { + lookup_locally_or_in_crate_store( + "impl_trait_refs", id, &self.impl_trait_refs, + || csearch::get_impl_trait(self, id)) + } + + /// Returns whether this DefId refers to an impl + pub fn is_impl(&self, id: ast::DefId) -> bool { + if id.krate == ast::LOCAL_CRATE { + if let Some(ast_map::NodeItem( + &ast::Item { node: ast::ItemImpl(..), .. })) = self.map.find(id.node) { + true + } else { + false + } + } else { + csearch::is_impl(&self.sess.cstore, id) } } - // This returns a String because (1.) it is only used for - // rendering an error message and (2.) a string can represent the - // full range from `i64::MIN` through `u64::MAX`. - fn disr_string(&self, val: Disr) -> String { - match *self { - SignedInt(ast::TyI8) => format!("{}", val as i8 ), - SignedInt(ast::TyI16) => format!("{}", val as i16), - SignedInt(ast::TyI32) => format!("{}", val as i32), - SignedInt(ast::TyI64) => format!("{}", val as i64), - UnsignedInt(ast::TyU8) => format!("{}", val as u8 ), - UnsignedInt(ast::TyU16) => format!("{}", val as u16), - UnsignedInt(ast::TyU32) => format!("{}", val as u32), - UnsignedInt(ast::TyU64) => format!("{}", val as u64), + pub fn trait_ref_to_def_id(&self, tr: &ast::TraitRef) -> ast::DefId { + self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id() + } - UnsignedInt(ast::TyUs) | - SignedInt(ast::TyIs) => unreachable!(), + pub fn try_add_builtin_trait(&self, + trait_def_id: ast::DefId, + builtin_bounds: &mut EnumSet) + -> bool + { + //! Checks whether `trait_ref` refers to one of the builtin + //! traits, like `Send`, and adds the corresponding + //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref` + //! is a builtin trait. + + match self.lang_items.to_builtin_kind(trait_def_id) { + Some(bound) => { builtin_bounds.insert(bound); true } + None => false } } - fn disr_wrap_incr(&self, val: Option) -> Disr { - macro_rules! add1 { - ($e:expr) => { ($e).wrapping_add(1) as Disr } + pub fn substd_enum_variants(&self, + id: ast::DefId, + substs: &Substs<'tcx>) + -> Vec>> { + self.enum_variants(id).iter().map(|variant_info| { + let substd_args = variant_info.args.iter() + .map(|aty| aty.subst(self, substs)).collect::>(); + + let substd_ctor_ty = variant_info.ctor_ty.subst(self, substs); + + Rc::new(VariantInfo { + args: substd_args, + ctor_ty: substd_ctor_ty, + ..(**variant_info).clone() + }) + }).collect() + } + + pub fn item_path_str(&self, id: ast::DefId) -> String { + self.with_path(id, |path| ast_map::path_to_string(path)) + } + + /* If struct_id names a struct with a dtor. */ + pub fn ty_dtor(&self, struct_id: DefId) -> DtorKind { + match self.destructor_for_type.borrow().get(&struct_id) { + Some(&method_def_id) => { + let flag = !self.has_attr(struct_id, "unsafe_no_drop_flag"); + + TraitDtor(method_def_id, flag) + } + None => NoDtor, } - let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE); - match *self { - SignedInt(ast::TyI8) => add1!(val as i8 ), - SignedInt(ast::TyI16) => add1!(val as i16), - SignedInt(ast::TyI32) => add1!(val as i32), - SignedInt(ast::TyI64) => add1!(val as i64), - UnsignedInt(ast::TyU8) => add1!(val as u8 ), - UnsignedInt(ast::TyU16) => add1!(val as u16), - UnsignedInt(ast::TyU32) => add1!(val as u32), - UnsignedInt(ast::TyU64) => add1!(val as u64), + } - UnsignedInt(ast::TyUs) | - SignedInt(ast::TyIs) => unreachable!(), + pub fn has_dtor(&self, struct_id: DefId) -> bool { + self.destructor_for_type.borrow().contains_key(&struct_id) + } + + pub fn with_path(&self, id: ast::DefId, f: F) -> T where + F: FnOnce(ast_map::PathElems) -> T, + { + if id.krate == ast::LOCAL_CRATE { + self.map.with_path(id.node, f) + } else { + f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty())) } } -} -/// Returns `(normalized_type, ty)`, where `normalized_type` is the -/// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8}, -/// and `ty` is the original type (i.e. may include `isize` or -/// `usize`). -pub fn enum_repr_type<'tcx>(cx: &ctxt<'tcx>, - opt_hint: Option<&attr::ReprAttr>) - -> (attr::IntType, Ty<'tcx>) -{ - let repr_type = match opt_hint { - // Feed in the given type - Some(&attr::ReprInt(_, int_t)) => int_t, - // ... but provide sensible default if none provided - // - // NB. Historically `fn enum_variants` generate i64 here, while - // rustc_typeck::check would generate isize. - _ => SignedInt(ast::TyIs), - }; - - let repr_type_ty = repr_type.to_ty(cx); - let repr_type = match repr_type { - SignedInt(ast::TyIs) => - SignedInt(cx.sess.target.int_type), - UnsignedInt(ast::TyUs) => - UnsignedInt(cx.sess.target.uint_type), - other => other - }; - - (repr_type, repr_type_ty) -} - -fn report_discrim_overflow(cx: &ctxt, - variant_span: Span, - variant_name: &str, - repr_type: attr::IntType, - prev_val: Disr) { - let computed_value = repr_type.disr_wrap_incr(Some(prev_val)); - let computed_value = repr_type.disr_string(computed_value); - let prev_val = repr_type.disr_string(prev_val); - let repr_type = repr_type.to_ty(cx); - span_err!(cx.sess, variant_span, E0370, - "enum discriminant overflowed on value after {}: {}; \ - set explicitly via {} = {} if that is desired outcome", - prev_val, repr_type, variant_name, computed_value); -} - -// This computes the discriminant values for the sequence of Variants -// attached to a particular enum, taking into account the #[repr] (if -// any) provided via the `opt_hint`. -fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>, - vs: &'tcx [P], - opt_hint: Option<&attr::ReprAttr>) - -> Vec>> { - let mut variants: Vec> = Vec::new(); - let mut prev_disr_val: Option = None; - - let (repr_type, repr_type_ty) = ty::enum_repr_type(cx, opt_hint); - - for v in vs { - // If the discriminant value is specified explicitly in the - // enum, check whether the initialization expression is valid, - // otherwise use the last value plus one. - let current_disr_val; - - // This closure marks cases where, when an error occurs during - // the computation, attempt to assign a (hopefully) fresh - // value to avoid spurious error reports downstream. - let attempt_fresh_value = move || -> Disr { - repr_type.disr_wrap_incr(prev_disr_val) + pub fn enum_is_univariant(&self, id: ast::DefId) -> bool { + self.enum_variants(id).len() == 1 + } + + /// Returns `(normalized_type, ty)`, where `normalized_type` is the + /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8}, + /// and `ty` is the original type (i.e. may include `isize` or + /// `usize`). + pub fn enum_repr_type(&self, opt_hint: Option<&attr::ReprAttr>) + -> (attr::IntType, Ty<'tcx>) { + let repr_type = match opt_hint { + // Feed in the given type + Some(&attr::ReprInt(_, int_t)) => int_t, + // ... but provide sensible default if none provided + // + // NB. Historically `fn enum_variants` generate i64 here, while + // rustc_typeck::check would generate isize. + _ => SignedInt(ast::TyIs), }; - match v.node.disr_expr { - Some(ref e) => { - debug!("disr expr, checking {}", pprust::expr_to_string(&**e)); - - // check_expr (from check_const pass) doesn't guarantee - // that the expression is in a form that eval_const_expr can - // handle, so we may still get an internal compiler error - // - // pnkfelix: The above comment was transcribed from - // the version of this code taken from rustc_typeck. - // Presumably the implication is that we need to deal - // with such ICE's as they arise. - // - // Since this can be called from `ty::enum_variants` - // anyway, best thing is to make `eval_const_expr` - // more robust (on case-by-case basis). - - match const_eval::eval_const_expr_partial(cx, &**e, Some(repr_type_ty)) { - Ok(ConstVal::Int(val)) => current_disr_val = val as Disr, - Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr, - Ok(_) => { - let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" }; - span_err!(cx.sess, e.span, E0079, - "expected {} integer constant", - sign_desc); - current_disr_val = attempt_fresh_value(); - } - Err(ref err) => { - span_err!(cx.sess, err.span, E0080, - "constant evaluation error: {}", - err.description()); - current_disr_val = attempt_fresh_value(); + let repr_type_ty = repr_type.to_ty(self); + let repr_type = match repr_type { + SignedInt(ast::TyIs) => + SignedInt(self.sess.target.int_type), + UnsignedInt(ast::TyUs) => + UnsignedInt(self.sess.target.uint_type), + other => other + }; + + (repr_type, repr_type_ty) + } + + fn report_discrim_overflow(&self, + variant_span: Span, + variant_name: &str, + repr_type: attr::IntType, + prev_val: Disr) { + let computed_value = repr_type.disr_wrap_incr(Some(prev_val)); + let computed_value = repr_type.disr_string(computed_value); + let prev_val = repr_type.disr_string(prev_val); + let repr_type = repr_type.to_ty(self); + span_err!(self.sess, variant_span, E0370, + "enum discriminant overflowed on value after {}: {}; \ + set explicitly via {} = {} if that is desired outcome", + prev_val, repr_type, variant_name, computed_value); + } + + // This computes the discriminant values for the sequence of Variants + // attached to a particular enum, taking into account the #[repr] (if + // any) provided via the `opt_hint`. + fn compute_enum_variants(&self, + vs: &'tcx [P], + opt_hint: Option<&attr::ReprAttr>) + -> Vec>> { + let mut variants: Vec> = Vec::new(); + let mut prev_disr_val: Option = None; + + let (repr_type, repr_type_ty) = self.enum_repr_type(opt_hint); + + for v in vs { + // If the discriminant value is specified explicitly in the + // enum, check whether the initialization expression is valid, + // otherwise use the last value plus one. + let current_disr_val; + + // This closure marks cases where, when an error occurs during + // the computation, attempt to assign a (hopefully) fresh + // value to avoid spurious error reports downstream. + let attempt_fresh_value = move || -> Disr { + repr_type.disr_wrap_incr(prev_disr_val) + }; + + match v.node.disr_expr { + Some(ref e) => { + debug!("disr expr, checking {}", pprust::expr_to_string(&**e)); + + // check_expr (from check_const pass) doesn't guarantee + // that the expression is in a form that eval_const_expr can + // handle, so we may still get an internal compiler error + // + // pnkfelix: The above comment was transcribed from + // the version of this code taken from rustc_typeck. + // Presumably the implication is that we need to deal + // with such ICE's as they arise. + // + // Since this can be called from `ty::enum_variants` + // anyway, best thing is to make `eval_const_expr` + // more robust (on case-by-case basis). + + match const_eval::eval_const_expr_partial(self, &**e, Some(repr_type_ty)) { + Ok(ConstVal::Int(val)) => current_disr_val = val as Disr, + Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr, + Ok(_) => { + let sign_desc = if repr_type.is_signed() { + "signed" + } else { + "unsigned" + }; + span_err!(self.sess, e.span, E0079, + "expected {} integer constant", + sign_desc); + current_disr_val = attempt_fresh_value(); + } + Err(ref err) => { + span_err!(self.sess, err.span, E0080, + "constant evaluation error: {}", + err.description()); + current_disr_val = attempt_fresh_value(); + } } - } - }, - None => { - current_disr_val = match prev_disr_val { - Some(prev_disr_val) => { - if let Some(v) = repr_type.disr_incr(prev_disr_val) { - v - } else { - report_discrim_overflow(cx, v.span, v.node.name.as_str(), - repr_type, prev_disr_val); - attempt_fresh_value() + }, + None => { + current_disr_val = match prev_disr_val { + Some(prev_disr_val) => { + if let Some(v) = repr_type.disr_incr(prev_disr_val) { + v + } else { + self.report_discrim_overflow(v.span, v.node.name.as_str(), + repr_type, prev_disr_val); + attempt_fresh_value() + } } + None => ty::INITIAL_DISCRIMINANT_VALUE } - None => ty::INITIAL_DISCRIMINANT_VALUE } } - } - let variant_info = Rc::new(VariantInfo::from_ast_variant(cx, &**v, current_disr_val)); - prev_disr_val = Some(current_disr_val); + let variant_info = Rc::new(VariantInfo::from_ast_variant(self, &**v, current_disr_val)); + prev_disr_val = Some(current_disr_val); - variants.push(variant_info); - } + variants.push(variant_info); + } - return variants; -} + variants + } -pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) - -> Rc>>> { - memoized(&cx.enum_var_cache, id, |id: ast::DefId| { - if ast::LOCAL_CRATE != id.krate { - Rc::new(csearch::get_enum_variants(cx, id)) - } else { - match cx.map.get(id.node) { - ast_map::NodeItem(ref item) => { - match item.node { - ast::ItemEnum(ref enum_definition, _) => { - Rc::new(compute_enum_variants( - cx, - &enum_definition.variants, - lookup_repr_hints(cx, id).get(0))) - } - _ => { - cx.sess.bug("enum_variants: id not bound to an enum") + pub fn enum_variants(&self, id: ast::DefId) -> Rc>>> { + memoized(&self.enum_var_cache, id, |id: ast::DefId| { + if ast::LOCAL_CRATE != id.krate { + Rc::new(csearch::get_enum_variants(self, id)) + } else { + match self.map.get(id.node) { + ast_map::NodeItem(ref item) => { + match item.node { + ast::ItemEnum(ref enum_definition, _) => { + Rc::new(self.compute_enum_variants( + &enum_definition.variants, + self.lookup_repr_hints(id).get(0))) + } + _ => { + self.sess.bug("enum_variants: id not bound to an enum") + } } } + _ => self.sess.bug("enum_variants: id not bound to an enum") } - _ => cx.sess.bug("enum_variants: id not bound to an enum") } - } - }) -} + }) + } -// Returns information about the enum variant with the given ID: -pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>, - enum_id: ast::DefId, - variant_id: ast::DefId) - -> Rc> { - enum_variants(cx, enum_id).iter() - .find(|variant| variant.id == variant_id) - .expect("enum_variant_with_id(): no variant exists with that ID") - .clone() -} + // Returns information about the enum variant with the given ID: + pub fn enum_variant_with_id(&self, + enum_id: ast::DefId, + variant_id: ast::DefId) + -> Rc> { + self.enum_variants(enum_id).iter() + .find(|variant| variant.id == variant_id) + .expect("enum_variant_with_id(): no variant exists with that ID") + .clone() + } -// If the given item is in an external crate, looks up its type and adds it to -// the type cache. Returns the type parameters and type. -pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>, - did: ast::DefId) - -> TypeScheme<'tcx> { - lookup_locally_or_in_crate_store( - "tcache", did, &cx.tcache, - || csearch::get_type(cx, did)) -} + // If the given item is in an external crate, looks up its type and adds it to + // the type cache. Returns the type parameters and type. + pub fn lookup_item_type(&self, did: ast::DefId) -> TypeScheme<'tcx> { + lookup_locally_or_in_crate_store( + "tcache", did, &self.tcache, + || csearch::get_type(self, did)) + } -/// Given the did of a trait, returns its canonical trait ref. -pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) - -> &'tcx TraitDef<'tcx> { - lookup_locally_or_in_crate_store( - "trait_defs", did, &cx.trait_defs, - || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did)) - ) -} + /// Given the did of a trait, returns its canonical trait ref. + pub fn lookup_trait_def(&self, did: ast::DefId) -> &'tcx TraitDef<'tcx> { + lookup_locally_or_in_crate_store( + "trait_defs", did, &self.trait_defs, + || self.arenas.trait_defs.alloc(csearch::get_trait_def(self, did)) + ) + } -/// Given the did of an item, returns its full set of predicates. -pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) - -> GenericPredicates<'tcx> -{ - lookup_locally_or_in_crate_store( - "predicates", did, &cx.predicates, - || csearch::get_predicates(cx, did)) -} + /// Given the did of an item, returns its full set of predicates. + pub fn lookup_predicates(&self, did: ast::DefId) -> GenericPredicates<'tcx> { + lookup_locally_or_in_crate_store( + "predicates", did, &self.predicates, + || csearch::get_predicates(self, did)) + } -/// Given the did of a trait, returns its superpredicates. -pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) - -> GenericPredicates<'tcx> -{ - lookup_locally_or_in_crate_store( - "super_predicates", did, &cx.super_predicates, - || csearch::get_super_predicates(cx, did)) -} + /// Given the did of a trait, returns its superpredicates. + pub fn lookup_super_predicates(&self, did: ast::DefId) -> GenericPredicates<'tcx> { + lookup_locally_or_in_crate_store( + "super_predicates", did, &self.super_predicates, + || csearch::get_super_predicates(self, did)) + } -/// Get the attributes of a definition. -pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId) - -> Cow<'tcx, [ast::Attribute]> { - if is_local(did) { - Cow::Borrowed(tcx.map.attrs(did.node)) - } else { - Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did)) + /// Get the attributes of a definition. + pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [ast::Attribute]> { + if is_local(did) { + Cow::Borrowed(self.map.attrs(did.node)) + } else { + Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did)) + } } -} -/// Determine whether an item is annotated with an attribute -pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool { - get_attrs(tcx, did).iter().any(|item| item.check_name(attr)) -} + /// Determine whether an item is annotated with an attribute + pub fn has_attr(&self, did: DefId, attr: &str) -> bool { + self.get_attrs(did).iter().any(|item| item.check_name(attr)) + } -/// Determine whether an item is annotated with `#[repr(packed)]` -pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool { - lookup_repr_hints(tcx, did).contains(&attr::ReprPacked) -} + /// Determine whether an item is annotated with `#[repr(packed)]` + pub fn lookup_packed(&self, did: DefId) -> bool { + self.lookup_repr_hints(did).contains(&attr::ReprPacked) + } -/// Determine whether an item is annotated with `#[simd]` -pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool { - has_attr(tcx, did, "simd") -} + /// Determine whether an item is annotated with `#[simd]` + pub fn lookup_simd(&self, did: DefId) -> bool { + self.has_attr(did, "simd") + } -/// Obtain the representation annotation for a struct definition. -pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc> { - memoized(&tcx.repr_hint_cache, did, |did: DefId| { - Rc::new(if did.krate == LOCAL_CRATE { - get_attrs(tcx, did).iter().flat_map(|meta| { - attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter() - }).collect() - } else { - csearch::get_repr_attrs(&tcx.sess.cstore, did) + /// Obtain the representation annotation for a struct definition. + pub fn lookup_repr_hints(&self, did: DefId) -> Rc> { + memoized(&self.repr_hint_cache, did, |did: DefId| { + Rc::new(if did.krate == LOCAL_CRATE { + self.get_attrs(did).iter().flat_map(|meta| { + attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter() + }).collect() + } else { + csearch::get_repr_attrs(&self.sess.cstore, did) + }) }) - }) -} + } -// Look up a field ID, whether or not it's local -pub fn lookup_field_type_unsubstituted<'tcx>(tcx: &ctxt<'tcx>, - struct_id: DefId, - id: DefId) - -> Ty<'tcx> { - if id.krate == ast::LOCAL_CRATE { - node_id_to_type(tcx, id.node) - } else { - let mut tcache = tcx.tcache.borrow_mut(); - tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty + // Look up a field ID, whether or not it's local + pub fn lookup_field_type_unsubstituted(&self, + struct_id: DefId, + id: DefId) + -> Ty<'tcx> { + if id.krate == ast::LOCAL_CRATE { + self.node_id_to_type(id.node) + } else { + let mut tcache = self.tcache.borrow_mut(); + tcache.entry(id).or_insert_with(|| csearch::get_field_type(self, struct_id, id)).ty + } } -} -// Look up a field ID, whether or not it's local -// Takes a list of type substs in case the struct is generic -pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>, - struct_id: DefId, - id: DefId, - substs: &Substs<'tcx>) - -> Ty<'tcx> { - lookup_field_type_unsubstituted(tcx, struct_id, id).subst(tcx, substs) -} + // Look up a field ID, whether or not it's local + // Takes a list of type substs in case the struct is generic + pub fn lookup_field_type(&self, + struct_id: DefId, + id: DefId, + substs: &Substs<'tcx>) + -> Ty<'tcx> { + self.lookup_field_type_unsubstituted(struct_id, id).subst(self, substs) + } -// Look up the list of field names and IDs for a given struct. -// Panics if the id is not bound to a struct. -pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec { - if did.krate == ast::LOCAL_CRATE { - let struct_fields = cx.struct_fields.borrow(); - match struct_fields.get(&did) { - Some(fields) => (**fields).clone(), - _ => { - cx.sess.bug( - &format!("ID not mapped to struct fields: {}", - cx.map.node_to_string(did.node))); + // Look up the list of field names and IDs for a given struct. + // Panics if the id is not bound to a struct. + pub fn lookup_struct_fields(&self, did: ast::DefId) -> Vec { + if did.krate == ast::LOCAL_CRATE { + let struct_fields = self.struct_fields.borrow(); + match struct_fields.get(&did) { + Some(fields) => (**fields).clone(), + _ => { + self.sess.bug( + &format!("ID not mapped to struct fields: {}", + self.map.node_to_string(did.node))); + } } + } else { + csearch::get_struct_fields(&self.sess.cstore, did) } - } else { - csearch::get_struct_fields(&cx.sess.cstore, did) } -} -pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool { - let fields = lookup_struct_fields(cx, did); - !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field) -} + pub fn is_tuple_struct(&self, did: ast::DefId) -> bool { + let fields = self.lookup_struct_fields(did); + !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field) + } -// Returns a list of fields corresponding to the struct's items. trans uses -// this. Takes a list of substs with which to instantiate field types. -pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tcx>) - -> Vec> { - lookup_struct_fields(cx, did).iter().map(|f| { - field { - name: f.name, - mt: mt { - ty: lookup_field_type(cx, did, f.id, substs), - mutbl: MutImmutable + // Returns a list of fields corresponding to the struct's items. trans uses + // this. Takes a list of substs with which to instantiate field types. + pub fn struct_fields(&self, did: ast::DefId, substs: &Substs<'tcx>) + -> Vec> { + self.lookup_struct_fields(did).iter().map(|f| { + field { + name: f.name, + mt: mt { + ty: self.lookup_field_type(did, f.id, substs), + mutbl: MutImmutable + } } - } - }).collect() -} + }).collect() + } -// Returns a list of fields corresponding to the tuple's items. trans uses -// this. -pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec> { - v.iter().enumerate().map(|(i, &f)| { - field { - name: token::intern(&i.to_string()), - mt: mt { - ty: f, - mutbl: MutImmutable + /// Returns the deeply last field of nested structures, or the same type, + /// if not a structure at all. Corresponds to the only possible unsized + /// field, and its type can be used to determine unsizing strategy. + pub fn struct_tail(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + while let TyStruct(def_id, substs) = ty.sty { + match self.struct_fields(def_id, substs).last() { + Some(f) => ty = f.mt.ty, + None => break } } - }).collect() -} - -/// Returns the deeply last field of nested structures, or the same type, -/// if not a structure at all. Corresponds to the only possible unsized -/// field, and its type can be used to determine unsizing strategy. -pub fn struct_tail<'tcx>(cx: &ctxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> { - while let TyStruct(def_id, substs) = ty.sty { - match struct_fields(cx, def_id, substs).last() { - Some(f) => ty = f.mt.ty, - None => break - } + ty } - ty -} -/// Same as applying struct_tail on `source` and `target`, but only -/// keeps going as long as the two types are instances of the same -/// structure definitions. -/// For `(Foo>, Foo)`, the result will be `(Foo, Trait)`, -/// whereas struct_tail produces `T`, and `Trait`, respectively. -pub fn struct_lockstep_tails<'tcx>(cx: &ctxt<'tcx>, - source: Ty<'tcx>, - target: Ty<'tcx>) - -> (Ty<'tcx>, Ty<'tcx>) { - let (mut a, mut b) = (source, target); - while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) { - if a_did != b_did { - continue; - } - if let Some(a_f) = struct_fields(cx, a_did, a_substs).last() { - if let Some(b_f) = struct_fields(cx, b_did, b_substs).last() { - a = a_f.mt.ty; - b = b_f.mt.ty; + /// Same as applying struct_tail on `source` and `target`, but only + /// keeps going as long as the two types are instances of the same + /// structure definitions. + /// For `(Foo>, Foo)`, the result will be `(Foo, Trait)`, + /// whereas struct_tail produces `T`, and `Trait`, respectively. + pub fn struct_lockstep_tails(&self, + source: Ty<'tcx>, + target: Ty<'tcx>) + -> (Ty<'tcx>, Ty<'tcx>) { + let (mut a, mut b) = (source, target); + while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) { + if a_did != b_did { + break; + } + if let Some(a_f) = self.struct_fields(a_did, a_substs).last() { + if let Some(b_f) = self.struct_fields(b_did, b_substs).last() { + a = a_f.mt.ty; + b = b_f.mt.ty; + } else { + break; + } } else { break; } - } else { - break; } + (a, b) } - (a, b) -} -#[derive(Copy, Clone)] -pub struct ClosureUpvar<'tcx> { - pub def: def::Def, - pub span: Span, - pub ty: Ty<'tcx>, -} + // Returns a list of `ClosureUpvar`s for each upvar. + pub fn closure_upvars(typer: &Typer<'tcx>, + closure_id: ast::DefId, + substs: &Substs<'tcx>) + -> Option>> + { + // Presently an unboxed closure type cannot "escape" out of a + // function, so we will only encounter ones that originated in the + // local crate or were inlined into it along with some function. + // This may change if abstract return types of some sort are + // implemented. + assert!(closure_id.krate == ast::LOCAL_CRATE); + let tcx = typer.tcx(); + match tcx.freevars.borrow().get(&closure_id.node) { + None => Some(vec![]), + Some(ref freevars) => { + freevars.iter() + .map(|freevar| { + let freevar_def_id = freevar.def.def_id(); + let freevar_ty = match typer.node_ty(freevar_def_id.node) { + Ok(t) => { t } + Err(()) => { return None; } + }; + let freevar_ty = freevar_ty.subst(tcx, substs); -// Returns a list of `ClosureUpvar`s for each upvar. -pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>, - closure_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> -{ - // Presently an unboxed closure type cannot "escape" out of a - // function, so we will only encounter ones that originated in the - // local crate or were inlined into it along with some function. - // This may change if abstract return types of some sort are - // implemented. - assert!(closure_id.krate == ast::LOCAL_CRATE); - let tcx = typer.tcx(); - match tcx.freevars.borrow().get(&closure_id.node) { - None => Some(vec![]), - Some(ref freevars) => { - freevars.iter() - .map(|freevar| { - let freevar_def_id = freevar.def.def_id(); - let freevar_ty = match typer.node_ty(freevar_def_id.node) { - Ok(t) => { t } - Err(()) => { return None; } - }; - let freevar_ty = freevar_ty.subst(tcx, substs); - - let upvar_id = ty::UpvarId { - var_id: freevar_def_id.node, - closure_expr_id: closure_id.node - }; - - typer.upvar_capture(upvar_id).map(|capture| { - let freevar_ref_ty = match capture { - UpvarCapture::ByValue => { - freevar_ty - } - UpvarCapture::ByRef(borrow) => { - tcx.mk_ref(tcx.mk_region(borrow.region), - ty::mt { - ty: freevar_ty, - mutbl: borrow.kind.to_mutbl_lossy(), - }) - } + let upvar_id = ty::UpvarId { + var_id: freevar_def_id.node, + closure_expr_id: closure_id.node }; - ClosureUpvar { - def: freevar.def, - span: freevar.span, - ty: freevar_ref_ty, - } + typer.upvar_capture(upvar_id).map(|capture| { + let freevar_ref_ty = match capture { + UpvarCapture::ByValue => { + freevar_ty + } + UpvarCapture::ByRef(borrow) => { + tcx.mk_ref(tcx.mk_region(borrow.region), + ty::mt { + ty: freevar_ty, + mutbl: borrow.kind.to_mutbl_lossy(), + }) + } + }; + + ClosureUpvar { + def: freevar.def, + span: freevar.span, + ty: freevar_ref_ty, + } + }) }) - }) - .collect() - } - } -} - -// Returns the repeat count for a repeating vector expression. -pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize { - match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) { - Ok(val) => { - let found = match val { - ConstVal::Uint(count) => return count as usize, - ConstVal::Int(count) if count >= 0 => return count as usize, - ConstVal::Int(_) => "negative integer", - ConstVal::Float(_) => "float", - ConstVal::Str(_) => "string", - ConstVal::Bool(_) => "boolean", - ConstVal::Binary(_) => "binary array", - ConstVal::Struct(..) => "struct", - ConstVal::Tuple(_) => "tuple" - }; - span_err!(tcx.sess, count_expr.span, E0306, - "expected positive integer for repeat count, found {}", - found); - } - Err(err) => { - let err_description = err.description(); - let found = match count_expr.node { - ast::ExprPath(None, ast::Path { - global: false, - ref segments, - .. - }) if segments.len() == 1 => - format!("{}", "found variable"), - _ => - format!("but {}", err_description), - }; - span_err!(tcx.sess, count_expr.span, E0307, - "expected constant integer for repeat count, {}", - found); + .collect() + } } } - 0 -} -// Iterate over a type parameter's bounded traits and any supertraits -// of those traits, ignoring kinds. -// Here, the supertraits are the transitive closure of the supertrait -// relation on the supertraits from each bounded trait's constraint -// list. -pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>, - bounds: &[PolyTraitRef<'tcx>], - mut f: F) - -> bool where - F: FnMut(PolyTraitRef<'tcx>) -> bool, -{ - for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { - if !f(bound_trait_ref) { - return false; + // Returns the repeat count for a repeating vector expression. + pub fn eval_repeat_count(&self, count_expr: &ast::Expr) -> usize { + match const_eval::eval_const_expr_partial(self, count_expr, Some(self.types.usize)) { + Ok(val) => { + let found = match val { + ConstVal::Uint(count) => return count as usize, + ConstVal::Int(count) if count >= 0 => return count as usize, + ConstVal::Int(_) => "negative integer", + ConstVal::Float(_) => "float", + ConstVal::Str(_) => "string", + ConstVal::Bool(_) => "boolean", + ConstVal::Binary(_) => "binary array", + ConstVal::Struct(..) => "struct", + ConstVal::Tuple(_) => "tuple" + }; + span_err!(self.sess, count_expr.span, E0306, + "expected positive integer for repeat count, found {}", + found); + } + Err(err) => { + let err_description = err.description(); + let found = match count_expr.node { + ast::ExprPath(None, ast::Path { + global: false, + ref segments, + .. + }) if segments.len() == 1 => + format!("{}", "found variable"), + _ => + format!("but {}", err_description), + }; + span_err!(self.sess, count_expr.span, E0307, + "expected constant integer for repeat count, {}", + found); + } } + 0 } - return true; -} -/// Given a set of predicates that apply to an object type, returns -/// the region bounds that the (erased) `Self` type must -/// outlive. Precisely *because* the `Self` type is erased, the -/// parameter `erased_self_ty` must be supplied to indicate what type -/// has been used to represent `Self` in the predicates -/// themselves. This should really be a unique type; `FreshTy(0)` is a -/// popular choice. -/// -/// Requires that trait definitions have been processed so that we can -/// elaborate predicates and walk supertraits. -pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>, - erased_self_ty: Ty<'tcx>, - predicates: Vec>) - -> Vec -{ - debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})", - erased_self_ty, - predicates); - - assert!(!erased_self_ty.has_escaping_regions()); - - traits::elaborate_predicates(tcx, predicates) - .filter_map(|predicate| { - match predicate { - ty::Predicate::Projection(..) | - ty::Predicate::Trait(..) | - ty::Predicate::Equate(..) | - ty::Predicate::RegionOutlives(..) => { - None - } - ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => { - // Search for a bound of the form `erased_self_ty - // : 'a`, but be wary of something like `for<'a> - // erased_self_ty : 'a` (we interpret a - // higher-ranked bound like that as 'static, - // though at present the code in `fulfill.rs` - // considers such bounds to be unsatisfiable, so - // it's kind of a moot point since you could never - // construct such an object, but this seems - // correct even if that code changes). - if t == erased_self_ty && !r.has_escaping_regions() { - if r.has_escaping_regions() { - Some(ty::ReStatic) + // Iterate over a type parameter's bounded traits and any supertraits + // of those traits, ignoring kinds. + // Here, the supertraits are the transitive closure of the supertrait + // relation on the supertraits from each bounded trait's constraint + // list. + pub fn each_bound_trait_and_supertraits(&self, + bounds: &[PolyTraitRef<'tcx>], + mut f: F) + -> bool where + F: FnMut(PolyTraitRef<'tcx>) -> bool, + { + for bound_trait_ref in traits::transitive_bounds(self, bounds) { + if !f(bound_trait_ref) { + return false; + } + } + return true; + } + + /// Given a set of predicates that apply to an object type, returns + /// the region bounds that the (erased) `Self` type must + /// outlive. Precisely *because* the `Self` type is erased, the + /// parameter `erased_self_ty` must be supplied to indicate what type + /// has been used to represent `Self` in the predicates + /// themselves. This should really be a unique type; `FreshTy(0)` is a + /// popular choice. + /// + /// Requires that trait definitions have been processed so that we can + /// elaborate predicates and walk supertraits. + pub fn required_region_bounds(&self, + erased_self_ty: Ty<'tcx>, + predicates: Vec>) + -> Vec + { + debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})", + erased_self_ty, + predicates); + + assert!(!erased_self_ty.has_escaping_regions()); + + traits::elaborate_predicates(self, predicates) + .filter_map(|predicate| { + match predicate { + ty::Predicate::Projection(..) | + ty::Predicate::Trait(..) | + ty::Predicate::Equate(..) | + ty::Predicate::RegionOutlives(..) => { + None + } + ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => { + // Search for a bound of the form `erased_self_ty + // : 'a`, but be wary of something like `for<'a> + // erased_self_ty : 'a` (we interpret a + // higher-ranked bound like that as 'static, + // though at present the code in `fulfill.rs` + // considers such bounds to be unsatisfiable, so + // it's kind of a moot point since you could never + // construct such an object, but this seems + // correct even if that code changes). + if t == erased_self_ty && !r.has_escaping_regions() { + if r.has_escaping_regions() { + Some(ty::ReStatic) + } else { + Some(r) + } } else { - Some(r) + None } - } else { - None } } - } - }) - .collect() -} - -pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { - lookup_locally_or_in_crate_store( - "item_variance_map", item_id, &tcx.item_variance_map, - || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id))) -} - -pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool { - populate_implementations_for_trait_if_necessary(tcx, trait_def_id); + }) + .collect() + } - let def = lookup_trait_def(tcx, trait_def_id); - def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL) -} + pub fn item_variances(&self, item_id: ast::DefId) -> Rc { + lookup_locally_or_in_crate_store( + "item_variance_map", item_id, &self.item_variance_map, + || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id))) + } -/// Records a trait-to-implementation mapping. -pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) { - let def = lookup_trait_def(tcx, trait_def_id); - def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL) -} + pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool { + self.populate_implementations_for_trait_if_necessary(trait_def_id); -/// Load primitive inherent implementations if necessary -pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt, - primitive_def_id: ast::DefId) { - if primitive_def_id.krate == LOCAL_CRATE { - return + let def = self.lookup_trait_def(trait_def_id); + def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL) } - if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) { - return + /// Records a trait-to-implementation mapping. + pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) { + let def = self.lookup_trait_def(trait_def_id); + def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL) } - debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", - primitive_def_id); + /// Load primitive inherent implementations if necessary + pub fn populate_implementations_for_primitive_if_necessary(&self, + primitive_def_id: ast::DefId) { + if primitive_def_id.krate == LOCAL_CRATE { + return + } - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id); + if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) { + return + } - // Store the implementation info. - tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items); - tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id); -} + debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", + primitive_def_id); -/// Populates the type context with all the inherent implementations for -/// the given type if necessary. -pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt, - type_id: ast::DefId) { - if type_id.krate == LOCAL_CRATE { - return - } + let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id); - if tcx.populated_external_types.borrow().contains(&type_id) { - return + // Store the implementation info. + self.impl_items.borrow_mut().insert(primitive_def_id, impl_items); + self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id); } - debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id); + /// Populates the type context with all the inherent implementations for + /// the given type if necessary. + pub fn populate_inherent_implementations_for_type_if_necessary(&self, + type_id: ast::DefId) { + if type_id.krate == LOCAL_CRATE { + return + } + + if self.populated_external_types.borrow().contains(&type_id) { + return + } - let mut inherent_impls = Vec::new(); - csearch::each_inherent_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| { - // Record the implementation. - inherent_impls.push(impl_def_id); + debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", + type_id); - // Store the implementation info. - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id); - tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items); - }); + let mut inherent_impls = Vec::new(); + csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| { + // Record the implementation. + inherent_impls.push(impl_def_id); - tcx.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls)); - tcx.populated_external_types.borrow_mut().insert(type_id); -} + // Store the implementation info. + let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id); + self.impl_items.borrow_mut().insert(impl_def_id, impl_items); + }); -/// Populates the type context with all the implementations for the given -/// trait if necessary. -pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) { - if trait_id.krate == LOCAL_CRATE { - return + self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls)); + self.populated_external_types.borrow_mut().insert(type_id); } - let def = lookup_trait_def(tcx, trait_id); - if def.flags.get().intersects(TraitFlags::IMPLS_VALID) { - return; - } + /// Populates the type context with all the implementations for the given + /// trait if necessary. + pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: ast::DefId) { + if trait_id.krate == LOCAL_CRATE { + return + } - debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def); + let def = self.lookup_trait_def(trait_id); + if def.flags.get().intersects(TraitFlags::IMPLS_VALID) { + return; + } - if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) { - record_trait_has_default_impl(tcx, trait_id); - } + debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def); - csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| { - let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id); - let trait_ref = impl_trait_ref(tcx, implementation_def_id).unwrap(); - // Record the trait->implementation mapping. - def.record_impl(tcx, implementation_def_id, trait_ref); + if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) { + self.record_trait_has_default_impl(trait_id); + } + + csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| { + let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id); + let trait_ref = self.impl_trait_ref(impl_def_id).unwrap(); + // Record the trait->implementation mapping. + def.record_impl(self, impl_def_id, trait_ref); - // For any methods that use a default implementation, add them to - // the map. This is a bit unfortunate. - for impl_item_def_id in &impl_items { - let method_def_id = impl_item_def_id.def_id(); - match impl_or_trait_item(tcx, method_def_id) { - MethodTraitItem(method) => { - if let Some(source) = method.provided_source { - tcx.provided_method_sources - .borrow_mut() - .insert(method_def_id, source); + // For any methods that use a default implementation, add them to + // the map. This is a bit unfortunate. + for impl_item_def_id in &impl_items { + let method_def_id = impl_item_def_id.def_id(); + match self.impl_or_trait_item(method_def_id) { + MethodTraitItem(method) => { + if let Some(source) = method.provided_source { + self.provided_method_sources + .borrow_mut() + .insert(method_def_id, source); + } } + _ => {} } - _ => {} } - } - - // Store the implementation info. - tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items); - }); - def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID); -} + // Store the implementation info. + self.impl_items.borrow_mut().insert(impl_def_id, impl_items); + }); -/// Given the def_id of an impl, return the def_id of the trait it implements. -/// If it implements no trait, return `None`. -pub fn trait_id_of_impl(tcx: &ctxt, - def_id: ast::DefId) - -> Option { - ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id) -} + def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID); + } -/// If the given def ID describes a method belonging to an impl, return the -/// ID of the impl that the method belongs to. Otherwise, return `None`. -pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId) - -> Option { - if def_id.krate != LOCAL_CRATE { - return match csearch::get_impl_or_trait_item(tcx, - def_id).container() { - TraitContainer(_) => None, - ImplContainer(def_id) => Some(def_id), - }; + /// Given the def_id of an impl, return the def_id of the trait it implements. + /// If it implements no trait, return `None`. + pub fn trait_id_of_impl(&self, def_id: ast::DefId) -> Option { + self.impl_trait_ref(def_id).map(|tr| tr.def_id) } - match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() { - Some(trait_item) => { - match trait_item.container() { + + /// If the given def ID describes a method belonging to an impl, return the + /// ID of the impl that the method belongs to. Otherwise, return `None`. + pub fn impl_of_method(&self, def_id: ast::DefId) -> Option { + if def_id.krate != LOCAL_CRATE { + return match csearch::get_impl_or_trait_item(self, + def_id).container() { TraitContainer(_) => None, ImplContainer(def_id) => Some(def_id), - } + }; } - None => None - } -} - -/// If the given def ID describes an item belonging to a trait (either a -/// default method or an implementation of a trait method), return the ID of -/// the trait that the method belongs to. Otherwise, return `None`. -pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option { - if def_id.krate != LOCAL_CRATE { - return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx); - } - match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() { - Some(impl_or_trait_item) => { - match impl_or_trait_item.container() { - TraitContainer(def_id) => Some(def_id), - ImplContainer(def_id) => trait_id_of_impl(tcx, def_id), + match self.impl_or_trait_items.borrow().get(&def_id).cloned() { + Some(trait_item) => { + match trait_item.container() { + TraitContainer(_) => None, + ImplContainer(def_id) => Some(def_id), + } } + None => None } - None => None } -} -/// If the given def ID describes an item belonging to a trait, (either a -/// default method or an implementation of a trait method), return the ID of -/// the method inside trait definition (this means that if the given def ID -/// is already that of the original trait method, then the return value is -/// the same). -/// Otherwise, return `None`. -pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId) - -> Option { - let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) { - Some(m) => m.clone(), - None => return None, - }; - let name = impl_item.name(); - match trait_of_item(tcx, def_id) { - Some(trait_did) => { - let trait_items = ty::trait_items(tcx, trait_did); - trait_items.iter() - .position(|m| m.name() == name) - .map(|idx| ty::trait_item(tcx, trait_did, idx).id()) + /// If the given def ID describes an item belonging to a trait (either a + /// default method or an implementation of a trait method), return the ID of + /// the trait that the method belongs to. Otherwise, return `None`. + pub fn trait_of_item(&self, def_id: ast::DefId) -> Option { + if def_id.krate != LOCAL_CRATE { + return csearch::get_trait_of_item(&self.sess.cstore, def_id, self); } - None => None - } -} - -/// Creates a hash of the type `Ty` which will be the same no matter what crate -/// context it's calculated within. This is used by the `type_id` intrinsic. -pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 { - let mut state = SipHasher::new(); - helper(tcx, ty, svh, &mut state); - return state.finish(); - - fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh, - state: &mut SipHasher) { - macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } } - macro_rules! hash { ($e:expr) => { $e.hash(state) } } - - let region = |state: &mut SipHasher, r: Region| { - match r { - ReStatic => {} - ReLateBound(db, BrAnon(i)) => { - db.hash(state); - i.hash(state); + match self.impl_or_trait_items.borrow().get(&def_id).cloned() { + Some(impl_or_trait_item) => { + match impl_or_trait_item.container() { + TraitContainer(def_id) => Some(def_id), + ImplContainer(def_id) => self.trait_id_of_impl(def_id), } - ReEmpty | - ReEarlyBound(..) | - ReLateBound(..) | - ReFree(..) | - ReScope(..) | - ReInfer(..) => { - tcx.sess.bug("unexpected region found when hashing a type") - } - } - }; - let did = |state: &mut SipHasher, did: DefId| { - let h = if ast_util::is_local(did) { - svh.clone() - } else { - tcx.sess.cstore.get_crate_hash(did.krate) - }; - h.as_str().hash(state); - did.node.hash(state); - }; - let mt = |state: &mut SipHasher, mt: mt| { - mt.mutbl.hash(state); - }; - let fn_sig = |state: &mut SipHasher, sig: &Binder>| { - let sig = anonymize_late_bound_regions(tcx, sig).0; - for a in &sig.inputs { helper(tcx, *a, svh, state); } - if let ty::FnConverging(output) = sig.output { - helper(tcx, output, svh, state); } + None => None + } + } + + /// If the given def ID describes an item belonging to a trait, (either a + /// default method or an implementation of a trait method), return the ID of + /// the method inside trait definition (this means that if the given def ID + /// is already that of the original trait method, then the return value is + /// the same). + /// Otherwise, return `None`. + pub fn trait_item_of_item(&self, def_id: ast::DefId) -> Option { + let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) { + Some(m) => m.clone(), + None => return None, }; - ty.maybe_walk(|ty| { - match ty.sty { - TyBool => byte!(2), - TyChar => byte!(3), - TyInt(i) => { - byte!(4); - hash!(i); - } - TyUint(u) => { - byte!(5); - hash!(u); - } - TyFloat(f) => { - byte!(6); - hash!(f); - } - TyStr => { - byte!(7); - } - TyEnum(d, _) => { - byte!(8); - did(state, d); - } - TyBox(_) => { - byte!(9); - } - TyArray(_, n) => { - byte!(10); - n.hash(state); - } - TySlice(_) => { - byte!(11); - } - TyRawPtr(m) => { - byte!(12); - mt(state, m); - } - TyRef(r, m) => { - byte!(13); - region(state, *r); - mt(state, m); + let name = impl_item.name(); + match self.trait_of_item(def_id) { + Some(trait_did) => { + let trait_items = self.trait_items(trait_did); + trait_items.iter() + .position(|m| m.name() == name) + .map(|idx| self.trait_item(trait_did, idx).id()) + } + None => None + } + } + + /// Creates a hash of the type `Ty` which will be the same no matter what crate + /// context it's calculated within. This is used by the `type_id` intrinsic. + pub fn hash_crate_independent(&self, ty: Ty<'tcx>, svh: &Svh) -> u64 { + let mut state = SipHasher::new(); + helper(self, ty, svh, &mut state); + return state.finish(); + + fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh, + state: &mut SipHasher) { + macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } } + macro_rules! hash { ($e:expr) => { $e.hash(state) } } + + let region = |state: &mut SipHasher, r: Region| { + match r { + ReStatic => {} + ReLateBound(db, BrAnon(i)) => { + db.hash(state); + i.hash(state); + } + ReEmpty | + ReEarlyBound(..) | + ReLateBound(..) | + ReFree(..) | + ReScope(..) | + ReInfer(..) => { + tcx.sess.bug("unexpected region found when hashing a type") + } } - TyBareFn(opt_def_id, ref b) => { - byte!(14); - hash!(opt_def_id); - hash!(b.unsafety); - hash!(b.abi); - fn_sig(state, &b.sig); - return false; + }; + let did = |state: &mut SipHasher, did: DefId| { + let h = if ast_util::is_local(did) { + svh.clone() + } else { + tcx.sess.cstore.get_crate_hash(did.krate) + }; + h.as_str().hash(state); + did.node.hash(state); + }; + let mt = |state: &mut SipHasher, mt: mt| { + mt.mutbl.hash(state); + }; + let fn_sig = |state: &mut SipHasher, sig: &Binder>| { + let sig = tcx.anonymize_late_bound_regions(sig).0; + for a in &sig.inputs { helper(tcx, *a, svh, state); } + if let ty::FnConverging(output) = sig.output { + helper(tcx, output, svh, state); } - TyTrait(ref data) => { - byte!(17); - did(state, data.principal_def_id()); - hash!(data.bounds); - - let principal = anonymize_late_bound_regions(tcx, &data.principal).0; - for subty in &principal.substs.types { - helper(tcx, subty, svh, state); + }; + ty.maybe_walk(|ty| { + match ty.sty { + TyBool => byte!(2), + TyChar => byte!(3), + TyInt(i) => { + byte!(4); + hash!(i); + } + TyUint(u) => { + byte!(5); + hash!(u); } + TyFloat(f) => { + byte!(6); + hash!(f); + } + TyStr => { + byte!(7); + } + TyEnum(d, _) => { + byte!(8); + did(state, d); + } + TyBox(_) => { + byte!(9); + } + TyArray(_, n) => { + byte!(10); + n.hash(state); + } + TySlice(_) => { + byte!(11); + } + TyRawPtr(m) => { + byte!(12); + mt(state, m); + } + TyRef(r, m) => { + byte!(13); + region(state, *r); + mt(state, m); + } + TyBareFn(opt_def_id, ref b) => { + byte!(14); + hash!(opt_def_id); + hash!(b.unsafety); + hash!(b.abi); + fn_sig(state, &b.sig); + return false; + } + TyTrait(ref data) => { + byte!(17); + did(state, data.principal_def_id()); + hash!(data.bounds); + + let principal = tcx.anonymize_late_bound_regions(&data.principal).0; + for subty in &principal.substs.types { + helper(tcx, subty, svh, state); + } - return false; - } - TyStruct(d, _) => { - byte!(18); - did(state, d); - } - TyTuple(ref inner) => { - byte!(19); - hash!(inner.len()); - } - TyParam(p) => { - byte!(20); - hash!(p.space); - hash!(p.idx); - hash!(token::get_name(p.name)); - } - TyInfer(_) => unreachable!(), - TyError => byte!(21), - TyClosure(d, _) => { - byte!(22); - did(state, d); - } - TyProjection(ref data) => { - byte!(23); - did(state, data.trait_ref.def_id); - hash!(token::get_name(data.item_name)); + return false; + } + TyStruct(d, _) => { + byte!(18); + did(state, d); + } + TyTuple(ref inner) => { + byte!(19); + hash!(inner.len()); + } + TyParam(p) => { + byte!(20); + hash!(p.space); + hash!(p.idx); + hash!(token::get_name(p.name)); + } + TyInfer(_) => unreachable!(), + TyError => byte!(21), + TyClosure(d, _) => { + byte!(22); + did(state, d); + } + TyProjection(ref data) => { + byte!(23); + did(state, data.trait_ref.def_id); + hash!(token::get_name(data.item_name)); + } } - } - true - }); - } -} - -impl fmt::Debug for Variance { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(match *self { - Covariant => "+", - Contravariant => "-", - Invariant => "o", - Bivariant => "*", - }) - } -} - -/// Construct a parameter environment suitable for static contexts or other contexts where there -/// are no free type/lifetime parameters in scope. -pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> { - ty::ParameterEnvironment { tcx: cx, - free_substs: Substs::empty(), - caller_bounds: Vec::new(), - implicit_region_bound: ty::ReEmpty, - selection_cache: traits::SelectionCache::new(), } -} - -/// Constructs and returns a substitution that can be applied to move from -/// the "outer" view of a type or method to the "inner" view. -/// In general, this means converting from bound parameters to -/// free parameters. Since we currently represent bound/free type -/// parameters in the same way, this only has an effect on regions. -pub fn construct_free_substs<'a,'tcx>( - tcx: &'a ctxt<'tcx>, - generics: &Generics<'tcx>, - free_id: ast::NodeId) - -> Substs<'tcx> -{ - // map T => T - let mut types = VecPerParamSpace::empty(); - push_types_from_defs(tcx, &mut types, generics.types.as_slice()); - - let free_id_outlive = region::DestructionScopeData::new(free_id); - - // map bound 'a => free 'a - let mut regions = VecPerParamSpace::empty(); - push_region_params(&mut regions, free_id_outlive, generics.regions.as_slice()); + true + }); + } + } + + /// Construct a parameter environment suitable for static contexts or other contexts where there + /// are no free type/lifetime parameters in scope. + pub fn empty_parameter_environment<'a>(&'a self) -> ParameterEnvironment<'a,'tcx> { + ty::ParameterEnvironment { tcx: self, + free_substs: Substs::empty(), + caller_bounds: Vec::new(), + implicit_region_bound: ty::ReEmpty, + selection_cache: traits::SelectionCache::new(), } + } + + /// Constructs and returns a substitution that can be applied to move from + /// the "outer" view of a type or method to the "inner" view. + /// In general, this means converting from bound parameters to + /// free parameters. Since we currently represent bound/free type + /// parameters in the same way, this only has an effect on regions. + pub fn construct_free_substs(&self, generics: &Generics<'tcx>, + free_id: ast::NodeId) -> Substs<'tcx> { + // map T => T + let mut types = VecPerParamSpace::empty(); + for def in generics.types.as_slice() { + debug!("construct_parameter_environment(): push_types_from_defs: def={:?}", + def); + types.push(def.space, self.mk_param_from_def(def)); + } - return Substs { - types: types, - regions: subst::NonerasedRegions(regions) - }; + let free_id_outlive = region::DestructionScopeData::new(free_id); - fn push_region_params(regions: &mut VecPerParamSpace, - all_outlive_extent: region::DestructionScopeData, - region_params: &[RegionParameterDef]) - { - for def in region_params { + // map bound 'a => free 'a + let mut regions = VecPerParamSpace::empty(); + for def in generics.regions.as_slice() { let region = - ReFree(FreeRegion { scope: all_outlive_extent, + ReFree(FreeRegion { scope: free_id_outlive, bound_region: BrNamed(def.def_id, def.name) }); debug!("push_region_params {:?}", region); regions.push(def.space, region); } - } - fn push_types_from_defs<'tcx>(tcx: &ctxt<'tcx>, - types: &mut VecPerParamSpace>, - defs: &[TypeParameterDef<'tcx>]) { - for def in defs { - debug!("construct_parameter_environment(): push_types_from_defs: def={:?}", - def); - let ty = tcx.mk_param_from_def(def); - types.push(def.space, ty); - } + Substs { + types: types, + regions: subst::NonerasedRegions(regions) + } } -} - -/// See `ParameterEnvironment` struct def'n for details -pub fn construct_parameter_environment<'a,'tcx>( - tcx: &'a ctxt<'tcx>, - span: Span, - generics: &ty::Generics<'tcx>, - generic_predicates: &ty::GenericPredicates<'tcx>, - free_id: ast::NodeId) - -> ParameterEnvironment<'a, 'tcx> -{ - // - // Construct the free substs. - // - - let free_substs = construct_free_substs(tcx, generics, free_id); - let free_id_outlive = region::DestructionScopeData::new(free_id); - - // - // Compute the bounds on Self and the type parameters. - // - - let bounds = generic_predicates.instantiate(tcx, &free_substs); - let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds)); - let predicates = bounds.predicates.into_vec(); - debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}", - free_id, - free_substs, - predicates); + /// See `ParameterEnvironment` struct def'n for details + pub fn construct_parameter_environment<'a>(&'a self, + span: Span, + generics: &ty::Generics<'tcx>, + generic_predicates: &ty::GenericPredicates<'tcx>, + free_id: ast::NodeId) + -> ParameterEnvironment<'a, 'tcx> + { + // + // Construct the free substs. + // - // - // Finally, we have to normalize the bounds in the environment, in - // case they contain any associated type projections. This process - // can yield errors if the put in illegal associated types, like - // `::Bar` where `i32` does not implement `Foo`. We - // report these errors right here; this doesn't actually feel - // right to me, because constructing the environment feels like a - // kind of a "idempotent" action, but I'm not sure where would be - // a better place. In practice, we construct environments for - // every fn once during type checking, and we'll abort if there - // are any errors at that point, so after type checking you can be - // sure that this will succeed without errors anyway. - // + let free_substs = self.construct_free_substs(generics, free_id); + let free_id_outlive = region::DestructionScopeData::new(free_id); - let unnormalized_env = ty::ParameterEnvironment { - tcx: tcx, - free_substs: free_substs, - implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()), - caller_bounds: predicates, - selection_cache: traits::SelectionCache::new(), - }; + // + // Compute the bounds on Self and the type parameters. + // - let cause = traits::ObligationCause::misc(span, free_id); - traits::normalize_param_env_or_error(unnormalized_env, cause) -} + let bounds = generic_predicates.instantiate(self, &free_substs); + let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds)); + let predicates = bounds.predicates.into_vec(); -impl BorrowKind { - pub fn from_mutbl(m: ast::Mutability) -> BorrowKind { - match m { - ast::MutMutable => MutBorrow, - ast::MutImmutable => ImmBorrow, - } - } + debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}", + free_id, + free_substs, + predicates); - /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow - /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a - /// mutability that is stronger than necessary so that it at least *would permit* the borrow in - /// question. - pub fn to_mutbl_lossy(self) -> ast::Mutability { - match self { - MutBorrow => ast::MutMutable, - ImmBorrow => ast::MutImmutable, + // + // Finally, we have to normalize the bounds in the environment, in + // case they contain any associated type projections. This process + // can yield errors if the put in illegal associated types, like + // `::Bar` where `i32` does not implement `Foo`. We + // report these errors right here; this doesn't actually feel + // right to me, because constructing the environment feels like a + // kind of a "idempotent" action, but I'm not sure where would be + // a better place. In practice, we construct environments for + // every fn once during type checking, and we'll abort if there + // are any errors at that point, so after type checking you can be + // sure that this will succeed without errors anyway. + // - // We have no type corresponding to a unique imm borrow, so - // use `&mut`. It gives all the capabilities of an `&uniq` - // and hence is a safe "over approximation". - UniqueImmBorrow => ast::MutMutable, - } - } + let unnormalized_env = ty::ParameterEnvironment { + tcx: self, + free_substs: free_substs, + implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()), + caller_bounds: predicates, + selection_cache: traits::SelectionCache::new(), + }; - pub fn to_user_str(&self) -> &'static str { - match *self { - MutBorrow => "mutable", - ImmBorrow => "immutable", - UniqueImmBorrow => "uniquely immutable", - } + let cause = traits::ObligationCause::misc(span, free_id); + traits::normalize_param_env_or_error(unnormalized_env, cause) } -} -impl<'tcx> ctxt<'tcx> { pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool { self.method_map.borrow().contains_key(&MethodCall::expr(expr_id)) } @@ -6777,13 +6679,13 @@ impl<'tcx> ctxt<'tcx> { } } -impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> { +impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> { fn node_ty(&self, id: ast::NodeId) -> mc::McResult> { - Ok(ty::node_id_to_type(self.tcx, id)) + Ok(self.tcx.node_id_to_type(id)) } fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult> { - Ok(ty::expr_ty_adjusted(self.tcx, expr)) + Ok(self.tcx.expr_ty_adjusted(expr)) } fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { @@ -6812,8 +6714,8 @@ impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> { self.tcx.upvar_capture(upvar_id) } - fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool { - type_moves_by_default(self, span, ty) + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { + ty.moves_by_default(self, span) } } @@ -6840,9 +6742,8 @@ impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> { fn closure_upvars(&self, def_id: ast::DefId, substs: &Substs<'tcx>) - -> Option>> - { - closure_upvars(self, def_id, substs) + -> Option>> { + ctxt::closure_upvars(self, def_id, substs) } } @@ -6856,53 +6757,54 @@ pub enum ExplicitSelfCategory { ByBoxExplicitSelfCategory, } -/// Pushes all the lifetimes in the given type onto the given list. A -/// "lifetime in a type" is a lifetime specified by a reference or a lifetime -/// in a list of type substitutions. This does *not* traverse into nominal -/// types, nor does it resolve fictitious types. -pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec, - ty: Ty) { - for ty in ty.walk() { - match ty.sty { - TyRef(region, _) => { - accumulator.push(*region) - } - TyTrait(ref t) => { - accumulator.push_all(t.principal.0.substs.regions().as_slice()); - } - TyEnum(_, substs) | - TyStruct(_, substs) => { - accum_substs(accumulator, substs); - } - TyClosure(_, substs) => { - accum_substs(accumulator, substs); - } - TyBool | - TyChar | - TyInt(_) | - TyUint(_) | - TyFloat(_) | - TyBox(_) | - TyStr | - TyArray(_, _) | - TySlice(_) | - TyRawPtr(_) | - TyBareFn(..) | - TyTuple(_) | - TyProjection(_) | - TyParam(_) | - TyInfer(_) | - TyError => { +impl<'tcx> TyS<'tcx> { + /// Pushes all the lifetimes in the given type onto the given list. A + /// "lifetime in a type" is a lifetime specified by a reference or a lifetime + /// in a list of type substitutions. This does *not* traverse into nominal + /// types, nor does it resolve fictitious types. + pub fn accumulate_lifetimes_in_type(&self, accumulator: &mut Vec) { + for ty in self.walk() { + match ty.sty { + TyRef(region, _) => { + accumulator.push(*region) + } + TyTrait(ref t) => { + accumulator.push_all(t.principal.0.substs.regions().as_slice()); + } + TyEnum(_, substs) | + TyStruct(_, substs) => { + accum_substs(accumulator, substs); + } + TyClosure(_, substs) => { + accum_substs(accumulator, substs); + } + TyBool | + TyChar | + TyInt(_) | + TyUint(_) | + TyFloat(_) | + TyBox(_) | + TyStr | + TyArray(_, _) | + TySlice(_) | + TyRawPtr(_) | + TyBareFn(..) | + TyTuple(_) | + TyProjection(_) | + TyParam(_) | + TyInfer(_) | + TyError => { + } } } - } - fn accum_substs(accumulator: &mut Vec, substs: &Substs) { - match substs.regions { - subst::ErasedRegions => {} - subst::NonerasedRegions(ref regions) => { - for region in regions { - accumulator.push(*region) + fn accum_substs(accumulator: &mut Vec, substs: &Substs) { + match substs.regions { + subst::ErasedRegions => {} + subst::NonerasedRegions(ref regions) => { + for region in regions { + accumulator.push(*region) + } } } } @@ -6930,15 +6832,6 @@ pub type TraitMap = NodeMap>; // imported. pub type GlobMap = HashMap>; -pub fn with_freevars(tcx: &ctxt, fid: ast::NodeId, f: F) -> T where - F: FnOnce(&[Freevar]) -> T, -{ - match tcx.freevars.borrow().get(&fid) { - None => f(&[]), - Some(d) => f(&d[..]) - } -} - impl<'tcx> AutoAdjustment<'tcx> { pub fn is_identity(&self) -> bool { match *self { @@ -6955,106 +6848,123 @@ impl<'tcx> AutoDerefRef<'tcx> { } } -/// Replace any late-bound regions bound in `value` with free variants attached to scope-id -/// `scope_id`. -pub fn liberate_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - all_outlive_scope: region::DestructionScopeData, - value: &Binder) - -> T - where T : TypeFoldable<'tcx> -{ - ty_fold::replace_late_bound_regions( - tcx, value, - |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0 -} +impl<'tcx> ctxt<'tcx> { + pub fn with_freevars(&self, fid: ast::NodeId, f: F) -> T where + F: FnOnce(&[Freevar]) -> T, + { + match self.freevars.borrow().get(&fid) { + None => f(&[]), + Some(d) => f(&d[..]) + } + } -pub fn count_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - value: &Binder) - -> usize - where T : TypeFoldable<'tcx> -{ - let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic); - skol_map.len() -} + /// Replace any late-bound regions bound in `value` with free variants attached to scope-id + /// `scope_id`. + pub fn liberate_late_bound_regions(&self, + all_outlive_scope: region::DestructionScopeData, + value: &Binder) + -> T + where T : TypeFoldable<'tcx> + { + ty_fold::replace_late_bound_regions( + self, value, + |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0 + } -pub fn binds_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - value: &Binder) - -> bool - where T : TypeFoldable<'tcx> -{ - count_late_bound_regions(tcx, value) > 0 -} + pub fn count_late_bound_regions(&self, value: &Binder) -> usize + where T : TypeFoldable<'tcx> + { + let (_, skol_map) = ty_fold::replace_late_bound_regions(self, value, |_| ty::ReStatic); + skol_map.len() + } -/// Flattens two binding levels into one. So `for<'a> for<'b> Foo` -/// becomes `for<'a,'b> Foo`. -pub fn flatten_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - bound2_value: &Binder>) - -> Binder - where T: TypeFoldable<'tcx> -{ - let bound0_value = bound2_value.skip_binder().skip_binder(); - let value = ty_fold::fold_regions(tcx, bound0_value, |region, current_depth| { - match region { - ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => { - // should be true if no escaping regions from bound2_value - assert!(debruijn.depth - current_depth <= 1); - ty::ReLateBound(DebruijnIndex::new(current_depth), br) - } - _ => { - region + pub fn binds_late_bound_regions(&self, value: &Binder) -> bool + where T : TypeFoldable<'tcx> + { + self.count_late_bound_regions(value) > 0 + } + + /// Flattens two binding levels into one. So `for<'a> for<'b> Foo` + /// becomes `for<'a,'b> Foo`. + pub fn flatten_late_bound_regions(&self, bound2_value: &Binder>) + -> Binder + where T: TypeFoldable<'tcx> + { + let bound0_value = bound2_value.skip_binder().skip_binder(); + let value = ty_fold::fold_regions(self, bound0_value, |region, current_depth| { + match region { + ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => { + // should be true if no escaping regions from bound2_value + assert!(debruijn.depth - current_depth <= 1); + ty::ReLateBound(DebruijnIndex::new(current_depth), br) + } + _ => { + region + } } + }); + Binder(value) + } + + pub fn no_late_bound_regions(&self, value: &Binder) -> Option + where T : TypeFoldable<'tcx> + { + if self.binds_late_bound_regions(value) { + None + } else { + Some(value.0.clone()) } - }); - Binder(value) -} + } -pub fn no_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - value: &Binder) - -> Option - where T : TypeFoldable<'tcx> -{ - if binds_late_bound_regions(tcx, value) { - None - } else { - Some(value.0.clone()) + /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also + /// method lookup and a few other places where precise region relationships are not required. + pub fn erase_late_bound_regions(&self, value: &Binder) -> T + where T : TypeFoldable<'tcx> + { + ty_fold::replace_late_bound_regions(self, value, |_| ty::ReStatic).0 } -} -/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also -/// method lookup and a few other places where precise region relationships are not required. -pub fn erase_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - value: &Binder) - -> T - where T : TypeFoldable<'tcx> -{ - ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0 -} + /// Rewrite any late-bound regions so that they are anonymous. Region numbers are + /// assigned starting at 1 and increasing monotonically in the order traversed + /// by the fold operation. + /// + /// The chief purpose of this function is to canonicalize regions so that two + /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become + /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and + /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization. + pub fn anonymize_late_bound_regions(&self, sig: &Binder) -> Binder + where T : TypeFoldable<'tcx>, + { + let mut counter = 0; + ty::Binder(ty_fold::replace_late_bound_regions(self, sig, |_| { + counter += 1; + ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter)) + }).0) + } -/// Rewrite any late-bound regions so that they are anonymous. Region numbers are -/// assigned starting at 1 and increasing monotonically in the order traversed -/// by the fold operation. -/// -/// The chief purpose of this function is to canonicalize regions so that two -/// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become -/// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and -/// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization. -pub fn anonymize_late_bound_regions<'tcx, T>( - tcx: &ctxt<'tcx>, - sig: &Binder) - -> Binder - where T : TypeFoldable<'tcx>, -{ - let mut counter = 0; - ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| { - counter += 1; - ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter)) - }).0) + pub fn make_substs_for_receiver_types(&self, + trait_ref: &ty::TraitRef<'tcx>, + method: &ty::Method<'tcx>) + -> subst::Substs<'tcx> + { + /*! + * Substitutes the values for the receiver's type parameters + * that are found in method, leaving the method's type parameters + * intact. + */ + + let meth_tps: Vec = + method.generics.types.get_slice(subst::FnSpace) + .iter() + .map(|def| self.mk_param_from_def(def)) + .collect(); + let meth_regions: Vec = + method.generics.regions.get_slice(subst::FnSpace) + .iter() + .map(|def| def.to_early_bound_region()) + .collect(); + trait_ref.substs.clone().with_method(meth_tps, meth_regions) + } } impl DebruijnIndex { @@ -7111,78 +7021,6 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { } } -pub fn make_substs_for_receiver_types<'tcx>(tcx: &ctxt<'tcx>, - trait_ref: &ty::TraitRef<'tcx>, - method: &ty::Method<'tcx>) - -> subst::Substs<'tcx> -{ - /*! - * Substitutes the values for the receiver's type parameters - * that are found in method, leaving the method's type parameters - * intact. - */ - - let meth_tps: Vec = - method.generics.types.get_slice(subst::FnSpace) - .iter() - .map(|def| tcx.mk_param_from_def(def)) - .collect(); - let meth_regions: Vec = - method.generics.regions.get_slice(subst::FnSpace) - .iter() - .map(|def| def.to_early_bound_region()) - .collect(); - trait_ref.substs.clone().with_method(meth_tps, meth_regions) -} - -#[derive(Copy, Clone)] -pub enum CopyImplementationError { - FieldDoesNotImplementCopy(ast::Name), - VariantDoesNotImplementCopy(ast::Name), - TypeIsStructural, - TypeHasDestructor, -} - -pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>, - span: Span, - self_type: Ty<'tcx>) - -> Result<(),CopyImplementationError> -{ - let tcx = param_env.tcx; - - let did = match self_type.sty { - ty::TyStruct(struct_did, substs) => { - let fields = ty::struct_fields(tcx, struct_did, substs); - for field in &fields { - if type_moves_by_default(param_env, span, field.mt.ty) { - return Err(FieldDoesNotImplementCopy(field.name)) - } - } - struct_did - } - ty::TyEnum(enum_did, substs) => { - let enum_variants = ty::enum_variants(tcx, enum_did); - for variant in enum_variants.iter() { - for variant_arg_type in &variant.args { - let substd_arg_type = - variant_arg_type.subst(tcx, substs); - if type_moves_by_default(param_env, span, substd_arg_type) { - return Err(VariantDoesNotImplementCopy(variant.name)) - } - } - } - enum_did - } - _ => return Err(TypeIsStructural), - }; - - if ty::has_dtor(tcx, did) { - return Err(TypeHasDestructor) - } - - Ok(()) -} - // FIXME(#20298) -- all of these traits basically walk various // structures to test whether types/regions are reachable with various // properties. It should be possible to express them in terms of one diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs index 422498624a9d3..4e88e23377d0c 100644 --- a/src/librustc/middle/ty_relate/mod.rs +++ b/src/librustc/middle/ty_relate/mod.rs @@ -113,7 +113,7 @@ fn relate_item_substs<'a,'tcx:'a,R>(relation: &mut R, let variances; let opt_variances = if relation.tcx().variance_computed.get() { - variances = ty::item_variances(relation.tcx(), item_def_id); + variances = relation.tcx().item_variances(item_def_id); Some(&*variances) } else { None diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 71f3675aecee1..dcdf457965efa 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -71,7 +71,7 @@ fn parameterized(f: &mut fmt::Formatter, where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx> { let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| { - try!(write!(f, "{}", ty::item_path_str(tcx, did))); + try!(write!(f, "{}", tcx.item_path_str(did))); Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose())) })); @@ -265,7 +265,7 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> { parameterized(f, trait_ref.substs, trait_ref.def_id, projection_bounds, - |tcx| ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone()) + |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone()) } } @@ -616,7 +616,7 @@ impl fmt::Display for ty::Binder> impl<'tcx> fmt::Display for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { parameterized(f, self.substs, self.def_id, &[], - |tcx| ty::lookup_trait_def(tcx, self.def_id).generics.clone()) + |tcx| tcx.lookup_trait_def(self.def_id).generics.clone()) } } @@ -671,7 +671,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { if let Some(def_id) = opt_def_id { try!(write!(f, " {{{}}}", ty::tls::with(|tcx| { - ty::item_path_str(tcx, def_id) + tcx.item_path_str(def_id) }))); } Ok(()) @@ -681,7 +681,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyParam(ref param_ty) => write!(f, "{}", param_ty), TyEnum(did, substs) | TyStruct(did, substs) => { parameterized(f, substs, did, &[], - |tcx| ty::lookup_item_type(tcx, did).generics) + |tcx| tcx.lookup_item_type(did).generics) } TyTrait(ref data) => write!(f, "{}", data), ty::TyProjection(ref data) => write!(f, "{}", data), @@ -720,7 +720,7 @@ impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "UpvarId({};`{}`;{})", self.var_id, - ty::tls::with(|tcx| ty::local_var_name_str(tcx, self.var_id)), + ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)), self.closure_expr_id) } } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 49933441cf01e..9d4fb4c994d40 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -752,7 +752,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { LpExtend(ref lp_base, _, LpInterior(InteriorField(_))) => { match lp_base.to_type().sty { ty::TyStruct(def_id, _) | ty::TyEnum(def_id, _) => { - if ty::has_dtor(self.tcx(), def_id) { + if self.tcx().has_dtor(def_id) { // In the case where the owner implements drop, then // the path must be initialized to prevent a case of // partial reinitialization diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index 93f5ac529d3fd..9bd4da28c99fb 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -353,7 +353,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>, } (&ty::TyStruct(def_id, ref _substs), None) => { - let fields = ty::lookup_struct_fields(tcx, def_id); + let fields = tcx.lookup_struct_fields(def_id); match *origin_field_name { mc::NamedField(ast_name) => { for f in &fields { @@ -378,7 +378,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>, (&ty::TyEnum(enum_def_id, substs), ref enum_variant_info) => { let variant_info = { - let mut variants = ty::substd_enum_variants(tcx, enum_def_id, substs); + let mut variants = tcx.substd_enum_variants(enum_def_id, substs); match *enum_variant_info { Some((variant_def_id, ref _lp2)) => variants.iter() @@ -442,9 +442,9 @@ fn add_fragment_sibling_core<'tcx>(this: &MoveData<'tcx>, let loan_path_elem = LpInterior(InteriorField(new_field_name)); let new_lp_type = match new_field_name { mc::NamedField(ast_name) => - ty::named_element_ty(tcx, parent.to_type(), ast_name, opt_variant_did), + tcx.named_element_ty(parent.to_type(), ast_name, opt_variant_did), mc::PositionalField(idx) => - ty::positional_element_ty(tcx, parent.to_type(), idx, opt_variant_did), + tcx.positional_element_ty(parent.to_type(), idx, opt_variant_did), }; let new_lp_variant = LpExtend(parent, mc, loan_path_elem); let new_lp = LoanPath::new(new_lp_variant, new_lp_type.unwrap()); diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 7b6c54dbaca44..2b33dde2cbe2d 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -35,7 +35,7 @@ pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, decl_id: ast::NodeId, _decl_span: Span, var_id: ast::NodeId) { - let ty = ty::node_id_to_type(bccx.tcx, var_id); + let ty = bccx.tcx.node_id_to_type(var_id); let loan_path = Rc::new(LoanPath::new(LpVar(var_id), ty)); move_data.add_move(bccx.tcx, loan_path, decl_id, Declared); } @@ -180,7 +180,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, mc::cat_interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => { match b.ty.sty { ty::TyStruct(did, _) | ty::TyEnum(did, _) => { - if ty::has_dtor(bccx.tcx, did) { + if bccx.tcx.has_dtor(did) { Some(cmt.clone()) } else { check_and_get_illegal_move_origin(bccx, b) diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index f00eb872642f4..44a4a0d250402 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -490,7 +490,7 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { fn visit_expr(&mut self, ex: &Expr) { if let ast::ExprAddrOf(mutbl, ref base) = ex.node { - let param_env = ty::empty_parameter_environment(self.bccx.tcx); + let param_env = self.bccx.tcx.empty_parameter_environment(); let mc = mc::MemCategorizationContext::new(¶m_env); let base_cmt = mc.cat_expr(&**base).unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index 9a29ed91339e2..5baabebea116b 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -137,7 +137,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, mc::cat_interior(ref b, mc::InteriorField(_)) => { match b.ty.sty { ty::TyStruct(did, _) | - ty::TyEnum(did, _) if ty::has_dtor(bccx.tcx, did) => { + ty::TyEnum(did, _) if bccx.tcx.has_dtor(did) => { bccx.span_err( move_from.span, &format!("cannot move out of type `{}`, \ diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index ec92c2ed05a36..4f726044a1bac 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -29,8 +29,8 @@ use rustc::middle::dataflow::DataFlowOperator; use rustc::middle::dataflow::KillFrom; use rustc::middle::expr_use_visitor as euv; use rustc::middle::free_region::FreeRegionMap; -use rustc::middle::infer::error_reporting::note_and_explain_region; use rustc::middle::mem_categorization as mc; +use rustc::middle::mem_categorization::Typer; use rustc::middle::region; use rustc::middle::ty::{self, Ty}; @@ -662,7 +662,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { .map .find(the_move.id) { Some(ast_map::NodeExpr(expr)) => { - (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span) + (self.tcx.expr_ty_adjusted(&*expr), expr.span) } r => { self.tcx.sess.bug(&format!("MoveExpr({}) maps to \ @@ -696,7 +696,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } move_data::MovePat => { - let pat_ty = ty::node_id_to_type(self.tcx, the_move.id); + let pat_ty = self.tcx.node_id_to_type(the_move.id); let span = self.tcx.map.span(the_move.id); self.tcx.sess.span_note(span, &format!("`{}` moved here{} because it has type `{}`, \ @@ -713,7 +713,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { .map .find(the_move.id) { Some(ast_map::NodeExpr(expr)) => { - (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span) + (self.tcx.expr_ty_adjusted(&*expr), expr.span) } r => { self.tcx.sess.bug(&format!("Captured({}) maps to \ @@ -747,7 +747,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { -> (&'static str, &'static str) { match ty.sty { _ => { - if ty::type_moves_by_default(param_env, span, ty) { + if param_env.type_moves_by_default(ty, span) { ("non-copyable", "perhaps you meant to use `clone()`?") } else { @@ -997,13 +997,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } err_out_of_scope(super_scope, sub_scope) => { - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "reference must be valid for ", sub_scope, "..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( "...but borrowed value is only valid for ", super_scope, ""); @@ -1020,14 +1018,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } None => self.cmt_to_string(&*err.cmt), }; - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( &format!("{} would have to be valid for ", descr), loan_scope, "..."); - note_and_explain_region( - self.tcx, + self.tcx.note_and_explain_region( &format!("...but {} is only valid for ", descr), ptr_scope, ""); @@ -1041,14 +1037,14 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match loan_path.kind { LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) | LpVar(id) => { - out.push_str(&ty::local_var_name_str(self.tcx, id)); + out.push_str(&self.tcx.local_var_name_str(id)); } LpDowncast(ref lp_base, variant_def_id) => { out.push('('); self.append_loan_path_to_string(&**lp_base, out); out.push_str(DOWNCAST_PRINTED_OPERATOR); - out.push_str(&ty::item_path_str(self.tcx, variant_def_id)); + out.push_str(&self.tcx.item_path_str(variant_def_id)); out.push(')'); } @@ -1094,7 +1090,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { out.push('('); self.append_autoderefd_loan_path_to_string(&**lp_base, out); out.push(':'); - out.push_str(&ty::item_path_str(self.tcx, variant_def_id)); + out.push_str(&self.tcx.item_path_str(variant_def_id)); out.push(')'); } @@ -1184,7 +1180,7 @@ impl<'tcx> fmt::Debug for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE { - ty::tls::with(|tcx| ty::item_path_str(tcx, variant_def_id)) + ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; @@ -1216,7 +1212,7 @@ impl<'tcx> fmt::Display for LoanPath<'tcx> { LpDowncast(ref lp, variant_def_id) => { let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE { - ty::tls::with(|tcx| ty::item_path_str(tcx, variant_def_id)) + ty::tls::with(|tcx| tcx.item_path_str(variant_def_id)) } else { format!("{:?}", variant_def_id) }; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d3297562aef16..1ad3f53c328d9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -648,16 +648,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session, time(time_passes, "static item recursion checking", (), |_| middle::check_static_recursion::check_crate(&sess, krate, &def_map, &ast_map)); - ty::with_ctxt(sess, - arenas, - def_map, - named_region_map, - ast_map, - freevars, - region_map, - lang_items, - stability::Index::new(krate), - |tcx| { + ty::ctxt::create_and_enter(sess, + arenas, + def_map, + named_region_map, + ast_map, + freevars, + region_map, + lang_items, + stability::Index::new(krate), + |tcx| { // passes are timed inside typeck typeck::check_crate(tcx, trait_map); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index a40cb94204d9c..610f3f3a75ee6 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -317,7 +317,7 @@ impl<'a, 'tcx> pprust::PpAnn for TypedAnnotation<'a, 'tcx> { try!(pp::word(&mut s.s, "as")); try!(pp::space(&mut s.s)); try!(pp::word(&mut s.s, - &ty::expr_ty(self.tcx, expr).to_string())); + &self.tcx.expr_ty(expr).to_string())); s.pclose() } _ => Ok(()) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 02ea8859b5c75..5ec6e293684cc 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -130,16 +130,16 @@ fn test_env(source_string: &str, resolve::resolve_crate(&sess, &ast_map, resolve::MakeGlobMap::No); let named_region_map = resolve_lifetime::krate(&sess, krate, &def_map); let region_map = region::resolve_crate(&sess, krate); - ty::with_ctxt(sess, - &arenas, - def_map, - named_region_map, - ast_map, - freevars, - region_map, - lang_items, - stability::Index::new(krate), - |tcx| { + ty::ctxt::create_and_enter(sess, + &arenas, + def_map, + named_region_map, + ast_map, + freevars, + region_map, + lang_items, + stability::Index::new(krate), + |tcx| { let infcx = infer::new_infer_ctxt(tcx); body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 29799d34ee583..8fe07da157970 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -30,6 +30,7 @@ use metadata::{csearch, decoder}; use middle::def::*; +use middle::mem_categorization::Typer; use middle::subst::Substs; use middle::ty::{self, Ty}; use middle::{def, pat_util, stability}; @@ -142,7 +143,7 @@ impl LintPass for TypeLimits { } }, _ => { - let t = ty::expr_ty(cx.tcx, &**expr); + let t = cx.tcx.expr_ty(&**expr); match t.sty { ty::TyUint(_) => { cx.span_lint(UNSIGNED_NEGATION, e.span, @@ -168,7 +169,7 @@ impl LintPass for TypeLimits { } if is_shift_binop(binop.node) { - let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty { + let opt_ty_bits = match cx.tcx.expr_ty(&**l).sty { ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)), ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)), _ => None @@ -193,7 +194,7 @@ impl LintPass for TypeLimits { } }, ast::ExprLit(ref lit) => { - match ty::expr_ty(cx.tcx, e).sty { + match cx.tcx.expr_ty(e).sty { ty::TyInt(t) => { match lit.node { ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) | @@ -343,7 +344,7 @@ impl LintPass for TypeLimits { } else { binop }; - match ty::expr_ty(tcx, expr).sty { + match tcx.expr_ty(expr).sty { ty::TyInt(int_ty) => { let (min, max) = int_ty_range(int_ty); let lit_val: i64 = match lit.node { @@ -412,7 +413,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { None => panic!("ast_ty_to_ty_cache was incomplete after typeck!") }; - if !ty::is_ffi_safe(self.cx.tcx, tty) { + if !tty.is_ffi_safe(self.cx.tcx) { self.cx.span_lint(IMPROPER_CTYPES, sp, "found type without foreign-function-safe \ representation annotation in foreign module, consider \ @@ -482,20 +483,11 @@ pub struct BoxPointers; impl BoxPointers { fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>, span: Span, ty: Ty<'tcx>) { - let mut n_uniq: usize = 0; - ty::fold_ty(cx.tcx, ty, |t| { - match t.sty { - ty::TyBox(_) => { - n_uniq += 1; - } - _ => () - }; - t - }); - - if n_uniq > 0 { - let m = format!("type uses owned (Box type) pointers: {}", ty); - cx.span_lint(BOX_POINTERS, span, &m[..]); + for leaf_ty in ty.walk() { + if let ty::TyBox(_) = leaf_ty.sty { + let m = format!("type uses owned (Box type) pointers: {}", ty); + cx.span_lint(BOX_POINTERS, span, &m); + } } } } @@ -512,7 +504,7 @@ impl LintPass for BoxPointers { ast::ItemEnum(..) | ast::ItemStruct(..) => self.check_heap_type(cx, it.span, - ty::node_id_to_type(cx.tcx, it.id)), + cx.tcx.node_id_to_type(it.id)), _ => () } @@ -521,7 +513,7 @@ impl LintPass for BoxPointers { ast::ItemStruct(ref struct_def, _) => { for struct_field in &struct_def.fields { self.check_heap_type(cx, struct_field.span, - ty::node_id_to_type(cx.tcx, struct_field.node.id)); + cx.tcx.node_id_to_type(struct_field.node.id)); } } _ => () @@ -529,7 +521,7 @@ impl LintPass for BoxPointers { } fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { - let ty = ty::expr_ty(cx.tcx, e); + let ty = cx.tcx.expr_ty(e); self.check_heap_type(cx, e.span, ty); } } @@ -582,13 +574,13 @@ impl LintPass for RawPointerDerive { ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => { // Deriving the Copy trait does not cause a warning if let &Some(ref trait_ref) = t_ref_opt { - let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref); + let def_id = cx.tcx.trait_ref_to_def_id(trait_ref); if Some(def_id) == cx.tcx.lang_items.copy_trait() { return; } } - match ty::node_id_to_type(cx.tcx, item.id).sty { + match cx.tcx.node_id_to_type(item.id).sty { ty::TyEnum(did, _) => did, ty::TyStruct(did, _) => did, _ => return, @@ -732,7 +724,7 @@ impl LintPass for UnusedResults { return; } - let t = ty::expr_ty(cx.tcx, expr); + let t = cx.tcx.expr_ty(expr); let warned = match t.sty { ty::TyTuple(ref tys) if tys.is_empty() => return, ty::TyBool => return, @@ -877,7 +869,7 @@ fn method_context(cx: &Context, id: ast::NodeId, span: Span) -> MethodContext { Some(item) => match item.container() { ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, ty::ImplContainer(cid) => { - match ty::impl_trait_ref(cx.tcx, cid) { + match cx.tcx.impl_trait_ref(cid) { Some(_) => MethodContext::TraitImpl, None => MethodContext::PlainImpl } @@ -1601,7 +1593,7 @@ impl LintPass for MissingDoc { ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_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 = ty::trait_ref_to_def_id(cx.tcx, trait_ref); + let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref); match cx.tcx.map.find(real_trait.node) { Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited { for itm in impl_items { @@ -1711,11 +1703,11 @@ impl LintPass for MissingCopyImplementations { } _ => return, }; - let parameter_environment = ty::empty_parameter_environment(cx.tcx); - if !ty::type_moves_by_default(¶meter_environment, item.span, ty) { + let parameter_environment = cx.tcx.empty_parameter_environment(); + if !parameter_environment.type_moves_by_default(ty, item.span) { return; } - if ty::can_type_implement_copy(¶meter_environment, item.span, ty).is_ok() { + if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() { cx.span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, "type could implement `Copy`; consider adding `impl \ @@ -1763,11 +1755,11 @@ impl LintPass for MissingDebugImplementations { }; if self.impling_types.is_none() { - let debug_def = ty::lookup_trait_def(cx.tcx, debug); + let debug_def = cx.tcx.lookup_trait_def(debug); let mut impls = NodeSet(); debug_def.for_each_impl(cx.tcx, |d| { if d.krate == ast::LOCAL_CRATE { - if let Some(ty_def) = ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)) { + if let Some(ty_def) = cx.tcx.node_id_to_type(d.node).ty_to_def_id() { impls.insert(ty_def.node); } } @@ -1878,7 +1870,7 @@ impl LintPass for UnconditionalRecursion { visit::FkFnBlock => return }; - let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id)) + let impl_def_id = cx.tcx.impl_of_method(local_def(id)) .unwrap_or(local_def(ast::DUMMY_NODE_ID)); assert!(ast_util::is_local(impl_def_id)); let impl_node_id = impl_def_id.node; @@ -2010,7 +2002,7 @@ impl LintPass for UnconditionalRecursion { // method instead. ty::MethodTypeParam( ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => { - ty::trait_item(tcx, trait_ref.def_id, method_num).def_id() + tcx.trait_item(trait_ref.def_id, method_num).def_id() } // The `impl` is known, so we check that with a @@ -2175,11 +2167,11 @@ impl LintPass for MutableTransmutes { ast::ExprPath(..) => (), _ => return None } - if let DefFn(did, _) = ty::resolve_expr(cx.tcx, expr) { + if let DefFn(did, _) = cx.tcx.resolve_expr(expr) { if !def_id_is_transmute(cx, did) { return None; } - let typ = ty::node_id_to_type(cx.tcx, expr.id); + let typ = cx.tcx.node_id_to_type(expr.id); match typ.sty { ty::TyBareFn(_, ref bare_fn) if bare_fn.abi == RustIntrinsic => { if let ty::FnConverging(to) = bare_fn.sig.0.output { @@ -2194,11 +2186,11 @@ impl LintPass for MutableTransmutes { } fn def_id_is_transmute(cx: &Context, def_id: DefId) -> bool { - match ty::lookup_item_type(cx.tcx, def_id).ty.sty { + match cx.tcx.lookup_item_type(def_id).ty.sty { ty::TyBareFn(_, ref bfty) if bfty.abi == RustIntrinsic => (), _ => return false } - ty::with_path(cx.tcx, def_id, |path| match path.last() { + cx.tcx.with_path(def_id, |path| match path.last() { Some(ref last) => last.name().as_str() == "transmute", _ => false }) @@ -2251,7 +2243,7 @@ impl LintPass for DropWithReprExtern { let (drop_impl_did, dtor_self_type) = if dtor_did.krate == ast::LOCAL_CRATE { let impl_did = ctx.tcx.map.get_parent_did(dtor_did.node); - let ty = ty::lookup_item_type(ctx.tcx, impl_did).ty; + let ty = ctx.tcx.lookup_item_type(impl_did).ty; (impl_did, ty) } else { continue; @@ -2261,9 +2253,9 @@ impl LintPass for DropWithReprExtern { ty::TyEnum(self_type_did, _) | ty::TyStruct(self_type_did, _) | ty::TyClosure(self_type_did, _) => { - let hints = ty::lookup_repr_hints(ctx.tcx, self_type_did); + let hints = ctx.tcx.lookup_repr_hints(self_type_did); if hints.iter().any(|attr| *attr == attr::ReprExtern) && - ty::ty_dtor(ctx.tcx, self_type_did).has_drop_flag() { + ctx.tcx.ty_dtor(self_type_did).has_drop_flag() { let drop_impl_span = ctx.tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP); let self_defn_span = ctx.tcx.map.def_id_span(self_type_did, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index cae93baaf74be..24803562fa373 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -273,7 +273,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { } _ => true, }; - let tr = ty::impl_trait_ref(self.tcx, local_def(item.id)); + let tr = self.tcx.impl_trait_ref(local_def(item.id)); let public_trait = tr.clone().map_or(false, |tr| { !is_local(tr.def_id) || self.exported_items.contains(&tr.def_id.node) @@ -423,7 +423,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { self.def_privacy(id) } ty::ImplContainer(id) => { - match ty::impl_trait_ref(self.tcx, id) { + match self.tcx.impl_trait_ref(id) { Some(t) => { debug!("privacy - impl of trait {:?}", id); self.def_privacy(t.def_id) @@ -451,7 +451,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { self.def_privacy(id) } ty::ImplContainer(id) => { - match ty::impl_trait_ref(self.tcx, id) { + match self.tcx.impl_trait_ref(id) { Some(t) => { debug!("privacy - impl of trait {:?}", id); self.def_privacy(t.def_id) @@ -476,7 +476,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { self.def_privacy(id) } ty::ImplContainer(id) => { - match ty::impl_trait_ref(self.tcx, id) { + match self.tcx.impl_trait_ref(id) { Some(t) => { debug!("privacy - impl of trait {:?}", id); self.def_privacy(t.def_id) @@ -537,7 +537,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { ast::MethodImplItem(..) => { let imp = self.tcx.map .get_parent_did(closest_private_id); - match ty::impl_trait_ref(self.tcx, imp) { + match self.tcx.impl_trait_ref(imp) { Some(..) => return Allowable, _ if ii.vis == ast::Public => { return Allowable @@ -696,7 +696,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { span: Span, id: ast::DefId, name: FieldName) { - let fields = ty::lookup_struct_fields(self.tcx, id); + let fields = self.tcx.lookup_struct_fields(id); let field = match name { NamedField(f_name) => { debug!("privacy - check named field {} in struct {:?}", f_name, id); @@ -709,10 +709,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { return } - let struct_type = ty::lookup_item_type(self.tcx, id).ty; + let struct_type = self.tcx.lookup_item_type(id).ty; let struct_desc = match struct_type.sty { ty::TyStruct(_, _) => - format!("struct `{}`", ty::item_path_str(self.tcx, id)), + format!("struct `{}`", self.tcx.item_path_str(id)), // struct variant fields have inherited visibility ty::TyEnum(..) => return, _ => self.tcx.sess.span_bug(span, "can't find struct for field") @@ -733,7 +733,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { name: ast::Name) { // If the method is a default method, we need to use the def_id of // the default implementation. - let method_id = match ty::impl_or_trait_item(self.tcx, method_id) { + let method_id = match self.tcx.impl_or_trait_item(method_id) { ty::MethodTraitItem(method_type) => { method_type.provided_source.unwrap_or(method_id) } @@ -893,12 +893,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &ast::Expr) { match expr.node { ast::ExprField(ref base, ident) => { - if let ty::TyStruct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty { + if let ty::TyStruct(id, _) = self.tcx.expr_ty_adjusted(&**base).sty { self.check_field(expr.span, id, NamedField(ident.node.name)); } } ast::ExprTupField(ref base, idx) => { - if let ty::TyStruct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty { + if let ty::TyStruct(id, _) = self.tcx.expr_ty_adjusted(&**base).sty { self.check_field(expr.span, id, UnnamedField(idx.node)); } } @@ -917,12 +917,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } ast::ExprStruct(_, ref fields, _) => { - match ty::expr_ty(self.tcx, expr).sty { + match self.tcx.expr_ty(expr).sty { ty::TyStruct(ctor_id, _) => { // RFC 736: ensure all unmentioned fields are visible. // Rather than computing the set of unmentioned fields // (i.e. `all_fields - fields`), just check them all. - let all_fields = ty::lookup_struct_fields(self.tcx, ctor_id); + let all_fields = self.tcx.lookup_struct_fields(ctor_id); for field in all_fields { self.check_field(expr.span, ctor_id, NamedField(field.name)); @@ -950,7 +950,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } ast::ExprPath(..) => { let guard = |did: ast::DefId| { - let fields = ty::lookup_struct_fields(self.tcx, did); + let fields = self.tcx.lookup_struct_fields(did); let any_priv = fields.iter().any(|f| { f.vis != ast::Public && ( !is_local(f.id) || @@ -994,7 +994,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { match pattern.node { ast::PatStruct(_, ref fields, _) => { - match ty::pat_ty(self.tcx, pattern).sty { + match self.tcx.pat_ty(pattern).sty { ty::TyStruct(id, _) => { for field in fields { self.check_field(pattern.span, id, @@ -1025,7 +1025,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { // Patterns which bind no fields are allowable (the path is check // elsewhere). ast::PatEnum(_, Some(ref fields)) => { - match ty::pat_ty(self.tcx, pattern).sty { + match self.tcx.pat_ty(pattern).sty { ty::TyStruct(id, _) => { for (i, field) in fields.iter().enumerate() { if let ast::PatWild(..) = field.node { @@ -1337,7 +1337,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> { let not_private_trait = trait_ref.as_ref().map_or(true, // no trait counts as public trait |tr| { - let did = ty::trait_ref_to_def_id(self.tcx, tr); + let did = self.tcx.trait_ref_to_def_id(tr); !is_local(did) || self.trait_is_public(did.node) }); diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 65d9d9809c926..5ddad0e1947e8 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -311,7 +311,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { let mut scope_id; // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. - let qualname = match ty::impl_of_method(self.tcx, ast_util::local_def(id)) { + let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) { Some(impl_id) => match self.tcx.map.get(impl_id.node) { NodeItem(item) => { scope_id = item.id; @@ -320,11 +320,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { let mut result = String::from("<"); result.push_str(&ty_to_string(&**ty)); - match ty::trait_of_item(self.tcx, ast_util::local_def(id)) { + match self.tcx.trait_of_item(ast_util::local_def(id)) { Some(def_id) => { result.push_str(" as "); result.push_str( - &ty::item_path_str(self.tcx, def_id)); + &self.tcx.item_path_str(def_id)); }, None => {} } @@ -344,12 +344,12 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { impl_id.node, id, self.tcx.map.get(impl_id.node))); }, }, - None => match ty::trait_of_item(self.tcx, ast_util::local_def(id)) { + None => match self.tcx.trait_of_item(ast_util::local_def(id)) { Some(def_id) => { scope_id = def_id.node; match self.tcx.map.get(def_id.node) { NodeItem(_) => { - format!("::{}", ty::item_path_str(self.tcx, def_id)) + format!("::{}", self.tcx.item_path_str(def_id)) } _ => { self.sess.span_bug(span, @@ -368,7 +368,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { let qualname = &format!("{}::{}", qualname, &token::get_name(name)); // record the decl for this def (if it has one) - let decl_id = ty::trait_item_of_item(self.tcx, ast_util::local_def(id)) + let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id)) .and_then(|new_id| { let def_id = new_id.def_id(); if def_id.node != 0 && def_id != ast_util::local_def(id) { @@ -776,10 +776,10 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { def::DefMethod(declid, provenence) => { let sub_span = self.span.sub_span_for_meth_name(span); let defid = if declid.krate == ast::LOCAL_CRATE { - let ti = ty::impl_or_trait_item(self.tcx, declid); + let ti = self.tcx.impl_or_trait_item(declid); match provenence { def::FromTrait(def_id) => { - Some(ty::trait_items(self.tcx, def_id) + Some(self.tcx.trait_items(def_id) .iter() .find(|mr| { mr.name() == ti.name() @@ -793,10 +793,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { .unwrap() .iter() .find(|mr| { - ty::impl_or_trait_item( - self.tcx, - mr.def_id() - ).name() == ti.name() + self.tcx.impl_or_trait_item(mr.def_id()).name() + == ti.name() }) .unwrap() .def_id()) @@ -826,7 +824,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { // modules or types in the path prefix match def { def::DefMethod(did, _) => { - let ti = ty::impl_or_trait_item(self.tcx, did); + let ti = self.tcx.impl_or_trait_item(did); if let ty::MethodTraitItem(m) = ti { if m.explicit_self == ty::StaticExplicitSelfCategory { self.write_sub_path_trait_truncated(path); @@ -895,14 +893,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { ty::MethodStaticClosure(def_id) => { // method invoked on an object with a concrete type (not a static method) let decl_id = - match ty::trait_item_of_item(self.tcx, def_id) { + match self.tcx.trait_item_of_item(def_id) { None => None, Some(decl_id) => Some(decl_id.def_id()), }; // This incantation is required if the method referenced is a // trait's default implementation. - let def_id = match ty::impl_or_trait_item(self.tcx, def_id) { + let def_id = match self.tcx.impl_or_trait_item(def_id) { ty::MethodTraitItem(method) => { method.provided_source.unwrap_or(def_id) } @@ -915,16 +913,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { } ty::MethodTypeParam(ref mp) => { // method invoked on a type parameter - let trait_item = ty::trait_item(self.tcx, - mp.trait_ref.def_id, - mp.method_num); + let trait_item = self.tcx.trait_item(mp.trait_ref.def_id, + mp.method_num); (None, Some(trait_item.def_id())) } ty::MethodTraitObject(ref mo) => { // method invoked on a trait instance - let trait_item = ty::trait_item(self.tcx, - mo.trait_ref.def_id, - mo.method_num); + let trait_item = self.tcx.trait_item(mo.trait_ref.def_id, + mo.method_num); (None, Some(trait_item.def_id())) } }; @@ -953,7 +949,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { def::DefConst(..) | def::DefAssociatedConst(..) => None, def::DefVariant(_, variant_id, _) => Some(variant_id), _ => { - match ty::ty_to_def_id(ty::node_id_to_type(self.tcx, p.id)) { + match self.tcx.node_id_to_type(p.id).ty_to_def_id() { None => { self.sess.span_bug(p.span, &format!("Could not find struct_def for `{}`", @@ -965,7 +961,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { }; if let Some(struct_def) = struct_def { - let struct_fields = ty::lookup_struct_fields(self.tcx, struct_def); + let struct_fields = self.tcx.lookup_struct_fields(struct_def); for &Spanned { node: ref field, span } in fields { let sub_span = self.span.span_for_first_ident(span); for f in &struct_fields { @@ -1252,10 +1248,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> { self.visit_expr(&**sub_ex); - let ty = &ty::expr_ty_adjusted(self.tcx, &**sub_ex).sty; + let ty = &self.tcx.expr_ty_adjusted(&**sub_ex).sty; match *ty { ty::TyStruct(def_id, _) => { - let fields = ty::lookup_struct_fields(self.tcx, def_id); + let fields = self.tcx.lookup_struct_fields(def_id); for (i, f) in fields.iter().enumerate() { if i == idx.node { let sub_span = self.span.sub_span_after_token(ex.span, token::Dot); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index fdfb101ed78cc..27805b9d8330b 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -327,10 +327,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { match expr.node { ast::ExprField(ref sub_ex, ident) => { - let ty = &ty::expr_ty_adjusted(self.tcx, &sub_ex).sty; + let ty = &self.tcx.expr_ty_adjusted(&sub_ex).sty; match *ty { ty::TyStruct(def_id, _) => { - let fields = ty::lookup_struct_fields(self.tcx, def_id); + let fields = self.tcx.lookup_struct_fields(def_id); for f in &fields { if f.name == ident.node.name { let sub_span = self.span_utils.span_for_last_ident(expr.span); @@ -354,7 +354,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } ast::ExprStruct(ref path, _, _) => { - let ty = &ty::expr_ty_adjusted(&self.tcx, expr).sty; + let ty = &self.tcx.expr_ty_adjusted(expr).sty; match *ty { ty::TyStruct(def_id, _) => { let sub_span = self.span_utils.span_for_last_ident(path.span); @@ -384,7 +384,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { struct_id: DefId, parent: NodeId) -> VariableRefData { - let fields = ty::lookup_struct_fields(&self.tcx, struct_id); + let fields = self.tcx.lookup_struct_fields(struct_id); let field_name = get_ident(field_ref.ident.node).to_string(); for f in &fields { if f.name == field_ref.ident.node.name { diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 4667e36c64a9a..47c2a5e579d94 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -197,6 +197,7 @@ use middle::def::{self, DefMap}; use middle::expr_use_visitor as euv; use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; +use middle::mem_categorization::Typer; use middle::pat_util::*; use trans::adt; use trans::base::*; @@ -235,7 +236,7 @@ struct ConstantExpr<'a>(&'a ast::Expr); impl<'a> ConstantExpr<'a> { fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool { match const_eval::compare_lit_exprs(tcx, self.0, other.0, None, - |id| {ty::node_id_item_substs(tcx, id).substs}) { + |id| {tcx.node_id_item_substs(id).substs}) { Some(result) => result == Ordering::Equal, None => panic!("compare_list_exprs: type mismatch"), } @@ -279,7 +280,7 @@ impl<'a, 'tcx> Opt<'a, 'tcx> { let ccx = bcx.ccx(); match *self { ConstantValue(ConstantExpr(lit_expr), _) => { - let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id); + let lit_ty = bcx.tcx().node_id_to_type(lit_expr.id); let (llval, _) = consts::const_expr(ccx, &*lit_expr, bcx.fcx.param_substs, None); let lit_datum = immediate_rvalue(llval, lit_ty); let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx)); @@ -562,7 +563,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>( check_match::Constructor::Variant(def_id) }; - let param_env = ty::empty_parameter_environment(bcx.tcx()); + let param_env = bcx.tcx().empty_parameter_environment(); let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx(), param_env: param_env, @@ -603,7 +604,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def()); match opt_def { Some(def::DefVariant(enum_id, var_id, _)) => { - let variant = ty::enum_variant_with_id(tcx, enum_id, var_id); + let variant = tcx.enum_variant_with_id(enum_id, var_id); Variant(variant.disr_val, adt::represent_node(bcx, cur.id), var_id, @@ -1067,7 +1068,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx(), - param_env: ty::empty_parameter_environment(bcx.tcx()), + param_env: bcx.tcx().empty_parameter_environment(), }; let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) { let repr = adt::represent_type(bcx.ccx(), left_ty); @@ -1090,9 +1091,9 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, // The last field is technically unsized but // since we can only ever match that field behind // a reference we construct a fat ptr here. - let fields = ty::lookup_struct_fields(bcx.tcx(), def_id); + let fields = bcx.tcx().lookup_struct_fields(def_id); let unsized_ty = fields.iter().last().map(|field| { - let fty = ty::lookup_field_type(bcx.tcx(), def_id, field.id, substs); + let fty = bcx.tcx().lookup_field_type(def_id, field.id, substs); monomorphize::normalize_associated_type(bcx.tcx(), &fty) }).unwrap(); let llty = type_of::type_of(bcx.ccx(), unsized_ty); @@ -1409,13 +1410,13 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); let tcx = bcx.tcx(); - let param_env = ty::empty_parameter_environment(tcx); + let param_env = tcx.empty_parameter_environment(); let llmatch; let trmode; match bm { ast::BindByValue(_) - if !ty::type_moves_by_default(¶m_env, span, variable_ty) || reassigned => + if !param_env.type_moves_by_default(variable_ty, span) || reassigned => { llmatch = alloca_no_lifetime(bcx, llvariable_ty.ptr_to(), @@ -1468,7 +1469,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>, } let t = node_id_type(bcx, discr_expr.id); - let chk = if ty::type_is_empty(tcx, t) { + let chk = if t.is_empty(tcx) { Unreachable } else { Infallible @@ -1747,9 +1748,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, match opt_def { Some(def::DefVariant(enum_id, var_id, _)) => { let repr = adt::represent_node(bcx, pat.id); - let vinfo = ty::enum_variant_with_id(ccx.tcx(), - enum_id, - var_id); + let vinfo = ccx.tcx().enum_variant_with_id(enum_id, var_id); let args = extract_variant_args(bcx, &*repr, vinfo.disr_val, @@ -1789,7 +1788,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let pat_repr = adt::represent_type(bcx.ccx(), pat_ty); expr::with_field_tys(tcx, pat_ty, Some(pat.id), |discr, field_tys| { for f in fields { - let ix = ty::field_idx_strict(tcx, f.node.ident.name, field_tys); + let ix = tcx.field_idx_strict(f.node.ident.name, field_tys); let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val, discr, ix); bcx = bind_irrefutable_pat(bcx, &*f.node.pat, fldptr, cleanup_scope); diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 255920aa96d54..3ce76167e8517 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -209,13 +209,13 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Univariant(mk_struct(cx, &elems[..], false, t), 0) } ty::TyStruct(def_id, substs) => { - let fields = ty::lookup_struct_fields(cx.tcx(), def_id); + let fields = cx.tcx().lookup_struct_fields(def_id); let mut ftys = fields.iter().map(|field| { - let fty = ty::lookup_field_type(cx.tcx(), def_id, field.id, substs); + let fty = cx.tcx().lookup_field_type(def_id, field.id, substs); monomorphize::normalize_associated_type(cx.tcx(), &fty) }).collect::>(); - let packed = ty::lookup_packed(cx.tcx(), def_id); - let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag(); + let packed = cx.tcx().lookup_packed(def_id); + let dtor = cx.tcx().ty_dtor(def_id).has_drop_flag(); if dtor { ftys.push(cx.tcx().dtor_type()); } @@ -230,10 +230,10 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ty::TyEnum(def_id, substs) => { let cases = get_cases(cx.tcx(), def_id, substs); - let hint = *ty::lookup_repr_hints(cx.tcx(), def_id).get(0) + let hint = *cx.tcx().lookup_repr_hints(def_id).get(0) .unwrap_or(&attr::ReprAny); - let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag(); + let dtor = cx.tcx().ty_dtor(def_id).has_drop_flag(); if cases.is_empty() { // Uninhabitable; represent as unit @@ -261,9 +261,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // been rejected by a checker before this point. if !cases.iter().enumerate().all(|(i,c)| c.discr == (i as Disr)) { cx.sess().bug(&format!("non-C-like enum {} with specified \ - discriminants", - ty::item_path_str(cx.tcx(), - def_id))); + discriminants", + cx.tcx().item_path_str(def_id))); } if cases.len() == 1 { @@ -411,9 +410,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, // Is this the NonZero lang item wrapping a pointer or integer type? ty::TyStruct(did, substs) if Some(did) == tcx.lang_items.non_zero() => { - let nonzero_fields = ty::lookup_struct_fields(tcx, did); + let nonzero_fields = tcx.lookup_struct_fields(did); assert_eq!(nonzero_fields.len(), 1); - let nonzero_field = ty::lookup_field_type(tcx, did, nonzero_fields[0].id, substs); + let nonzero_field = tcx.lookup_field_type(did, nonzero_fields[0].id, substs); match nonzero_field.sty { ty::TyRawPtr(ty::mt { ty, .. }) if !type_is_sized(tcx, ty) => { path.push_all(&[0, FAT_PTR_ADDR]); @@ -430,9 +429,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, // Perhaps one of the fields of this struct is non-zero // let's recurse and find out ty::TyStruct(def_id, substs) => { - let fields = ty::lookup_struct_fields(tcx, def_id); + let fields = tcx.lookup_struct_fields(def_id); for (j, field) in fields.iter().enumerate() { - let field_ty = ty::lookup_field_type(tcx, def_id, field.id, substs); + let field_ty = tcx.lookup_field_type(def_id, field.id, substs); if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) { fpath.push(j); return Some(fpath); @@ -504,7 +503,7 @@ fn get_cases<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: ast::DefId, substs: &subst::Substs<'tcx>) -> Vec> { - ty::enum_variants(tcx, def_id).iter().map(|vi| { + tcx.enum_variants(def_id).iter().map(|vi| { let arg_tys = vi.args.iter().map(|&raw_ty| { monomorphize::apply_param_substs(tcx, substs, &raw_ty) }).collect(); diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index db29a43afce77..b432560bc4b3c 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -153,7 +153,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx _ => ccx.sess().bug("expected closure or function.") }; - let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); + let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); let mut attrs = llvm::AttrBuilder::new(); let ret_ty = fn_sig.output; @@ -274,7 +274,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx // `&T` where `T` contains no `UnsafeCell` is immutable, and can be marked as // both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely // on memory dependencies rather than pointer equality - let interior_unsafe = ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe(); + let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe(); if mt.mutbl == ast::MutMutable || !interior_unsafe { attrs.arg(idx, llvm::Attribute::NoAlias); diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index b86bf67869d77..42108d6d6e7b7 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -232,7 +232,7 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, // don't do this then linker errors can be generated where the linker // complains that one object files has a thread local version of the // symbol and another one doesn't. - for attr in ty::get_attrs(ccx.tcx(), did).iter() { + for attr in ccx.tcx().get_attrs(did).iter() { if attr.check_name("thread_local") { llvm::set_thread_local(c, true); } @@ -462,7 +462,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, let ccx = fcx.ccx; let repr = adt::represent_type(ccx, t); - let variants = ty::enum_variants(ccx.tcx(), tid); + let variants = ccx.tcx().enum_variants(tid); let n_variants = (*variants).len(); // NB: we must hit the discriminant first so that structural @@ -1216,7 +1216,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, llfn: llfndecl, llenv: None, llretslotptr: Cell::new(None), - param_env: ty::empty_parameter_environment(ccx.tcx()), + param_env: ccx.tcx().empty_parameter_environment(), alloca_insert_pt: Cell::new(None), llreturn: Cell::new(None), needs_ret_allocas: nested_returns, @@ -1668,8 +1668,8 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let _s = StatRecorder::new(ccx, ccx.tcx().map.path_to_string(id).to_string()); debug!("trans_fn(param_substs={:?})", param_substs); let _icx = push_ctxt("trans_fn"); - let fn_ty = ty::node_id_to_type(ccx.tcx(), id); - let output_type = ty::erase_late_bound_regions(ccx.tcx(), &fn_ty.fn_ret()); + let fn_ty = ccx.tcx().node_id_to_type(id); + let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret()); let abi = fn_ty.fn_abi(); trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi, closure::ClosureEnv::NotClosure); @@ -1704,7 +1704,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let result_ty = match ctor_ty.sty { ty::TyBareFn(_, ref bft) => { - ty::erase_late_bound_regions(bcx.tcx(), &bft.sig.output()).unwrap() + bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap() } _ => ccx.sess().bug( &format!("trans_enum_variant_constructor: \ @@ -1777,12 +1777,12 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx disr: ty::Disr, param_substs: &'tcx Substs<'tcx>, llfndecl: ValueRef) { - let ctor_ty = ty::node_id_to_type(ccx.tcx(), ctor_id); + let ctor_ty = ccx.tcx().node_id_to_type(ctor_id); let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty); let result_ty = match ctor_ty.sty { ty::TyBareFn(_, ref bft) => { - ty::erase_late_bound_regions(ccx.tcx(), &bft.sig.output()) + ccx.tcx().erase_late_bound_regions(&bft.sig.output()) } _ => ccx.sess().bug( &format!("trans_enum_variant_or_tuple_like_struct: \ @@ -1798,9 +1798,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx assert!(!fcx.needs_ret_allocas); - let arg_tys = - ty::erase_late_bound_regions( - ccx.tcx(), &ctor_ty.fn_args()); + let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args()); let arg_datums = create_datums_for_fn_args(bcx, &arg_tys[..]); @@ -1836,7 +1834,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, return } - let ty = ty::node_id_to_type(ccx.tcx(), id); + let ty = ccx.tcx().node_id_to_type(id); let avar = adt::represent_type(ccx, ty); match *avar { adt::General(_, ref variants, _) => { @@ -2035,7 +2033,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { // error in trans. This is used to write compile-fail tests // that actually test that compilation succeeds without // reporting an error. - if ty::has_attr(ccx.tcx(), local_def(item.id), "rustc_error") { + if ccx.tcx().has_attr(local_def(item.id), "rustc_error") { ccx.tcx().sess.span_fatal(item.span, "compilation successful"); } } @@ -2314,7 +2312,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { debug!("get_item_val: id={} item={:?}", id, item); let val = match item { ast_map::NodeItem(i) => { - let ty = ty::node_id_to_type(ccx.tcx(), i.id); + let ty = ccx.tcx().node_id_to_type(i.id); let sym = || exported_name(ccx, id, ty, &i.attrs); let v = match i.node { @@ -2421,7 +2419,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { match ni.node { ast::ForeignItemFn(..) => { let abi = ccx.tcx().map.get_foreign_abi(id); - let ty = ty::node_id_to_type(ccx.tcx(), ni.id); + let ty = ccx.tcx().node_id_to_type(ni.id); let name = foreign::link_name(&*ni); let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name); attributes::from_fn_attrs(ccx, &ni.attrs, llfn); @@ -2442,7 +2440,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { } }; assert!(!args.is_empty()); - let ty = ty::node_id_to_type(ccx.tcx(), id); + let ty = ccx.tcx().node_id_to_type(id); let parent = ccx.tcx().map.get_parent(id); let enm = ccx.tcx().map.expect_item(parent); let sym = exported_name(ccx, @@ -2471,7 +2469,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { }; let parent = ccx.tcx().map.get_parent(id); let struct_item = ccx.tcx().map.expect_item(parent); - let ty = ty::node_id_to_type(ccx.tcx(), ctor_id); + let ty = ccx.tcx().node_id_to_type(ctor_id); let sym = exported_name(ccx, id, ty, @@ -2503,7 +2501,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { fn register_method(ccx: &CrateContext, id: ast::NodeId, attrs: &[ast::Attribute], span: Span) -> ValueRef { - let mty = ty::node_id_to_type(ccx.tcx(), id); + let mty = ccx.tcx().node_id_to_type(id); let sym = exported_name(ccx, id, mty, &attrs); diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index a7c01036f845e..24abe0ed3fdd2 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -173,7 +173,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr) bcx.fcx.param_substs).val) } def::DefVariant(tid, vid, _) => { - let vinfo = ty::enum_variant_with_id(bcx.tcx(), tid, vid); + let vinfo = bcx.tcx().enum_variant_with_id(tid, vid); let substs = common::node_id_substs(bcx.ccx(), ExprId(ref_expr.id), bcx.fcx.param_substs); @@ -307,7 +307,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( bare_fn_ty)); } }; - let sig = ty::erase_late_bound_regions(tcx, sig); + let sig = tcx.erase_late_bound_regions(sig); let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec()); let tuple_fn_ty = tcx.mk_fn(opt_def_id, tcx.mk_bare_fn(ty::BareFnTy { @@ -406,17 +406,17 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( let substs = substs.erase_regions(); // Load the info for the appropriate trait if necessary. - match ty::trait_of_item(tcx, def_id) { + match tcx.trait_of_item(def_id) { None => {} Some(trait_id) => { - ty::populate_implementations_for_trait_if_necessary(tcx, trait_id) + tcx.populate_implementations_for_trait_if_necessary(trait_id) } } // We need to do a bunch of special handling for default methods. // We need to modify the def_id and our substs in order to monomorphize // the function. - let (is_default, def_id, substs) = match ty::provided_source(tcx, def_id) { + let (is_default, def_id, substs) = match tcx.provided_source(def_id) { None => { (false, def_id, tcx.mk_substs(substs)) } @@ -434,16 +434,16 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( // So, what we need to do is find this substitution and // compose it with the one we already have. - let impl_id = ty::impl_or_trait_item(tcx, def_id).container() + let impl_id = tcx.impl_or_trait_item(def_id).container() .id(); - let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id); + let impl_or_trait_item = tcx.impl_or_trait_item(source_id); match impl_or_trait_item { ty::MethodTraitItem(method) => { - let trait_ref = ty::impl_trait_ref(tcx, impl_id).unwrap(); + let trait_ref = tcx.impl_trait_ref(impl_id).unwrap(); // Compute the first substitution let first_subst = - ty::make_substs_for_receiver_types(tcx, &trait_ref, &*method) + tcx.make_substs_for_receiver_types(&trait_ref, &*method) .erase_regions(); // And compose them @@ -516,7 +516,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( // Monotype of the REFERENCE to the function (type params // are subst'd) let ref_ty = match node { - ExprId(id) => ty::node_id_to_type(tcx, id), + ExprId(id) => tcx.node_id_to_type(id), MethodCallKey(method_call) => { tcx.method_map.borrow().get(&method_call).unwrap().ty } @@ -534,7 +534,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( } // Type scheme of the function item (may have type params) - let fn_type_scheme = ty::lookup_item_type(tcx, def_id); + let fn_type_scheme = tcx.lookup_item_type(def_id); let fn_type = monomorphize::normalize_associated_type(tcx, &fn_type_scheme.ty); // Find the actual function pointer. @@ -640,7 +640,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug_loc: DebugLoc) -> Result<'blk, 'tcx> { let fty = if did.krate == ast::LOCAL_CRATE { - ty::node_id_to_type(bcx.tcx(), did.node) + bcx.tcx().node_id_to_type(did.node) } else { csearch::get_type(bcx.tcx(), did).ty }; @@ -692,7 +692,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let (abi, ret_ty) = match callee_ty.sty { ty::TyBareFn(_, ref f) => { - let output = ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output()); + let output = bcx.tcx().erase_late_bound_regions(&f.sig.output()); (f.abi, output) } _ => panic!("expected bare rust fn or closure in trans_call_inner") @@ -914,9 +914,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>( ignore_self: bool) -> Block<'blk, 'tcx> { - let args = - ty::erase_late_bound_regions( - bcx.tcx(), &fn_ty.fn_args()); + let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args()); // Translate the `self` argument first. if !ignore_self { @@ -977,7 +975,7 @@ fn trans_overloaded_call_args<'blk, 'tcx>( ignore_self: bool) -> Block<'blk, 'tcx> { // Translate the `self` argument first. - let arg_tys = ty::erase_late_bound_regions(bcx.tcx(), &fn_ty.fn_args()); + let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args()); if !ignore_self { let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0])); bcx = trans_arg_datum(bcx, @@ -1023,7 +1021,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, debug!("trans_args(abi={})", abi); let _icx = push_ctxt("trans_args"); - let arg_tys = ty::erase_late_bound_regions(cx.tcx(), &fn_ty.fn_args()); + let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args()); let variadic = fn_ty.fn_sig().0.variadic; let mut bcx = cx; diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index b1c8671383767..cb30bcdbf5399 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -135,7 +135,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc return None } - let function_type = ty::node_id_to_type(ccx.tcx(), closure_id.node); + let function_type = ccx.tcx().node_id_to_type(closure_id.node); let function_type = monomorphize::apply_param_substs(ccx.tcx(), substs, &function_type); // Normalize type so differences in regions and typedefs don't cause @@ -218,9 +218,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, let function_type = typer.closure_type(closure_id, param_substs); let freevars: Vec = - ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect()); + tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); - let sig = ty::erase_late_bound_regions(tcx, &function_type.sig); + let sig = tcx.erase_late_bound_regions(&function_type.sig); trans_closure(ccx, decl, @@ -392,7 +392,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( ccx.sess().bug(&format!("symbol `{}` already defined", function_name)); }); - let sig = ty::erase_late_bound_regions(tcx, &llonce_bare_fn_ty.sig); + let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig); let (block_arena, fcx): (TypedArena<_>, FunctionContext); block_arena = TypedArena::new(); fcx = new_fn_ctxt(ccx, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 2aa12e088aa12..777b61f25f0ef 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -23,6 +23,7 @@ use middle::def; use middle::infer; use middle::lang_items::LangItem; use middle::mem_categorization as mc; +use middle::mem_categorization::Typer; use middle::region; use middle::subst::{self, Subst, Substs}; use trans::base; @@ -89,7 +90,7 @@ pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder where T : TypeFoldable<'tcx> { - let u = ty::anonymize_late_bound_regions(self.tcx(), t); + let u = self.tcx().anonymize_late_bound_regions(t); ty_fold::super_fold_binder(self, &u) } @@ -119,7 +120,7 @@ pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T /// Is the type's representation size known at compile time? pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { - ty::type_is_sized(None, tcx, DUMMY_SP, ty) + ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP) } pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { @@ -161,7 +162,7 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty< ty::TyFloat(_) | ty::TyTuple(_) | ty::TyRawPtr(_) => false, ty::TyEnum(did, substs) => - ty::enum_variants(tcx, did).iter().any(|v| + tcx.enum_variants(did).iter().any(|v| v.args.iter().any(|&aty| { let t = aty.subst(tcx, substs); type_needs_unwind_cleanup_(tcx, t, tycache) @@ -183,7 +184,7 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty< /// (Note that this implies that if `ty` has a destructor attached, /// then `type_needs_drop` will definitely return `true` for `ty`.) pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { - type_needs_drop_given_env(cx, ty, &ty::empty_parameter_environment(cx)) + type_needs_drop_given_env(cx, ty, &cx.empty_parameter_environment()) } /// Core implementation of type_needs_drop, potentially making use of @@ -195,7 +196,7 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>, // normalized version of the type, and therefore will definitely // know whether the type implements Copy (and thus needs no // cleanup/drop/zeroing) ... - let implements_copy = !ty::type_moves_by_default(¶m_env, DUMMY_SP, ty); + let implements_copy = !param_env.type_moves_by_default(ty, DUMMY_SP); if implements_copy { return false; } @@ -210,7 +211,7 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>, // bound attached (see above), it is sound to treat it as having a // destructor (e.g. zero its memory on move). - let contents = ty::type_contents(cx, ty); + let contents = ty.type_contents(cx); debug!("type_needs_drop ty={:?} contents={:?}", ty, contents); contents.needs_drop(cx) } @@ -218,9 +219,9 @@ fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>, fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { match ty.sty { ty::TyStruct(def_id, substs) => { - let fields = ty::lookup_struct_fields(ccx.tcx(), def_id); + let fields = ccx.tcx().lookup_struct_fields(def_id); fields.len() == 1 && { - let ty = ty::lookup_field_type(ccx.tcx(), def_id, fields[0].id, substs); + let ty = ccx.tcx().lookup_field_type(def_id, fields[0].id, substs); let ty = monomorphize::normalize_associated_type(ccx.tcx(), &ty); type_is_immediate(ccx, ty) } @@ -267,7 +268,7 @@ pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) - /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI /// compatibility). pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool { - ty.is_nil() || ty::type_is_empty(ccx.tcx(), ty) + ty.is_nil() || ty.is_empty(ccx.tcx()) } /// Generates a unique symbol based off the name given. This is used to create @@ -661,8 +662,8 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone()) } - fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool { - self.fcx.param_env.type_moves_by_default(span, ty) + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { + self.fcx.param_env.type_moves_by_default(ty, span) } } @@ -952,7 +953,7 @@ pub fn monomorphize_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, t: Ty<'tcx>) -> T pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> { let tcx = bcx.tcx(); - let t = ty::node_id_to_type(tcx, id); + let t = tcx.node_id_to_type(id); monomorphize_type(bcx, t) } @@ -961,7 +962,7 @@ pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> } pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> { - monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex)) + monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex)) } /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we @@ -989,7 +990,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}", trait_ref, trait_ref.def_id()); - ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id()); + tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx); // Do the initial selection for the obligation. This yields the @@ -1077,7 +1078,7 @@ impl<'a,'tcx> NormalizingClosureTyper<'a,'tcx> { pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> { // Parameter environment is used to give details about type parameters, // but since we are in trans, everything is fully monomorphized. - NormalizingClosureTyper { param_env: ty::empty_parameter_environment(tcx) } + NormalizingClosureTyper { param_env: tcx.empty_parameter_environment() } } } @@ -1111,7 +1112,7 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> { { // the substitutions in `substs` are already monomorphized, // but we still must normalize associated types - let result = ty::closure_upvars(&self.param_env, def_id, substs); + let result = self.param_env.closure_upvars(def_id, substs); monomorphize::normalize_associated_type(self.param_env.tcx, &result) } } @@ -1187,7 +1188,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let substs = match node { ExprId(id) => { - ty::node_id_item_substs(tcx, id).substs + tcx.node_id_item_substs(id).substs } MethodCallKey(method_call) => { tcx.method_map.borrow().get(&method_call).unwrap().substs.clone() diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index a12c07c975017..8ec60000ee842 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -57,7 +57,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) C_integral(Type::uint_from_ty(cx, t), u, false) } ast::LitInt(i, ast::UnsuffixedIntLit(_)) => { - let lit_int_ty = ty::node_id_to_type(cx.tcx(), e.id); + let lit_int_ty = cx.tcx().node_id_to_type(e.id); match lit_int_ty.sty { ty::TyInt(t) => { C_integral(Type::int_from_ty(cx, t), i as u64, true) @@ -75,7 +75,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) C_floating(&fs, Type::float_from_ty(cx, t)) } ast::LitFloatUnsuffixed(ref fs) => { - let lit_float_ty = ty::node_id_to_type(cx.tcx(), e.id); + let lit_float_ty = cx.tcx().node_id_to_type(e.id); match lit_float_ty.sty { ty::TyFloat(t) => { C_floating(&fs, Type::float_from_ty(cx, t)) @@ -249,7 +249,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Avoid autorefs as they would create global instead of stack // references, even when only the latter are correct. let ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, - &ty::expr_ty(ccx.tcx(), expr)); + &ccx.tcx().expr_ty(expr)); const_expr_unadjusted(ccx, expr, ty, param_substs, None) } else { const_expr(ccx, expr, param_substs, None).0 @@ -276,11 +276,11 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fn_args: FnArgMap) -> (ValueRef, Ty<'tcx>) { let ety = monomorphize::apply_param_substs(cx.tcx(), param_substs, - &ty::expr_ty(cx.tcx(), e)); + &cx.tcx().expr_ty(e)); let llconst = const_expr_unadjusted(cx, e, ety, param_substs, fn_args); let mut llconst = llconst; let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs, - &ty::expr_ty_adjusted(cx.tcx(), e)); + &cx.tcx().expr_ty_adjusted(e)); let opt_adj = cx.tcx().adjustments.borrow().get(&e.id).cloned(); match opt_adj { Some(ty::AdjustReifyFnPointer) => { @@ -588,7 +588,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args); let brepr = adt::represent_type(cx, bt); expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { - let ix = ty::field_idx_strict(cx.tcx(), field.node.name, field_tys); + let ix = cx.tcx().field_idx_strict(field.node.name, field_tys); adt::const_get_field(cx, &*brepr, bv, discr, ix) }) } @@ -803,7 +803,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprRepeat(ref elem, ref count) => { let unit_ty = ety.sequence_element_type(cx.tcx()); let llunitty = type_of::type_of(cx, unit_ty); - let n = ty::eval_repeat_count(cx.tcx(), count); + let n = cx.tcx().eval_repeat_count(count); let unit_val = const_expr(cx, &**elem, param_substs, fn_args).0; let vs: Vec<_> = repeat(unit_val).take(n).collect(); if val_ty(unit_val) != llunitty { @@ -829,9 +829,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, const_deref_ptr(cx, get_const_val(cx, def_id, e)) } def::DefVariant(enum_did, variant_did, _) => { - let vinfo = ty::enum_variant_with_id(cx.tcx(), - enum_did, - variant_did); + let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did); if !vinfo.args.is_empty() { // N-ary variant. expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val @@ -884,9 +882,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } def::DefVariant(enum_did, variant_did, _) => { let repr = adt::represent_type(cx, ety); - let vinfo = ty::enum_variant_with_id(cx.tcx(), - enum_did, - variant_did); + let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did); adt::trans_const(cx, &*repr, vinfo.disr_val, @@ -945,8 +941,8 @@ pub fn trans_static(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) -> // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. if m != ast::MutMutable { - let node_ty = ty::node_id_to_type(ccx.tcx(), id); - let tcontents = ty::type_contents(ccx.tcx(), node_ty); + let node_ty = ccx.tcx().node_id_to_type(id); + let tcontents = node_ty.type_contents(ccx.tcx()); if !tcontents.interior_unsafe() { llvm::LLVMSetGlobalConstant(g, True); } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index d7083eb2d3336..2c539b67cb627 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -101,7 +101,8 @@ use trans::cleanup::CleanupMethods; use trans::expr; use trans::tvec; use trans::type_of; -use middle::ty::{self, Ty}; +use middle::mem_categorization::Typer; +use middle::ty::Ty; use std::fmt; use syntax::ast; @@ -605,9 +606,8 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> { * affine values (since they must never be duplicated). */ - assert!(!ty::type_moves_by_default(&ty::empty_parameter_environment(bcx.tcx()), - DUMMY_SP, - self.ty)); + assert!(!bcx.tcx().empty_parameter_environment() + .type_moves_by_default(self.ty, DUMMY_SP)); self.shallow_copy_raw(bcx, dst) } diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 54cb87f8a7b3c..1fbbf0763aa53 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -242,9 +242,7 @@ impl<'tcx> TypeMap<'tcx> { ty::TyTrait(ref trait_data) => { unique_type_id.push_str("trait "); - let principal = - ty::erase_late_bound_regions(cx.tcx(), - &trait_data.principal); + let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal); from_def_id_and_substs(self, cx, @@ -261,7 +259,7 @@ impl<'tcx> TypeMap<'tcx> { unique_type_id.push_str(" fn("); - let sig = ty::erase_late_bound_regions(cx.tcx(), sig); + let sig = cx.tcx().erase_late_bound_regions(sig); for ¶meter_type in &sig.inputs { let parameter_type_id = @@ -376,7 +374,7 @@ impl<'tcx> TypeMap<'tcx> { unique_type_id.push_str("|"); - let sig = ty::erase_late_bound_regions(cx.tcx(), sig); + let sig = cx.tcx().erase_late_bound_regions(sig); for ¶meter_type in &sig.inputs { let parameter_type_id = @@ -626,7 +624,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, span: Span) -> MetadataCreationResult { - let signature = ty::erase_late_bound_regions(cx.tcx(), signature); + let signature = cx.tcx().erase_late_bound_regions(signature); let mut signature_metadata: Vec = Vec::with_capacity(signature.inputs.len() + 1); @@ -1176,7 +1174,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unique_type_id, containing_scope); - let mut fields = ty::struct_fields(cx.tcx(), def_id, substs); + let mut fields = cx.tcx().struct_fields(def_id, substs); // The `Ty` values returned by `ty::struct_fields` can still contain // `TyProjection` variants, so normalize those away. @@ -1588,7 +1586,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let loc = span_start(cx, definition_span); let file_metadata = file_metadata(cx, &loc.file.name); - let variants = ty::enum_variants(cx.tcx(), enum_def_id); + let variants = cx.tcx().enum_variants(enum_def_id); let enumerators_metadata: Vec = variants .iter() @@ -1891,7 +1889,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, }; let is_local_to_unit = is_node_local_to_unit(cx, node_id); - let variable_type = ty::node_id_to_type(cx.tcx(), node_id); + let variable_type = cx.tcx().node_id_to_type(node_id); let type_metadata = type_metadata(cx, variable_type, span); let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id)); let var_name = token::get_name(name).to_string(); diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 3c63f0fa30c1a..7487e8d331bf5 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -30,7 +30,7 @@ use rustc::ast_map; use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block}; use trans; use trans::monomorphize; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{Ty, ClosureTyper}; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; @@ -412,7 +412,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 assert_type_for_node_id(cx, fn_ast_id, error_reporting_span); - let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id); + let return_type = cx.tcx().node_id_to_type(fn_ast_id); let return_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &return_type); @@ -425,7 +425,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Arguments types for arg in &fn_decl.inputs { assert_type_for_node_id(cx, arg.pat.id, arg.pat.span); - let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id); + let arg_type = cx.tcx().node_id_to_type(arg.pat.id); let arg_type = monomorphize::apply_param_substs(cx.tcx(), param_substs, &arg_type); diff --git a/src/librustc_trans/trans/debuginfo/namespace.rs b/src/librustc_trans/trans/debuginfo/namespace.rs index e6fe674f22057..2e5943a248a5f 100644 --- a/src/librustc_trans/trans/debuginfo/namespace.rs +++ b/src/librustc_trans/trans/debuginfo/namespace.rs @@ -16,7 +16,7 @@ use llvm; use llvm::debuginfo::DIScope; use rustc::ast_map; use trans::common::CrateContext; -use middle::ty::{self, ClosureTyper}; +use middle::ty::ClosureTyper; use std::ffi::CString; use std::ptr; @@ -56,7 +56,7 @@ pub fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str { } pub fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc { - ty::with_path(cx.tcx(), def_id, |path| { + cx.tcx().with_path(def_id, |path| { // prepend crate name if not already present let krate = if def_id.krate == ast::LOCAL_CRATE { let crate_namespace_name = token::intern(crate_root_namespace(cx)); diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index 4092ba8bfa55a..6ea43d7392c94 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -106,7 +106,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push(']'); }, ty::TyTrait(ref trait_data) => { - let principal = ty::erase_late_bound_regions(cx.tcx(), &trait_data.principal); + let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal); push_item_name(cx, principal.def_id, false, output); push_type_params(cx, principal.substs, output); }, @@ -123,7 +123,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("fn("); - let sig = ty::erase_late_bound_regions(cx.tcx(), sig); + let sig = cx.tcx().erase_late_bound_regions(sig); if !sig.inputs.is_empty() { for ¶meter_type in &sig.inputs { push_debuginfo_type_name(cx, parameter_type, true, output); @@ -170,7 +170,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, def_id: ast::DefId, qualified: bool, output: &mut String) { - ty::with_path(cx.tcx(), def_id, |path| { + cx.tcx().with_path(def_id, |path| { if qualified { if def_id.krate == ast::LOCAL_CRATE { output.push_str(crate_root_namespace(cx)); diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index 8bc3326d30093..646ca6733c3b6 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -128,7 +128,7 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, _ => ccx.sess().bug("expected closure or fn") }; - let sig = ty::Binder(ty::erase_late_bound_regions(ccx.tcx(), sig)); + let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig)); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi); debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty)); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 2187b7f6ae1c6..8fd88055b8e45 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -73,7 +73,6 @@ use trans::monomorphize; use trans::tvec; use trans::type_of; use middle::cast::{CastKind, CastTy}; -use middle::ty::{struct_fields, tup_fields}; use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AdjustUnsafeFnPointer}; use middle::ty::{self, Ty}; use middle::ty::MethodCall; @@ -313,7 +312,7 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, old_info: Option, param_substs: &'tcx Substs<'tcx>) -> ValueRef { - let (source, target) = ty::struct_lockstep_tails(ccx.tcx(), source, target); + let (source, target) = ccx.tcx().struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { (&ty::TyArray(_, len), &ty::TySlice(_)) => C_uint(ccx, len), (&ty::TyTrait(_), &ty::TyTrait(_)) => { @@ -500,7 +499,7 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let kind = match fulfill_obligation(bcx.ccx(), span, trait_ref) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { - ty::custom_coerce_unsized_kind(bcx.tcx(), impl_def_id) + bcx.tcx().custom_coerce_unsized_kind(impl_def_id) } vtable => { bcx.sess().span_bug(span, &format!("invalid CoerceUnsized vtable: {:?}", @@ -748,7 +747,7 @@ fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, base: &ast::Expr, field: ast::Name) -> DatumBlock<'blk, 'tcx, Expr> { - trans_field(bcx, base, |tcx, field_tys| ty::field_idx_strict(tcx, field, field_tys)) + trans_field(bcx, base, |tcx, field_tys| tcx.field_idx_strict(field, field_tys)) } /// Translates `base.`. @@ -789,8 +788,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let ix_datum = unpack_datum!(bcx, trans(bcx, idx)); let ref_ty = // invoked methods have LB regions instantiated: - ty::no_late_bound_regions( - bcx.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); + bcx.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap(); let elt_ty = match ref_ty.builtin_deref(true) { None => { bcx.tcx().sess.span_bug(index_expr.span, @@ -1227,7 +1225,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, match def { def::DefVariant(tid, vid, _) => { - let variant_info = ty::enum_variant_with_id(bcx.tcx(), tid, vid); + let variant_info = bcx.tcx().enum_variant_with_id(tid, vid); if !variant_info.args.is_empty() { // N-ary variant. let llfn = callee::trans_fn_ref(bcx.ccx(), vid, @@ -1247,7 +1245,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, def::DefStruct(_) => { let ty = expr_ty(bcx, ref_expr); match ty.sty { - ty::TyStruct(did, _) if ty::has_dtor(bcx.tcx(), did) => { + ty::TyStruct(did, _) if bcx.tcx().has_dtor(did) => { let repr = adt::represent_type(bcx.ccx(), ty); adt::trans_set_discr(bcx, &*repr, lldest, 0); } @@ -1342,13 +1340,22 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, { match ty.sty { ty::TyStruct(did, substs) => { - let fields = struct_fields(tcx, did, substs); + let fields = tcx.struct_fields(did, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); op(0, &fields[..]) } ty::TyTuple(ref v) => { - op(0, &tup_fields(&v[..])) + let fields: Vec<_> = v.iter().enumerate().map(|(i, &f)| { + ty::field { + name: token::intern(&i.to_string()), + mt: ty::mt { + ty: f, + mutbl: ast::MutImmutable + } + } + }).collect(); + op(0, &fields) } ty::TyEnum(_, substs) => { @@ -1364,8 +1371,8 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>, let def = tcx.def_map.borrow().get(&node_id).unwrap().full_def(); match def { def::DefVariant(enum_id, variant_id, _) => { - let variant_info = ty::enum_variant_with_id(tcx, enum_id, variant_id); - let fields = struct_fields(tcx, variant_id, substs); + let variant_info = tcx.enum_variant_with_id(enum_id, variant_id); + let fields = tcx.struct_fields(variant_id, substs); let fields = monomorphize::normalize_associated_type(tcx, &fields); op(variant_info.disr_val, &fields[..]) } @@ -2241,8 +2248,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, }; let ref_ty = // invoked methods have their LB regions instantiated - ty::no_late_bound_regions( - ccx.tcx(), &method_ty.fn_ret()).unwrap().unwrap(); + ccx.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap(); let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref"); unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call, @@ -2629,9 +2635,9 @@ fn expr_kind(tcx: &ty::ctxt, expr: &ast::Expr) -> ExprKind { match expr.node { ast::ExprPath(..) => { - match ty::resolve_expr(tcx, expr) { + match tcx.resolve_expr(expr) { def::DefStruct(_) | def::DefVariant(..) => { - if let ty::TyBareFn(..) = ty::node_id_to_type(tcx, expr.id).sty { + if let ty::TyBareFn(..) = tcx.node_id_to_type(expr.id).sty { // ctor function ExprKind::RvalueDatum } else { diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 6f3346b9329a2..9e8c0189a9762 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -109,7 +109,7 @@ pub fn llvm_calling_convention(ccx: &CrateContext, pub fn register_static(ccx: &CrateContext, foreign_item: &ast::ForeignItem) -> ValueRef { - let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id); + let ty = ccx.tcx().node_id_to_type(foreign_item.id); let llty = type_of::type_of(ccx, ty); let ident = link_name(foreign_item); @@ -245,7 +245,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ty::TyBareFn(_, ref fn_ty) => (fn_ty.abi, &fn_ty.sig), _ => ccx.sess().bug("trans_native_call called on non-function type") }; - let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); + let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]); let fn_type = cabi::compute_abi_info(ccx, &llsig.llarg_tys, @@ -478,7 +478,7 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) { match foreign_mod.abi { Rust | RustIntrinsic => {} abi => { - let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id); + let ty = ccx.tcx().node_id_to_type(foreign_item.id); match ty.sty { ty::TyBareFn(_, bft) => gate_simd_ffi(ccx.tcx(), &**decl, bft), _ => ccx.tcx().sess.span_bug(foreign_item.span, @@ -554,7 +554,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext, let tys = foreign_types_for_id(ccx, node_id); let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys); - let t = ty::node_id_to_type(ccx.tcx(), node_id); + let t = ccx.tcx().node_id_to_type(node_id); let cconv = match t.sty { ty::TyBareFn(_, ref fn_ty) => { llvm_calling_convention(ccx, fn_ty.abi) @@ -578,7 +578,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, hash: Option<&str>) { let _icx = push_ctxt("foreign::build_foreign_fn"); - let fnty = ty::node_id_to_type(ccx.tcx(), id); + let fnty = ccx.tcx().node_id_to_type(id); let mty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fnty); let tys = foreign_types_for_fn_ty(ccx, mty); @@ -601,7 +601,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, { let _icx = push_ctxt("foreign::foreign::build_rust_fn"); let tcx = ccx.tcx(); - let t = ty::node_id_to_type(tcx, id); + let t = tcx.node_id_to_type(id); let t = monomorphize::apply_param_substs(tcx, param_substs, &t); let ps = ccx.tcx().map.with_path(id, |path| { @@ -933,7 +933,7 @@ fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn foreign_types_for_id<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId) -> ForeignTypes<'tcx> { - foreign_types_for_fn_ty(ccx, ty::node_id_to_type(ccx.tcx(), id)) + foreign_types_for_fn_ty(ccx, ccx.tcx().node_id_to_type(id)) } fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, @@ -942,7 +942,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::TyBareFn(_, ref fn_ty) => &fn_ty.sig, _ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type") }; - let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); + let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig); let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs); let fn_ty = cabi::compute_abi_info(ccx, &llsig.llarg_tys, diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index 7a5ccd5b9c617..3bcdcd89c47f5 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -326,7 +326,7 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } else { let tcx = ccx.tcx(); let name = csearch::get_symbol(&ccx.sess().cstore, did); - let class_ty = ty::lookup_item_type(tcx, parent_id).ty.subst(tcx, substs); + let class_ty = tcx.lookup_item_type(parent_id).ty.subst(tcx, substs); let llty = type_of_dtor(ccx, class_ty); let dtor_ty = ccx.tcx().mk_ctor_fn(did, &[get_drop_glue_type(ccx, t)], @@ -399,7 +399,7 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, in // Recurse to get the size of the dynamically sized field (must be // the last field). - let fields = ty::struct_fields(bcx.tcx(), id, substs); + let fields = bcx.tcx().struct_fields(id, substs); let last_field = fields[fields.len()-1]; let field_ty = last_field.mt.ty; let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info); @@ -495,7 +495,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK } ty::TyStruct(did, substs) | ty::TyEnum(did, substs) => { let tcx = bcx.tcx(); - match (ty::ty_dtor(tcx, did), skip_dtor) { + match (tcx.ty_dtor(did), skip_dtor) { (ty::TraitDtor(dtor, true), false) => { // FIXME(16758) Since the struct is unsized, it is hard to // find the drop flag (which is at the end of the struct). diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index f860fe44f28e7..75c80690f2ad4 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -14,7 +14,6 @@ use middle::astencode; use middle::subst::Substs; use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn}; use trans::common::*; -use middle::ty; use syntax::ast; use syntax::ast_util::local_def; @@ -28,7 +27,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) Some(&Some(node_id)) => { // Already inline debug!("instantiate_inline({}): already inline as node id {}", - ty::item_path_str(ccx.tcx(), fn_id), node_id); + ccx.tcx().item_path_str(fn_id), node_id); return Some(local_def(node_id)); } Some(&None) => { @@ -104,8 +103,8 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) let mut my_id = 0; match item.node { ast::ItemEnum(_, _) => { - let vs_here = ty::enum_variants(ccx.tcx(), local_def(item.id)); - let vs_there = ty::enum_variants(ccx.tcx(), parent_id); + let vs_here = ccx.tcx().enum_variants(local_def(item.id)); + let vs_there = ccx.tcx().enum_variants(parent_id); for (here, there) in vs_here.iter().zip(vs_there.iter()) { if there.id == fn_id { my_id = here.id.node; } ccx.external().borrow_mut().insert(there.id, Some(here.id.node)); @@ -140,7 +139,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) // the logic to do that already exists in `middle`. In order to // reuse that code, it needs to be able to look up the traits for // inlined items. - let ty_trait_item = ty::impl_or_trait_item(ccx.tcx(), fn_id).clone(); + let ty_trait_item = ccx.tcx().impl_or_trait_item(fn_id).clone(); ccx.tcx().impl_or_trait_items.borrow_mut() .insert(local_def(trait_item.id), ty_trait_item); @@ -157,7 +156,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) // Translate monomorphic impl methods immediately. if let ast::MethodImplItem(ref sig, ref body) = impl_item.node { - let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did); + let impl_tpt = ccx.tcx().lookup_item_type(impl_did); if impl_tpt.generics.types.is_empty() && sig.generics.ty_params.is_empty() { let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index a90b462b98572..b449c3ad060b8 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -163,7 +163,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let ret_ty = match callee_ty.sty { ty::TyBareFn(_, ref f) => { - ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output()) + bcx.tcx().erase_late_bound_regions(&f.sig.output()) } _ => panic!("expected bare_fn in trans_intrinsic_call") }; @@ -411,10 +411,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, C_str_slice(ccx, ty_name) } (_, "type_id") => { - let hash = ty::hash_crate_independent( - ccx.tcx(), - *substs.types.get(FnSpace, 0), - &ccx.link_meta().crate_hash); + let hash = ccx.tcx().hash_crate_independent(*substs.types.get(FnSpace, 0), + &ccx.link_meta().crate_hash); C_u64(ccx, hash) } (_, "init_dropped") => { diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index c6107f7d268af..a3e5b640fd0f1 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -182,7 +182,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \ expr_id={})", method_id, - ty::item_path_str(tcx, trait_id), + tcx.item_path_str(trait_id), expr_id); let mname = if method_id.krate == ast::LOCAL_CRATE { @@ -282,7 +282,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } traits::VtableObject(ref data) => { let trait_item_def_ids = - ty::trait_item_def_ids(ccx.tcx(), trait_id); + ccx.tcx().trait_item_def_ids(trait_id); let method_offset_in_trait = trait_item_def_ids.iter() .position(|item| item.def_id() == method_id) @@ -314,7 +314,7 @@ fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name) .expect("could not find impl while translating"); let meth_did = impl_items.iter() .find(|&did| { - ty::impl_or_trait_item(ccx.tcx(), did.def_id()).name() == name + ccx.tcx().impl_or_trait_item(did.def_id()).name() == name }).expect("could not find method while \ translating"); @@ -334,7 +334,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, traits::VtableImpl(vtable_impl) => { let ccx = bcx.ccx(); let impl_did = vtable_impl.impl_def_id; - let mname = match ty::trait_item(ccx.tcx(), trait_id, n_method) { + let mname = match ccx.tcx().trait_item(trait_id, n_method) { ty::MethodTraitItem(method) => method.name, _ => { bcx.tcx().sess.bug("can't monomorphize a non-method trait \ @@ -567,12 +567,12 @@ pub fn trans_object_shim<'a, 'tcx>( }; // Upcast to the trait in question and extract out the substitutions. - let upcast_trait_ref = ty::erase_late_bound_regions(tcx, &upcast_trait_ref); + let upcast_trait_ref = tcx.erase_late_bound_regions(&upcast_trait_ref); let object_substs = upcast_trait_ref.substs.clone().erase_regions(); debug!("trans_object_shim: object_substs={:?}", object_substs); // Lookup the type of this method as declared in the trait and apply substitutions. - let method_ty = match ty::trait_item(tcx, trait_id, method_offset_in_trait) { + let method_ty = match tcx.trait_item(trait_id, method_offset_in_trait) { ty::MethodTraitItem(method) => method, _ => { tcx.sess.bug("can't create a method shim for a non-method item") @@ -591,7 +591,7 @@ pub fn trans_object_shim<'a, 'tcx>( ccx.sess().bug(&format!("symbol `{}` already defined", function_name)); }); - let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig); + let sig = ccx.tcx().erase_late_bound_regions(&fty.sig); let empty_substs = tcx.mk_substs(Substs::trans_empty()); let (block_arena, fcx): (TypedArena<_>, FunctionContext); @@ -747,16 +747,16 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, substs, param_substs); - let trt_id = match ty::impl_trait_ref(tcx, impl_id) { + let trt_id = match tcx.impl_trait_ref(impl_id) { Some(t_id) => t_id.def_id, None => ccx.sess().bug("make_impl_vtable: don't know how to \ make a vtable for a type impl!") }; - ty::populate_implementations_for_trait_if_necessary(tcx, trt_id); + tcx.populate_implementations_for_trait_if_necessary(trt_id); let nullptr = C_null(Type::nil(ccx).ptr_to()); - let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id); + let trait_item_def_ids = tcx.trait_item_def_ids(trt_id); trait_item_def_ids .iter() @@ -775,7 +775,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("emit_vtable_methods: trait_method_def_id={:?}", trait_method_def_id); - let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) { + let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) { ty::MethodTraitItem(m) => m, _ => ccx.sess().bug("should be a method, not other assoc item"), }; @@ -793,7 +793,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // The substitutions we have are on the impl, so we grab // the method type from the impl to substitute into. let impl_method_def_id = method_with_name(ccx, impl_id, name); - let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) { + let impl_method_type = match tcx.impl_or_trait_item(impl_method_def_id) { ty::MethodTraitItem(m) => m, _ => ccx.sess().bug("should be a method, not other assoc item"), }; @@ -806,7 +806,7 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // particular set of type parameters. Note that this // method could then never be called, so we do not want to // try and trans it, in that case. Issue #23435. - if ty::provided_source(tcx, impl_method_def_id).is_some() { + if tcx.provided_source(impl_method_def_id).is_some() { let predicates = impl_method_type.predicates.predicates.subst(tcx, &substs); if !normalize_and_test_predicates(ccx, predicates.into_vec()) { debug!("emit_vtable_methods: predicates do not hold"); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 4d64b1c03b800..cae810c9082e5 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -56,7 +56,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, params: &psubsts.types }; - let item_ty = ty::lookup_item_type(ccx.tcx(), fn_id).ty; + let item_ty = ccx.tcx().lookup_item_type(fn_id).ty; debug!("monomorphic_fn about to subst into {:?}", item_ty); let mono_ty = item_ty.subst(ccx.tcx(), psubsts); @@ -64,7 +64,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, match ccx.monomorphized().borrow().get(&hash_id) { Some(&val) => { debug!("leaving monomorphic fn {}", - ty::item_path_str(ccx.tcx(), fn_id)); + ccx.tcx().item_path_str(fn_id)); return (val, mono_ty, false); } None => () @@ -198,7 +198,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } ast_map::NodeVariant(v) => { let parent = ccx.tcx().map.get_parent(fn_id.node); - let tvs = ty::enum_variants(ccx.tcx(), local_def(parent)); + let tvs = ccx.tcx().enum_variants(local_def(parent)); let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); let d = mk_lldecl(abi::Rust); attributes::inline(d, attributes::InlineAttr::Hint); @@ -284,7 +284,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.monomorphizing().borrow_mut().insert(fn_id, depth); - debug!("leaving monomorphic fn {}", ty::item_path_str(ccx.tcx(), fn_id)); + debug!("leaving monomorphic fn {}", ccx.tcx().item_path_str(fn_id)); (lldecl, mono_ty, true) } diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 3c6770caef8d1..d94a0e235ee86 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -225,7 +225,7 @@ fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, return expr::trans_into(bcx, &**element, Ignore); } SaveIn(lldest) => { - match ty::eval_repeat_count(bcx.tcx(), &**count_expr) { + match bcx.tcx().eval_repeat_count(&**count_expr) { 0 => expr::trans_into(bcx, &**element, Ignore), 1 => expr::trans_into(bcx, &**element, SaveIn(lldest)), count => { @@ -277,7 +277,7 @@ fn elements_required(bcx: Block, content_expr: &ast::Expr) -> usize { }, ast::ExprVec(ref es) => es.len(), ast::ExprRepeat(_, ref count_expr) => { - ty::eval_repeat_count(bcx.tcx(), &**count_expr) + bcx.tcx().eval_repeat_count(&**count_expr) } _ => bcx.tcx().sess.span_bug(content_expr.span, "unexpected vec content") diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 96eae5fd184ab..20d25518e2700 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -102,7 +102,7 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, sig, abi); - let sig = ty::erase_late_bound_regions(cx.tcx(), sig); + let sig = cx.tcx().erase_late_bound_regions(sig); assert!(!sig.variadic); // rust fns are never variadic let mut atys: Vec = Vec::new(); @@ -362,7 +362,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> cx.tn().find_type("str_slice").unwrap() } else { let ptr_ty = in_memory_type_of(cx, ty).ptr_to(); - let unsized_part = ty::struct_tail(cx.tcx(), ty); + let unsized_part = cx.tcx().struct_tail(ty); let info_ty = match unsized_part.sty { ty::TyStr | ty::TyArray(..) | ty::TySlice(_) => { Type::uint_from_ty(cx, ast::TyUs) @@ -454,7 +454,7 @@ fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, did: ast::DefId, tps: &[Ty<'tcx>]) -> String { - let base = ty::item_path_str(cx.tcx(), did); + let base = cx.tcx().item_path_str(did); let strings: Vec = tps.iter().map(|t| t.to_string()).collect(); let tstr = if strings.is_empty() { base diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d5e57e163029d..2575dc0184f8c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -124,7 +124,7 @@ pub trait AstConv<'tcx> { item_name: ast::Name) -> Ty<'tcx> { - if ty::binds_late_bound_regions(self.tcx(), &poly_trait_ref) { + if self.tcx().binds_late_bound_regions(&poly_trait_ref) { span_err!(self.tcx().sess, span, E0212, "cannot extract an associated type from a higher-ranked trait bound \ in this context"); @@ -513,7 +513,7 @@ fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec) for (input_type, input_pat) in input_tys.iter().zip(input_pats) { let mut accumulator = Vec::new(); - ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type); + input_type.accumulate_lifetimes_in_type(&mut accumulator); if accumulator.len() == 1 { // there's a chance that the unique lifetime of this @@ -1060,7 +1060,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>, let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> = traits::supertraits(tcx, object_trait_ref) .flat_map(|tr| { - let trait_def = ty::lookup_trait_def(tcx, tr.def_id()); + let trait_def = tcx.lookup_trait_def(tr.def_id()); trait_def.associated_type_names .clone() .into_iter() @@ -1078,7 +1078,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>, span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` (from the trait `{}`) must be specified", name, - ty::item_path_str(tcx, trait_def_id)); + tcx.item_path_str(trait_def_id)); } tcx.mk_trait(object.principal, object.bounds) @@ -1265,7 +1265,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>, _ => unreachable!() } } else { - let trait_items = ty::trait_items(tcx, trait_did); + let trait_items = tcx.trait_items(trait_did); let item = trait_items.iter().find(|i| i.name() == assoc_name); item.expect("missing associated type").def_id() }; @@ -1290,7 +1290,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>, let self_ty = if let Some(ty) = opt_self_ty { ty } else { - let path_str = ty::item_path_str(tcx, trait_def_id); + let path_str = tcx.item_path_str(trait_def_id); report_ambiguous_associated_type(tcx, span, "Type", @@ -2116,8 +2116,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => { match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) { def::DefTrait(trait_did) => { - if ty::try_add_builtin_trait(tcx, - trait_did, + if tcx.try_add_builtin_trait(trait_did, &mut builtin_bounds) { let segments = &b.trait_ref.path.segments; let parameters = &segments[segments.len() - 1].parameters; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index c223809b8c80e..87f867d7f90ac 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -147,7 +147,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, } ast::PatEnum(..) | ast::PatIdent(..) if pat_is_resolved_const(&tcx.def_map, pat) => { let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id(); - let const_scheme = ty::lookup_item_type(tcx, const_did); + let const_scheme = tcx.lookup_item_type(const_did); assert!(const_scheme.generics.is_empty()); let const_ty = pcx.fcx.instantiate_type_scheme(pat.span, &Substs::empty(), @@ -227,8 +227,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, resolve_ty_and_def_ufcs(fcx, path_res, Some(self_ty), path, pat.span, pat.id) { if check_assoc_item_is_const(pcx, def, pat.span) { - let scheme = ty::lookup_item_type(tcx, def.def_id()); - let predicates = ty::lookup_predicates(tcx, def.def_id()); + let scheme = tcx.lookup_item_type(def.def_id()); + let predicates = tcx.lookup_predicates(def.def_id()); instantiate_path(fcx, segments, scheme, &predicates, opt_ty, def, pat.span, pat.id); @@ -555,7 +555,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat, return; }, _ => { - let def_type = ty::lookup_item_type(tcx, def.def_id()); + let def_type = tcx.lookup_item_type(def.def_id()); match def_type.ty.sty { ty::TyStruct(struct_def_id, _) => (struct_def_id, struct_def_id), @@ -579,8 +579,8 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat, instantiate_path(pcx.fcx, &path.segments, - ty::lookup_item_type(tcx, enum_def_id), - &ty::lookup_predicates(tcx, enum_def_id), + tcx.lookup_item_type(enum_def_id), + &tcx.lookup_predicates(enum_def_id), None, def, pat.span, @@ -595,7 +595,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat, .map(|substs| substs.substs.clone()) .unwrap_or_else(|| Substs::empty()); - let struct_fields = ty::struct_fields(tcx, variant_def_id, &item_substs); + let struct_fields = tcx.struct_fields(variant_def_id, &item_substs); check_struct_pat_fields(pcx, pat.span, fields, &struct_fields, variant_def_id, etc); } @@ -631,10 +631,10 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, let enum_def = def.variant_def_ids() .map_or_else(|| def.def_id(), |(enum_def, _)| enum_def); - let ctor_scheme = ty::lookup_item_type(tcx, enum_def); - let ctor_predicates = ty::lookup_predicates(tcx, enum_def); + let ctor_scheme = tcx.lookup_item_type(enum_def); + let ctor_predicates = tcx.lookup_predicates(enum_def); let path_scheme = if ctor_scheme.ty.is_fn() { - let fn_ret = ty::no_late_bound_regions(tcx, &ctor_scheme.ty.fn_ret()).unwrap(); + let fn_ret = tcx.no_late_bound_regions(&ctor_scheme.ty.fn_ret()).unwrap(); ty::TypeScheme { ty: fn_ret.unwrap(), generics: ctor_scheme.generics, @@ -664,14 +664,14 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, ty::TyEnum(enum_def_id, expected_substs) if def == def::DefVariant(enum_def_id, def.def_id(), false) => { - let variant = ty::enum_variant_with_id(tcx, enum_def_id, def.def_id()); + let variant = tcx.enum_variant_with_id(enum_def_id, def.def_id()); (variant.args.iter() .map(|t| fcx.instantiate_type_scheme(pat.span, expected_substs, t)) .collect(), "variant") } ty::TyStruct(struct_def_id, expected_substs) => { - let struct_fields = ty::struct_fields(tcx, struct_def_id, expected_substs); + let struct_fields = tcx.struct_fields(struct_def_id, expected_substs); (struct_fields.iter() .map(|field| fcx.instantiate_type_scheme(pat.span, expected_substs, @@ -761,7 +761,7 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, .unwrap_or_else(|| { span_err!(tcx.sess, span, E0026, "struct `{}` does not have a field named `{}`", - ty::item_path_str(tcx, struct_id), + tcx.item_path_str(struct_id), token::get_ident(field.ident)); tcx.types.err }) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 30ed9d9eb2f24..7109e45b55279 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -358,9 +358,8 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { // can't because of the annoying need for a TypeTrace. // (This always bites me, should find a way to // refactor it.) - let method_sig = - ty::no_late_bound_regions(fcx.tcx(), - method_callee.ty.fn_sig()).unwrap(); + let method_sig = fcx.tcx().no_late_bound_regions(method_callee.ty.fn_sig()) + .unwrap(); debug!("attempt_resolution: method_callee={:?}", method_callee); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 1ff4c4eb0f455..49b47da517720 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -80,7 +80,7 @@ fn unsize_kind<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>, ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length), ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal_def_id())), ty::TyStruct(did, substs) => { - match ty::struct_fields(fcx.tcx(), did, substs).pop() { + match fcx.tcx().struct_fields(did, substs).pop() { None => None, Some(f) => unsize_kind(fcx, f.mt.ty) } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index ec4c4a3271433..d431c0fda9865 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -65,10 +65,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, fcx.write_ty(expr.id, closure_type); - let fn_sig = - ty::liberate_late_bound_regions(fcx.tcx(), - region::DestructionScopeData::new(body.id), - &fn_ty.sig); + let fn_sig = fcx.tcx().liberate_late_bound_regions( + region::DestructionScopeData::new(body.id), &fn_ty.sig); check_fn(fcx.ccx, ast::Unsafety::Normal, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 612b574dfa7c6..73b9a16d1ebea 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -271,7 +271,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } _ => (source, None) }; - let source = ty::adjust_ty_for_autoref(self.tcx(), source, reborrow); + let source = source.adjust_for_autoref(self.tcx(), reborrow); let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 44768990d68c4..349d1a8bb65a8 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -100,7 +100,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, token::get_name(trait_m.name), impl_m.fty.sig.0.inputs.len(), if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"}, - ty::item_path_str(tcx, trait_m.def_id), + tcx.item_path_str(trait_m.def_id), trait_m.fty.sig.0.inputs.len()); return; } diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index fb17f41d88d9a..a48cffb4472f4 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -37,8 +37,8 @@ use syntax::codemap::{self, Span}; /// pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(), ()> { let ty::TypeScheme { generics: ref dtor_generics, - ty: dtor_self_type } = ty::lookup_item_type(tcx, drop_impl_did); - let dtor_predicates = ty::lookup_predicates(tcx, drop_impl_did); + ty: dtor_self_type } = tcx.lookup_item_type(drop_impl_did); + let dtor_predicates = tcx.lookup_predicates(drop_impl_did); match dtor_self_type.sty { ty::TyEnum(self_type_did, self_to_impl_substs) | ty::TyStruct(self_type_did, self_to_impl_substs) | @@ -91,7 +91,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( let ty::TypeScheme { generics: ref named_type_generics, ty: named_type } = - ty::lookup_item_type(tcx, self_type_did); + tcx.lookup_item_type(self_type_did); let infcx = infer::new_infer_ctxt(tcx); infcx.commit_if_ok(|snapshot| { @@ -179,7 +179,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( // We can assume the predicates attached to struct/enum definition // hold. - let generic_assumptions = ty::lookup_predicates(tcx, self_type_did); + let generic_assumptions = tcx.lookup_predicates(self_type_did); let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs); assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::SelfSpace)); @@ -288,7 +288,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx> rcx.tcx().sess, span, "overflowed on enum {} variant {} argument {} type: {}", - ty::item_path_str(tcx, def_id), + tcx.item_path_str(def_id), variant, arg_index, detected_on_typ); @@ -298,7 +298,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx> rcx.tcx().sess, span, "overflowed on struct {} field {} type: {}", - ty::item_path_str(tcx, def_id), + tcx.item_path_str(def_id), field, detected_on_typ); } @@ -365,7 +365,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( let (typ, xref_depth) = match typ.sty { ty::TyStruct(struct_did, substs) => { if opt_phantom_data_def_id == Some(struct_did) { - let item_type = ty::lookup_item_type(rcx.tcx(), struct_did); + let item_type = rcx.tcx().lookup_item_type(struct_did); let tp_def = item_type.generics.types .opt_get(subst::TypeSpace, 0).unwrap(); let new_typ = substs.type_for_def(tp_def); @@ -471,13 +471,11 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( walker.skip_current_subtree(); let fields = - ty::lookup_struct_fields(rcx.tcx(), struct_did); + rcx.tcx().lookup_struct_fields(struct_did); for field in &fields { - let field_type = - ty::lookup_field_type(rcx.tcx(), - struct_did, - field.id, - substs); + let field_type = rcx.tcx().lookup_field_type(struct_did, + field.id, + substs); try!(iterate_over_potentially_unsafe_regions_in_type( rcx, breadcrumbs, @@ -501,9 +499,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( walker.skip_current_subtree(); let all_variant_info = - ty::substd_enum_variants(rcx.tcx(), - enum_did, - substs); + rcx.tcx().substd_enum_variants(enum_did, substs); for variant_info in &all_variant_info { for (i, arg_type) in variant_info.args.iter().enumerate() { try!(iterate_over_potentially_unsafe_regions_in_type( @@ -591,13 +587,13 @@ fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>, } } DtorKind::KnownDropMethod(dtor_method_did) => { - let impl_did = ty::impl_of_method(tcx, dtor_method_did) + let impl_did = tcx.impl_of_method(dtor_method_did) .unwrap_or_else(|| { tcx.sess.span_bug( span, "no Drop impl found for drop method") }); - let dtor_typescheme = ty::lookup_item_type(tcx, impl_did); + let dtor_typescheme = tcx.lookup_item_type(impl_did); let dtor_generics = dtor_typescheme.generics; let mut has_pred_of_interest = false; @@ -609,7 +605,7 @@ fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>, continue; } - for pred in ty::lookup_predicates(tcx, item_def_id).predicates { + for pred in tcx.lookup_predicates(item_def_id).predicates { let result = match pred { ty::Predicate::Equate(..) | ty::Predicate::RegionOutlives(..) | @@ -623,7 +619,7 @@ fn has_dtor_of_interest<'tcx>(tcx: &ty::ctxt<'tcx>, ty::Predicate::Trait(ty::Binder(ref t_pred)) => { let def_id = t_pred.trait_ref.def_id; - if ty::trait_items(tcx, def_id).len() != 0 { + if tcx.trait_items(def_id).len() != 0 { // If trait has items, assume it adds // capability to access borrowed data. true diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 2104ebaec45c9..5f7a78ec611a2 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -139,7 +139,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { let region = self.infcx().next_region_var(infer::Autoref(self.span)); let autoref = ty::AutoPtr(self.tcx().mk_region(region), mutbl); (Some(autoref), pick.unsize.map(|target| { - ty::adjust_ty_for_autoref(self.tcx(), target, Some(autoref)) + target.adjust_for_autoref(self.tcx(), Some(autoref)) })) } else { // No unsizing should be performed without autoref (at @@ -179,7 +179,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { if let Some(target) = unsize { target } else { - ty::adjust_ty_for_autoref(self.tcx(), autoderefd_ty, autoref) + autoderefd_ty.adjust_for_autoref(self.tcx(), autoref) } } @@ -199,7 +199,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { { match pick.kind { probe::InherentImplPick(impl_def_id) => { - assert!(ty::impl_trait_ref(self.tcx(), impl_def_id).is_none(), + assert!(self.tcx().impl_trait_ref(impl_def_id).is_none(), "impl {:?} is not an inherent impl", impl_def_id); let impl_polytype = check::impl_self_ty(self.fcx, self.span, impl_def_id); @@ -254,7 +254,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { self.fcx.instantiate_type_scheme( self.span, &impl_polytype.substs, - &ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap()); + &self.tcx().impl_trait_ref(impl_def_id).unwrap()); let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(), method_num: method_num, impl_def_id: Some(impl_def_id) }); @@ -262,7 +262,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } probe::TraitPick(trait_def_id, method_num) => { - let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + let trait_def = self.tcx().lookup_trait_def(trait_def_id); // Make a trait reference `$0 : Trait<$1...$n>` // consisting entirely of type variables. Later on in diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 6ba9704aa987f..0f8048f27a0e3 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -167,7 +167,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, m_name, trait_def_id); - let trait_def = ty::lookup_trait_def(fcx.tcx(), trait_def_id); + let trait_def = fcx.tcx().lookup_trait_def(trait_def_id); let expected_number_of_input_types = trait_def.generics.types.len(subst::TypeSpace); let input_types = match opt_input_types { @@ -359,7 +359,7 @@ fn trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, item_name: ast::Name) -> Option<(usize, ty::ImplOrTraitItem<'tcx>)> { - let trait_items = ty::trait_items(tcx, trait_def_id); + let trait_items = tcx.trait_items(trait_def_id); trait_items .iter() .enumerate() @@ -376,6 +376,6 @@ fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>, let impl_items = impl_items.get(&impl_def_id).unwrap(); impl_items .iter() - .map(|&did| ty::impl_or_trait_item(tcx, did.def_id())) + .map(|&did| tcx.impl_or_trait_item(did.def_id())) .find(|m| m.name() == item_name) } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index a8fc411410567..8026fce69ecca 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -377,7 +377,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option) { if let Some(impl_def_id) = lang_def_id { - ty::populate_implementations_for_primitive_if_necessary(self.tcx(), impl_def_id); + self.tcx().populate_implementations_for_primitive_if_necessary(impl_def_id); self.assemble_inherent_impl_probe(impl_def_id); } @@ -386,7 +386,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) { // Read the inherent implementation candidates for this type from the // metadata if necessary. - ty::populate_inherent_implementations_for_type_if_necessary(self.tcx(), def_id); + self.tcx().populate_inherent_implementations_for_type_if_necessary(def_id); if let Some(impl_infos) = self.tcx().inherent_impls.borrow().get(&def_id) { for &impl_def_id in impl_infos.iter() { @@ -606,7 +606,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // Check whether `trait_def_id` defines a method with suitable name: let trait_items = - ty::trait_items(self.tcx(), trait_def_id); + self.tcx().trait_items(trait_def_id); let matching_index = trait_items.iter() .position(|item| item.name() == self.item_name); @@ -647,7 +647,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { item: ty::ImplOrTraitItem<'tcx>, item_index: usize) { - let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + let trait_def = self.tcx().lookup_trait_def(trait_def_id); // FIXME(arielb1): can we use for_each_relevant_impl here? trait_def.for_each_impl(self.tcx(), |impl_def_id| { @@ -665,7 +665,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("impl_substs={:?}", impl_substs); let impl_trait_ref = - ty::impl_trait_ref(self.tcx(), impl_def_id) + self.tcx().impl_trait_ref(impl_def_id) .unwrap() // we know this is a trait impl .subst(self.tcx(), &impl_substs); @@ -705,7 +705,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { None => { return true; } }; - let impl_type = ty::lookup_item_type(self.tcx(), impl_def_id); + let impl_type = self.tcx().lookup_item_type(impl_def_id); let impl_simplified_type = match fast_reject::simplify_type(self.tcx(), impl_type.ty, false) { Some(simplified_type) => simplified_type, @@ -759,7 +759,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // for the purposes of our method lookup, we only take // receiver type into account, so we can just substitute // fresh types here to use during substitution and subtyping. - let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + let trait_def = self.tcx().lookup_trait_def(trait_def_id); let substs = self.infcx().fresh_substs_for_trait(self.span, &trait_def.generics, step.self_ty); @@ -802,8 +802,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("assemble_projection_candidates: projection_trait_ref={:?}", projection_trait_ref); - let trait_predicates = ty::lookup_predicates(self.tcx(), - projection_trait_ref.def_id); + let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id); let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs); let predicates = bounds.predicates.into_vec(); debug!("assemble_projection_candidates: predicates={:?}", @@ -894,7 +893,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { match source { TraitSource(id) => id, ImplSource(impl_id) => { - match ty::trait_id_of_impl(tcx, impl_id) { + match tcx.trait_id_of_impl(impl_id) { Some(id) => id, None => tcx.sess.span_bug(span, @@ -1081,7 +1080,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); // Check whether the impl imposes obligations we have to worry about. - let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id); + let impl_bounds = self.tcx().lookup_predicates(impl_def_id); let impl_bounds = impl_bounds.instantiate(self.tcx(), substs); let traits::Normalized { value: impl_bounds, obligations: norm_obligations } = @@ -1266,7 +1265,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { impl_def_id: ast::DefId) -> (Ty<'tcx>, subst::Substs<'tcx>) { - let impl_pty = ty::lookup_item_type(self.tcx(), impl_def_id); + let impl_pty = self.tcx().lookup_item_type(impl_def_id); let type_vars = impl_pty.generics.types.map( @@ -1301,7 +1300,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { fn erase_late_bound_regions(&self, value: &ty::Binder) -> T where T : TypeFoldable<'tcx> { - ty::erase_late_bound_regions(self.tcx(), value) + self.tcx().erase_late_bound_regions(value) } } @@ -1314,7 +1313,7 @@ fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>, let impl_items = impl_items.get(&impl_def_id).unwrap(); impl_items .iter() - .map(|&did| ty::impl_or_trait_item(tcx, did.def_id())) + .map(|&did| tcx.impl_or_trait_item(did.def_id())) .find(|item| item.name() == item_name) } @@ -1325,7 +1324,7 @@ fn trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, item_name: ast::Name) -> Option<(usize, ty::ImplOrTraitItem<'tcx>)> { - let trait_items = ty::trait_items(tcx, trait_def_id); + let trait_items = tcx.trait_items(trait_def_id); debug!("trait_method; items: {:?}", trait_items); trait_items .iter() diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index de8629da3cade..b193ddcb21349 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -66,7 +66,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // If the item has the name of a field, give a help note if let (&ty::TyStruct(did, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) { - let fields = ty::lookup_struct_fields(cx, did); + let fields = cx.lookup_struct_fields(did); if let Some(field) = fields.iter().find(|f| f.name == item_name) { let expr_string = match cx.sess.codemap().span_to_snippet(expr.span) { @@ -89,7 +89,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, }; // Determine if the field can be used as a function in some way - let field_ty = ty::lookup_field_type(cx, did, field.id, substs); + let field_ty = cx.lookup_field_type(did, field.id, substs); if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) { let infcx = fcx.infcx(); infcx.probe(|_| { @@ -159,7 +159,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, invoked on this closure as we have not yet inferred what \ kind of closure it is", item_name, - ty::item_path_str(fcx.tcx(), trait_def_id)); + fcx.tcx().item_path_str(trait_def_id)); let msg = if let Some(callee) = rcvr_expr { format!("{}; use overloaded call notation instead (e.g., `{}()`)", msg, pprust::expr_to_string(callee)) @@ -188,11 +188,12 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let impl_ty = check::impl_self_ty(fcx, span, impl_did).ty; - let insertion = match ty::impl_trait_ref(fcx.tcx(), impl_did) { + let insertion = match fcx.tcx().impl_trait_ref(impl_did) { None => format!(""), - Some(trait_ref) => format!(" of the trait `{}`", - ty::item_path_str(fcx.tcx(), - trait_ref.def_id)), + Some(trait_ref) => { + format!(" of the trait `{}`", + fcx.tcx().item_path_str(trait_ref.def_id)) + } }; span_note!(fcx.sess(), item_span, @@ -207,7 +208,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span_note!(fcx.sess(), item_span, "candidate #{} is defined in the trait `{}`", idx + 1, - ty::item_path_str(fcx.tcx(), trait_did)); + fcx.tcx().item_path_str(trait_did)); } } } @@ -243,7 +244,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.sess().fileline_help(span, &*format!("candidate #{}: use `{}`", i + 1, - ty::item_path_str(fcx.tcx(), *trait_did))) + fcx.tcx().item_path_str(*trait_did))) } return @@ -289,7 +290,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fcx.sess().fileline_help(span, &*format!("candidate #{}: `{}`", i + 1, - ty::item_path_str(fcx.tcx(), trait_info.def_id))) + fcx.tcx().item_path_str(trait_info.def_id))) } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6826c33359aee..299ccd579ccb7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,6 @@ use middle::traits::{self, report_fulfillment_errors}; use middle::ty::{FnSig, GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; -use middle::ty::liberate_late_bound_regions; use middle::ty::{MethodCall, MethodCallee, MethodMap}; use middle::ty_fold::{TypeFolder, TypeFoldable}; use rscope::RegionScope; @@ -308,7 +307,7 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id)); self.resolve_type_vars_or_error(&ty) } - fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool { + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { let ty = self.infcx().resolve_type_vars_if_possible(&ty); !traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span) } @@ -363,9 +362,8 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { fn closure_upvars(&self, def_id: ast::DefId, substs: &Substs<'tcx>) - -> Option>> - { - ty::closure_upvars(self, def_id, substs) + -> Option>> { + ty::ctxt::closure_upvars(self, def_id, substs) } } @@ -430,7 +428,7 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>) -> Inherited<'a, 'tcx> { // It's kind of a kludge to manufacture a fake function context // and statement context, but we might as well do write the code only once - let param_env = ty::empty_parameter_environment(ccx.tcx); + let param_env = ccx.tcx.empty_parameter_environment(); Inherited::new(ccx.tcx, param_env) } @@ -512,9 +510,8 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let fn_sig = fn_ty.sig.subst(ccx.tcx, &inh.param_env.free_substs); let fn_sig = - liberate_late_bound_regions(ccx.tcx, - region::DestructionScopeData::new(body.id), - &fn_sig); + ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), + &fn_sig); let fn_sig = inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig); @@ -718,7 +715,7 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { check_representable(tcx, span, id, "struct"); check_instantiable(tcx, span, id); - if ty::lookup_simd(tcx, local_def(id)) { + if tcx.lookup_simd(local_def(id)) { check_simd(tcx, span, id); } } @@ -726,7 +723,7 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { debug!("check_item_type(it.id={}, it.ident={})", it.id, - ty::item_path_str(ccx.tcx, local_def(it.id))); + ccx.tcx.item_path_str(local_def(it.id))); let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. @@ -741,7 +738,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { ast::ItemFn(..) => {} // entirely within check_item_body ast::ItemImpl(_, _, _, _, _, ref impl_items) => { debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id); - match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) { + match ccx.tcx.impl_trait_ref(local_def(it.id)) { Some(impl_trait_ref) => { check_impl_items_against_trait(ccx, it.span, @@ -758,7 +755,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { check_struct(ccx, it.id, it.span); } ast::ItemTy(ref t, ref generics) => { - let pty_ty = ty::node_id_to_type(ccx.tcx, it.id); + let pty_ty = ccx.tcx.node_id_to_type(it.id); check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty); } ast::ItemForeignMod(ref m) => { @@ -768,7 +765,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { } } else { for item in &m.items { - let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id)); + let pty = ccx.tcx.lookup_item_type(local_def(item.id)); if !pty.generics.types.is_empty() { span_err!(ccx.tcx.sess, item.span, E0044, "foreign items may not have type parameters"); @@ -790,18 +787,18 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { debug!("check_item_body(it.id={}, it.ident={})", it.id, - ty::item_path_str(ccx.tcx, local_def(it.id))); + ccx.tcx.item_path_str(local_def(it.id))); let _indenter = indenter(); match it.node { ast::ItemFn(ref decl, _, _, _, _, ref body) => { - let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); + let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id)); let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id); check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env); } ast::ItemImpl(_, _, _, _, _, ref impl_items) => { debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id); - let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id)); + let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id)); for impl_item in impl_items { match impl_item.node { @@ -820,7 +817,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) { } } ast::ItemTrait(_, _, _, ref trait_items) => { - let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id)); + let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id)); for trait_item in trait_items { match trait_item.node { ast::ConstTraitItem(_, Some(ref expr)) => { @@ -921,7 +918,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, item_generics, id); let param_env = ParameterEnvironment::for_item(ccx.tcx, id); - let fty = ty::node_id_to_type(ccx.tcx, id); + let fty = ccx.tcx.node_id_to_type(id); debug!("check_method_body: fty={:?}", fty); check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env); @@ -933,7 +930,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, impl_items: &[P]) { // Locate trait methods let tcx = ccx.tcx; - let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id); + let trait_items = tcx.trait_items(impl_trait_ref.def_id); // Check existing impl methods to see if they are both present in trait // and compatible with trait signature @@ -941,8 +938,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, match impl_item.node { ast::ConstImplItem(..) => { let impl_const_def_id = local_def(impl_item.id); - let impl_const_ty = ty::impl_or_trait_item(ccx.tcx, - impl_const_def_id); + let impl_const_ty = ccx.tcx.impl_or_trait_item(impl_const_def_id); // Find associated const definition. let opt_associated_const = @@ -985,8 +981,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, check_trait_fn_not_const(ccx, impl_item.span, sig.constness); let impl_method_def_id = local_def(impl_item.id); - let impl_item_ty = ty::impl_or_trait_item(ccx.tcx, - impl_method_def_id); + let impl_item_ty = ccx.tcx.impl_or_trait_item(impl_method_def_id); // If this is an impl of a trait method, find the // corresponding method definition in the trait. @@ -1027,8 +1022,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } ast::TypeImplItem(_) => { let typedef_def_id = local_def(impl_item.id); - let typedef_ty = ty::impl_or_trait_item(ccx.tcx, - typedef_def_id); + let typedef_ty = ccx.tcx.impl_or_trait_item(typedef_def_id); // If this is an impl of an associated type, find the // corresponding type definition in the trait. @@ -1067,8 +1061,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } // Check for missing items from trait - let provided_methods = ty::provided_trait_methods(tcx, impl_trait_ref.def_id); - let associated_consts = ty::associated_consts(tcx, impl_trait_ref.def_id); + let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id); + let associated_consts = tcx.associated_consts(impl_trait_ref.def_id); let mut missing_items = Vec::new(); for trait_item in trait_items.iter() { match *trait_item { @@ -1189,13 +1183,13 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn get_item_type_scheme(&self, _: Span, id: ast::DefId) -> Result, ErrorReported> { - Ok(ty::lookup_item_type(self.tcx(), id)) + Ok(self.tcx().lookup_item_type(id)) } fn get_trait_def(&self, _: Span, id: ast::DefId) -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported> { - Ok(ty::lookup_trait_def(self.tcx(), id)) + Ok(self.tcx().lookup_trait_def(id)) } fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> { @@ -1238,7 +1232,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { assoc_name: ast::Name) -> bool { - let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id); + let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id); trait_def.associated_type_names.contains(&assoc_name) } @@ -1506,9 +1500,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> TypeAndSubsts<'tcx> { let type_scheme = - ty::lookup_item_type(self.tcx(), def_id); + self.tcx().lookup_item_type(def_id); let type_predicates = - ty::lookup_predicates(self.tcx(), def_id); + self.tcx().lookup_predicates(def_id); let substs = self.infcx().fresh_substs_for_generics( span, @@ -1543,7 +1537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx(); let ty::TypeScheme { generics, ty: decl_ty } = - ty::lookup_item_type(tcx, did); + tcx.lookup_item_type(did); let substs = astconv::ast_path_substs_for_ty(self, self, path.span, @@ -1651,14 +1645,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let raw_ty = self.expr_ty(expr); let raw_ty = self.infcx().shallow_resolve(raw_ty); let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty); - ty::adjust_ty(self.tcx(), - expr.span, - expr.id, - raw_ty, - adjustment, - |method_call| self.inh.method_map.borrow() - .get(&method_call) - .map(|method| resolve_ty(method.ty))) + raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| { + self.inh.method_map.borrow().get(&method_call) + .map(|method| resolve_ty(method.ty)) + }) } pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { @@ -1798,7 +1788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> Option> { let o_field = items.iter().find(|f| f.name == fieldname); - o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs)) + o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs)) .map(|t| self.normalize_associated_types_in(span, &t)) } @@ -1811,7 +1801,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> Option> { let o_field = if idx < items.len() { Some(&items[idx]) } else { None }; - o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs)) + o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs)) .map(|t| self.normalize_associated_types_in(span, &t)) } @@ -2046,7 +2036,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // extract method method return type, which will be &T; // all LB regions should have been instantiated during method lookup let ret_ty = method.ty.fn_ret(); - let ret_ty = ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap(); + let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap(); if let Some(method_call) = method_call { fcx.inh.method_map.borrow_mut().insert(method_call, method); @@ -2528,7 +2518,7 @@ pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, -> TypeAndSubsts<'tcx> { let tcx = fcx.tcx(); - let ity = ty::lookup_item_type(tcx, did); + let ity = tcx.lookup_item_type(did); let (n_tps, rps, raw_ty) = (ity.generics.types.len(subst::TypeSpace), ity.generics.regions.get_slice(subst::TypeSpace), @@ -2738,7 +2728,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, match base_t.sty { ty::TyStruct(base_id, substs) => { debug!("struct named {:?}", base_t); - let fields = ty::lookup_struct_fields(tcx, base_id); + let fields = tcx.lookup_struct_fields(base_id); fcx.lookup_field_ty(expr.span, base_id, &fields[..], field.node.name, &(*substs)) } @@ -2794,7 +2784,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let name = &ident; // only find fits with at least one matching letter let mut best_dist = name.len(); - let fields = ty::lookup_struct_fields(tcx, id); + let fields = tcx.lookup_struct_fields(id); let mut best = None; for elem in &fields { let n = elem.name.as_str(); @@ -2839,10 +2829,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, |base_t, _| { match base_t.sty { ty::TyStruct(base_id, substs) => { - tuple_like = ty::is_tuple_struct(tcx, base_id); + tuple_like = tcx.is_tuple_struct(base_id); if tuple_like { debug!("tuple struct named {:?}", base_t); - let fields = ty::lookup_struct_fields(tcx, base_id); + let fields = tcx.lookup_struct_fields(base_id); fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..], idx.node, &(*substs)) } else { @@ -2915,8 +2905,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, field.ident.span, |actual| match enum_id_opt { Some(enum_id) => { - let variant_type = ty::enum_variant_with_id(tcx, - enum_id, + let variant_type = tcx.enum_variant_with_id(enum_id, class_id); format!("struct variant `{}::{}` has no field named `{}`", actual, variant_type.name.as_str(), @@ -2934,7 +2923,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str()); let actual_id = match enum_id_opt { Some(_) => class_id, - None => ty::ty_to_def_id(struct_ty).unwrap() + None => struct_ty.ty_to_def_id().unwrap() }; suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect()); error_happened = true; @@ -2947,8 +2936,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } Some((field_id, false)) => { expected_field_type = - ty::lookup_field_type( - tcx, class_id, field_id, substitutions); + tcx.lookup_field_type(class_id, field_id, substitutions); expected_field_type = fcx.normalize_associated_types_in( field.span, &expected_field_type); @@ -3008,7 +2996,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } = fcx.instantiate_type(span, class_id); // Look up and check the fields. - let class_fields = ty::lookup_struct_fields(tcx, class_id); + let class_fields = tcx.lookup_struct_fields(class_id); check_struct_or_variant_fields(fcx, struct_type, span, @@ -3051,7 +3039,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } = fcx.instantiate_type(span, enum_id); // Look up and check the enum variant fields. - let variant_fields = ty::lookup_struct_fields(tcx, variant_id); + let variant_fields = tcx.lookup_struct_fields(variant_id); check_struct_or_variant_fields(fcx, enum_type, span, @@ -3208,7 +3196,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| { match ty.sty { ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => { - if ty::expr_is_lval(fcx.tcx(), &**oprnd) { + if fcx.tcx().expr_is_lval(&**oprnd) { // Lvalues may legitimately have unsized types. // For example, dereferences of a fat pointer and // the last field of a struct can be unsized. @@ -3336,7 +3324,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue); let tcx = fcx.tcx(); - if !ty::expr_is_lval(tcx, &**lhs) { + if !tcx.expr_is_lval(&**lhs) { span_err!(tcx.sess, expr.span, E0070, "illegal left-hand side expression"); } @@ -3465,7 +3453,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprRepeat(ref element, ref count_expr) => { check_expr_has_type(fcx, &**count_expr, tcx.types.usize); - let count = ty::eval_repeat_count(fcx.tcx(), &**count_expr); + let count = fcx.tcx().eval_repeat_count(&**count_expr); let uty = match expected { ExpectHasType(uty) => { @@ -3558,7 +3546,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }, def => { // Verify that this was actually a struct. - let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id()); + let typ = fcx.ccx.tcx.lookup_item_type(def.def_id()); match typ.ty.sty { ty::TyStruct(struct_did, _) => { check_struct_constructor(fcx, @@ -3605,7 +3593,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, .ty_to_string( actual_structure_type), type_error); - ty::note_and_explain_type_err(tcx, &type_error, path.span); + tcx.note_and_explain_type_err(&type_error, path.span); } } } @@ -3700,7 +3688,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }; if let Some(did) = did { - let predicates = ty::lookup_predicates(tcx, did); + let predicates = tcx.lookup_predicates(did); let substs = Substs::new_type(vec![idx_type], vec![]); let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates); fcx.add_obligations_for_parameters( @@ -4096,7 +4084,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, e: &'tcx ast::Expr, id: ast::NodeId) { let inh = static_inherited_fields(ccx); - let rty = ty::node_id_to_type(ccx.tcx, id); + let rty = ccx.tcx.node_id_to_type(id); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id); let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty; check_const_with_ty(&fcx, sp, e, declty); @@ -4129,14 +4117,14 @@ pub fn check_representable(tcx: &ty::ctxt, sp: Span, item_id: ast::NodeId, designation: &str) -> bool { - let rty = ty::node_id_to_type(tcx, item_id); + let rty = tcx.node_id_to_type(item_id); // Check that it is possible to represent this type. This call identifies // (1) types that contain themselves and (2) types that contain a different // recursive type. It is only necessary to throw an error on those that // contain themselves. For case 2, there must be an inner type that will be // caught by case 1. - match ty::is_type_representable(tcx, sp, rty) { + match rty.is_representable(tcx, sp) { ty::SelfRecursive => { span_err!(tcx.sess, sp, E0072, "illegal recursive {} type; \ @@ -4164,8 +4152,8 @@ pub fn check_instantiable(tcx: &ty::ctxt, sp: Span, item_id: ast::NodeId) -> bool { - let item_ty = ty::node_id_to_type(tcx, item_id); - if !ty::is_instantiable(tcx, item_ty) { + let item_ty = tcx.node_id_to_type(item_id); + if !item_ty.is_instantiable(tcx) { span_err!(tcx.sess, sp, E0073, "this type cannot be instantiated without an \ instance of itself"); @@ -4178,21 +4166,21 @@ pub fn check_instantiable(tcx: &ty::ctxt, } pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) { - let t = ty::node_id_to_type(tcx, id); + let t = tcx.node_id_to_type(id); if t.needs_subst() { span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic"); return; } match t.sty { ty::TyStruct(did, substs) => { - let fields = ty::lookup_struct_fields(tcx, did); + let fields = tcx.lookup_struct_fields(did); if fields.is_empty() { span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty"); return; } - let e = ty::lookup_field_type(tcx, did, fields[0].id, substs); + let e = tcx.lookup_field_type(did, fields[0].id, substs); if !fields.iter().all( - |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) { + |f| tcx.lookup_field_type(did, f.id, substs) == e) { span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous"); return; } @@ -4244,13 +4232,13 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, hint: attr::ReprAttr) { #![allow(trivial_numeric_casts)] - let rty = ty::node_id_to_type(ccx.tcx, id); + let rty = ccx.tcx.node_id_to_type(id); let mut disr_vals: Vec = Vec::new(); let inh = static_inherited_fields(ccx); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id); - let (_, repr_type_ty) = ty::enum_repr_type(ccx.tcx, Some(&hint)); + let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint)); for v in vs { if let Some(ref e) = v.node.disr_expr { check_const_with_ty(&fcx, e.span, e, repr_type_ty); @@ -4261,7 +4249,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, // ty::enum_variants guards against discriminant overflows, so // we need not check for that. - let variants = ty::enum_variants(ccx.tcx, def_id); + let variants = ccx.tcx.enum_variants(def_id); for (v, variant) in vs.iter().zip(variants.iter()) { let current_disr_val = variant.disr_val; @@ -4295,7 +4283,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, } } - let hint = *ty::lookup_repr_hints(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id }) + let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id }) .get(0).unwrap_or(&attr::ReprAny); if hint != attr::ReprAny && vs.len() <= 1 { @@ -4333,7 +4321,7 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::DefFn(id, _) | def::DefMethod(id, _) | def::DefStatic(id, _) | def::DefVariant(_, id, _) | def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => { - (ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id)) + (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id)) } def::DefTrait(_) | def::DefTy(..) | @@ -4595,7 +4583,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // is inherent, there is no `Self` parameter, instead, the impl needs // type parameters, which we can infer by unifying the provided `Self` // with the substituted impl type. - let impl_scheme = ty::lookup_item_type(fcx.tcx(), impl_def_id); + let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id); assert_eq!(substs.types.len(subst::TypeSpace), impl_scheme.generics.types.len(subst::TypeSpace)); assert_eq!(substs.regions().len(subst::TypeSpace), @@ -5221,7 +5209,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { variadic: false, }), })); - let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id)); + let i_ty = ccx.tcx.lookup_item_type(local_def(it.id)); let i_n_tps = i_ty.generics.types.len(subst::FnSpace); if i_n_tps != n_tps { span_err!(tcx.sess, it.span, E0094, diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index b41bb9feb5212..5a114c811191c 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -56,7 +56,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, } let tcx = fcx.tcx(); - if !ty::expr_is_lval(tcx, lhs_expr) { + if !tcx.expr_is_lval(lhs_expr) { span_err!(tcx.sess, lhs_expr.span, E0067, "illegal left-hand side expression"); } @@ -335,7 +335,7 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, // extract return type for method; all late bound regions // should have been instantiated by now let ret_ty = method_ty.fn_ret(); - Ok(ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap()) + Ok(fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap()) } None => { Err(()) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index c659357dd0305..13961834aebdd 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -265,10 +265,10 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { if ty_unadjusted.references_error() { ty_unadjusted } else { - let tcx = self.fcx.tcx(); - ty::adjust_ty(tcx, expr.span, expr.id, ty_unadjusted, - self.fcx.inh.adjustments.borrow().get(&expr.id), - |method_call| self.resolve_method_type(method_call)) + ty_unadjusted.adjust( + self.fcx.tcx(), expr.span, expr.id, + self.fcx.inh.adjustments.borrow().get(&expr.id), + |method_call| self.resolve_method_type(method_call)) } } @@ -662,7 +662,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { constrain_call(rcx, expr, Some(&**base), None::.iter(), true); let fn_ret = // late-bound regions in overloaded method calls are instantiated - ty::no_late_bound_regions(rcx.tcx(), &method.ty.fn_ret()).unwrap(); + rcx.tcx().no_late_bound_regions(&method.ty.fn_ret()).unwrap(); fn_ret.unwrap() } None => rcx.resolve_node_type(base.id) @@ -893,7 +893,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, // was applied on the base type, as that is always the case. let fn_sig = method.ty.fn_sig(); let fn_sig = // late-bound regions should have been instantiated - ty::no_late_bound_regions(rcx.tcx(), fn_sig).unwrap(); + rcx.tcx().no_late_bound_regions(fn_sig).unwrap(); let self_ty = fn_sig.inputs[0]; let (m, r) = match self_ty.sty { ty::TyRef(r, ref m) => (m.mutbl, r), @@ -1017,9 +1017,9 @@ fn type_of_node_must_outlive<'a, 'tcx>( // is going to fail anyway, so just stop here and let typeck // report errors later on in the writeback phase. let ty0 = rcx.resolve_node_type(id); - let ty = ty::adjust_ty(tcx, origin.span(), id, ty0, - rcx.fcx.inh.adjustments.borrow().get(&id), - |method_call| rcx.resolve_method_type(method_call)); + let ty = ty0.adjust(tcx, origin.span(), id, + rcx.fcx.inh.adjustments.borrow().get(&id), + |method_call| rcx.resolve_method_type(method_call)); debug!("constrain_regions_in_type_of_node(\ ty={}, ty0={}, id={}, minimum_lifetime={:?})", ty, ty0, @@ -1172,10 +1172,8 @@ fn link_region_from_node_type<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, id, mutbl, cmt_borrowed); let rptr_ty = rcx.resolve_node_type(id); - if !rptr_ty.references_error() { - let tcx = rcx.fcx.ccx.tcx; + if let ty::TyRef(&r, _) = rptr_ty.sty { debug!("rptr_ty={}", rptr_ty); - let r = ty::ty_region(tcx, span, rptr_ty); link_region(rcx, span, &r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed); } @@ -1462,10 +1460,8 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, generic); // To start, collect bounds from user: - let mut param_bounds = - ty::required_region_bounds(rcx.tcx(), - generic.to_ty(rcx.tcx()), - param_env.caller_bounds.clone()); + let mut param_bounds = rcx.tcx().required_region_bounds(generic.to_ty(rcx.tcx()), + param_env.caller_bounds.clone()); // In the case of a projection T::Foo, we may be able to extract bounds from the trait def: match *generic { @@ -1532,7 +1528,7 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>, // ``` // // we can thus deduce that `>::SomeType : 'a`. - let trait_predicates = ty::lookup_predicates(tcx, projection_ty.trait_ref.def_id); + let trait_predicates = tcx.lookup_predicates(projection_ty.trait_ref.def_id); let predicates = trait_predicates.predicates.as_slice().to_vec(); traits::elaborate_predicates(tcx, predicates) .filter_map(|predicate| { diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 99e6309918c97..1345f322476b9 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -136,7 +136,7 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { closure_def_id); } - ty::with_freevars(self.tcx(), expr.id, |freevars| { + self.tcx().with_freevars(expr.id, |freevars| { for freevar in freevars { let var_node_id = freevar.def.local_node_id(); let upvar_id = ty::UpvarId { var_id: var_node_id, diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index aa6f533401dd6..00bbbafd5cd32 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -16,7 +16,6 @@ use middle::region; use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; use middle::traits; use middle::ty::{self, Ty}; -use middle::ty::liberate_late_bound_regions; use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty}; use std::collections::HashSet; @@ -56,7 +55,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let ccx = self.ccx; debug!("check_item_well_formed(it.id={}, it.ident={})", item.id, - ty::item_path_str(ccx.tcx, local_def(item.id))); + ccx.tcx.item_path_str(local_def(item.id))); match item.node { /// Right now we check that every default trait implementation @@ -80,13 +79,12 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { self.check_impl(item); } ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => { - let trait_ref = ty::impl_trait_ref(ccx.tcx, - local_def(item.id)).unwrap(); - ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id); + let trait_ref = ccx.tcx.impl_trait_ref(local_def(item.id)).unwrap(); + ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id); match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) { Some(ty::BoundSend) | Some(ty::BoundSync) => {} Some(_) | None => { - if !ty::trait_has_default_impl(ccx.tcx, trait_ref.def_id) { + if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) { span_err!(ccx.tcx.sess, item.span, E0192, "negative impls are only allowed for traits with \ default impls (e.g., `Send` and `Sync`)") @@ -119,9 +117,9 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { } ast::ItemTrait(_, _, _, ref items) => { let trait_predicates = - ty::lookup_predicates(ccx.tcx, local_def(item.id)); + ccx.tcx.lookup_predicates(local_def(item.id)); reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates); - if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) { + if ccx.tcx.trait_has_default_impl(local_def(item.id)) { if !items.is_empty() { span_err!(ccx.tcx.sess, item.span, E0380, "traits with default impls (`e.g. unsafe impl \ @@ -138,15 +136,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { { let ccx = self.ccx; let item_def_id = local_def(item.id); - let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id); - let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id); + let type_scheme = ccx.tcx.lookup_item_type(item_def_id); + let type_predicates = ccx.tcx.lookup_predicates(item_def_id); reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates); - let param_env = - ty::construct_parameter_environment(ccx.tcx, - item.span, - &type_scheme.generics, - &type_predicates, - item.id); + let param_env = ccx.tcx.construct_parameter_environment(item.span, + &type_scheme.generics, + &type_predicates, + item.id); let inh = Inherited::new(ccx.tcx, param_env); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id); f(self, &fcx); @@ -201,7 +197,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { Some(&mut this.cache)); debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope); - let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(item.id)); + let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id)); let item_ty = fcx.instantiate_type_scheme(item.span, &fcx.inh.param_env.free_substs, &type_scheme.ty); @@ -222,7 +218,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // Find the impl self type as seen from the "inside" -- // that is, with all type parameters converted from bound // to free. - let self_ty = ty::node_id_to_type(fcx.tcx(), item.id); + let self_ty = fcx.tcx().node_id_to_type(item.id); let self_ty = fcx.instantiate_type_scheme(item.span, &fcx.inh.param_env.free_substs, &self_ty); @@ -231,7 +227,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // Similarly, obtain an "inside" reference to the trait // that the impl implements. - let trait_ref = match ty::impl_trait_ref(fcx.tcx(), local_def(item.id)) { + let trait_ref = match fcx.tcx().impl_trait_ref(local_def(item.id)) { None => { return; } Some(t) => { t } }; @@ -258,7 +254,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // Find the supertrait bounds. This will add `int:Bar`. let poly_trait_ref = ty::Binder(trait_ref); - let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id()); + let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id()); let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); let predicates = { let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx); @@ -278,8 +274,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { ast_generics: &ast::Generics) { let item_def_id = local_def(item.id); - let ty_predicates = ty::lookup_predicates(self.tcx(), item_def_id); - let variances = ty::item_variances(self.tcx(), item_def_id); + let ty_predicates = self.tcx().lookup_predicates(item_def_id); + let variances = self.tcx().item_variances(item_def_id); let mut constrained_parameters: HashSet<_> = variances.types @@ -358,7 +354,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { span, &format!("consider removing `{}` or using a marker such as `{}`", param_name, - ty::item_path_str(self.tcx(), def_id))); + self.tcx().item_path_str(def_id))); } None => { // no lang items, no help! @@ -432,7 +428,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { match fk { visit::FkFnBlock | visit::FkItemFn(..) => {} visit::FkMethod(..) => { - match ty::impl_or_trait_item(self.tcx(), local_def(id)) { + match self.tcx().impl_or_trait_item(local_def(id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics) } @@ -445,7 +441,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) { if let ast::MethodTraitItem(_, None) = trait_item.node { - match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) { + match self.tcx().impl_or_trait_item(local_def(trait_item.id)) { ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { reject_non_type_param_bounds( self.tcx(), @@ -496,7 +492,7 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> { /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated /// to the point where impl `A : Trait` is implemented). pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, span: Span) { - let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id); + let trait_predicates = self.fcx.tcx().lookup_predicates(trait_ref.def_id); let bounds = self.fcx.instantiate_bounds(span, trait_ref.substs, @@ -538,8 +534,7 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { where T : TypeFoldable<'tcx> { self.binding_count += 1; - let value = liberate_late_bound_regions( - self.fcx.tcx(), + let value = self.fcx.tcx().liberate_late_bound_regions( region::DestructionScopeData::new(self.scope), binder); debug!("BoundsChecker::fold_binder: late-bound regions replaced: {:?} at scope: {:?}", @@ -567,7 +562,7 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { match t.sty{ ty::TyStruct(type_id, substs) | ty::TyEnum(type_id, substs) => { - let type_predicates = ty::lookup_predicates(self.fcx.tcx(), type_id); + let type_predicates = self.fcx.tcx().lookup_predicates(type_id); let bounds = self.fcx.instantiate_bounds(self.span, substs, &type_predicates); @@ -638,7 +633,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, struct_def.fields .iter() .map(|field| { - let field_ty = ty::node_id_to_type(fcx.tcx(), field.node.id); + let field_ty = fcx.tcx().node_id_to_type(field.node.id); let field_ty = fcx.instantiate_type_scheme(field.span, &fcx.inh.param_env.free_substs, &field_ty); @@ -655,13 +650,11 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, .map(|variant| { match variant.node.kind { ast::TupleVariantKind(ref args) if !args.is_empty() => { - let ctor_ty = ty::node_id_to_type(fcx.tcx(), variant.node.id); + let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id); // the regions in the argument types come from the // enum def'n, and hence will all be early bound - let arg_tys = - ty::no_late_bound_regions( - fcx.tcx(), &ctor_ty.fn_args()).unwrap(); + let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap(); AdtVariant { fields: args.iter().enumerate().map(|(index, arg)| { let arg_ty = arg_tys[index]; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 9abee1a3aaab6..29119f3b5946d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -171,7 +171,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { debug!("Type for pattern binding {} (id {}) resolved to {:?}", pat_to_string(p), p.id, - ty::node_id_to_type(self.tcx(), p.id)); + self.tcx().node_id_to_type(p.id)); visit::walk_pat(self, p); } @@ -334,11 +334,11 @@ impl ResolveReason { ResolvingLocal(s) => s, ResolvingPattern(s) => s, ResolvingUpvar(upvar_id) => { - ty::expr_span(tcx, upvar_id.closure_expr_id) + tcx.expr_span(upvar_id.closure_expr_id) } ResolvingClosure(did) => { if did.krate == ast::LOCAL_CRATE { - ty::expr_span(tcx, did.node) + tcx.expr_span(did.node) } else { DUMMY_SP } @@ -403,7 +403,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { let span = self.reason.span(self.tcx); span_err!(self.tcx.sess, span, E0104, "cannot resolve lifetime for captured variable `{}`: {}", - ty::local_var_name_str(self.tcx, upvar_id.var_id).to_string(), + self.tcx.local_var_name_str(upvar_id.var_id).to_string(), infer::fixup_err_to_string(e)); } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 266babda57824..06bd572ac12f3 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -139,15 +139,14 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fn check_implementation(&self, item: &Item) { let tcx = self.crate_context.tcx; let impl_did = local_def(item.id); - let self_type = ty::lookup_item_type(tcx, impl_did); + let self_type = tcx.lookup_item_type(impl_did); // If there are no traits, then this implementation must have a // base type. let impl_items = self.create_impl_from_item(item); - if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, - impl_did) { + if let Some(trait_ref) = self.crate_context.tcx.impl_trait_ref(impl_did) { debug!("(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, item.ident); @@ -181,9 +180,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { debug!("instantiate_default_methods(impl_id={:?}, trait_ref={:?})", impl_id, trait_ref); - let impl_type_scheme = ty::lookup_item_type(tcx, impl_id); + let impl_type_scheme = tcx.lookup_item_type(impl_id); - let prov = ty::provided_trait_methods(tcx, trait_ref.def_id); + let prov = tcx.provided_trait_methods(trait_ref.def_id); for trait_method in &prov { // Synthesize an ID. let new_id = tcx.sess.next_node_id(); @@ -245,8 +244,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'tcx>, impl_def_id: DefId) { debug!("add_trait_impl: impl_trait_ref={:?} impl_def_id={:?}", impl_trait_ref, impl_def_id); - let trait_def = ty::lookup_trait_def(self.crate_context.tcx, - impl_trait_ref.def_id); + let trait_def = self.crate_context.tcx.lookup_trait_def(impl_trait_ref.def_id); trait_def.record_impl(self.crate_context.tcx, impl_def_id, impl_trait_ref); } @@ -273,11 +271,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }).collect(); - if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx, - local_def(item.id)) { - self.instantiate_default_methods(local_def(item.id), - &trait_ref, - &mut items); + let def_id = local_def(item.id); + if let Some(trait_ref) = self.crate_context.tcx.impl_trait_ref(def_id) { + self.instantiate_default_methods(def_id, &trait_ref, &mut items); } items @@ -299,8 +295,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { let drop_trait = match tcx.lang_items.drop_trait() { Some(id) => id, None => { return } }; - ty::populate_implementations_for_trait_if_necessary(tcx, drop_trait); - let drop_trait = ty::lookup_trait_def(tcx, drop_trait); + tcx.populate_implementations_for_trait_if_necessary(drop_trait); + let drop_trait = tcx.lookup_trait_def(drop_trait); let impl_items = tcx.impl_items.borrow(); @@ -312,7 +308,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } let method_def_id = items[0]; - let self_type = ty::lookup_item_type(tcx, impl_did); + let self_type = tcx.lookup_item_type(impl_did); match self_type.ty.sty { ty::TyEnum(type_def_id, _) | ty::TyStruct(type_def_id, _) | @@ -355,8 +351,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { Some(id) => id, None => return, }; - ty::populate_implementations_for_trait_if_necessary(tcx, copy_trait); - let copy_trait = ty::lookup_trait_def(tcx, copy_trait); + tcx.populate_implementations_for_trait_if_necessary(copy_trait); + let copy_trait = tcx.lookup_trait_def(copy_trait); copy_trait.for_each_impl(tcx, |impl_did| { debug!("check_implementations_of_copy: impl_did={:?}", @@ -368,7 +364,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { return } - let self_type = ty::lookup_item_type(tcx, impl_did); + let self_type = tcx.lookup_item_type(impl_did); debug!("check_implementations_of_copy: self_type={:?} (bound)", self_type); @@ -380,7 +376,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { debug!("check_implementations_of_copy: self_type={:?} (free)", self_type); - match ty::can_type_implement_copy(¶m_env, span, self_type) { + match param_env.can_type_implement_copy(self_type, span) { Ok(()) => {} Err(ty::FieldDoesNotImplementCopy(name)) => { span_err!(tcx.sess, span, E0204, @@ -425,7 +421,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }; - let trait_def = ty::lookup_trait_def(tcx, coerce_unsized_trait); + let trait_def = tcx.lookup_trait_def(coerce_unsized_trait); trait_def.for_each_impl(tcx, |impl_did| { debug!("check_implementations_of_coerce_unsized: impl_did={:?}", @@ -437,9 +433,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { return; } - let source = ty::lookup_item_type(tcx, impl_did).ty; - let trait_ref = ty::impl_trait_ref(self.crate_context.tcx, - impl_did).unwrap(); + let source = tcx.lookup_item_type(impl_did).ty; + let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap(); let target = *trait_ref.substs.types.get(subst::TypeSpace, 0); debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)", source, target); @@ -478,8 +473,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { (&ty::TyStruct(def_id_a, substs_a), &ty::TyStruct(def_id_b, substs_b)) => { if def_id_a != def_id_b { - let source_path = ty::item_path_str(tcx, def_id_a); - let target_path = ty::item_path_str(tcx, def_id_b); + let source_path = tcx.item_path_str(def_id_a); + let target_path = tcx.item_path_str(def_id_b); span_err!(tcx.sess, span, E0377, "the trait `CoerceUnsized` may only be implemented \ for a coercion between structures with the same \ @@ -489,9 +484,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } let origin = infer::Misc(span); - let fields = ty::lookup_struct_fields(tcx, def_id_a); + let fields = tcx.lookup_struct_fields(def_id_a); let diff_fields = fields.iter().enumerate().filter_map(|(i, f)| { - let ty = ty::lookup_field_type_unsubstituted(tcx, def_id_a, f.id); + let ty = tcx.lookup_field_type_unsubstituted(def_id_a, f.id); let (a, b) = (ty.subst(tcx, substs_a), ty.subst(tcx, substs_b)); if infcx.sub_types(false, origin, b, a).is_ok() { None @@ -592,7 +587,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, provided_source: Option) -> ty::Method<'tcx> { - let combined_substs = ty::make_substs_for_receiver_types(tcx, trait_ref, method); + let combined_substs = tcx.make_substs_for_receiver_types(trait_ref, method); debug!("subst_receiver_types_in_method_ty: combined_substs={:?}", combined_substs); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 8376b92da3dea..e585b8cd2bde0 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -67,7 +67,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { // defined in this crate. debug!("coherence2::orphan check: inherent impl {}", self.tcx.map.node_to_string(item.id)); - let self_ty = ty::lookup_item_type(self.tcx, def_id).ty; + let self_ty = self.tcx.lookup_item_type(def_id).ty; match self_ty.sty { ty::TyEnum(def_id, _) | ty::TyStruct(def_id, _) => { @@ -210,7 +210,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { // "Trait" impl debug!("coherence2::orphan check: trait impl {}", self.tcx.map.node_to_string(item.id)); - let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap(); + let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); let trait_def_id = trait_ref.def_id; match traits::orphan_check(self.tcx, def_id) { Ok(()) => { } @@ -269,9 +269,9 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { debug!("trait_ref={:?} trait_def_id={:?} trait_has_default_impl={}", trait_ref, trait_def_id, - ty::trait_has_default_impl(self.tcx, trait_def_id)); + self.tcx.trait_has_default_impl(trait_def_id)); if - ty::trait_has_default_impl(self.tcx, trait_def_id) && + self.tcx.trait_has_default_impl(trait_def_id) && trait_def_id.krate != ast::LOCAL_CRATE { let self_ty = trait_ref.self_ty(); @@ -297,7 +297,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { "cross-crate traits with a default impl, like `{}`, \ can only be implemented for a struct/enum type \ defined in the current crate", - ty::item_path_str(self.tcx, trait_def_id))) + self.tcx.item_path_str(trait_def_id))) } } _ => { @@ -305,7 +305,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { "cross-crate traits with a default impl, like `{}`, \ can only be implemented for a struct/enum type, \ not `{}`", - ty::item_path_str(self.tcx, trait_def_id), + self.tcx.item_path_str(trait_def_id), self_ty)) } }; @@ -332,7 +332,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> { // "Trait" impl debug!("coherence2::orphan check: default trait impl {}", self.tcx.map.node_to_string(item.id)); - let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap(); + let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); if trait_ref.def_id.krate != ast::LOCAL_CRATE { span_err!(self.tcx.sess, item.span, E0318, "cannot create default implementations for traits outside the \ diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 0e8067e7181bd..b4ad55ef2e46b 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -50,9 +50,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { let trait_defs: Vec<_> = self.tcx.trait_defs.borrow().values().cloned().collect(); for trait_def in trait_defs { - ty::populate_implementations_for_trait_if_necessary( - self.tcx, - trait_def.trait_ref.def_id); + self.tcx.populate_implementations_for_trait_if_necessary(trait_def.trait_ref.def_id); self.check_for_overlapping_impls_of_trait(trait_def); } } @@ -147,7 +145,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { span_err!(self.tcx.sess, self.span_of_impl(impl1), E0119, "conflicting implementations for trait `{}`", - ty::item_path_str(self.tcx, trait_def_id)); + self.tcx.item_path_str(trait_def_id)); self.report_overlap_note(impl1, impl2); } @@ -181,7 +179,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { // general orphan/coherence rules, it must always be // in this crate. let impl_def_id = ast_util::local_def(item.id); - let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap(); + let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id); match prev_default_impl { Some(prev_id) => { @@ -194,7 +192,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { } ast::ItemImpl(_, _, _, Some(_), ref self_ty, _) => { let impl_def_id = ast_util::local_def(item.id); - let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap(); + let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; match trait_ref.self_ty().sty { ty::TyTrait(ref data) => { @@ -208,7 +206,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { // giving a misleading message below. span_err!(self.tcx.sess, self_ty.span, E0372, "the trait `{}` cannot be made into an object", - ty::item_path_str(self.tcx, data.principal_def_id())); + self.tcx.item_path_str(data.principal_def_id())); } else { let mut supertrait_def_ids = traits::supertrait_def_ids(self.tcx, data.principal_def_id()); @@ -217,7 +215,7 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { "the object type `{}` automatically \ implements the trait `{}`", trait_ref.self_ty(), - ty::item_path_str(self.tcx, trait_def_id)); + self.tcx.item_path_str(trait_def_id)); } } } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index fa39e9d0491f9..c0323ba60fc47 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -30,7 +30,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { fn check_unsafety_coherence(&mut self, item: &'v ast::Item, unsafety: ast::Unsafety, polarity: ast::ImplPolarity) { - match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) { + match self.tcx.impl_trait_ref(ast_util::local_def(item.id)) { None => { // Inherent impl. match unsafety { @@ -43,7 +43,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { } Some(trait_ref) => { - let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id); + let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id); match (trait_def.unsafety, unsafety, polarity) { (ast::Unsafety::Unsafe, ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4c550e5d44ae4..e43a3542b6e33 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -242,12 +242,12 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { AstConvRequest::GetTraitDef(def_id) => { tcx.sess.note( &format!("the cycle begins when processing `{}`...", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::EnsureSuperPredicates(def_id) => { tcx.sess.note( &format!("the cycle begins when computing the supertraits of `{}`...", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); @@ -264,12 +264,12 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { AstConvRequest::GetTraitDef(def_id) => { tcx.sess.note( &format!("...which then requires processing `{}`...", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::EnsureSuperPredicates(def_id) => { tcx.sess.note( &format!("...which then requires computing the supertraits of `{}`...", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); @@ -286,13 +286,13 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { AstConvRequest::GetTraitDef(def_id) => { tcx.sess.note( &format!("...which then again requires processing `{}`, completing the cycle.", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::EnsureSuperPredicates(def_id) => { tcx.sess.note( &format!("...which then again requires computing the supertraits of `{}`, \ completing the cycle.", - ty::item_path_str(tcx, def_id))); + tcx.item_path_str(def_id))); } AstConvRequest::GetTypeParameterBounds(id) => { let def = tcx.type_parameter_def(id); @@ -311,7 +311,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> { let tcx = self.tcx; if trait_id.krate != ast::LOCAL_CRATE { - return ty::lookup_trait_def(tcx, trait_id) + return tcx.lookup_trait_def(trait_id) } let item = match tcx.map.get(trait_id.node) { @@ -399,7 +399,7 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> { if trait_def_id.krate == ast::LOCAL_CRATE { trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name) } else { - let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id); + let trait_def = self.tcx().lookup_trait_def(trait_def_id); trait_def.associated_type_names.contains(&assoc_name) } } @@ -822,7 +822,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ast_trait_ref, None); - ty::record_trait_has_default_impl(tcx, trait_ref.def_id); + tcx.record_trait_has_default_impl(trait_ref.def_id); tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), Some(trait_ref)); } @@ -944,7 +944,7 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let _: Result<(), ErrorReported> = // any error is already reported, can ignore ccx.ensure_super_predicates(it.span, local_def(it.id)); convert_trait_predicates(ccx, it); - let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id)); + let trait_predicates = tcx.lookup_predicates(local_def(it.id)); debug!("convert: trait_bounds={:?}", trait_predicates); @@ -1230,7 +1230,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"), }; - let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar"); + let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar"); if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures { ccx.tcx.sess.span_err( it.span, @@ -1343,7 +1343,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) } }; - let super_predicates = ty::lookup_super_predicates(ccx.tcx, def_id); + let super_predicates = ccx.tcx.lookup_super_predicates(def_id); // `ty_generic_predicates` below will consider the bounds on the type // parameters (including `Self`) and the explicit where-clauses, @@ -1407,7 +1407,7 @@ fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, -> ty::TypeScheme<'tcx> { if def_id.krate != ast::LOCAL_CRATE { - return ty::lookup_item_type(ccx.tcx, def_id); + return ccx.tcx.lookup_item_type(def_id); } match ccx.tcx.map.find(def_id.node) { @@ -1529,7 +1529,7 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, assert!(prev_predicates.is_none()); // Debugging aid. - if ty::has_attr(tcx, local_def(it.id), "rustc_object_lifetime_default") { + if tcx.has_attr(local_def(it.id), "rustc_object_lifetime_default") { let object_lifetime_default_reprs: String = scheme.generics.types.iter() .map(|t| match t.object_lifetime_default { @@ -1691,20 +1691,20 @@ fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>, match unbound { Some(ref tpb) => { // FIXME(#8559) currently requires the unbound to be built-in. - let trait_def_id = ty::trait_ref_to_def_id(tcx, tpb); + let trait_def_id = tcx.trait_ref_to_def_id(tpb); match kind_id { Ok(kind_id) if trait_def_id != kind_id => { tcx.sess.span_warn(span, "default bound relaxed for a type parameter, but \ this does nothing because the given bound is not \ a default. Only `?Sized` is supported"); - ty::try_add_builtin_trait(tcx, kind_id, bounds); + tcx.try_add_builtin_trait(kind_id, bounds); } _ => {} } } _ if kind_id.is_ok() => { - ty::try_add_builtin_trait(tcx, kind_id.unwrap(), bounds); + tcx.try_add_builtin_trait(kind_id.unwrap(), bounds); } // No lang item for Sized, so we can't add it as a bound. None => {} @@ -2187,8 +2187,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( let required_type_free = liberate_early_bound_regions( tcx, body_scope, - &ty::liberate_late_bound_regions( - tcx, body_scope, &ty::Binder(required_type))); + &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type))); // The "base type" comes from the impl. It too may have late-bound // regions from the method. @@ -2196,8 +2195,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( let base_type_free = liberate_early_bound_regions( tcx, body_scope, - &ty::liberate_late_bound_regions( - tcx, body_scope, &ty::Binder(base_type))); + &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type))); debug!("required_type={:?} required_type_free={:?} \ base_type={:?} base_type_free={:?}", @@ -2262,9 +2260,9 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, impl_def_id: ast::DefId, impl_items: &[P]) { - let impl_scheme = ty::lookup_item_type(tcx, impl_def_id); - let impl_predicates = ty::lookup_predicates(tcx, impl_def_id); - let impl_trait_ref = ty::impl_trait_ref(tcx, impl_def_id); + let impl_scheme = tcx.lookup_item_type(impl_def_id); + let impl_predicates = tcx.lookup_predicates(impl_def_id); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); // The trait reference is an input, so find all type parameters // reachable from there, to start (if this is an inherent impl, @@ -2293,7 +2291,7 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>, let lifetimes_in_associated_types: HashSet<_> = impl_items.iter() - .map(|item| ty::impl_or_trait_item(tcx, local_def(item.id))) + .map(|item| tcx.impl_or_trait_item(local_def(item.id))) .filter_map(|item| match item { ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty, ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 34f166e0e0dfb..fc825c198e751 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -199,7 +199,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, Ok(_) => true, Err(ref terr) => { span_err!(tcx.sess, span, E0211, "{}: {}", msg(), terr); - ty::note_and_explain_type_err(tcx, terr, span); + tcx.note_and_explain_type_err(terr, span); false } } @@ -209,7 +209,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, main_id: ast::NodeId, main_span: Span) { let tcx = ccx.tcx; - let main_t = ty::node_id_to_type(tcx, main_id); + let main_t = tcx.node_id_to_type(main_id); match main_t.sty { ty::TyBareFn(..) => { match tcx.map.find(main_id) { @@ -254,7 +254,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt, start_id: ast::NodeId, start_span: Span) { let tcx = ccx.tcx; - let start_t = ty::node_id_to_type(tcx, start_id); + let start_t = tcx.node_id_to_type(start_id); match start_t.sty { ty::TyBareFn(..) => { match tcx.map.find(start_id) { diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 1f4e134365121..c1f9725fc8134 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -485,7 +485,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { param_id={}, \ inf_index={:?}, \ initial_variance={:?})", - ty::item_path_str(self.tcx, ast_util::local_def(item_id)), + self.tcx.item_path_str(ast_util::local_def(item_id)), item_id, kind, space, index, param_id, inf_index, initial_variance); } @@ -603,7 +603,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { match item.node { ast::ItemEnum(ref enum_definition, _) => { - let scheme = ty::lookup_item_type(tcx, did); + let scheme = tcx.lookup_item_type(did); // Not entirely obvious: constraints on structs/enums do not // affect the variance of their type parameters. See discussion @@ -633,7 +633,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { } ast::ItemStruct(..) => { - let scheme = ty::lookup_item_type(tcx, did); + let scheme = tcx.lookup_item_type(did); // Not entirely obvious: constraints on structs/enums do not // affect the variance of their type parameters. See discussion @@ -641,16 +641,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { // // self.add_constraints_from_generics(&scheme.generics); - let struct_fields = ty::lookup_struct_fields(tcx, did); + let struct_fields = tcx.lookup_struct_fields(did); for field_info in &struct_fields { assert_eq!(field_info.id.krate, ast::LOCAL_CRATE); - let field_ty = ty::node_id_to_type(tcx, field_info.id.node); + let field_ty = tcx.node_id_to_type(field_info.id.node); self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant); } } ast::ItemTrait(..) => { - let trait_def = ty::lookup_trait_def(tcx, did); + let trait_def = tcx.lookup_trait_def(did); self.add_constraints_from_trait_ref(&trait_def.generics, trait_def.trait_ref, self.invariant); @@ -781,7 +781,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } else { // Parameter on an item defined within another crate: // variance already inferred, just look it up. - let variances = ty::item_variances(self.tcx(), item_def_id); + let variances = self.tcx().item_variances(item_def_id); let variance = match kind { TypeParam => *variances.types.get(space, index), RegionParam => *variances.regions.get(space, index), @@ -848,7 +848,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { trait_ref, variance); - let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id); + let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id); self.add_constraints_from_substs( generics, @@ -904,7 +904,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::TyEnum(def_id, substs) | ty::TyStruct(def_id, substs) => { - let item_type = ty::lookup_item_type(self.tcx(), def_id); + let item_type = self.tcx().lookup_item_type(def_id); // All type parameters on enums and structs should be // in the TypeSpace. @@ -924,7 +924,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::TyProjection(ref data) => { let trait_ref = &data.trait_ref; - let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id); + let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id); self.add_constraints_from_substs( generics, trait_ref.def_id, @@ -1200,7 +1200,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { // For unit testing: check for a special "rustc_variance" // attribute and report an error with various results if found. - if ty::has_attr(tcx, item_def_id, "rustc_variance") { + if tcx.has_attr(item_def_id, "rustc_variance") { span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{:?}", item_variances); } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 53063c6247efb..e80fd360e04fd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -150,9 +150,9 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait { - let def = ty::lookup_trait_def(tcx, did); - let trait_items = ty::trait_items(tcx, did).clean(cx); - let predicates = ty::lookup_predicates(tcx, did); + let def = tcx.lookup_trait_def(did); + let trait_items = tcx.trait_items(did).clean(cx); + let predicates = tcx.lookup_predicates(did); let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); @@ -165,12 +165,12 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, } fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Function { - let t = ty::lookup_item_type(tcx, did); + let t = tcx.lookup_item_type(did); let (decl, style, abi) = match t.ty.sty { ty::TyBareFn(_, ref f) => ((did, &f.sig).clean(cx), f.unsafety, f.abi), _ => panic!("bad function"), }; - let predicates = ty::lookup_predicates(tcx, did); + let predicates = tcx.lookup_predicates(did); clean::Function { decl: decl, generics: (&t.generics, &predicates, subst::FnSpace).clean(cx), @@ -183,9 +183,9 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct { use syntax::parse::token::special_idents::unnamed_field; - let t = ty::lookup_item_type(tcx, did); - let predicates = ty::lookup_predicates(tcx, did); - let fields = ty::lookup_struct_fields(tcx, did); + let t = tcx.lookup_item_type(did); + let predicates = tcx.lookup_predicates(did); + let fields = tcx.lookup_struct_fields(did); clean::Struct { struct_type: match &*fields { @@ -201,14 +201,14 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru } fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum { - let t = ty::lookup_item_type(tcx, did); - let predicates = ty::lookup_predicates(tcx, did); + let t = tcx.lookup_item_type(did); + let predicates = tcx.lookup_predicates(did); match t.ty.sty { ty::TyEnum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => { return clean::EnumItem(clean::Enum { generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx), variants_stripped: false, - variants: ty::enum_variants(tcx, edid).clean(cx), + variants: tcx.enum_variants(edid).clean(cx), }) } _ => {} @@ -222,7 +222,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> Vec { - ty::populate_inherent_implementations_for_type_if_necessary(tcx, did); + tcx.populate_inherent_implementations_for_type_if_necessary(did); let mut impls = Vec::new(); match tcx.inherent_impls.borrow().get(&did) { @@ -307,16 +307,16 @@ pub fn build_impl(cx: &DocContext, }); } - let predicates = ty::lookup_predicates(tcx, did); + let predicates = tcx.lookup_predicates(did); let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did) .iter() .filter_map(|did| { let did = did.def_id(); - let impl_item = ty::impl_or_trait_item(tcx, did); + let impl_item = tcx.impl_or_trait_item(did); match impl_item { ty::ConstTraitItem(ref assoc_const) => { let did = assoc_const.def_id; - let type_scheme = ty::lookup_item_type(tcx, did); + let type_scheme = tcx.lookup_item_type(did); let default = match assoc_const.default { Some(_) => Some(const_eval::lookup_const_by_id(tcx, did, None) .unwrap().span.to_src(cx)), @@ -383,7 +383,7 @@ pub fn build_impl(cx: &DocContext, } }).collect::>(); let polarity = csearch::get_impl_polarity(tcx, did); - let ty = ty::lookup_item_type(tcx, did); + let ty = tcx.lookup_item_type(did); let trait_ = associated_trait.clean(cx).map(|bound| { match bound { clean::TraitBound(polyt, _) => polyt.trait_, @@ -477,7 +477,7 @@ fn build_const(cx: &DocContext, tcx: &ty::ctxt, debug!("got snippet {}", sn); clean::Constant { - type_: ty::lookup_item_type(tcx, did).ty.clean(cx), + type_: tcx.lookup_item_type(did).ty.clean(cx), expr: sn } } @@ -486,7 +486,7 @@ fn build_static(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId, mutable: bool) -> clean::Static { clean::Static { - type_: ty::lookup_item_type(tcx, did).ty.clean(cx), + type_: tcx.lookup_item_type(did).ty.clean(cx), mutability: if mutable {clean::Mutable} else {clean::Immutable}, expr: "\n\n\n".to_string(), // trigger the "[definition]" links } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8ba4470c3efbd..c25267520ccd8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1332,7 +1332,7 @@ impl<'tcx> Clean for ty::Method<'tcx> { let provided = match self.container { ty::ImplContainer(..) => false, ty::TraitContainer(did) => { - ty::provided_trait_methods(cx.tcx(), did).iter().any(|m| { + cx.tcx().provided_trait_methods(did).iter().any(|m| { m.def_id == self.def_id }) } @@ -1742,7 +1742,7 @@ impl Clean for ty::field_ty { (Some(self.name), Some(attr_map.get(&self.id.node).unwrap())) }; - let ty = ty::lookup_item_type(cx.tcx(), self.id); + let ty = cx.tcx().lookup_item_type(self.id); Item { name: name.clean(cx), @@ -2731,8 +2731,8 @@ impl<'tcx> Clean for ty::AssociatedType<'tcx> { // are actually located on the trait/impl itself, so we need to load // all of the generics from there and then look for bounds that are // applied to this associated type in question. - let def = ty::lookup_trait_def(cx.tcx(), did); - let predicates = ty::lookup_predicates(cx.tcx(), did); + let def = cx.tcx().lookup_trait_def(did); + let predicates = cx.tcx().lookup_predicates(did); let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx); generics.where_predicates.iter().filter_map(|pred| { let (name, self_type, trait_, bounds) = match *pred { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 2bde8d5bfb5fc..e65cdd8ff5de6 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -30,7 +30,6 @@ use std::mem; use std::collections::HashMap; use rustc::middle::subst; -use rustc::middle::ty; use syntax::ast; use clean::PathParameters as PP; @@ -154,8 +153,8 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: ast::DefId, if child == trait_ { return true } - let def = ty::lookup_trait_def(cx.tcx(), child); - let predicates = ty::lookup_predicates(cx.tcx(), child); + let def = cx.tcx().lookup_trait_def(child); + let predicates = cx.tcx().lookup_predicates(child); let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx); generics.where_predicates.iter().filter_map(|pred| { match *pred { From 2051b3e28fc245b44d82336cca31b25bbd637688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 26 Jun 2015 16:40:51 +0200 Subject: [PATCH 15/36] Avoid storing fat pointers as first class aggregates Storing them as FCAs is a regression from the recent change that made fat pointers immediate return values so that they are passed in registers instead of memory. --- src/librustc_trans/trans/base.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 461739a362d30..7a37a3e5ee43a 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -832,9 +832,14 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t return; } - let store = Store(cx, from_arg_ty(cx, v, t), to_arg_ty_ptr(cx, dst, t)); - unsafe { - llvm::LLVMSetAlignment(store, type_of::align_of(cx.ccx(), t)); + if common::type_is_fat_ptr(cx.tcx(), t) { + Store(cx, ExtractValue(cx, v, abi::FAT_PTR_ADDR), expr::get_dataptr(cx, dst)); + Store(cx, ExtractValue(cx, v, abi::FAT_PTR_EXTRA), expr::get_len(cx, dst)); + } else { + let store = Store(cx, from_arg_ty(cx, v, t), to_arg_ty_ptr(cx, dst, t)); + unsafe { + llvm::LLVMSetAlignment(store, type_of::align_of(cx.ccx(), t)); + } } } From 30cde078c6887f7be79884054ec16334fb76a467 Mon Sep 17 00:00:00 2001 From: Richo Healey Date: Fri, 26 Jun 2015 09:53:56 -0700 Subject: [PATCH 16/36] std: clean up duplicated attrs and comment on panic --- src/libstd/macros.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 02c35e9526d36..697b934c6760d 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -14,28 +14,6 @@ //! library. Each macro is available for use when linking against the standard //! library. -/// The entry point for panic of Rust threads. -/// -/// This macro is used to inject panic into a Rust thread, causing the thread to -/// unwind and panic entirely. Each thread's panic can be reaped as the -/// `Box` type, and the single-argument form of the `panic!` macro will be -/// the value which is transmitted. -/// -/// The multi-argument form of this macro panics with a string and has the -/// `format!` syntax for building a string. -/// -/// # Examples -/// -/// ```should_panic -/// # #![allow(unreachable_code)] -/// panic!(); -/// panic!("this is a terrible mistake!"); -/// panic!(4); // panic with the value of 4 to be collected elsewhere -/// panic!("this is a {} {message}", "fancy", message = "message"); -/// ``` -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -#[allow_internal_unstable] /// The entry point for panic of Rust threads. /// /// This macro is used to inject panic into a Rust thread, causing the thread to From c98e46c7cabd44a306ac52c95d961bcebd899b0f Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Fri, 26 Jun 2015 11:44:02 -0700 Subject: [PATCH 17/36] accessing private fields is not safe, and io isn't scary --- src/doc/reference.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index a3e13acccae28..7e28651c6aafb 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1047,11 +1047,8 @@ This is a list of behavior not considered *unsafe* in Rust terms, but that may be undesired. * Deadlocks -* Reading data from private fields (`std::repr`) * Leaks of memory and other resources * Exiting without calling destructors -* Sending signals -* Accessing/modifying the file system * Integer overflow - Overflow is considered "unexpected" behavior and is always user-error, unless the `wrapping` primitives are used. In non-optimized builds, the compiler From 9001da658ae020199b479f416b21eb71d0d48492 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Fri, 26 Jun 2015 12:06:05 -0700 Subject: [PATCH 18/36] make book match reference --- src/doc/trpl/unsafe.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index fdb9c33a2b0b5..e8f1b829061c2 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -12,7 +12,7 @@ two contexts. The first one is to mark a function as unsafe: ```rust unsafe fn danger_will_robinson() { - // scary stuff + // scary stuff } ``` @@ -68,11 +68,8 @@ Whew! That’s a bunch of stuff. It’s also important to notice all kinds of behaviors that are certainly bad, but are expressly _not_ unsafe: * Deadlocks -* Reading data from private fields -* Leaks due to reference count cycles +* Leaks of memory or other resources * Exiting without calling destructors -* Sending signals -* Accessing/modifying the file system * Integer overflow Rust cannot prevent all kinds of software problems. Buggy code can and will be From 532235be276de640d22c9d974d81f723e6094cf1 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 26 Jun 2015 22:29:40 +0200 Subject: [PATCH 19/36] Use Box::into_raw rather than the deprecated boxed::into_raw in tests and documentation. --- src/liballoc/boxed.rs | 6 ++---- src/liballoc/boxed_test.rs | 8 ++++---- src/libcore/ptr.rs | 10 ++++------ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 1039756363e9f..c941629b871ef 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -116,7 +116,7 @@ impl Box { /// of `T` and releases memory. Since the way `Box` allocates and /// releases memory is unspecified, the only valid pointer to pass /// to this function is the one taken from another `Box` with - /// `boxed::into_raw` function. + /// `Box::into_raw` function. /// /// Function is unsafe, because improper use of this function may /// lead to memory problems like double-free, for example if the @@ -140,10 +140,8 @@ impl Box { /// # Examples /// ``` /// # #![feature(box_raw)] - /// use std::boxed; - /// /// let seventeen = Box::new(17u32); - /// let raw = boxed::into_raw(seventeen); + /// let raw = Box::into_raw(seventeen); /// let boxed_again = unsafe { Box::from_raw(raw) }; /// ``` #[unstable(feature = "box_raw", reason = "may be renamed")] diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs index fc44ac4eac628..2ef23b26a56a7 100644 --- a/src/liballoc/boxed_test.rs +++ b/src/liballoc/boxed_test.rs @@ -76,9 +76,9 @@ fn deref() { #[test] fn raw_sized() { + let x = Box::new(17); + let p = Box::into_raw(x); unsafe { - let x = Box::new(17); - let p = boxed::into_raw(x); assert_eq!(17, *p); *p = 19; let y = Box::from_raw(p); @@ -105,9 +105,9 @@ fn raw_trait() { } } + let x: Box = Box::new(Bar(17)); + let p = Box::into_raw(x); unsafe { - let x: Box = Box::new(Bar(17)); - let p = boxed::into_raw(x); assert_eq!(17, (*p).get()); (*p).set(19); let y: Box = Box::from_raw(p); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f2792a525d66b..7b33a41f9556a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -50,14 +50,12 @@ //! //! ``` //! # #![feature(box_raw)] -//! use std::boxed; +//! let my_speed: Box = Box::new(88); +//! let my_speed: *mut i32 = Box::into_raw(my_speed); //! +//! // By taking ownership of the original `Box` though +//! // we are obligated to put it together later to be destroyed. //! unsafe { -//! let my_speed: Box = Box::new(88); -//! let my_speed: *mut i32 = boxed::into_raw(my_speed); -//! -//! // By taking ownership of the original `Box` though -//! // we are obligated to put it together later to be destroyed. //! drop(Box::from_raw(my_speed)); //! } //! ``` From 0f6d4aa786e565c91df2f361dfb3bee5b202bdca Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Fri, 26 Jun 2015 15:00:31 -0700 Subject: [PATCH 20/36] core: fix deprecation since version of align_of_min. These will first be deprecated in 1.2.0, not 1.1.0. --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 4177e0666e3a5..b53b61e517397 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -155,7 +155,7 @@ pub fn size_of_val(val: &T) -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(reason = "use `align_of` instead", since = "1.1.0")] +#[deprecated(reason = "use `align_of` instead", since = "1.2.0")] pub fn min_align_of() -> usize { unsafe { intrinsics::min_align_of::() } } @@ -171,7 +171,7 @@ pub fn min_align_of() -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(reason = "use `align_of_val` instead", since = "1.1.0")] +#[deprecated(reason = "use `align_of_val` instead", since = "1.2.0")] pub fn min_align_of_val(val: &T) -> usize { unsafe { intrinsics::min_align_of_val(val) } } From 1aabbd01c3fb28a15510f37877d5471e7e725b13 Mon Sep 17 00:00:00 2001 From: Cruz Julian Bishop Date: Sat, 27 Jun 2015 09:16:11 +1000 Subject: [PATCH 21/36] Initial documentation for 1.2.0, uploading to test markdown --- RELEASES.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 203da02c373ef..b8ccc4387f2d9 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,18 @@ +Version 1.2.0 (August 2015) +=========================== + +Highlights +---------- + +* [Parallel codegen][parcodegen] is now working again, which can substantially + speed up large builds in debug mode; It also gets another ~33% speedup when + bootstrapping on a 4 core machine (using 8 jobs). It's not enabled by default, + but will be "in the near future" + + +[parcodegen]: https://github.com/rust-lang/rust/pull/26018 + + Version 1.1.0 (June 2015) ========================= From ca0601a1c23793dd4ad3f65441dd1064f1b47545 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 27 Jun 2015 15:25:15 +0200 Subject: [PATCH 22/36] std: someone missed removing this doc and the annotations Should have happened in 69abc12b0044d641e714bdd73a299cfa4136b7b8 --- src/libstd/macros.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 02c35e9526d36..697b934c6760d 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -14,28 +14,6 @@ //! library. Each macro is available for use when linking against the standard //! library. -/// The entry point for panic of Rust threads. -/// -/// This macro is used to inject panic into a Rust thread, causing the thread to -/// unwind and panic entirely. Each thread's panic can be reaped as the -/// `Box` type, and the single-argument form of the `panic!` macro will be -/// the value which is transmitted. -/// -/// The multi-argument form of this macro panics with a string and has the -/// `format!` syntax for building a string. -/// -/// # Examples -/// -/// ```should_panic -/// # #![allow(unreachable_code)] -/// panic!(); -/// panic!("this is a terrible mistake!"); -/// panic!(4); // panic with the value of 4 to be collected elsewhere -/// panic!("this is a {} {message}", "fancy", message = "message"); -/// ``` -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -#[allow_internal_unstable] /// The entry point for panic of Rust threads. /// /// This macro is used to inject panic into a Rust thread, causing the thread to From ae36d4f72ad8b34343dba391f2f239ff29840117 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 15:30:00 -0700 Subject: [PATCH 23/36] mk: Add support for i686-pc-windows-msvc This commit modifies the configure script and our makefiles to support building 32-bit MSVC targets. The MSVC toolchain is now parameterized over whether it can produce a 32-bit or 64-bit binary. The configure script was updated to export more variables at configure time, and the makefiles were rejiggered to selectively reexport the relevant environment variables for the applicable targets they're going to run for. --- configure | 60 +++++++++++++++++++++++++------- mk/cfg/i686-pc-windows-msvc.mk | 29 +++++++++++++++ mk/cfg/x86_64-pc-windows-msvc.mk | 10 +++--- mk/platform.mk | 18 +--------- mk/rt.mk | 19 ++++++++++ mk/target.mk | 37 ++++++++++++++++++++ 6 files changed, 138 insertions(+), 35 deletions(-) create mode 100644 mk/cfg/i686-pc-windows-msvc.mk diff --git a/configure b/configure index 891f524a706e0..5d4a017b6fbfa 100755 --- a/configure +++ b/configure @@ -1114,7 +1114,7 @@ do fi ;; - x86_64-*-msvc) + *-msvc) # Currently the build system is not configured to build jemalloc # with MSVC, so we omit this optional dependency. step_msg "targeting MSVC, disabling jemalloc" @@ -1154,22 +1154,45 @@ do CFG_MSVC_ROOT=$(echo "$install" | grep InstallDir | sed 's/.*REG_SZ[ ]*//') CFG_MSVC_ROOT=$(dirname "$CFG_MSVC_ROOT") CFG_MSVC_ROOT=$(dirname "$CFG_MSVC_ROOT") - CFG_MSVC_CL="${CFG_MSVC_ROOT}/VC/bin/amd64/cl.exe" - CFG_MSVC_LIB="${CFG_MSVC_ROOT}/VC/bin/amd64/lib.exe" - CFG_MSVC_LINK="${CFG_MSVC_ROOT}/VC/bin/amd64/link.exe" + putvar CFG_MSVC_ROOT + + case $i in + x86_64-*) + bits=x86_64 + msvc_part=amd64 + ;; + i686-*) + bits=i386 + msvc_part= + ;; + *) + err "can only target x86 targets for MSVC" + ;; + esac + bindir="${CFG_MSVC_ROOT}/VC/bin" + if [ ! -z "$msvc_part" ]; then + bindir="$bindir/$msvc_part" + fi + eval CFG_MSVC_BINDIR_$bits="\"$bindir\"" + eval CFG_MSVC_CL_$bits="\"$bindir/cl.exe\"" + eval CFG_MSVC_LIB_$bits="\"$bindir/lib.exe\"" + eval CFG_MSVC_LINK_$bits="\"$bindir/link.exe\"" vcvarsall="${CFG_MSVC_ROOT}/VC/vcvarsall.bat" - CFG_MSVC_INCLUDE_PATH=$(cmd /c "\"$vcvarsall\" amd64 && cmd /c echo %INCLUDE%") + include_path=$(cmd /c "\"$vcvarsall\" $msvc_part && cmd /c echo %INCLUDE%") need_ok "failed to learn about MSVC's INCLUDE" - CFG_MSVC_LIB_PATH=$(cmd /c "\"$vcvarsall\" amd64 && cmd /c echo %LIB%") + lib_path=$(cmd /c "\"$vcvarsall\" $msvc_part && cmd /c echo %LIB%") need_ok "failed to learn about MSVC's LIB" - putvar CFG_MSVC_ROOT - putvar CFG_MSVC_CL - putvar CFG_MSVC_LIB - putvar CFG_MSVC_LINK - putvar CFG_MSVC_INCLUDE_PATH - putvar CFG_MSVC_LIB_PATH + eval CFG_MSVC_INCLUDE_PATH_${bits}="\"$include_path\"" + eval CFG_MSVC_LIB_PATH_${bits}="\"$lib_path\"" + + putvar CFG_MSVC_BINDIR_${bits} + putvar CFG_MSVC_CL_${bits} + putvar CFG_MSVC_LIB_${bits} + putvar CFG_MSVC_LINK_${bits} + putvar CFG_MSVC_INCLUDE_PATH_${bits} + putvar CFG_MSVC_LIB_PATH_${bits} ;; *) @@ -1408,8 +1431,19 @@ do msg "configuring LLVM with:" msg "$CMAKE_ARGS" + case "$t" in + x86_64-*) + generator="Visual Studio 12 2013 Win64" + ;; + i686-*) + generator="Visual Studio 12 2013" + ;; + *) + err "can only build LLVM for x86 platforms" + ;; + esac (cd $LLVM_BUILD_DIR && "$CFG_CMAKE" $CFG_LLVM_SRC_DIR \ - -G "Visual Studio 12 2013 Win64" \ + -G "$generator" \ $CMAKE_ARGS) need_ok "LLVM cmake configure failed" fi diff --git a/mk/cfg/i686-pc-windows-msvc.mk b/mk/cfg/i686-pc-windows-msvc.mk new file mode 100644 index 0000000000000..bb1280688a716 --- /dev/null +++ b/mk/cfg/i686-pc-windows-msvc.mk @@ -0,0 +1,29 @@ +# i686-pc-windows-msvc configuration +CC_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo +LINK_i686-pc-windows-msvc="$(CFG_MSVC_LINK_i386)" -nologo +CXX_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo +CPP_i686-pc-windows-msvc="$(CFG_MSVC_CL_i386)" -nologo +AR_i686-pc-windows-msvc="$(CFG_MSVC_LIB_i386)" -nologo +CFG_LIB_NAME_i686-pc-windows-msvc=$(1).dll +CFG_STATIC_LIB_NAME_i686-pc-windows-msvc=$(1).lib +CFG_LIB_GLOB_i686-pc-windows-msvc=$(1)-*.{dll,lib} +CFG_LIB_DSYM_GLOB_i686-pc-windows-msvc=$(1)-*.dylib.dSYM +CFG_JEMALLOC_CFLAGS_i686-pc-windows-msvc := +CFG_GCCISH_CFLAGS_i686-pc-windows-msvc := -MD +CFG_GCCISH_CXXFLAGS_i686-pc-windows-msvc := -MD +CFG_GCCISH_LINK_FLAGS_i686-pc-windows-msvc := +CFG_GCCISH_DEF_FLAG_i686-pc-windows-msvc := +CFG_LLC_FLAGS_i686-pc-windows-msvc := +CFG_INSTALL_NAME_i686-pc-windows-msvc = +CFG_EXE_SUFFIX_i686-pc-windows-msvc := .exe +CFG_WINDOWSY_i686-pc-windows-msvc := 1 +CFG_UNIXY_i686-pc-windows-msvc := +CFG_LDPATH_i686-pc-windows-msvc := +CFG_RUN_i686-pc-windows-msvc=$(2) +CFG_RUN_TARG_i686-pc-windows-msvc=$(call CFG_RUN_i686-pc-windows-msvc,,$(2)) +CFG_GNU_TRIPLE_i686-pc-windows-msvc := i686-pc-win32 + +# All windows nightiles are currently a GNU triple, so this MSVC triple is not +# bootstrapping from itself. This is relevant during stage0, and other parts of +# the build system take this into account. +BOOTSTRAP_FROM_i686-pc-windows-msvc := i686-pc-windows-gnu diff --git a/mk/cfg/x86_64-pc-windows-msvc.mk b/mk/cfg/x86_64-pc-windows-msvc.mk index edeffcdd09b9b..6f12836f05624 100644 --- a/mk/cfg/x86_64-pc-windows-msvc.mk +++ b/mk/cfg/x86_64-pc-windows-msvc.mk @@ -1,9 +1,9 @@ # x86_64-pc-windows-msvc configuration -CC_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo -LINK_x86_64-pc-windows-msvc="$(CFG_MSVC_LINK)" -nologo -CXX_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo -CPP_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo -AR_x86_64-pc-windows-msvc="$(CFG_MSVC_LIB)" -nologo +CC_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo +LINK_x86_64-pc-windows-msvc="$(CFG_MSVC_LINK_x86_64)" -nologo +CXX_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo +CPP_x86_64-pc-windows-msvc="$(CFG_MSVC_CL_x86_64)" -nologo +AR_x86_64-pc-windows-msvc="$(CFG_MSVC_LIB_x86_64)" -nologo CFG_LIB_NAME_x86_64-pc-windows-msvc=$(1).dll CFG_STATIC_LIB_NAME_x86_64-pc-windows-msvc=$(1).lib CFG_LIB_GLOB_x86_64-pc-windows-msvc=$(1)-*.{dll,lib} diff --git a/mk/platform.mk b/mk/platform.mk index abc9cc038d022..60fe22cb32ee6 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -239,23 +239,6 @@ endef $(foreach target,$(CFG_TARGET), \ $(eval $(call CFG_MAKE_TOOLCHAIN,$(target)))) -# These two environment variables are scraped by the `./configure` script and -# are necessary for `cl.exe` to find standard headers (the INCLUDE variable) and -# for `link.exe` to find standard libraries (the LIB variable). -ifdef CFG_MSVC_INCLUDE_PATH -export INCLUDE := $(CFG_MSVC_INCLUDE_PATH) -endif -ifdef CFG_MSVC_LIB_PATH -export LIB := $(CFG_MSVC_LIB_PATH) -endif - -# Unfortunately `link.exe` is also a program in `/usr/bin` on MinGW installs, -# but it's not the one that we want. As a result we make sure that our detected -# `link.exe` shows up in PATH first. -ifdef CFG_MSVC_LINK -export PATH := $(CFG_MSVC_ROOT)/VC/bin/amd64:$(PATH) -endif - # There are more comments about this available in the target specification for # Windows MSVC in the compiler, but the gist of it is that we use `llvm-ar.exe` # instead of `lib.exe` for assembling archives, so we need to inject this custom @@ -307,3 +290,4 @@ endef $(foreach target,$(CFG_TARGET), \ $(eval $(call ADD_RUSTC_LLVM_DEF_TO_MSVC,$(target)))) + diff --git a/mk/rt.mk b/mk/rt.mk index 6513cf107726a..c70f9e8a37add 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -55,7 +55,11 @@ NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \ rust_android_dummy.c NATIVE_DEPS_rustrt_native_$(1) := arch/$$(HOST_$(1))/record_sp.S ifeq ($$(findstring msvc,$(1)),msvc) +ifeq ($$(findstring i686,$(1)),i686) +NATIVE_DEPS_rustrt_native_$(1) += rust_try_msvc_32.ll +else NATIVE_DEPS_rustrt_native_$(1) += rust_try_msvc_64.ll +endif else NATIVE_DEPS_rustrt_native_$(1) += rust_try.ll endif @@ -93,6 +97,17 @@ $$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.S $$(MKFILE_DEPS) \ @mkdir -p $$(@D) @$$(call E, compile: $$@) $$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<) + +# On MSVC targets the compiler's default include path (e.g. where to find system +# headers) is specified by the INCLUDE environment variable. This may not be set +# so the ./configure script scraped the relevant values and this is the location +# that we put them into cl.exe's environment. +ifeq ($$(findstring msvc,$(1)),msvc) +$$(RT_OUTPUT_DIR_$(1))/%.o: \ + export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1))) +$(1)/rustllvm/%.o: \ + export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1))) +endif endef $(foreach target,$(CFG_TARGET),$(eval $(call NATIVE_LIBRARIES,$(target)))) @@ -240,8 +255,12 @@ COMPRT_CFLAGS_$(1) := $$(CFG_GCCISH_CFLAGS_$(1)) ifeq ($$(findstring msvc,$(1)),msvc) COMPRT_CC_$(1) := gcc COMPRT_AR_$(1) := ar +ifeq ($$(findstring i686,$(1)),i686) +COMPRT_CFLAGS_$(1) := $$(CFG_GCCISH_CFLAGS_$(1)) -m32 +else COMPRT_CFLAGS_$(1) := $$(CFG_GCCISH_CFLAGS_$(1)) -m64 endif +endif $$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) @$$(call E, make: compiler-rt) diff --git a/mk/target.mk b/mk/target.mk index 3c274dc4fd5f2..c398950965f54 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -220,3 +220,40 @@ $(foreach target,$(CFG_TARGET), \ $(foreach crate,$(CRATES), \ $(foreach tool,$(NATIVE_TOOL_DEPS_$(crate)_T_$(target)), \ $(eval $(call MOVE_TOOLS_TO_SNAPSHOT_HOST_DIR,0,$(target),$(BOOTSTRAP_FROM_$(target)),$(crate),$(tool)))))) + +# For MSVC targets we need to set up some environment variables for the linker +# to work correctly when building Rust crates. These two variables are: +# +# - LIB tells the linker the default search path for finding system libraries, +# for example kernel32.dll +# - PATH needs to be modified to ensure that MSVC's link.exe is first in the +# path instead of MinGW's /usr/bin/link.exe (entirely unrelated) +# +# The values for these variables are detected by the configure script. +define SETUP_LIB_MSVC_ENV_VARS +ifeq ($$(findstring msvc,$(2)),msvc) +$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ + export LIB := $$(CFG_MSVC_LIB_PATH_$$(HOST_$(2))) +$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ + export PATH := $$(CFG_MSVC_BINDIR_$$(HOST_$(2))):$$(PATH) +endif +endef +define SETUP_TOOL_MSVC_ENV_VARS +ifeq ($$(findstring msvc,$(2)),msvc) +$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ + export LIB := $$(CFG_MSVC_LIB_PATH_$$(HOST_$(2))) +$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \ + export PATH := $$(CFG_MSVC_BINDIR_$$(HOST_$(2))):$$(PATH) +endif +endef + +$(foreach host,$(CFG_HOST), \ + $(foreach target,$(CFG_TARGET), \ + $(foreach stage,$(STAGES), \ + $(foreach crate,$(CRATES), \ + $(eval $(call SETUP_LIB_MSVC_ENV_VARS,$(stage),$(target),$(host),$(crate))))))) +$(foreach host,$(CFG_HOST), \ + $(foreach target,$(CFG_TARGET), \ + $(foreach stage,$(STAGES), \ + $(foreach tool,$(TOOLS), \ + $(eval $(call SETUP_TOOL_MSVC_ENV_VARS,$(stage),$(target),$(host),$(tool))))))) From 5de665e8b31fc0459839c6377157b9559e4679cc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 15:32:10 -0700 Subject: [PATCH 24/36] rustc_back: Learn about i686-pc-windows-msvc This commit adds the i686-pc-windows-msvc triple to the compiler's repertoire of triples to prepare for targeting 32-bit MSVC. --- .../target/i686_pc_windows_msvc.rs | 27 +++++++++++++++++++ src/librustc_back/target/mod.rs | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/librustc_back/target/i686_pc_windows_msvc.rs diff --git a/src/librustc_back/target/i686_pc_windows_msvc.rs b/src/librustc_back/target/i686_pc_windows_msvc.rs new file mode 100644 index 0000000000000..d71aa1526660e --- /dev/null +++ b/src/librustc_back/target/i686_pc_windows_msvc.rs @@ -0,0 +1,27 @@ +// Copyright 2015 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 target::Target; + +pub fn target() -> Target { + let mut base = super::windows_msvc_base::opts(); + base.cpu = "i686".to_string(); + + Target { + data_layout: "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string(), + llvm_target: "i686-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + arch: "x86".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + options: base, + } +} diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 402fbcd8d8d8e..a42f861d19056 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -381,7 +381,8 @@ impl Target { x86_64_pc_windows_gnu, i686_pc_windows_gnu, - x86_64_pc_windows_msvc + x86_64_pc_windows_msvc, + i686_pc_windows_msvc ); From 87909582374be91bc5affdd2e74e265077a6e571 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 15:33:42 -0700 Subject: [PATCH 25/36] std: Avoid missing fns on i686-pc-windows-msvc It turns out that the 32-bit toolchain for MSVC has many of these functions as `static inline` functions in header files so there's not actually a symbol for Rust to call. All of the implementations just cast floats to their 64-bit variants and then cast back to 32-bit at the end, so the standard library now takes this strategy. --- src/libcore/num/f32.rs | 60 +++++++++++++++++++++++--- src/libcore/ops.rs | 44 ++++++++++++------- src/libstd/num/f32.rs | 95 ++++++++++++++++++++++++++++++++---------- 3 files changed, 157 insertions(+), 42 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index aade9061657b7..c8f95a3672d4a 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -215,13 +215,37 @@ impl Float for f32 { /// Rounds towards minus infinity. #[inline] fn floor(self) -> f32 { - unsafe { intrinsics::floorf32(self) } + return floorf(self); + + // On MSVC LLVM will lower many math intrinsics to a call to the + // corresponding function. On MSVC, however, many of these functions + // aren't actually available as symbols to call, but rather they are all + // `static inline` functions in header files. This means that from a C + // perspective it's "compatible", but not so much from an ABI + // perspective (which we're worried about). + // + // The inline header functions always just cast to a f64 and do their + // operation, so we do that here as well, but only for MSVC targets. + // + // Note that there are many MSVC-specific float operations which + // redirect to this comment, so `floorf` is just one case of a missing + // function on MSVC, but there are many others elsewhere. + #[cfg(target_env = "msvc")] + fn floorf(f: f32) -> f32 { (f as f64).floor() as f32 } + #[cfg(not(target_env = "msvc"))] + fn floorf(f: f32) -> f32 { unsafe { intrinsics::floorf32(f) } } } /// Rounds towards plus infinity. #[inline] fn ceil(self) -> f32 { - unsafe { intrinsics::ceilf32(self) } + return ceilf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn ceilf(f: f32) -> f32 { (f as f64).ceil() as f32 } + #[cfg(not(target_env = "msvc"))] + fn ceilf(f: f32) -> f32 { unsafe { intrinsics::ceilf32(f) } } } /// Rounds to nearest integer. Rounds half-way cases away from zero. @@ -299,7 +323,13 @@ impl Float for f32 { #[inline] fn powf(self, n: f32) -> f32 { - unsafe { intrinsics::powf32(self, n) } + return powf(self, n); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn powf(f: f32, n: f32) -> f32 { (f as f64).powf(n as f64) as f32 } + #[cfg(not(target_env = "msvc"))] + fn powf(f: f32, n: f32) -> f32 { unsafe { intrinsics::powf32(f, n) } } } #[inline] @@ -317,7 +347,13 @@ impl Float for f32 { /// Returns the exponential of the number. #[inline] fn exp(self) -> f32 { - unsafe { intrinsics::expf32(self) } + return expf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn expf(f: f32) -> f32 { (f as f64).exp() as f32 } + #[cfg(not(target_env = "msvc"))] + fn expf(f: f32) -> f32 { unsafe { intrinsics::expf32(f) } } } /// Returns 2 raised to the power of the number. @@ -329,7 +365,13 @@ impl Float for f32 { /// Returns the natural logarithm of the number. #[inline] fn ln(self) -> f32 { - unsafe { intrinsics::logf32(self) } + return logf(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn logf(f: f32) -> f32 { (f as f64).ln() as f32 } + #[cfg(not(target_env = "msvc"))] + fn logf(f: f32) -> f32 { unsafe { intrinsics::logf32(f) } } } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -345,7 +387,13 @@ impl Float for f32 { /// Returns the base 10 logarithm of the number. #[inline] fn log10(self) -> f32 { - unsafe { intrinsics::log10f32(self) } + return log10f(self); + + // see notes above in `floor` + #[cfg(target_env = "msvc")] + fn log10f(f: f32) -> f32 { (f as f64).log10() as f32 } + #[cfg(not(target_env = "msvc"))] + fn log10f(f: f32) -> f32 { unsafe { intrinsics::log10f32(f) } } } /// Converts to degrees, assuming the number is in radians. diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 48b1cbeef4fdd..9a22fe3a493f1 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -419,26 +419,40 @@ macro_rules! rem_impl { )*) } -macro_rules! rem_float_impl { - ($t:ty, $fmod:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl Rem for $t { - type Output = $t; +rem_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } - #[inline] - fn rem(self, other: $t) -> $t { - extern { fn $fmod(a: $t, b: $t) -> $t; } - unsafe { $fmod(self, other) } - } - } +#[stable(feature = "rust1", since = "1.0.0")] +impl Rem for f32 { + type Output = f32; + + // see notes in `core::f32::Float::floor` + #[inline] + #[cfg(target_env = "msvc")] + fn rem(self, other: f32) -> f32 { + (self as f64).rem(other as f64) as f32 + } - forward_ref_binop! { impl Rem, rem for $t, $t } + #[inline] + #[cfg(not(target_env = "msvc"))] + fn rem(self, other: f32) -> f32 { + extern { fn fmodf(a: f32, b: f32) -> f32; } + unsafe { fmodf(self, other) } } } -rem_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 } -rem_float_impl! { f32, fmodf } -rem_float_impl! { f64, fmod } +#[stable(feature = "rust1", since = "1.0.0")] +impl Rem for f64 { + type Output = f64; + + #[inline] + fn rem(self, other: f64) -> f64 { + extern { fn fmod(a: f64, b: f64) -> f64; } + unsafe { fmod(self, other) } + } +} + +forward_ref_binop! { impl Rem, rem for f64, f64 } +forward_ref_binop! { impl Rem, rem for f32, f32 } /// The `Neg` trait is used to specify the functionality of unary `-`. /// diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0c40f6c1fc8a8..c2fb2fa417598 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -18,6 +18,7 @@ use prelude::v1::*; use core::num; +#[cfg(not(target_env = "msvc"))] use intrinsics; use libc::c_int; use num::{FpCategory, ParseFloatError}; @@ -33,12 +34,7 @@ mod cmath { use libc::{c_float, c_int}; extern { - pub fn acosf(n: c_float) -> c_float; - pub fn asinf(n: c_float) -> c_float; - pub fn atanf(n: c_float) -> c_float; - pub fn atan2f(a: c_float, b: c_float) -> c_float; pub fn cbrtf(n: c_float) -> c_float; - pub fn coshf(n: c_float) -> c_float; pub fn erff(n: c_float) -> c_float; pub fn erfcf(n: c_float) -> c_float; pub fn expm1f(n: c_float) -> c_float; @@ -51,32 +47,77 @@ mod cmath { pub fn log1pf(n: c_float) -> c_float; pub fn ilogbf(n: c_float) -> c_int; pub fn modff(n: c_float, iptr: &mut c_float) -> c_float; - pub fn sinhf(n: c_float) -> c_float; - pub fn tanf(n: c_float) -> c_float; - pub fn tanhf(n: c_float) -> c_float; pub fn tgammaf(n: c_float) -> c_float; #[cfg_attr(all(windows, target_env = "msvc"), link_name = "__lgammaf_r")] pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float; #[cfg_attr(all(windows, target_env = "msvc"), link_name = "_hypotf")] pub fn hypotf(x: c_float, y: c_float) -> c_float; + } - #[cfg(any(unix, all(windows, not(target_env = "msvc"))))] + // See the comments in `core::float::Float::floor` for why MSVC is special + // here. + #[cfg(not(target_env = "msvc"))] + extern { + pub fn acosf(n: c_float) -> c_float; + pub fn asinf(n: c_float) -> c_float; + pub fn atan2f(a: c_float, b: c_float) -> c_float; + pub fn atanf(n: c_float) -> c_float; + pub fn coshf(n: c_float) -> c_float; pub fn frexpf(n: c_float, value: &mut c_int) -> c_float; - #[cfg(any(unix, all(windows, not(target_env = "msvc"))))] pub fn ldexpf(x: c_float, n: c_int) -> c_float; + pub fn sinhf(n: c_float) -> c_float; + pub fn tanf(n: c_float) -> c_float; + pub fn tanhf(n: c_float) -> c_float; } - #[cfg(all(windows, target_env = "msvc"))] - pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float { - f64::ldexp(x as f64, n as isize) as c_float - } + #[cfg(target_env = "msvc")] + pub use self::shims::*; + #[cfg(target_env = "msvc")] + mod shims { + use libc::{c_float, c_int}; + + pub unsafe fn acosf(n: c_float) -> c_float { + f64::acos(n as f64) as c_float + } + + pub unsafe fn asinf(n: c_float) -> c_float { + f64::asin(n as f64) as c_float + } + + pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float { + f64::atan2(n as f64, b as f64) as c_float + } + + pub unsafe fn atanf(n: c_float) -> c_float { + f64::atan(n as f64) as c_float + } + + pub unsafe fn coshf(n: c_float) -> c_float { + f64::cosh(n as f64) as c_float + } + + pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float { + let (a, b) = f64::frexp(x as f64); + *value = b as c_int; + a as c_float + } + + pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float { + f64::ldexp(x as f64, n as isize) as c_float + } + + pub unsafe fn sinhf(n: c_float) -> c_float { + f64::sinh(n as f64) as c_float + } - #[cfg(all(windows, target_env = "msvc"))] - pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float { - let (a, b) = f64::frexp(x as f64); - *value = b as c_int; - a as c_float + pub unsafe fn tanf(n: c_float) -> c_float { + f64::tan(n as f64) as c_float + } + + pub unsafe fn tanhf(n: c_float) -> c_float { + f64::tanh(n as f64) as c_float + } } } @@ -761,7 +802,13 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn sin(self) -> f32 { - unsafe { intrinsics::sinf32(self) } + return sinf(self); + + // see notes in `core::f32::Float::floor` + #[cfg(target_env = "msvc")] + fn sinf(f: f32) -> f32 { (f as f64).sin() as f32 } + #[cfg(not(target_env = "msvc"))] + fn sinf(f: f32) -> f32 { unsafe { intrinsics::sinf32(f) } } } /// Computes the cosine of a number (in radians). @@ -778,7 +825,13 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn cos(self) -> f32 { - unsafe { intrinsics::cosf32(self) } + return cosf(self); + + // see notes in `core::f32::Float::floor` + #[cfg(target_env = "msvc")] + fn cosf(f: f32) -> f32 { (f as f64).cos() as f32 } + #[cfg(not(target_env = "msvc"))] + fn cosf(f: f32) -> f32 { unsafe { intrinsics::cosf32(f) } } } /// Computes the tangent of a number (in radians). From 79d02895fffa865c6a4ccfaad1fa35d8f732d497 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 24 Jun 2015 13:40:54 -0700 Subject: [PATCH 26/36] Begin refactor type checking state This first patch starts by moving around pieces of state related to type checking. The goal is to slowly unify the type checking state into a single typing context. This initial patch moves the ParameterEnvironment into the InferCtxt and moves shared tables from Inherited and ty::ctxt into their own struct Tables. This is the foundational work to refactoring the type checker to enable future evolution of the language and tooling. --- src/librustc/lib.rs | 1 + src/librustc/middle/astencode.rs | 26 +-- src/librustc/middle/cfg/construct.rs | 4 +- src/librustc/middle/check_const.rs | 9 +- src/librustc/middle/check_match.rs | 1 + src/librustc/middle/const_eval.rs | 5 +- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 9 +- src/librustc/middle/infer/mod.rs | 8 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/mem_categorization.rs | 8 +- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/stability.rs | 2 +- src/librustc/middle/traits/mod.rs | 13 +- src/librustc/middle/ty.rs | 197 +++++++++++++++----- src/librustc/util/ppaux.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_trans/lib.rs | 1 + src/librustc_trans/save/dump_csv.rs | 2 +- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/callee.rs | 4 +- src/librustc_trans/trans/closure.rs | 2 +- src/librustc_trans/trans/common.rs | 32 ++-- src/librustc_trans/trans/consts.rs | 6 +- src/librustc_trans/trans/expr.rs | 33 ++-- src/librustc_trans/trans/meth.rs | 12 +- src/librustc_trans/trans/monomorphize.rs | 5 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/closure.rs | 6 +- src/librustc_typeck/check/compare_method.rs | 14 +- src/librustc_typeck/check/dropck.rs | 3 +- src/librustc_typeck/check/method/confirm.rs | 7 +- src/librustc_typeck/check/method/probe.rs | 6 +- src/librustc_typeck/check/mod.rs | 129 +++++++------ src/librustc_typeck/check/op.rs | 3 +- src/librustc_typeck/check/regionck.rs | 27 +-- src/librustc_typeck/check/upvar.rs | 18 +- src/librustc_typeck/check/wf.rs | 14 +- src/librustc_typeck/check/writeback.rs | 35 ++-- src/librustc_typeck/coherence/mod.rs | 8 +- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/lib.rs | 5 +- 45 files changed, 427 insertions(+), 252 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c19ba19f5b76b..2cec42b76bce3 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -61,6 +61,7 @@ #![feature(str_match_indices)] #![feature(vec_push_all)] #![feature(wrapping)] +#![feature(cell_extras)] #![cfg_attr(test, feature(test))] #![allow(trivial_casts)] diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 21e2ad198810e..f2ae396173bc0 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1027,7 +1027,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - if let Some(item_substs) = tcx.item_substs.borrow().get(&id) { + if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) { rbml_w.tag(c::tag_table_item_subst, |rbml_w| { rbml_w.id(id); rbml_w.emit_substs(ecx, &item_substs.substs); @@ -1051,7 +1051,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, var_id: var_id, closure_expr_id: id }; - let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone(); + let upvar_capture = tcx.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone(); var_id.encode(rbml_w); upvar_capture.encode(rbml_w); }) @@ -1074,19 +1074,19 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } let method_call = MethodCall::expr(id); - if let Some(method) = tcx.method_map.borrow().get(&method_call) { + if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) { rbml_w.tag(c::tag_table_method_map, |rbml_w| { rbml_w.id(id); encode_method_callee(ecx, rbml_w, method_call.autoderef, method) }) } - if let Some(adjustment) = tcx.adjustments.borrow().get(&id) { + if let Some(adjustment) = tcx.tables.borrow().adjustments.get(&id) { match *adjustment { ty::AdjustDerefRef(ref adj) => { for autoderef in 0..adj.autoderefs { let method_call = MethodCall::autoderef(id, autoderef as u32); - if let Some(method) = tcx.method_map.borrow().get(&method_call) { + if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) { rbml_w.tag(c::tag_table_method_map, |rbml_w| { rbml_w.id(id); encode_method_callee(ecx, rbml_w, @@ -1104,14 +1104,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) { + if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&ast_util::local_def(id)) { rbml_w.tag(c::tag_table_closure_tys, |rbml_w| { rbml_w.id(id); rbml_w.emit_closure_type(ecx, closure_type); }) } - if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) { + if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&ast_util::local_def(id)) { rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| { rbml_w.id(id); encode_closure_kind(rbml_w, *closure_kind) @@ -1630,7 +1630,7 @@ fn decode_side_tables(dcx: &DecodeContext, let item_substs = ty::ItemSubsts { substs: val_dsr.read_substs(dcx) }; - dcx.tcx.item_substs.borrow_mut().insert( + dcx.tcx.tables.borrow_mut().item_substs.insert( id, item_substs); } c::tag_table_freevars => { @@ -1646,7 +1646,7 @@ fn decode_side_tables(dcx: &DecodeContext, closure_expr_id: id }; let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap(); - dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx)); + dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub.tr(dcx)); } c::tag_table_tcache => { let type_scheme = val_dsr.read_type_scheme(dcx); @@ -1663,22 +1663,22 @@ fn decode_side_tables(dcx: &DecodeContext, expr_id: id, autoderef: autoderef }; - dcx.tcx.method_map.borrow_mut().insert(method_call, method); + dcx.tcx.tables.borrow_mut().method_map.insert(method_call, method); } c::tag_table_adjustments => { let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx); - dcx.tcx.adjustments.borrow_mut().insert(id, adj); + dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj); } c::tag_table_closure_tys => { let closure_ty = val_dsr.read_closure_ty(dcx); - dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id), + dcx.tcx.tables.borrow_mut().closure_tys.insert(ast_util::local_def(id), closure_ty); } c::tag_table_closure_kinds => { let closure_kind = val_dsr.read_closure_kind(dcx); - dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id), + dcx.tcx.tables.borrow_mut().closure_kinds.insert(ast_util::local_def(id), closure_kind); } c::tag_table_cast_kinds => { diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 801b3a721e40d..7d62b6ff90040 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -411,7 +411,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { func_or_rcvr: &ast::Expr, args: I) -> CFGIndex { let method_call = ty::MethodCall::expr(call_expr.id); - let fn_ty = match self.tcx.method_map.borrow().get(&method_call) { + let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) { Some(method) => method.ty, None => self.tcx.expr_ty_adjusted(func_or_rcvr) }; @@ -634,6 +634,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { fn is_method_call(&self, expr: &ast::Expr) -> bool { let method_call = ty::MethodCall::expr(expr.id); - self.tcx.method_map.borrow().contains_key(&method_call) + self.tcx.tables.borrow().method_map.contains_key(&method_call) } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 62bf1648725cd..b156a2c087b02 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -283,12 +283,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_static_type(&self, e: &ast::Expr) { let ty = self.tcx.node_id_to_type(e.id); - let infcx = infer::new_infer_ctxt(self.tcx); + let infcx = infer::new_infer_ctxt(self.tcx, None); let mut fulfill_cx = traits::FulfillmentContext::new(false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - let env = self.tcx.empty_parameter_environment(); - match fulfill_cx.select_all_or_error(&infcx, &env) { + match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); @@ -544,7 +543,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, match e.node { ast::ExprUnary(..) | ast::ExprBinary(..) | - ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => { + ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => { v.add_qualif(ConstQualif::NOT_CONST); if v.mode != Mode::Var { span_err!(v.tcx.sess, e.span, E0011, @@ -695,7 +694,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } } ast::ExprMethodCall(..) => { - let method_did = match v.tcx.method_map.borrow()[&method_call].origin { + let method_did = match v.tcx.tables.borrow().method_map[&method_call].origin { ty::MethodStatic(did) => Some(did), _ => None }; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index d2b3b83e4f42f..f61884e213666 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -98,6 +98,7 @@ impl<'a> FromIterator> for Matrix<'a> { } } +//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv pub struct MatchCheckCtxt<'a, 'tcx: 'a> { pub tcx: &'a ty::ctxt<'tcx>, pub param_env: ParameterEnvironment<'a, 'tcx>, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 1b1725dd15c85..8f19a6e9e152b 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, substs: trait_substs }); tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); - let param_env = tcx.empty_parameter_environment(); - let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index bd8b8afbdfe88..d8ee38b847830 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn lookup_and_handle_method(&mut self, id: ast::NodeId, span: codemap::Span) { let method_call = ty::MethodCall::expr(id); - match self.tcx.method_map.borrow().get(&method_call) { + match self.tcx.tables.borrow().method_map.get(&method_call) { Some(method) => { match method.origin { ty::MethodStatic(def_id) => { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index c48d5d5da4020..8084c2b0c39b8 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { match expr.node { ast::ExprMethodCall(_, _, _) => { let method_call = MethodCall::expr(expr.id); - let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty; + let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty; debug!("effect: method call case, base type is {:?}", base_type); if type_is_unsafe_function(base_type) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index a15d02ea29605..25728c50c61f4 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -257,8 +257,9 @@ impl OverloadedCallType { fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId) -> OverloadedCallType { let trait_did = - tcx.closure_kinds + tcx.tables .borrow() + .closure_kinds .get(&closure_did) .expect("OverloadedCallType::from_closure: didn't find closure id") .trait_did(tcx); @@ -787,8 +788,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // process. fn walk_adjustment(&mut self, expr: &ast::Expr) { let typer = self.typer; - if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) { - match *adjustment { + //NOTE(@jroesch): mixed RefCell borrow causes crash + let adj = typer.adjustments().get(&expr.id).map(|x| x.clone()); + if let Some(adjustment) = adj { + match adjustment { ty::AdjustReifyFnPointer | ty::AdjustUnsafeFnPointer => { // Creating a closure/fn-pointer or unsizing consumes diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index f1af2705d4ed8..8e53747e89973 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -77,6 +77,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> { // For region variables. region_vars: RegionVarBindings<'a, 'tcx>, + + pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, + + // pub tables: &'a RefCell> } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -309,7 +313,8 @@ pub fn fixup_err_to_string(f: fixup_err) -> String { } } -pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>) +pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, + param_env: Option>) -> InferCtxt<'a, 'tcx> { InferCtxt { tcx: tcx, @@ -317,6 +322,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>) int_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(UnificationTable::new()), region_vars: RegionVarBindings::new(tcx), + parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()) } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d354c1667da38..7d237a511c4a1 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1150,7 +1150,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ast::ExprMethodCall(_, _, ref args) => { let method_call = ty::MethodCall::expr(expr.id); - let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty; + let method_ty = self.ir.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty; let succ = if method_ty.fn_ret().diverges() { self.s.exit_ln } else { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 969ffaf88a719..13e127e912613 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -83,7 +83,7 @@ use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap::Span; -use std::cell::RefCell; +use std::cell::Ref; use std::fmt; use std::rc::Rc; @@ -289,7 +289,7 @@ pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> { fn node_method_ty(&self, method_call: ty::MethodCall) -> Option>; fn node_method_origin(&self, method_call: ty::MethodCall) -> Option>; - fn adjustments<'a>(&'a self) -> &'a RefCell>>; + fn adjustments(&self) -> Ref>>; fn is_method_call(&self, id: ast::NodeId) -> bool; fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option; fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option; @@ -408,7 +408,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { let unadjusted_ty = try!(self.expr_ty(expr)); Ok(unadjusted_ty.adjust( self.tcx(), expr.span, expr.id, - self.typer.adjustments().borrow().get(&expr.id), + self.typer.adjustments().get(&expr.id), |method_call| self.typer.node_method_ty(method_call))) } @@ -440,7 +440,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } pub fn cat_expr(&self, expr: &ast::Expr) -> McResult> { - match self.typer.adjustments().borrow().get(&expr.id) { + match self.typer.adjustments().get(&expr.id) { None => { // No adjustments. self.cat_expr_unadjusted(expr) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 0bbcfa700388c..6ea726062cad6 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { } ast::ExprMethodCall(..) => { let method_call = ty::MethodCall::expr(expr.id); - match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin { + match self.tcx.tables.borrow().method_map.get(&method_call).unwrap().origin { ty::MethodStatic(def_id) => { if is_local(def_id) { if self.def_id_represents_local_inlined_item(def_id) { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 4766ae8933d0b..e6bbae6405bf4 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr, ast::ExprMethodCall(i, _, _) => { span = i.span; let method_call = ty::MethodCall::expr(e.id); - match tcx.method_map.borrow().get(&method_call) { + match tcx.tables.borrow().method_map.get(&method_call) { Some(method) => { match method.origin { ty::MethodStatic(def_id) => { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 845ba62307fa5..eb839eade143f 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } +// TODO: this is gonna need to be removed ... /// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>, cause: ObligationCause<'tcx>) @@ -396,13 +397,13 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi let elaborated_env = unnormalized_env.with_caller_bounds(predicates); - let infcx = infer::new_infer_ctxt(tcx); - let predicates = match fully_normalize(&infcx, &elaborated_env, cause, - &elaborated_env.caller_bounds) { + let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env)); + let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause, + &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, Err(errors) => { report_fulfillment_errors(&infcx, &errors); - return unnormalized_env; // an unnormalized env is better than nothing + return infcx.parameter_environment; // an unnormalized env is better than nothing } }; @@ -420,11 +421,11 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi // all things considered. let err_msg = fixup_err_to_string(fixup_err); tcx.sess.span_err(span, &err_msg); - return elaborated_env; // an unnormalized env is better than nothing + return infcx.parameter_environment; // an unnormalized env is better than nothing } }; - elaborated_env.with_caller_bounds(predicates) + infcx.parameter_environment.with_caller_bounds(predicates) } pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 302ec08db6f26..cdf7f6ef9b6b6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -728,7 +728,7 @@ impl MethodCall { // maps from an expression id that corresponds to a method call to the details // of the method to be invoked -pub type MethodMap<'tcx> = RefCell>>; +pub type MethodMap<'tcx> = FnvHashMap>; // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. @@ -815,6 +815,48 @@ pub struct CommonTypes<'tcx> { pub err: Ty<'tcx>, } +pub struct Tables<'tcx> { + /// Stores the types for various nodes in the AST. Note that this table + /// is not guaranteed to be populated until after typeck. See + /// typeck::check::fn_ctxt for details. + pub node_types: NodeMap>, + + /// Stores the type parameters which were substituted to obtain the type + /// of this node. This only applies to nodes that refer to entities + /// parameterized by type parameters, such as generic fns, types, or + /// other items. + pub item_substs: NodeMap>, + + pub adjustments: NodeMap>, + + pub method_map: MethodMap<'tcx>, + + /// Borrows + pub upvar_capture_map: UpvarCaptureMap, + + /// Records the type of each closure. The def ID is the ID of the + /// expression defining the closure. + pub closure_tys: DefIdMap>, + + /// Records the type of each closure. The def ID is the ID of the + /// expression defining the closure. + pub closure_kinds: DefIdMap, +} + +impl<'tcx> Tables<'tcx> { + pub fn empty() -> Tables<'tcx> { + Tables { + node_types: FnvHashMap(), + item_substs: NodeMap(), + adjustments: NodeMap(), + method_map: FnvHashMap(), + upvar_capture_map: FnvHashMap(), + closure_tys: DefIdMap(), + closure_kinds: DefIdMap(), + } + } +} + /// The data structure to keep track of all the information that typechecker /// generates so that so that it can be reused and doesn't have to be redone /// later on. @@ -850,17 +892,9 @@ pub struct ctxt<'tcx> { // borrowck. (They are not used during trans, and hence are not // serialized or needed for cross-crate fns.) free_region_maps: RefCell>, + // FIXME: jroesch make this a refcell - /// Stores the types for various nodes in the AST. Note that this table - /// is not guaranteed to be populated until after typeck. See - /// typeck::check::fn_ctxt for details. - node_types: RefCell>>, - - /// Stores the type parameters which were substituted to obtain the type - /// of this node. This only applies to nodes that refer to entities - /// parameterized by type parameters, such as generic fns, types, or - /// other items. - pub item_substs: RefCell>>, + pub tables: RefCell>, /// Maps from a trait item to the trait item "descriptor" pub impl_or_trait_items: RefCell>>, @@ -894,7 +928,6 @@ pub struct ctxt<'tcx> { pub ast_ty_to_ty_cache: RefCell>>, pub enum_var_cache: RefCell>>>>>, pub ty_param_defs: RefCell>>, - pub adjustments: RefCell>>, pub normalized_cache: RefCell, Ty<'tcx>>>, pub lang_items: middle::lang_items::LanguageItems, /// A mapping of fake provided method def_ids to the default implementation @@ -944,26 +977,13 @@ pub struct ctxt<'tcx> { /// FIXME(arielb1): why is this separate from populated_external_types? pub populated_external_primitive_impls: RefCell, - /// Borrows - pub upvar_capture_map: RefCell, - /// These caches are used by const_eval when decoding external constants. pub extern_const_statics: RefCell>, pub extern_const_variants: RefCell>, pub extern_const_fns: RefCell>, - pub method_map: MethodMap<'tcx>, - pub dependency_formats: RefCell, - /// Records the type of each closure. The def ID is the ID of the - /// expression defining the closure. - pub closure_kinds: RefCell>, - - /// Records the type of each closure. The def ID is the ID of the - /// expression defining the closure. - pub closure_tys: RefCell>>, - pub node_lint_levels: RefCell>, @@ -1000,9 +1020,16 @@ pub struct ctxt<'tcx> { } impl<'tcx> ctxt<'tcx> { - pub fn node_types(&self) -> Ref>> { self.node_types.borrow() } + pub fn node_types(&self) -> Ref>> { + fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { + &tables.node_types + } + + Ref::map(self.tables.borrow(), projection) + } + pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) { - self.node_types.borrow_mut().insert(id, ty); + self.tables.borrow_mut().node_types.insert(id, ty); } pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> { @@ -3195,6 +3222,84 @@ impl<'tcx> CommonTypes<'tcx> { } } +/// Create a type context and call the closure with a `&ty::ctxt` reference +/// to the context. The closure enforces that the type context and any interned +/// value (types, substs, etc.) can only be used while `ty::tls` has a valid +/// reference to the context, to allow formatting values that need it. +pub fn with_ctxt<'tcx, F, R>(s: Session, + arenas: &'tcx CtxtArenas<'tcx>, + def_map: DefMap, + named_region_map: resolve_lifetime::NamedRegionMap, + map: ast_map::Map<'tcx>, + freevars: RefCell, + region_maps: RegionMaps, + lang_items: middle::lang_items::LanguageItems, + stability: stability::Index<'tcx>, + f: F) -> (Session, R) + where F: FnOnce(&ctxt<'tcx>) -> R +{ + let mut interner = FnvHashMap(); + let common_types = CommonTypes::new(&arenas.type_, &mut interner); + + tls::enter(ctxt { + arenas: arenas, + interner: RefCell::new(interner), + substs_interner: RefCell::new(FnvHashMap()), + bare_fn_interner: RefCell::new(FnvHashMap()), + region_interner: RefCell::new(FnvHashMap()), + stability_interner: RefCell::new(FnvHashMap()), + types: common_types, + named_region_map: named_region_map, + region_maps: region_maps, + free_region_maps: RefCell::new(FnvHashMap()), + item_variance_map: RefCell::new(DefIdMap()), + variance_computed: Cell::new(false), + sess: s, + def_map: def_map, + tables: RefCell::new(Tables::empty()), + impl_trait_refs: RefCell::new(DefIdMap()), + trait_defs: RefCell::new(DefIdMap()), + predicates: RefCell::new(DefIdMap()), + super_predicates: RefCell::new(DefIdMap()), + fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()), + map: map, + freevars: freevars, + tcache: RefCell::new(DefIdMap()), + rcache: RefCell::new(FnvHashMap()), + tc_cache: RefCell::new(FnvHashMap()), + ast_ty_to_ty_cache: RefCell::new(NodeMap()), + enum_var_cache: RefCell::new(DefIdMap()), + impl_or_trait_items: RefCell::new(DefIdMap()), + trait_item_def_ids: RefCell::new(DefIdMap()), + trait_items_cache: RefCell::new(DefIdMap()), + ty_param_defs: RefCell::new(NodeMap()), + normalized_cache: RefCell::new(FnvHashMap()), + lang_items: lang_items, + provided_method_sources: RefCell::new(DefIdMap()), + struct_fields: RefCell::new(DefIdMap()), + destructor_for_type: RefCell::new(DefIdMap()), + destructors: RefCell::new(DefIdSet()), + inherent_impls: RefCell::new(DefIdMap()), + impl_items: RefCell::new(DefIdMap()), + used_unsafe: RefCell::new(NodeSet()), + used_mut_nodes: RefCell::new(NodeSet()), + populated_external_types: RefCell::new(DefIdSet()), + populated_external_primitive_impls: RefCell::new(DefIdSet()), + extern_const_statics: RefCell::new(DefIdMap()), + extern_const_variants: RefCell::new(DefIdMap()), + extern_const_fns: RefCell::new(DefIdMap()), + dependency_formats: RefCell::new(FnvHashMap()), + node_lint_levels: RefCell::new(FnvHashMap()), + transmute_restrictions: RefCell::new(Vec::new()), + stability: RefCell::new(stability), + selection_cache: traits::SelectionCache::new(), + repr_hint_cache: RefCell::new(DefIdMap()), + const_qualif_map: RefCell::new(NodeMap()), + custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), + cast_kinds: RefCell::new(NodeMap()), + }, f) +} + struct FlagComputation { flags: TypeFlags, @@ -3421,8 +3526,7 @@ impl<'tcx> ctxt<'tcx> { variance_computed: Cell::new(false), sess: s, def_map: def_map, - node_types: RefCell::new(FnvHashMap()), - item_substs: RefCell::new(NodeMap()), + tables: RefCell::new(Tables::empty()), impl_trait_refs: RefCell::new(DefIdMap()), trait_defs: RefCell::new(DefIdMap()), predicates: RefCell::new(DefIdMap()), @@ -3439,7 +3543,6 @@ impl<'tcx> ctxt<'tcx> { trait_item_def_ids: RefCell::new(DefIdMap()), trait_items_cache: RefCell::new(DefIdMap()), ty_param_defs: RefCell::new(NodeMap()), - adjustments: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FnvHashMap()), lang_items: lang_items, provided_method_sources: RefCell::new(DefIdMap()), @@ -3452,14 +3555,10 @@ impl<'tcx> ctxt<'tcx> { used_mut_nodes: RefCell::new(NodeSet()), populated_external_types: RefCell::new(DefIdSet()), populated_external_primitive_impls: RefCell::new(DefIdSet()), - upvar_capture_map: RefCell::new(FnvHashMap()), extern_const_statics: RefCell::new(DefIdMap()), extern_const_variants: RefCell::new(DefIdMap()), extern_const_fns: RefCell::new(DefIdMap()), - method_map: RefCell::new(FnvHashMap()), dependency_formats: RefCell::new(FnvHashMap()), - closure_kinds: RefCell::new(DefIdMap()), - closure_tys: RefCell::new(DefIdMap()), node_lint_levels: RefCell::new(FnvHashMap()), transmute_restrictions: RefCell::new(Vec::new()), stability: RefCell::new(stability), @@ -3515,7 +3614,7 @@ impl<'tcx> ctxt<'tcx> { } pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind { - *self.closure_kinds.borrow().get(&def_id).unwrap() + *self.tables.borrow().closure_kinds.get(&def_id).unwrap() } pub fn closure_type(&self, @@ -3523,7 +3622,7 @@ impl<'tcx> ctxt<'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs) + self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, substs) } pub fn type_parameter_def(&self, @@ -4369,7 +4468,7 @@ impl<'tcx> TyS<'tcx> { span: Span) -> bool { - let infcx = infer::new_infer_ctxt(param_env.tcx()); + let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone())); let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, self, bound, span); @@ -5276,11 +5375,11 @@ impl<'tcx> ctxt<'tcx> { } pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option> { - self.node_types.borrow().get(&id).cloned() + self.tables.borrow().node_types.get(&id).cloned() } pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> { - match self.item_substs.borrow().get(&id) { + match self.tables.borrow().item_substs.get(&id) { None => ItemSubsts::empty(), Some(ts) => ts.clone(), } @@ -5325,9 +5424,9 @@ impl<'tcx> ctxt<'tcx> { pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> { self.expr_ty(expr) .adjust(self, expr.span, expr.id, - self.adjustments.borrow().get(&expr.id), + self.tables.borrow().adjustments.get(&expr.id), |method_call| { - self.method_map.borrow().get(&method_call).map(|method| method.ty) + self.tables.borrow().method_map.get(&method_call).map(|method| method.ty) }) } @@ -6671,11 +6770,11 @@ impl<'tcx> ctxt<'tcx> { } pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool { - self.method_map.borrow().contains_key(&MethodCall::expr(expr_id)) + self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id)) } pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone()) + Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone()) } } @@ -6689,17 +6788,21 @@ impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> { } fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty) + self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty) } fn node_method_origin(&self, method_call: ty::MethodCall) -> Option> { - self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone()) + self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone()) } - fn adjustments(&self) -> &RefCell>> { - &self.tcx.adjustments + fn adjustments(&self) -> Ref>> { + fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tcx.tables.borrow(), projection) } fn is_method_call(&self, id: ast::NodeId) -> bool { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index dcdf457965efa..de2f33e8a4ac9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -688,7 +688,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyStr => write!(f, "str"), TyClosure(ref did, substs) => ty::tls::with(|tcx| { try!(write!(f, "[closure")); - let closure_tys = tcx.closure_tys.borrow(); + let closure_tys = &tcx.tables.borrow().closure_tys; try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| { tcx.lift(&substs).map(|substs| sig.subst(tcx, substs)) }).map(|sig| { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 8fe07da157970..db48608823d21 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1446,7 +1446,7 @@ impl LintPass for UnusedAllocation { _ => return } - if let Some(adjustment) = cx.tcx.adjustments.borrow().get(&e.id) { + if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) { if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment { match autoref { &Some(ty::AutoPtr(_, ast::MutImmutable)) => { @@ -1984,7 +1984,7 @@ impl LintPass for UnconditionalRecursion { method_id: ast::NodeId, method_name: ast::Ident, id: ast::NodeId) -> bool { - let did = match tcx.method_map.borrow().get(&ty::MethodCall::expr(id)) { + let did = match tcx.tables.borrow().method_map.get(&ty::MethodCall::expr(id)) { None => return false, Some(m) => match m.origin { // There's no way to know if a method call via a diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 24803562fa373..239141df9e8c7 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } ast::ExprMethodCall(ident, _, _) => { let method_call = MethodCall::expr(expr.id); - match self.tcx.method_map.borrow().get(&method_call) { + match self.tcx.tables.borrow().method_map.get(&method_call) { None => { self.tcx.sess.span_bug(expr.span, "method call not in \ diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bb7e95cd4ae44..dc692b0e765dd 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,6 +43,7 @@ #![feature(unicode)] #![feature(unicode)] #![feature(vec_push_all)] +#![feature(cell_extras)] #![allow(trivial_casts)] diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 5ddad0e1947e8..d86242f39cea7 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -886,7 +886,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { fn process_method_call(&mut self, ex: &ast::Expr, args: &Vec>) { - let method_map = self.tcx.method_map.borrow(); + let method_map = &self.tcx.tables.borrow().method_map; let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap(); let (def_id, decl_id) = match method_callee.origin { ty::MethodStatic(def_id) | diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index f035b32e3596d..0cd6bbad03aa9 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -212,7 +212,7 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind { - *ccx.tcx().closure_kinds.borrow().get(&closure_id).unwrap() + *ccx.tcx().tables.borrow().closure_kinds.get(&closure_id).unwrap() } pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 24abe0ed3fdd2..dfe807d6c9152 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -518,7 +518,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( let ref_ty = match node { ExprId(id) => tcx.node_id_to_type(id), MethodCallKey(method_call) => { - tcx.method_map.borrow().get(&method_call).unwrap().ty + tcx.tables.borrow().method_map.get(&method_call).unwrap().ty } }; let ref_ty = monomorphize::apply_param_substs(tcx, @@ -610,7 +610,7 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_expr={:?})", call_expr); let method_call = MethodCall::expr(call_expr.id); - let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) { + let method_ty = match bcx.tcx().tables.borrow().method_map.get(&method_call) { Some(method) => match method.origin { ty::MethodTraitObject(_) => match method.ty.sty { ty::TyBareFn(_, ref fty) => { diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index cb30bcdbf5399..b637806285540 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -130,7 +130,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc closure_id: ast::DefId, substs: &Substs<'tcx>) -> Option> { - if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) { + if !ccx.tcx().tables.borrow().closure_kinds.contains_key(&closure_id) { // Not a closure. return None } diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 777b61f25f0ef..dc8c92429615d 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -47,7 +47,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; use arena::TypedArena; use libc::{c_uint, c_char}; use std::ffi::CString; -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, RefCell, Ref}; use std::result::Result as StdResult; use std::vec::Vec; use syntax::ast; @@ -353,7 +353,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> { // section of the executable we're generating. pub llfn: ValueRef, - // always an empty parameter-environment + // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv pub param_env: ty::ParameterEnvironment<'a, 'tcx>, // The environment argument in a closure. @@ -630,8 +630,9 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { self.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .map(|method| monomorphize_type(self, method.ty)) } @@ -640,18 +641,23 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { -> Option> { self.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .map(|method| method.origin.clone()) } - fn adjustments<'a>(&'a self) -> &'a RefCell>> { - &self.tcx().adjustments + fn adjustments<'a>(&'a self) -> Ref>> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tcx().tables.borrow(), project_adjustments) } fn is_method_call(&self, id: ast::NodeId) -> bool { - self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id)) + self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) } fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { @@ -659,7 +665,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone()) + Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone()) } fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { @@ -991,7 +997,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trait_ref, trait_ref.def_id()); tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -1053,7 +1059,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, predicates); let tcx = ccx.tcx(); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let mut fulfill_cx = traits::FulfillmentContext::new(false); @@ -1070,6 +1076,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok() } +// NOTE: here is another use of parameter environment without an InferCtxt, +// this is obviously related to the typer interface requiring a parameter env. +// We should pay attention to this when refactoring +// - @jroesch pub struct NormalizingClosureTyper<'a,'tcx:'a> { param_env: ty::ParameterEnvironment<'a, 'tcx> } @@ -1191,7 +1201,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, tcx.node_id_item_substs(id).substs } MethodCallKey(method_call) => { - tcx.method_map.borrow().get(&method_call).unwrap().substs.clone() + tcx.tables.borrow().method_map.get(&method_call).unwrap().substs.clone() } }; diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 8ec60000ee842..57af688ef60d7 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -228,7 +228,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def(); match def { def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => { - if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) { + if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) { debug!("get_const_expr_as_global ({:?}): found const {:?}", expr.id, def_id); return get_const_val(ccx, def_id, expr); @@ -281,7 +281,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let mut llconst = llconst; let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs, &cx.tcx().expr_ty_adjusted(e)); - let opt_adj = cx.tcx().adjustments.borrow().get(&e.id).cloned(); + let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned(); match opt_adj { Some(ty::AdjustReifyFnPointer) => { // FIXME(#19925) once fn item types are @@ -894,7 +894,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprMethodCall(_, _, ref args) => { let arg_vals = map_list(args); let method_call = ty::MethodCall::expr(e.id); - let method_did = match cx.tcx().method_map.borrow()[&method_call].origin { + let method_did = match cx.tcx().tables.borrow().method_map[&method_call].origin { ty::MethodStatic(did) => did, _ => cx.sess().span_bug(e.span, "expected a const method def") }; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 8fd88055b8e45..045cc69bf954b 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -117,7 +117,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debuginfo::set_source_location(bcx.fcx, expr.id, expr.span); - if bcx.tcx().adjustments.borrow().contains_key(&expr.id) { + if bcx.tcx().tables.borrow().adjustments.contains_key(&expr.id) { // use trans, which may be less efficient but // which will perform the adjustments: let datum = unpack_datum!(bcx, trans(bcx, expr)); @@ -345,7 +345,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, { let mut bcx = bcx; let mut datum = datum; - let adjustment = match bcx.tcx().adjustments.borrow().get(&expr.id).cloned() { + let adjustment = match bcx.tcx().tables.borrow().adjustments.get(&expr.id).cloned() { None => { return DatumBlock::new(bcx, datum); } @@ -372,7 +372,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Don't skip a conversion from Box to &T, etc. ty::TyRef(..) => { let method_call = MethodCall::autoderef(expr.id, 0); - if bcx.tcx().method_map.borrow().contains_key(&method_call) { + if bcx.tcx().tables.borrow().method_map.contains_key(&method_call) { // Don't skip an overloaded deref. 0 } else { @@ -774,8 +774,9 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Check for overloaded index. let method_ty = ccx.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .map(|method| method.ty); let elt_datum = match method_ty { @@ -1617,7 +1618,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Otherwise, we should be in the RvalueDpsExpr path. assert!( op == ast::UnDeref || - !ccx.tcx().method_map.borrow().contains_key(&method_call)); + !ccx.tcx().tables.borrow().method_map.contains_key(&method_call)); let un_ty = expr_ty(bcx, expr); @@ -1910,7 +1911,7 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let ccx = bcx.ccx(); // if overloaded, would be RvalueDpsExpr - assert!(!ccx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id))); + assert!(!ccx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id))); match op.node { ast::BiAnd => { @@ -1950,7 +1951,12 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, dest: Option, autoref: bool) -> Result<'blk, 'tcx> { - let method_ty = bcx.tcx().method_map.borrow().get(&method_call).unwrap().ty; + let method_ty = bcx.tcx() + .tables + .borrow() + .method_map + .get(&method_call).unwrap().ty; + callee::trans_call_inner(bcx, expr.debug_loc(), monomorphize_type(bcx, method_ty), @@ -1973,8 +1979,9 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, debug!("trans_overloaded_call {}", expr.id); let method_call = MethodCall::expr(expr.id); let method_type = bcx.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .unwrap() .ty; @@ -2154,7 +2161,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("trans_assign_op(expr={:?})", expr); // User-defined operator methods cannot be used with `+=` etc right now - assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id))); + assert!(!bcx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id))); // Evaluate LHS (destination), which should be an lvalue let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op")); @@ -2229,8 +2236,12 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let mut bcx = bcx; // Check for overloaded deref. - let method_ty = ccx.tcx().method_map.borrow() + let method_ty = ccx.tcx() + .tables + .borrow() + .method_map .get(&method_call).map(|method| method.ty); + let datum = match method_ty { Some(method_ty) => { let method_ty = monomorphize_type(bcx, method_ty); @@ -2615,7 +2626,7 @@ enum ExprKind { } fn expr_kind(tcx: &ty::ctxt, expr: &ast::Expr) -> ExprKind { - if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) { + if tcx.tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)) { // Overloaded operations are generally calls, and hence they are // generated via DPS, but there are a few exceptions: return match expr.node { diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index a3e5b640fd0f1..e46c3b5fab1f7 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -109,11 +109,13 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("meth::trans_method_callee"); let (origin, method_ty) = - bcx.tcx().method_map - .borrow() - .get(&method_call) - .map(|method| (method.origin.clone(), method.ty)) - .unwrap(); + bcx.tcx() + .tables + .borrow() + .method_map + .get(&method_call) + .map(|method| (method.origin.clone(), method.ty)) + .unwrap(); match origin { ty::MethodStatic(did) | diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index cae810c9082e5..fa992511cc19b 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -322,8 +322,9 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T } // FIXME(#20304) -- cache - - let infcx = infer::new_infer_ctxt(tcx); + // NOTE: @jroesch + // Here is of an example where we do not use a param_env but use a typer instead. + let infcx = infer::new_infer_ctxt(tcx, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let cause = traits::ObligationCause::dummy(); diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 7109e45b55279..c2170686faccb 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -324,7 +324,7 @@ fn write_overloaded_call_method_map<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>, call_expr: &ast::Expr, method_callee: ty::MethodCallee<'tcx>) { let method_call = ty::MethodCall::expr(call_expr.id); - fcx.inh.method_map.borrow_mut().insert(method_call, method_callee); + fcx.inh.tables.borrow_mut().method_map.insert(method_call, method_callee); } #[derive(Debug)] diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index d431c0fda9865..b5ee46ece94be 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -61,7 +61,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expected_sig); let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id, - fcx.ccx.tcx.mk_substs(fcx.inh.param_env.free_substs.clone())); + fcx.ccx.tcx.mk_substs(fcx.inh.infcx.parameter_environment.free_substs.clone())); fcx.write_ty(expr.id, closure_type); @@ -86,9 +86,9 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, fn_ty.sig, opt_kind); - fcx.inh.closure_tys.borrow_mut().insert(expr_def_id, fn_ty); + fcx.inh.tables.borrow_mut().closure_tys.insert(expr_def_id, fn_ty); match opt_kind { - Some(kind) => { fcx.inh.closure_kinds.borrow_mut().insert(expr_def_id, kind); } + Some(kind) => { fcx.inh.tables.borrow_mut().closure_kinds.insert(expr_def_id, kind); } None => { } } } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 349d1a8bb65a8..dc8ef46a7ba64 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}", impl_trait_ref); - let infcx = infer::new_infer_ctxt(tcx); + let mut infcx = infer::new_infer_ctxt(tcx, None); let mut fulfillment_cx = traits::FulfillmentContext::new(true); let trait_to_impl_substs = &impl_trait_ref.substs; @@ -240,11 +240,13 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.into_vec()); let trait_param_env = traits::normalize_param_env_or_error(trait_param_env, normalize_cause.clone()); + // TODO (@jroesch) this seems ugly, but is a temporary change + infcx.parameter_environment = trait_param_env; debug!("compare_impl_method: trait_bounds={:?}", - trait_param_env.caller_bounds); + infcx.parameter_environment.caller_bounds); - let mut selcx = traits::SelectionContext::new(&infcx, &trait_param_env); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); for predicate in impl_pred.fns { let traits::Normalized { value: predicate, .. } = @@ -345,7 +347,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // Check that all obligations are satisfied by the implementation's // version. - match fulfillment_cx.select_all_or_error(&infcx, &trait_param_env) { + match fulfillment_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) } Ok(_) => {} } @@ -360,7 +362,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // anyway, so it shouldn't be needed there either. Anyway, we can // always add more relations later (it's backwards compat). let mut free_regions = FreeRegionMap::new(); - free_regions.relate_free_regions_from_predicates(tcx, &trait_param_env.caller_bounds); + free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds); infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id); @@ -416,7 +418,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); let mut fulfillment_cx = traits::FulfillmentContext::new(true); // The below is for the most part highly similar to the procedure diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index a48cffb4472f4..4abfd84d8ef3c 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -93,7 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( ty: named_type } = tcx.lookup_item_type(self_type_did); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); + infcx.commit_if_ok(|snapshot| { let (named_type_to_skolem, skol_map) = infcx.construct_skolemized_subst(named_type_generics, snapshot); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 5f7a78ec611a2..5601888a1f073 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -488,8 +488,9 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // Count autoderefs. let autoderef_count = match self.fcx .inh - .adjustments + .tables .borrow() + .adjustments .get(&expr.id) { Some(&ty::AdjustDerefRef(ref adj)) => adj.autoderefs, Some(_) | None => 0, @@ -527,7 +528,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // expects. This is annoying and horrible. We // ought to recode this routine so it doesn't // (ab)use the normal type checking paths. - let adj = self.fcx.inh.adjustments.borrow().get(&base_expr.id).cloned(); + let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id).cloned(); let (autoderefs, unsize) = match adj { Some(ty::AdjustDerefRef(adr)) => match adr.autoref { None => { @@ -589,7 +590,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // if this is an overloaded deref, then re-evaluate with // a preference for mut let method_call = MethodCall::expr(expr.id); - if self.fcx.inh.method_map.borrow().contains_key(&method_call) { + if self.fcx.inh.tables.borrow().method_map.contains_key(&method_call) { check::try_overloaded_deref( self.fcx, expr.span, diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 8026fce69ecca..2cf041919147c 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -477,7 +477,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // FIXME -- Do we want to commit to this behavior for param bounds? let bounds: Vec<_> = - self.fcx.inh.param_env.caller_bounds + self.fcx.inh.infcx.parameter_environment.caller_bounds .iter() .filter_map(|predicate| { match *predicate { @@ -742,7 +742,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { _ => continue, }; - let closure_kinds = self.fcx.inh.closure_kinds.borrow(); + let closure_kinds = &self.fcx.inh.tables.borrow().closure_kinds; let closure_kind = match closure_kinds.get(&closure_def_id) { Some(&k) => k, None => { @@ -845,7 +845,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("assemble_where_clause_candidates(trait_def_id={:?})", trait_def_id); - let caller_predicates = self.fcx.inh.param_env.caller_bounds.clone(); + let caller_predicates = self.fcx.inh.infcx.parameter_environment.caller_bounds.clone(); for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates) .filter_map(|p| p.to_opt_poly_trait_ref()) .filter(|b| b.def_id() == trait_def_id) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 299ccd579ccb7..058cbe020b7d6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,7 @@ use middle::traits::{self, report_fulfillment_errors}; use middle::ty::{FnSig, GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; -use middle::ty::{MethodCall, MethodCallee, MethodMap}; +use middle::ty::{MethodCall, MethodCallee}; use middle::ty_fold::{TypeFolder, TypeFoldable}; use rscope::RegionScope; use session::Session; @@ -152,16 +152,8 @@ mod op; pub struct Inherited<'a, 'tcx: 'a> { infcx: infer::InferCtxt<'a, 'tcx>, locals: RefCell>>, - param_env: ty::ParameterEnvironment<'a, 'tcx>, - // Temporary tables: - node_types: RefCell>>, - item_substs: RefCell>>, - adjustments: RefCell>>, - method_map: MethodMap<'tcx>, - upvar_capture_map: RefCell, - closure_tys: RefCell>>, - closure_kinds: RefCell>, + tables: &'a RefCell>, // A mapping from each fn's id to its signature, with all bound // regions replaced with free ones. Unlike the other tables, this @@ -303,52 +295,68 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { let ty = self.node_ty(id); self.resolve_type_vars_or_error(&ty) } + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { - let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id)); + let ty = self.adjust_expr_ty(expr, self.inh.tables.borrow().adjustments.get(&expr.id)); self.resolve_type_vars_or_error(&ty) } + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { let ty = self.infcx().resolve_type_vars_if_possible(&ty); !traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span) } + fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - self.inh.method_map.borrow() - .get(&method_call) - .map(|method| method.ty) - .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty)) + self.inh.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.ty) + .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty)) } + fn node_method_origin(&self, method_call: ty::MethodCall) -> Option> { - self.inh.method_map.borrow() - .get(&method_call) - .map(|method| method.origin.clone()) + self.inh.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.origin.clone()) } - fn adjustments(&self) -> &RefCell>> { - &self.inh.adjustments + + fn adjustments(&self) -> Ref>> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.inh.tables.borrow(), project_adjustments) } + fn is_method_call(&self, id: ast::NodeId) -> bool { - self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id)) + self.inh.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) } + fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { self.param_env().temporary_scope(rvalue_id) } + fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.inh.upvar_capture_map.borrow().get(&upvar_id).cloned() + self.inh.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() } } impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - &self.inh.param_env + &self.inh.infcx.parameter_environment } fn closure_kind(&self, def_id: ast::DefId) -> Option { - self.inh.closure_kinds.borrow().get(&def_id).cloned() + self.inh.tables.borrow().closure_kinds.get(&def_id).cloned() } fn closure_type(&self, @@ -356,7 +364,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs) + self.inh.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx(), substs) } fn closure_upvars(&self, @@ -369,19 +377,14 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { impl<'a, 'tcx> Inherited<'a, 'tcx> { fn new(tcx: &'a ty::ctxt<'tcx>, + tables: &'a RefCell>, param_env: ty::ParameterEnvironment<'a, 'tcx>) -> Inherited<'a, 'tcx> { + Inherited { - infcx: infer::new_infer_ctxt(tcx), + infcx: infer::new_infer_ctxt(tcx, Some(param_env)), locals: RefCell::new(NodeMap()), - param_env: param_env, - node_types: RefCell::new(NodeMap()), - item_substs: RefCell::new(NodeMap()), - adjustments: RefCell::new(NodeMap()), - method_map: RefCell::new(FnvHashMap()), - upvar_capture_map: RefCell::new(FnvHashMap()), - closure_tys: RefCell::new(DefIdMap()), - closure_kinds: RefCell::new(DefIdMap()), + tables: tables, fn_sig_map: RefCell::new(NodeMap()), fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)), deferred_call_resolutions: RefCell::new(DefIdMap()), @@ -424,12 +427,12 @@ pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, } } -fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>) +fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, tables: &'a RefCell>) -> Inherited<'a, 'tcx> { // It's kind of a kludge to manufacture a fake function context // and statement context, but we might as well do write the code only once let param_env = ccx.tcx.empty_parameter_environment(); - Inherited::new(ccx.tcx, param_env) + Inherited::new(ccx.tcx, &tables, param_env) } struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } @@ -504,16 +507,20 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, { match raw_fty.sty { ty::TyBareFn(_, ref fn_ty) => { - let inh = Inherited::new(ccx.tcx, param_env); + let tables = RefCell::new(ty::Tables::empty()); + let inh = Inherited::new(ccx.tcx, &tables, param_env); // Compute the fty from point of view of inside fn. let fn_sig = - fn_ty.sig.subst(ccx.tcx, &inh.param_env.free_substs); + fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs); let fn_sig = ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig); + inh.normalize_associated_types_in(&inh.infcx.parameter_environment, + body.span, + body.id, + &fn_sig); let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig, decl, fn_id, body, &inh); @@ -1198,7 +1205,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn get_free_substs(&self) -> Option<&Substs<'tcx>> { - Some(&self.inh.param_env.free_substs) + Some(&self.inh.infcx.parameter_environment.free_substs) } fn get_type_parameter_bounds(&self, @@ -1207,7 +1214,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { -> Result>, ErrorReported> { let def = self.tcx().type_parameter_def(node_id); - let r = self.inh.param_env.caller_bounds + let r = self.inh.infcx.parameter_environment + .caller_bounds .iter() .filter_map(|predicate| { match *predicate { @@ -1273,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> { - &self.inh.param_env + &self.inh.infcx.parameter_environment } pub fn sess(&self) -> &Session { @@ -1368,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64. pub fn default_type_parameters(&self) { use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither}; - for (_, &mut ref ty) in &mut *self.inh.node_types.borrow_mut() { + for (_, &mut ref ty) in &mut self.inh.tables.borrow_mut().node_types { let resolved = self.infcx().resolve_type_vars_if_possible(ty); if self.infcx().type_var_diverges(resolved) { demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil()); @@ -1390,7 +1398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) { debug!("write_ty({}, {:?}) in fcx {}", node_id, ty, self.tag()); - self.inh.node_types.borrow_mut().insert(node_id, ty); + self.inh.tables.borrow_mut().node_types.insert(node_id, ty); } pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) { @@ -1400,7 +1408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { substs, self.tag()); - self.inh.item_substs.borrow_mut().insert(node_id, substs); + self.inh.tables.borrow_mut().item_substs.insert(node_id, substs); } } @@ -1426,7 +1434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.inh.adjustments.borrow_mut().insert(node_id, adj); + self.inh.tables.borrow_mut().adjustments.insert(node_id, adj); } /// Basically whenever we are converting from a type scheme into @@ -1627,7 +1635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> { - match self.inh.node_types.borrow().get(&ex.id) { + match self.inh.tables.borrow().node_types.get(&ex.id) { Some(&t) => t, None => { self.tcx().sess.bug(&format!("no type for expr in fcx {}", @@ -1646,13 +1654,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let raw_ty = self.infcx().shallow_resolve(raw_ty); let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty); raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| { - self.inh.method_map.borrow().get(&method_call) + self.inh.tables.borrow().method_map.get(&method_call) .map(|method| resolve_ty(method.ty)) }) } pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { - match self.inh.node_types.borrow().get(&id) { + match self.inh.tables.borrow().node_types.get(&id) { Some(&t) => t, None if self.err_count_since_creation() != 0 => self.tcx().types.err, None => { @@ -1665,7 +1673,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn item_substs(&self) -> Ref>> { - self.inh.item_substs.borrow() + // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if it changes + // when we upgrade the snapshot compiler + fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + &tables.item_substs + } + + Ref::map(self.inh.tables.borrow(), project_item_susbts) } pub fn opt_node_ty_substs(&self, @@ -1673,7 +1687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { f: F) where F: FnOnce(&ty::ItemSubsts<'tcx>), { - match self.inh.item_substs.borrow().get(&id) { + match self.inh.tables.borrow().item_substs.get(&id) { Some(s) => { f(s) } None => { } } @@ -2039,7 +2053,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap(); if let Some(method_call) = method_call { - fcx.inh.method_map.borrow_mut().insert(method_call, method); + fcx.inh.tables.borrow_mut().method_map.insert(method_call, method); } // method returns &T, but the type as visible to user is T, so deref @@ -2640,7 +2654,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, Ok(method) => { let method_ty = method.ty; let method_call = MethodCall::expr(expr.id); - fcx.inh.method_map.borrow_mut().insert(method_call, method); + fcx.inh.tables.borrow_mut().method_map.insert(method_call, method); method_ty } Err(error) => { @@ -4074,7 +4088,8 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>, expr: &'tcx ast::Expr, expected_type: Ty<'tcx>) { - let inh = static_inherited_fields(ccx); + let tables = RefCell::new(ty::Tables::empty()); + let inh = static_inherited_fields(ccx, &tables); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id); check_const_with_ty(&fcx, expr.span, expr, expected_type); } @@ -4083,7 +4098,8 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, sp: Span, e: &'tcx ast::Expr, id: ast::NodeId) { - let inh = static_inherited_fields(ccx); + let tables = RefCell::new(ty::Tables::empty()); + let inh = static_inherited_fields(ccx, &tables); let rty = ccx.tcx.node_id_to_type(id); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id); let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty; @@ -4235,7 +4251,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let rty = ccx.tcx.node_id_to_type(id); let mut disr_vals: Vec = Vec::new(); - let inh = static_inherited_fields(ccx); + let tables = RefCell::new(ty::Tables::empty()); + let inh = static_inherited_fields(ccx, &tables); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id); let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint)); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 5a114c811191c..c419a986f95b1 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -330,7 +330,7 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, // HACK(eddyb) Fully qualified path to work around a resolve bug. let method_call = ::middle::ty::MethodCall::expr(expr.id); - fcx.inh.method_map.borrow_mut().insert(method_call, method); + fcx.inh.tables.borrow_mut().method_map.insert(method_call, method); // extract return type for method; all late bound regions // should have been instantiated by now @@ -454,4 +454,3 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>, } } } - diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 13961834aebdd..8f8ec0f7264aa 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -124,7 +124,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) { pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) { let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id)); let tcx = fcx.tcx(); - rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds); + rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds); rcx.visit_region_obligations(item.id); rcx.resolve_regions_and_report_errors(); } @@ -143,7 +143,7 @@ pub fn regionck_fn(fcx: &FnCtxt, } let tcx = fcx.tcx(); - rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds); + rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds); rcx.resolve_regions_and_report_errors(); @@ -254,7 +254,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { } fn resolve_method_type(&self, method_call: MethodCall) -> Option> { - let method_ty = self.fcx.inh.method_map.borrow() + let method_ty = self.fcx.inh.tables.borrow().method_map .get(&method_call).map(|method| method.ty); method_ty.map(|method_ty| self.resolve_type(method_ty)) } @@ -267,7 +267,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { } else { ty_unadjusted.adjust( self.fcx.tcx(), expr.span, expr.id, - self.fcx.inh.adjustments.borrow().get(&expr.id), + self.fcx.inh.tables.borrow().adjustments.get(&expr.id), |method_call| self.resolve_method_type(method_call)) } } @@ -511,12 +511,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { expr_ty, ty::ReScope(CodeExtent::from_node_id(expr.id))); let method_call = MethodCall::expr(expr.id); - let has_method_map = rcx.fcx.inh.method_map.borrow().contains_key(&method_call); + let has_method_map = rcx.fcx.inh.tables.borrow().method_map.contains_key(&method_call); // Check any autoderefs or autorefs that appear. - if let Some(adjustment) = rcx.fcx.inh.adjustments.borrow().get(&expr.id) { + let adjustment = rcx.fcx.inh.tables.borrow().adjustments.get(&expr.id).map(|a| a.clone()); + if let Some(adjustment) = adjustment { debug!("adjustment={:?}", adjustment); - match *adjustment { + match adjustment { ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, ref autoref, ..}) => { let expr_ty = rcx.resolve_node_type(expr.id); constrain_autoderefs(rcx, expr, autoderefs, expr_ty); @@ -657,7 +658,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { ast::ExprUnary(ast::UnDeref, ref base) => { // For *a, the lifetime of a must enclose the deref let method_call = MethodCall::expr(expr.id); - let base_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) { + let base_ty = match rcx.fcx.inh.tables.borrow().method_map.get(&method_call) { Some(method) => { constrain_call(rcx, expr, Some(&**base), None::.iter(), true); @@ -884,7 +885,9 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, let method_call = MethodCall::autoderef(deref_expr.id, i as u32); debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs); - derefd_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) { + let method = rcx.fcx.inh.tables.borrow().method_map.get(&method_call).map(|m| m.clone()); + + derefd_ty = match method { Some(method) => { debug!("constrain_autoderefs: #{} is overloaded, method={:?}", i, method); @@ -1018,7 +1021,7 @@ fn type_of_node_must_outlive<'a, 'tcx>( // report errors later on in the writeback phase. let ty0 = rcx.resolve_node_type(id); let ty = ty0.adjust(tcx, origin.span(), id, - rcx.fcx.inh.adjustments.borrow().get(&id), + rcx.fcx.inh.tables.borrow().adjustments.get(&id), |method_call| rcx.resolve_method_type(method_call)); debug!("constrain_regions_in_type_of_node(\ ty={}, ty0={}, id={}, minimum_lifetime={:?})", @@ -1292,7 +1295,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, // Detect by-ref upvar `x`: let cause = match note { mc::NoteUpvarRef(ref upvar_id) => { - let upvar_capture_map = rcx.fcx.inh.upvar_capture_map.borrow_mut(); + let upvar_capture_map = &rcx.fcx.inh.tables.borrow_mut().upvar_capture_map; match upvar_capture_map.get(upvar_id) { Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => { // The mutability of the upvar may have been modified @@ -1453,7 +1456,7 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region, generic: &GenericKind<'tcx>) { - let param_env = &rcx.fcx.inh.param_env; + let param_env = &rcx.fcx.inh.infcx.parameter_environment; debug!("param_must_outlive(region={:?}, generic={:?})", region, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 1345f322476b9..db32b29ebab81 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -129,9 +129,9 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { _body: &ast::Block) { let closure_def_id = ast_util::local_def(expr.id); - if !self.fcx.inh.closure_kinds.borrow().contains_key(&closure_def_id) { + if !self.fcx.inh.tables.borrow().closure_kinds.contains_key(&closure_def_id) { self.closures_with_inferred_kinds.insert(expr.id); - self.fcx.inh.closure_kinds.borrow_mut().insert(closure_def_id, ty::FnClosureKind); + self.fcx.inh.tables.borrow_mut().closure_kinds.insert(closure_def_id, ty::FnClosureKind); debug!("check_closure: adding closure_id={:?} to closures_with_inferred_kinds", closure_def_id); } @@ -156,7 +156,7 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { } }; - self.fcx.inh.upvar_capture_map.borrow_mut().insert(upvar_id, capture_kind); + self.fcx.inh.tables.borrow_mut().upvar_capture_map.insert(upvar_id, capture_kind); } }); } @@ -267,7 +267,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // to move out of an upvar, this must be a FnOnce closure self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnOnceClosureKind); - let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut(); + let upvar_capture_map = &mut self.fcx.inh.tables.borrow_mut().upvar_capture_map; upvar_capture_map.insert(upvar_id, ty::UpvarCapture::ByValue); } mc::NoteClosureEnv(upvar_id) => { @@ -374,9 +374,11 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // upvar, then we need to modify the // borrow_kind of the upvar to make sure it // is inferred to mutable if necessary - let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut(); - let ub = upvar_capture_map.get_mut(&upvar_id).unwrap(); - self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind); + { + let upvar_capture_map = &mut self.fcx.inh.tables.borrow_mut().upvar_capture_map; + let ub = upvar_capture_map.get_mut(&upvar_id).unwrap(); + self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind); + } // also need to be in an FnMut closure since this is not an ImmBorrow self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnMutClosureKind); @@ -442,7 +444,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { } let closure_def_id = ast_util::local_def(closure_id); - let mut closure_kinds = self.fcx.inh.closure_kinds.borrow_mut(); + let closure_kinds = &mut self.fcx.inh.tables.borrow_mut().closure_kinds; let existing_kind = *closure_kinds.get(&closure_def_id).unwrap(); debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}", diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 00bbbafd5cd32..c2852e425b6f9 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -18,6 +18,7 @@ use middle::traits; use middle::ty::{self, Ty}; use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty}; +use std::cell::RefCell; use std::collections::HashSet; use syntax::ast; use syntax::ast_util::local_def; @@ -143,7 +144,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &type_scheme.generics, &type_predicates, item.id); - let inh = Inherited::new(ccx.tcx, param_env); + let tables = RefCell::new(ty::Tables::empty()); + let inh = Inherited::new(ccx.tcx, &tables, param_env); let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id); f(self, &fcx); fcx.select_all_obligations_or_error(); @@ -199,7 +201,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id)); let item_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh.param_env.free_substs, + &fcx.inh.infcx.parameter_environment.free_substs, &type_scheme.ty); bounds_checker.check_traits_in_ty(item_ty, item.span); @@ -220,7 +222,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // to free. let self_ty = fcx.tcx().node_id_to_type(item.id); let self_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh.param_env.free_substs, + &fcx.inh.infcx.parameter_environment.free_substs, &self_ty); bounds_checker.check_traits_in_ty(self_ty, item.span); @@ -233,7 +235,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { }; let trait_ref = fcx.instantiate_type_scheme(item.span, - &fcx.inh.param_env.free_substs, + &fcx.inh.infcx.parameter_environment.free_substs, &trait_ref); // We are stricter on the trait-ref in an impl than the @@ -635,7 +637,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, .map(|field| { let field_ty = fcx.tcx().node_id_to_type(field.node.id); let field_ty = fcx.instantiate_type_scheme(field.span, - &fcx.inh.param_env.free_substs, + &fcx.inh.infcx.parameter_environment.free_substs, &field_ty); AdtField { ty: field_ty, span: field.span } }) @@ -660,7 +662,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let arg_ty = arg_tys[index]; let arg_ty = fcx.instantiate_type_scheme(variant.span, - &fcx.inh.param_env.free_substs, + &fcx.inh.infcx.parameter_environment.free_substs, &arg_ty); AdtField { ty: arg_ty, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 29119f3b5946d..d990697949659 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -96,14 +96,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty); if lhs_ty.is_scalar() && rhs_ty.is_scalar() { - self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id)); + self.fcx.inh.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id)); // weird but true: the by-ref binops put an // adjustment on the lhs but not the rhs; the // adjustment for rhs is kind of baked into the // system. if !ast_util::is_by_value_binop(op.node) { - self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id); + self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id); } } } @@ -204,7 +204,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { return; } - for (upvar_id, upvar_capture) in self.fcx.inh.upvar_capture_map.borrow().iter() { + for (upvar_id, upvar_capture) in self.fcx.inh.tables.borrow().upvar_capture_map.iter() { let new_upvar_capture = match *upvar_capture { ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue, ty::UpvarCapture::ByRef(ref upvar_borrow) => { @@ -217,7 +217,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug!("Upvar capture for {:?} resolved to {:?}", upvar_id, new_upvar_capture); - self.fcx.tcx().upvar_capture_map.borrow_mut().insert(*upvar_id, new_upvar_capture); + self.fcx.tcx().tables.borrow_mut().upvar_capture_map.insert(*upvar_id, new_upvar_capture); } } @@ -226,13 +226,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { return } - for (def_id, closure_ty) in self.fcx.inh.closure_tys.borrow().iter() { + for (def_id, closure_ty) in self.fcx.inh.tables.borrow().closure_tys.iter() { let closure_ty = self.resolve(closure_ty, ResolvingClosure(*def_id)); - self.fcx.tcx().closure_tys.borrow_mut().insert(*def_id, closure_ty); + self.fcx.tcx().tables.borrow_mut().closure_tys.insert(*def_id, closure_ty); } - for (def_id, &closure_kind) in self.fcx.inh.closure_kinds.borrow().iter() { - self.fcx.tcx().closure_kinds.borrow_mut().insert(*def_id, closure_kind); + for (def_id, &closure_kind) in self.fcx.inh.tables.borrow().closure_kinds.iter() { + self.fcx.tcx().tables.borrow_mut().closure_kinds.insert(*def_id, closure_kind); } } @@ -254,7 +254,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) { - match self.fcx.inh.adjustments.borrow_mut().remove(&id) { + let adjustments = self.fcx.inh.tables.borrow_mut().adjustments.remove(&id); + match adjustments { None => { debug!("No adjustments for node {}", id); } @@ -281,7 +282,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } }; debug!("Adjustments for node {}: {:?}", id, resolved_adjustment); - self.tcx().adjustments.borrow_mut().insert( + self.tcx().tables.borrow_mut().adjustments.insert( id, resolved_adjustment); } } @@ -291,7 +292,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { reason: ResolveReason, method_call: MethodCall) { // Resolve any method map entry - match self.fcx.inh.method_map.borrow_mut().remove(&method_call) { + let new_method = match self.fcx.inh.tables.borrow_mut().method_map.remove(&method_call) { Some(method) => { debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})", method_call, @@ -302,9 +303,17 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { substs: self.resolve(&method.substs, reason), }; - self.tcx().method_map.borrow_mut().insert( + Some(new_method) + } + None => None + }; + + //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE + match new_method { + Some(method) => { + self.tcx().tables.borrow_mut().method_map.insert( method_call, - new_method); + method); } None => {} } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 06bd572ac12f3..5441f0b677200 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)", source, target); - let infcx = new_infer_ctxt(tcx); + let infcx = new_infer_ctxt(tcx, Some(param_env)); let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>, mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| { @@ -540,13 +540,13 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fulfill_cx.register_predicate_obligation(&infcx, predicate); // Check that all transitive obligations are satisfied. - if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, ¶m_env) { + if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { traits::report_fulfillment_errors(&infcx, &errors); } // Finally, resolve all regions. let mut free_regions = FreeRegionMap::new(); - free_regions.relate_free_regions_from_predicates(tcx, ¶m_env.caller_bounds); + free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds); infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node); if let Some(kind) = kind { @@ -630,7 +630,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, - inference_context: new_infer_ctxt(crate_context.tcx), + inference_context: new_infer_ctxt(crate_context.tcx, None), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); unsafety::check(crate_context.tcx); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index b4ad55ef2e46b..a851bb93e3fc7 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { impl1_def_id, impl2_def_id); - let infcx = infer::new_infer_ctxt(self.tcx); + let infcx = infer::new_infer_ctxt(self.tcx, None); if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) { self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e43a3542b6e33..3e2a88e1f79c1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( base_type, base_type_free); - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); drop(::require_same_types(tcx, Some(&infcx), false, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index fc825c198e751..5d589d2ec78c9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -88,6 +88,7 @@ This API is completely unstable and subject to change. #![feature(slice_extras)] #![feature(staged_api)] #![feature(vec_push_all)] +#![feature(cell_extras)] #[macro_use] extern crate log; #[macro_use] extern crate syntax; @@ -162,7 +163,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, assert!(!item_substs.substs.types.needs_infer()); - tcx.item_substs.borrow_mut().insert(node_id, item_substs); + tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs); } } @@ -187,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, { let result = match maybe_infcx { None => { - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, None); infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2) } Some(infcx) => { From 480cd8fe678ddd34c7dc626791deaed2b49a0bda Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Thu, 25 Jun 2015 13:08:10 -0700 Subject: [PATCH 27/36] Ground work for replacing the ClosureTyper trait --- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/mod.rs | 154 +++++++++++++++++++- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/traits/select.rs | 2 + src/librustc/middle/ty.rs | 3 +- src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/monomorphize.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 +- src/librustc_typeck/check/dropck.rs | 4 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 4 +- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- 15 files changed, 170 insertions(+), 21 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index b156a2c087b02..8bbb6ae757fc1 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -283,7 +283,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn check_static_type(&self, e: &ast::Expr) { let ty = self.tcx.node_id_to_type(e.id); - let infcx = infer::new_infer_ctxt(self.tcx, None); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None); let mut fulfill_cx = traits::FulfillmentContext::new(false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 8f19a6e9e152b..a6b7d7f832a3c 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1031,7 +1031,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, substs: trait_substs }); tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 8e53747e89973..7727f6a647007 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -23,19 +23,24 @@ pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; use middle::free_region::FreeRegionMap; +use middle::mem_categorization as mc; +use middle::mem_categorization::McResult; +use middle::region::{self, CodeExtent}; use middle::subst; use middle::subst::Substs; +use middle::subst::Subst; +use middle::traits; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; use middle::ty_relate::{Relate, RelateResult, TypeRelation}; use rustc_data_structures::unify::{self, UnificationTable}; -use std::cell::{RefCell}; +use std::cell::{RefCell, Ref}; use std::fmt; use syntax::ast; use syntax::codemap; use syntax::codemap::Span; -use util::nodemap::FnvHashMap; +use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; use self::combine::CombineFields; use self::region_inference::{RegionVarBindings, RegionSnapshot}; @@ -64,6 +69,8 @@ pub type fres = Result; // "fixup result" pub struct InferCtxt<'a, 'tcx: 'a> { pub tcx: &'a ty::ctxt<'tcx>, + pub tables: &'a RefCell>, + // We instantiate UnificationTable with bounds because the // types that might instantiate a general type variable have an // order, represented by its upper and lower bounds. @@ -80,7 +87,9 @@ pub struct InferCtxt<'a, 'tcx: 'a> { pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, - // pub tables: &'a RefCell> + normalize: bool, + + err_count_on_creation: usize, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -314,15 +323,19 @@ pub fn fixup_err_to_string(f: fixup_err) -> String { } pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, + tables: &'a RefCell>, param_env: Option>) -> InferCtxt<'a, 'tcx> { InferCtxt { tcx: tcx, + tables: tables, type_variables: RefCell::new(type_variable::TypeVariableTable::new()), int_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(UnificationTable::new()), region_vars: RegionVarBindings::new(tcx), - parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()) + parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()), + normalize: true, + err_count_on_creation: tcx.sess.err_count() } } @@ -437,6 +450,92 @@ pub struct CombinedSnapshot { region_vars_snapshot: RegionSnapshot, } +impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { + fn node_ty(&self, id: ast::NodeId) -> McResult> { + let ty = self.node_ty(id); + self.resolve_type_vars_or_error(&ty) + } + + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { + let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id)); + self.resolve_type_vars_or_error(&ty) + } + + fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { + let ty = self.resolve_type_vars_if_possible(&ty); + !traits::type_known_to_meet_builtin_bound(self, self, ty, ty::BoundCopy, span) + } + + fn node_method_ty(&self, method_call: ty::MethodCall) + -> Option> { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.ty) + .map(|ty| self.resolve_type_vars_if_possible(&ty)) + } + + fn node_method_origin(&self, method_call: ty::MethodCall) + -> Option> + { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.origin.clone()) + } + + fn adjustments(&self) -> Ref>> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tables.borrow(), project_adjustments) + } + + fn is_method_call(&self, id: ast::NodeId) -> bool { + self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) + } + + fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { + self.parameter_environment.temporary_scope(rvalue_id) + } + + fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { + self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() + } +} + +impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { + fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.parameter_environment + } + + fn closure_kind(&self, + def_id: ast::DefId) + -> Option + { + self.tables.borrow().closure_kinds.get(&def_id).cloned() + } + + fn closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx, substs) + } + + fn closure_upvars(&self, + def_id: ast::DefId, + substs: &Substs<'tcx>) + -> Option>> + { + ty::ctxt::closure_upvars(self, def_id, substs) + } +} + impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn freshen>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) @@ -858,6 +957,48 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.region_vars.new_bound(debruijn) } + /// Apply `adjustment` to the type of `expr` + pub fn adjust_expr_ty(&self, + expr: &ast::Expr, + adjustment: Option<&ty::AutoAdjustment<'tcx>>) + -> Ty<'tcx> + { + let raw_ty = self.expr_ty(expr); + let raw_ty = self.shallow_resolve(raw_ty); + let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty); + raw_ty.adjust(self.tcx, + expr.span, + expr.id, + adjustment, + |method_call| self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| resolve_ty(method.ty))) + } + + pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { + match self.tables.borrow().node_types.get(&id) { + Some(&t) => t, + // FIXME + None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 => self.tcx.types.err, + None => { + self.tcx.sess.bug( + &format!("no type for node {}: {} in fcx", + id, self.tcx.map.node_to_string(id))); + } + } + } + + pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> { + match self.tables.borrow().node_types.get(&ex.id) { + Some(&t) => t, + None => { + self.tcx.sess.bug(&format!("no type for expr in fcx")); + } + } + } + pub fn resolve_regions_and_report_errors(&self, free_regions: &FreeRegionMap, subject_node_id: ast::NodeId) { @@ -932,6 +1073,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { value.fold_with(&mut r) } + fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult> { + let ty = self.resolve_type_vars_if_possible(t); + if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } + } + pub fn fully_resolve>(&self, value: &T) -> fres { /*! * Attempts to resolve all type/region variables in diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index eb839eade143f..69b9762b7b982 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -397,7 +397,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi let elaborated_env = unnormalized_env.with_caller_bounds(predicates); - let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env)); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env)); let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 01faa6b7cf7b9..ae15c8aa8e028 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -54,6 +54,7 @@ use util::nodemap::FnvHashMap; pub struct SelectionContext<'cx, 'tcx:'cx> { infcx: &'cx InferCtxt<'cx, 'tcx>, + closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx), /// Freshener used specifically for skolemizing entries on the @@ -77,6 +78,7 @@ pub struct SelectionContext<'cx, 'tcx:'cx> { /// other words, we consider `$0 : Bar` to be unimplemented if /// there is no type that the user could *actually name* that /// would satisfy it. This avoids crippling inference, basically. + intercrate: bool, } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index cdf7f6ef9b6b6..7616879d10257 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4468,7 +4468,8 @@ impl<'tcx> TyS<'tcx> { span: Span) -> bool { - let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone())); + let tcx = param_env.tcx(); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone())); let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, self, bound, span); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index dc8c92429615d..c549d8cd22d64 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -997,7 +997,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, trait_ref, trait_ref.def_id()); tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -1059,7 +1059,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, predicates); let tcx = ccx.tcx(); - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let mut fulfill_cx = traits::FulfillmentContext::new(false); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index fa992511cc19b..67ccf64621a85 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -324,7 +324,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T // FIXME(#20304) -- cache // NOTE: @jroesch // Here is of an example where we do not use a param_env but use a typer instead. - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let cause = traits::ObligationCause::dummy(); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index dc8ef46a7ba64..85f4fdc893201 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}", impl_trait_ref); - let mut infcx = infer::new_infer_ctxt(tcx, None); + let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); let mut fulfillment_cx = traits::FulfillmentContext::new(true); let trait_to_impl_substs = &impl_trait_ref.substs; @@ -418,7 +418,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); let mut fulfillment_cx = traits::FulfillmentContext::new(true); // The below is for the most part highly similar to the procedure diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 4abfd84d8ef3c..6f0fbfebf46cc 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -93,8 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( ty: named_type } = tcx.lookup_item_type(self_type_did); - let infcx = infer::new_infer_ctxt(tcx, None); - + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); + infcx.commit_if_ok(|snapshot| { let (named_type_to_skolem, skol_map) = infcx.construct_skolemized_subst(named_type_generics, snapshot); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 058cbe020b7d6..e91be5fa9df51 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -382,7 +382,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { -> Inherited<'a, 'tcx> { Inherited { - infcx: infer::new_infer_ctxt(tcx, Some(param_env)), + infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)), locals: RefCell::new(NodeMap()), tables: tables, fn_sig_map: RefCell::new(NodeMap()), diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 5441f0b677200..af2c3a32150d8 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)", source, target); - let infcx = new_infer_ctxt(tcx, Some(param_env)); + let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env)); let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>, mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| { @@ -630,7 +630,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, - inference_context: new_infer_ctxt(crate_context.tcx, None), + inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); unsafety::check(crate_context.tcx); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index a851bb93e3fc7..3495714fcc736 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { impl1_def_id, impl2_def_id); - let infcx = infer::new_infer_ctxt(self.tcx, None); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None); if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) { self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3e2a88e1f79c1..ef9dcd56a578b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( base_type, base_type_free); - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); drop(::require_same_types(tcx, Some(&infcx), false, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5d589d2ec78c9..48a64675c708a 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -188,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>, { let result = match maybe_infcx { None => { - let infcx = infer::new_infer_ctxt(tcx, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2) } Some(infcx) => { From e5b3684872d42e531ce3f51edc914b3917658905 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Thu, 25 Jun 2015 17:11:02 -0700 Subject: [PATCH 28/36] Remove ClosureTyper impl for FnCtxt --- src/librustc/middle/infer/mod.rs | 36 +++++++++-- src/librustc_typeck/check/callee.rs | 6 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 6 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 69 ++------------------- src/librustc_typeck/check/regionck.rs | 27 ++++---- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/wf.rs | 2 +- 10 files changed, 62 insertions(+), 92 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 7727f6a647007..c21ec9fbbb3bf 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -25,7 +25,7 @@ pub use self::region_inference::GenericKind; use middle::free_region::FreeRegionMap; use middle::mem_categorization as mc; use middle::mem_categorization::McResult; -use middle::region::{self, CodeExtent}; +use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; @@ -40,7 +40,7 @@ use std::fmt; use syntax::ast; use syntax::codemap; use syntax::codemap::Span; -use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; +use util::nodemap::{FnvHashMap, NodeMap}; use self::combine::CombineFields; use self::region_inference::{RegionVarBindings, RegionSnapshot}; @@ -524,7 +524,21 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx, substs) + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + let closure_ty = self.tables + .borrow() + .closure_tys + .get(&def_id) + .unwrap() + .subst(self.tcx, substs); + + if self.normalize { + // NOTE: this flag is *always* set to false currently + panic!("issue XXXX: must finish fulfill refactor") // normalize_associated_type(self.param_env.tcx, &closure_ty) + } else { + closure_ty + } } fn closure_upvars(&self, @@ -532,7 +546,16 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { substs: &Substs<'tcx>) -> Option>> { - ty::ctxt::closure_upvars(self, def_id, substs) + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + let result = ty::ctxt::closure_upvars(self, def_id, substs) + + if self.normalize { + // NOTE: this flag is *always* set to false currently + panic!("issue XXXX: must finish fulfill refactor") // monomorphize::normalize_associated_type(self.param_env.tcx, &result) + } else { + result + } } } @@ -1073,6 +1096,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { value.fold_with(&mut r) } + /// Resolves all type variables in `t` and then, if any were left + /// unresolved, substitutes an error type. This is used after the + /// main checking when doing a second pass before writeback. The + /// justification is that writeback will produce an error for + /// these unconstrained type variables. fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult> { let ty = self.resolve_type_vars_if_possible(t); if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index c2170686faccb..d29c0494572cb 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -137,9 +137,9 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // Check whether this is a call to a closure where we // haven't yet decided on whether the closure is fn vs // fnmut vs fnonce. If so, we have to defer further processing. - if fcx.closure_kind(def_id).is_none() { + if fcx.infcx().closure_kind(def_id).is_none() { let closure_ty = - fcx.closure_type(def_id, substs); + fcx.infcx().closure_type(def_id, substs); let fn_sig = fcx.infcx().replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, @@ -344,7 +344,7 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { // we should not be invoked until the closure kind has been // determined by upvar inference - assert!(fcx.closure_kind(self.closure_def_id).is_some()); + assert!(fcx.infcx().closure_kind(self.closure_def_id).is_some()); // We may now know enough to figure out fn vs fnmut etc. match try_overloaded_call_traits(fcx, self.call_expr, self.callee_expr, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 73b9a16d1ebea..b38b6884a98ad 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -273,7 +273,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }; let source = source.adjust_for_autoref(self.tcx(), reborrow); - let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); // Use a FIFO queue for this custom fulfillment procedure. let mut queue = VecDeque::new(); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 0f8048f27a0e3..f312db9c4dcf2 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -195,7 +195,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, poly_trait_ref.to_predicate()); // Now we want to know if this can be matched - let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx); + let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); if !selcx.evaluate_obligation(&obligation) { debug!("--> Cannot match obligation"); return None; // Cannot be matched, no such method resolution is possible. diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 2cf041919147c..94a2050829dfa 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -421,7 +421,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // We can't use normalize_associated_types_in as it will pollute the // fcx's fulfillment context after this probe is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}", @@ -681,7 +681,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // as it will pollute the fcx's fulfillment context after this probe // is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); @@ -1076,7 +1076,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { match probe.kind { InherentImplCandidate(impl_def_id, ref substs, ref ref_obligations) | ExtensionImplCandidate(impl_def_id, _, ref substs, _, ref ref_obligations) => { - let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx); + let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx.infcx()); let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); // Check whether the impl imposes obligations we have to worry about. diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b193ddcb21349..b81b672e684a5 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -102,7 +102,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let obligation = Obligation::misc(span, fcx.body_id, poly_trait_ref.to_predicate()); - let mut selcx = SelectionContext::new(infcx, fcx); + let mut selcx = SelectionContext::new(infcx, fcx.infcx()); if selcx.evaluate_obligation(&obligation) { span_stored_function(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e91be5fa9df51..2dc0b7d326181 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -316,65 +316,6 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty)) } - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option> - { - self.inh.tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.origin.clone()) - } - - fn adjustments(&self) -> Ref>> { - fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { - &tables.adjustments - } - - Ref::map(self.inh.tables.borrow(), project_adjustments) - } - - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.inh.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.param_env().temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.inh.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() - } -} - -impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - &self.inh.infcx.parameter_environment - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - self.inh.tables.borrow().closure_kinds.get(&def_id).cloned() - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.inh.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx(), substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> { - ty::ctxt::closure_upvars(self, def_id, substs) - } -} - impl<'a, 'tcx> Inherited<'a, 'tcx> { fn new(tcx: &'a ty::ctxt<'tcx>, tables: &'a RefCell>, @@ -1473,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn normalize_associated_types_in(&self, span: Span, value: &T) -> T where T : TypeFoldable<'tcx> + HasTypeFlags { - self.inh.normalize_associated_types_in(self, span, self.body_id, value) + self.inh.normalize_associated_types_in(self.infcx(), span, self.body_id, value) } fn normalize_associated_type(&self, @@ -1488,7 +1429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), - self, + self.infcx(), ty::ProjectionTy { trait_ref: trait_ref, item_name: item_name, @@ -1843,7 +1784,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.select_all_obligations_and_apply_defaults(); let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut(); - match fulfillment_cx.select_all_or_error(self.infcx(), self) { + match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } } @@ -1854,7 +1795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.fulfillment_cx .borrow_mut() - .select_where_possible(self.infcx(), self) + .select_where_possible(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -1869,7 +1810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.fulfillment_cx .borrow_mut() - .select_new_obligations(self.infcx(), self) + .select_new_obligations(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 8f8ec0f7264aa..796f6d646939f 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -86,6 +86,7 @@ use astconv::AstConv; use check::dropck; use check::FnCtxt; use middle::free_region::FreeRegionMap; +use middle::infer::InferCtxt; use middle::implicator; use middle::mem_categorization as mc; use middle::region::CodeExtent; @@ -353,7 +354,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { debug!("relate_free_regions(t={:?})", ty); let body_scope = CodeExtent::from_node_id(body_id); let body_scope = ty::ReScope(body_scope); - let implications = implicator::implications(self.fcx.infcx(), self.fcx, body_id, + let implications = implicator::implications(self.fcx.infcx(), self.fcx.infcx(), body_id, ty, body_scope, span); // Record any relations between free regions that we observe into the free-region-map. @@ -549,7 +550,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { // If necessary, constrain destructors in the unadjusted form of this // expression. let cmt_result = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); mc.cat_expr_unadjusted(expr) }; match cmt_result { @@ -568,7 +569,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { // If necessary, constrain destructors in this expression. This will be // the adjusted form if there is an adjustment. let cmt_result = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); mc.cat_expr(expr) }; match cmt_result { @@ -912,7 +913,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, r, m); { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i)); debug!("constrain_autoderefs: self_cmt={:?}", self_cmt); @@ -1037,7 +1038,7 @@ fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr, debug!("link_addr_of(expr={:?}, base={:?})", expr, base); let cmt = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); ignore_err!(mc.cat_expr(base)) }; @@ -1055,7 +1056,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) { None => { return; } Some(ref expr) => &**expr, }; - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); link_pattern(rcx, mc, discr_cmt, &*local.pat); } @@ -1065,7 +1066,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) { /// linked to the lifetime of its guarantor (if any). fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { debug!("regionck::for_match()"); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let discr_cmt = ignore_err!(mc.cat_expr(discr)); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { @@ -1080,7 +1081,7 @@ fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { /// linked to the lifetime of its guarantor (if any). fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); for arg in args { let arg_ty = rcx.fcx.node_ty(arg.id); let re_scope = ty::ReScope(body_scope); @@ -1095,7 +1096,7 @@ fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) { /// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if /// needed. fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, - mc: mc::MemCategorizationContext>, + mc: mc::MemCategorizationContext>, discr_cmt: mc::cmt<'tcx>, root_pat: &ast::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", @@ -1134,7 +1135,7 @@ fn link_autoref(rcx: &Rcx, autoref: &ty::AutoRef) { debug!("link_autoref(autoref={:?})", autoref); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs)); debug!("expr_cmt={:?}", expr_cmt); @@ -1158,7 +1159,7 @@ fn link_by_ref(rcx: &Rcx, callee_scope: CodeExtent) { debug!("link_by_ref(expr={:?}, callee_scope={:?})", expr, callee_scope); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let expr_cmt = ignore_err!(mc.cat_expr(expr)); let borrow_region = ty::ReScope(callee_scope); link_region(rcx, expr.span, &borrow_region, ty::ImmBorrow, expr_cmt); @@ -1402,7 +1403,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, ty, region); - let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx, rcx.body_id, + let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx.infcx(), rcx.body_id, ty, region, origin.span()); for implication in implications { debug!("implication: {:?}", implication); @@ -1443,7 +1444,7 @@ fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, debug!("closure_must_outlive(region={:?}, def_id={:?}, substs={:?})", region, def_id, substs); - let upvars = rcx.fcx.closure_upvars(def_id, substs).unwrap(); + let upvars = rcx.fcx.infcx().closure_upvars(def_id, substs).unwrap(); for upvar in upvars { let var_id = upvar.def.def_id().local_id(); type_must_outlive( diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index db32b29ebab81..19a0345e8088f 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -186,7 +186,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { debug!("analyzing closure `{}` with fn body id `{}`", id, body.id); - let mut euv = euv::ExprUseVisitor::new(self, self.fcx); + let mut euv = euv::ExprUseVisitor::new(self, self.fcx.infcx()); euv.walk_fn(decl, body); // If we had not yet settled on a closure kind for this closure, diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index c2852e425b6f9..18e05cd73fb7d 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -259,7 +259,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id()); let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); let predicates = { - let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx); + let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); traits::normalize(selcx, cause.clone(), &predicates) }; for predicate in predicates.value.predicates { From ba7b47eb55028c405c2852a4378a31c74fb96902 Mon Sep 17 00:00:00 2001 From: Richo Healey Date: Fri, 26 Jun 2015 10:32:27 -0700 Subject: [PATCH 29/36] rustc_driver: Fix incorrect comment --- src/librustc_driver/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 96d1ab23ad523..a9787987611f7 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -481,8 +481,7 @@ pub fn commit_date_str() -> Option<&'static str> { option_env!("CFG_VER_DATE") } -/// Prints version information and returns None on success or an error -/// message on panic. +/// Prints version information pub fn version(binary: &str, matches: &getopts::Matches) { let verbose = matches.opt_present("verbose"); From 9e58fb85efabadf40ecde8417ad74f7f8898991a Mon Sep 17 00:00:00 2001 From: Richo Healey Date: Fri, 26 Jun 2015 10:52:53 -0700 Subject: [PATCH 30/36] rt: Update comment for new location of unwind --- src/rt/rust_try.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rt/rust_try.ll b/src/rt/rust_try.ll index 226dc55cb8d5a..845fc097cdc78 100644 --- a/src/rt/rust_try.ll +++ b/src/rt/rust_try.ll @@ -12,7 +12,7 @@ ; When f(...) returns normally, the return value is null. ; When f(...) throws, the return value is a pointer to the caught exception object. -; See also: libstd/rt/unwind.rs +; See also: libstd/rt/unwind/mod.rs define i8* @rust_try(void (i8*)* %f, i8* %env) { From 10b103af48368c5df644fa61dc417a36083922c8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 26 Jun 2015 09:30:35 -0700 Subject: [PATCH 31/36] std: Fix Windows XP compatibility This commit enables executables linked against the standard library to run on Windows XP. There are two main components of this commit: * APIs not available on XP are shimmed to have a fallback implementation and use runtime detection to determine if they are available. * Mutexes on Windows were reimplemented to use critical sections on XP where rwlocks are not available. The APIs which are not available on XP are: * SetFileInformationByHandle - this is just used by `File::truncate` and that function just returns an error now. * SetThreadStackGuarantee - this is used by the stack overflow support on windows, but if this isn't available then it's just ignored (it seems non-critical). * All condition variable APIs are missing - the shims added for these apis simply always panic for now. We may eventually provide a fallback implementation, but for now the standard library does not rely on condition variables for normal use. * RWLocks, like condition variables, are missing entirely. The same story for condition variables is taken here. These APIs are all now panicking stubs as the standard library doesn't rely on RWLocks for normal use. Currently, as an optimization, we use SRWLOCKs for the standard `sync::Mutex` implementation on Windows, which is indeed required for normal operation of the standard library. To allow the standard library to run on XP, this commit reimplements mutexes on Windows to use SRWLOCK instances *if available* and otherwise a CriticalSection is used (with some checking for recursive locking). With all these changes put together, a 32-bit MSVC-built executable can run on Windows XP and print "hello world" Closes #12842 Closes #19992 Closes #24776 --- src/libstd/dynamic_lib.rs | 2 +- src/libstd/sys/windows/c.rs | 211 +++++++++++------------ src/libstd/sys/windows/compat.rs | 88 ++++++++++ src/libstd/sys/windows/condvar.rs | 28 +-- src/libstd/sys/windows/fs.rs | 8 +- src/libstd/sys/windows/mod.rs | 3 +- src/libstd/sys/windows/mutex.rs | 159 +++++++++++++---- src/libstd/sys/windows/rwlock.rs | 18 +- src/libstd/sys/windows/stack_overflow.rs | 19 +- src/libstd/sys/windows/sync.rs | 60 ------- 10 files changed, 353 insertions(+), 243 deletions(-) create mode 100644 src/libstd/sys/windows/compat.rs delete mode 100644 src/libstd/sys/windows/sync.rs diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index ddafe416305e1..a17d121e60a2a 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -263,7 +263,7 @@ mod dl { use sys::os; use os::windows::prelude::*; use ptr; - use sys::c::compat::kernel32::SetThreadErrorMode; + use sys::c::SetThreadErrorMode; pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { // disable "dll load failed" error dialog. diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 3c9b2ef1b986e..7f89ea979391e 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -13,6 +13,9 @@ #![allow(bad_style, dead_code, overflowing_literals)] use libc; +use libc::{c_uint, c_ulong}; +use libc::{DWORD, BOOL, BOOLEAN, ERROR_CALL_NOT_IMPLEMENTED, LPVOID, HANDLE}; +use libc::{LPCWSTR, LONG}; pub use self::GET_FILEEX_INFO_LEVELS::*; pub use self::FILE_INFO_BY_HANDLE_CLASS::*; @@ -240,7 +243,32 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER { pub PathBuffer: libc::WCHAR, } +pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE; +pub type PSRWLOCK = *mut SRWLOCK; +pub type ULONG = c_ulong; +pub type ULONG_PTR = c_ulong; + +#[repr(C)] +pub struct CONDITION_VARIABLE { pub ptr: LPVOID } +#[repr(C)] +pub struct SRWLOCK { pub ptr: LPVOID } +#[repr(C)] +pub struct CRITICAL_SECTION { + CriticalSectionDebug: LPVOID, + LockCount: LONG, + RecursionCount: LONG, + OwningThread: HANDLE, + LockSemaphore: HANDLE, + SpinCount: ULONG_PTR +} + +pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { + ptr: 0 as *mut _, +}; +pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ }; + #[link(name = "ws2_32")] +#[link(name = "userenv")] extern "system" { pub fn WSAStartup(wVersionRequested: libc::WORD, lpWSAData: LPWSADATA) -> libc::c_int; @@ -295,115 +323,13 @@ extern "system" { pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL; pub fn CancelIoEx(hFile: libc::HANDLE, lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL; -} - -pub mod compat { - use prelude::v1::*; - use ffi::CString; - use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID}; - use sync::atomic::{AtomicUsize, Ordering}; + pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION); + pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION); + pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN; + pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION); + pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION); - extern "system" { - fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; - fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID; - } - - fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str, - fallback: usize) -> usize { - let mut module: Vec = module.utf16_units().collect(); - module.push(0); - let symbol = CString::new(symbol).unwrap(); - let func = unsafe { - let handle = GetModuleHandleW(module.as_ptr()); - GetProcAddress(handle, symbol.as_ptr()) as usize - }; - let value = if func == 0 {fallback} else {func}; - ptr.store(value, Ordering::SeqCst); - value - } - - /// Macro for creating a compatibility fallback for a Windows function - /// - /// # Examples - /// ``` - /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) { - /// // Fallback implementation - /// }) - /// ``` - /// - /// Note that arguments unused by the fallback implementation should not be - /// called `_` as they are used to be passed to the real function if - /// available. - macro_rules! compat_fn { - ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*) - -> $rettype:ty { $fallback:expr }) => ( - #[inline(always)] - pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype { - use sync::atomic::{AtomicUsize, Ordering}; - use mem; - - static PTR: AtomicUsize = AtomicUsize::new(0); - - fn load() -> usize { - ::sys::c::compat::store_func(&PTR, - stringify!($module), - stringify!($symbol), - fallback as usize) - } - - extern "system" fn fallback($($argname: $argtype),*) - -> $rettype { $fallback } - - let addr = match PTR.load(Ordering::SeqCst) { - 0 => load(), - n => n, - }; - let f: extern "system" fn($($argtype),*) -> $rettype = - mem::transmute(addr); - f($($argname),*) - } - ) - } - - /// Compatibility layer for functions in `kernel32.dll` - /// - /// Latest versions of Windows this is needed for: - /// - /// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003 - /// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003 - pub mod kernel32 { - use libc::c_uint; - use libc::types::os::arch::extra::{DWORD, LPCWSTR, BOOLEAN, HANDLE}; - use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED; - use sys::c::SetLastError; - - compat_fn! { - kernel32::CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR, - _lpTargetFileName: LPCWSTR, - _dwFlags: DWORD) -> BOOLEAN { - unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } - } - } - - compat_fn! { - kernel32::GetFinalPathNameByHandleW(_hFile: HANDLE, - _lpszFilePath: LPCWSTR, - _cchFilePath: DWORD, - _dwFlags: DWORD) -> DWORD { - unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } - } - } - - compat_fn! { - kernel32::SetThreadErrorMode(_dwNewMode: DWORD, _lpOldMode: *mut DWORD) -> c_uint { - unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } - } - } - } -} - -extern "system" { // FIXME - pInputControl should be PCONSOLE_READCONSOLE_CONTROL pub fn ReadConsoleW(hConsoleInput: libc::HANDLE, lpBuffer: libc::LPVOID, @@ -447,10 +373,6 @@ extern "system" { lpCreationTime: *const libc::FILETIME, lpLastAccessTime: *const libc::FILETIME, lpLastWriteTime: *const libc::FILETIME) -> libc::BOOL; - pub fn SetFileInformationByHandle(hFile: libc::HANDLE, - FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, - lpFileInformation: libc::LPVOID, - dwBufferSize: libc::DWORD) -> libc::BOOL; pub fn GetTempPathW(nBufferLength: libc::DWORD, lpBuffer: libc::LPCWSTR) -> libc::DWORD; pub fn OpenProcessToken(ProcessHandle: libc::HANDLE, @@ -483,11 +405,70 @@ extern "system" { pub fn SwitchToThread() -> libc::BOOL; pub fn Sleep(dwMilliseconds: libc::DWORD); pub fn GetProcessId(handle: libc::HANDLE) -> libc::DWORD; -} - -#[link(name = "userenv")] -extern "system" { pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE, lpProfileDir: libc::LPCWSTR, lpcchSize: *mut libc::DWORD) -> libc::BOOL; } + +// Functions that aren't available on Windows XP, but we still use them and just +// provide some form of a fallback implementation. +compat_fn! { + kernel32: + + pub fn CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR, + _lpTargetFileName: LPCWSTR, + _dwFlags: DWORD) -> BOOLEAN { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + pub fn GetFinalPathNameByHandleW(_hFile: HANDLE, + _lpszFilePath: LPCWSTR, + _cchFilePath: DWORD, + _dwFlags: DWORD) -> DWORD { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + pub fn SetThreadErrorMode(_dwNewMode: DWORD, + _lpOldMode: *mut DWORD) -> c_uint { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + pub fn SetFileInformationByHandle(_hFile: HANDLE, + _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, + _lpFileInformation: LPVOID, + _dwBufferSize: DWORD) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE, + SRWLock: PSRWLOCK, + dwMilliseconds: DWORD, + Flags: ULONG) -> BOOL { + panic!("condition variables not available") + } + pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE) + -> () { + panic!("condition variables not available") + } + pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE) + -> () { + panic!("condition variables not available") + } + pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> () { + panic!("rwlocks not available") + } + pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK) -> () { + panic!("rwlocks not available") + } + pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK) -> () { + panic!("rwlocks not available") + } + pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK) -> () { + panic!("rwlocks not available") + } + pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN { + panic!("rwlocks not available") + } + pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN { + panic!("rwlocks not available") + } +} diff --git a/src/libstd/sys/windows/compat.rs b/src/libstd/sys/windows/compat.rs new file mode 100644 index 0000000000000..3a03b91f24ed3 --- /dev/null +++ b/src/libstd/sys/windows/compat.rs @@ -0,0 +1,88 @@ +// Copyright 2014 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. + +//! A "compatibility layer" for spanning XP and Windows 7 +//! +//! The standard library currently binds many functions that are not available +//! on Windows XP, but we would also like to support building executables that +//! run on XP. To do this we specify all non-XP APIs as having a fallback +//! implementation to do something reasonable. +//! +//! This dynamic runtime detection of whether a function is available is +//! implemented with `GetModuleHandle` and `GetProcAddress` paired with a +//! static-per-function which caches the result of the first check. In this +//! manner we pay a semi-large one-time cost up front for detecting whether a +//! function is available but afterwards it's just a load and a jump. + +use prelude::v1::*; + +use ffi::CString; +use libc::{LPVOID, LPCWSTR, HMODULE, LPCSTR}; +use sync::atomic::{AtomicUsize, Ordering}; + +extern "system" { + fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; + fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID; +} + +pub fn lookup(module: &str, symbol: &str) -> Option { + let mut module: Vec = module.utf16_units().collect(); + module.push(0); + let symbol = CString::new(symbol).unwrap(); + unsafe { + let handle = GetModuleHandleW(module.as_ptr()); + match GetProcAddress(handle, symbol.as_ptr()) as usize { + 0 => None, + n => Some(n), + } + } +} + +pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str, + fallback: usize) -> usize { + let value = lookup(module, symbol).unwrap_or(fallback); + ptr.store(value, Ordering::SeqCst); + value +} + +macro_rules! compat_fn { + ($module:ident: $( + pub fn $symbol:ident($($argname:ident: $argtype:ty),*) + -> $rettype:ty { + $($body:expr);* + } + )*) => ($( + #[allow(unused_variables)] + pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype { + use sync::atomic::{AtomicUsize, Ordering}; + use mem; + type F = unsafe extern "system" fn($($argtype),*) -> $rettype; + + static PTR: AtomicUsize = AtomicUsize::new(0); + + fn load() -> usize { + ::sys::compat::store_func(&PTR, + stringify!($module), + stringify!($symbol), + fallback as usize) + } + unsafe extern "system" fn fallback($($argname: $argtype),*) + -> $rettype { + $($body);* + } + + let addr = match PTR.load(Ordering::SeqCst) { + 0 => load(), + n => n, + }; + mem::transmute::(addr)($($argname),*) + } + )*) +} diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs index baa7d1ceea331..04d62200e9bcc 100644 --- a/src/libstd/sys/windows/condvar.rs +++ b/src/libstd/sys/windows/condvar.rs @@ -12,35 +12,35 @@ use prelude::v1::*; use cell::UnsafeCell; use libc::{self, DWORD}; -use sys::os; +use sys::c; use sys::mutex::{self, Mutex}; -use sys::sync as ffi; +use sys::os; use time::Duration; -pub struct Condvar { inner: UnsafeCell } +pub struct Condvar { inner: UnsafeCell } unsafe impl Send for Condvar {} unsafe impl Sync for Condvar {} impl Condvar { pub const fn new() -> Condvar { - Condvar { inner: UnsafeCell::new(ffi::CONDITION_VARIABLE_INIT) } + Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) } } #[inline] pub unsafe fn wait(&self, mutex: &Mutex) { - let r = ffi::SleepConditionVariableSRW(self.inner.get(), - mutex::raw(mutex), - libc::INFINITE, - 0); + let r = c::SleepConditionVariableSRW(self.inner.get(), + mutex::raw(mutex), + libc::INFINITE, + 0); debug_assert!(r != 0); } pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - let r = ffi::SleepConditionVariableSRW(self.inner.get(), - mutex::raw(mutex), - super::dur2timeout(dur), - 0); + let r = c::SleepConditionVariableSRW(self.inner.get(), + mutex::raw(mutex), + super::dur2timeout(dur), + 0); if r == 0 { const ERROR_TIMEOUT: DWORD = 0x5B4; debug_assert_eq!(os::errno() as usize, ERROR_TIMEOUT as usize); @@ -52,12 +52,12 @@ impl Condvar { #[inline] pub unsafe fn notify_one(&self) { - ffi::WakeConditionVariable(self.inner.get()) + c::WakeConditionVariable(self.inner.get()) } #[inline] pub unsafe fn notify_all(&self) { - ffi::WakeAllConditionVariable(self.inner.get()) + c::WakeAllConditionVariable(self.inner.get()) } pub unsafe fn destroy(&self) { diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 437b2cc649117..36fabe72aa0c1 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -497,12 +497,11 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> { } pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> { - use sys::c::compat::kernel32::CreateSymbolicLinkW; let src = to_utf16(src); let dst = to_utf16(dst); let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 }; try!(cvt(unsafe { - CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL + c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL })); Ok(()) } @@ -565,14 +564,13 @@ pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> { } pub fn canonicalize(p: &Path) -> io::Result { - use sys::c::compat::kernel32::GetFinalPathNameByHandleW; let mut opts = OpenOptions::new(); opts.read(true); let f = try!(File::open(p, &opts)); super::fill_utf16_buf(|buf, sz| unsafe { - GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, - libc::VOLUME_NAME_DOS) + c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, + libc::VOLUME_NAME_DOS) }, |buf| { PathBuf::from(OsString::from_wide(buf)) }) diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 18c8add17a6d6..b6d080109df05 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -22,6 +22,8 @@ use os::windows::ffi::{OsStrExt, OsStringExt}; use path::PathBuf; use time::Duration; +#[macro_use] pub mod compat; + pub mod backtrace; pub mod c; pub mod condvar; @@ -36,7 +38,6 @@ pub mod pipe; pub mod process; pub mod rwlock; pub mod stack_overflow; -pub mod sync; pub mod thread; pub mod thread_local; pub mod time; diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index 29e370698ad74..277c3d14c0ec5 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -8,57 +8,154 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! System Mutexes +//! +//! The Windows implementation of mutexes is a little odd and it may not be +//! immediately obvious what's going on. The primary oddness is that SRWLock is +//! used instead of CriticalSection, and this is done because: +//! +//! 1. SRWLock is several times faster than CriticalSection according to +//! benchmarks performed on both Windows 8 and Windows 7. +//! +//! 2. CriticalSection allows recursive locking while SRWLock deadlocks. The +//! Unix implementation deadlocks so consistency is preferred. See #19962 for +//! more details. +//! +//! 3. While CriticalSection is fair and SRWLock is not, the current Rust policy +//! is there there are no guarantees of fairness. +//! +//! The downside of this approach, however, is that SRWLock is not available on +//! Windows XP, so we continue to have a fallback implementation where +//! CriticalSection is used and we keep track of who's holding the mutex to +//! detect recursive locks. + use prelude::v1::*; use cell::UnsafeCell; -use sys::sync as ffi; use mem; +use sync::atomic::{AtomicUsize, Ordering}; +use sys::c; +use sys::compat; -pub struct Mutex { inner: UnsafeCell } +pub struct Mutex { + lock: AtomicUsize, + held: UnsafeCell, +} unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} -#[inline] -pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK { - m.inner.get() +#[derive(Clone, Copy)] +enum Kind { + SRWLock = 1, + CriticalSection = 2, } -// So you might be asking why we're using SRWLock instead of CriticalSection? -// -// 1. SRWLock is several times faster than CriticalSection according to -// benchmarks performed on both Windows 8 and Windows 7. -// -// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix -// implementation deadlocks so consistency is preferred. See #19962 for more -// details. -// -// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy -// is there there are no guarantees of fairness. +#[inline] +pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK { + debug_assert!(mem::size_of::() <= mem::size_of_val(&m.lock)); + &m.lock as *const _ as *mut _ +} impl Mutex { pub const fn new() -> Mutex { - Mutex { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) } + Mutex { + lock: AtomicUsize::new(0), + held: UnsafeCell::new(false), + } } - #[inline] pub unsafe fn lock(&self) { - ffi::AcquireSRWLockExclusive(self.inner.get()) + match kind() { + Kind::SRWLock => c::AcquireSRWLockExclusive(raw(self)), + Kind::CriticalSection => { + let re = self.remutex(); + (*re).lock(); + if !self.flag_locked() { + (*re).unlock(); + panic!("cannot recursively lock a mutex"); + } + } + } } - #[inline] pub unsafe fn try_lock(&self) -> bool { - ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0 + match kind() { + Kind::SRWLock => c::TryAcquireSRWLockExclusive(raw(self)) != 0, + Kind::CriticalSection => { + let re = self.remutex(); + if !(*re).try_lock() { + false + } else if self.flag_locked() { + true + } else { + (*re).unlock(); + false + } + } + } } - #[inline] pub unsafe fn unlock(&self) { - ffi::ReleaseSRWLockExclusive(self.inner.get()) + *self.held.get() = false; + match kind() { + Kind::SRWLock => c::ReleaseSRWLockExclusive(raw(self)), + Kind::CriticalSection => (*self.remutex()).unlock(), + } } - #[inline] pub unsafe fn destroy(&self) { - // ... + match kind() { + Kind::SRWLock => {} + Kind::CriticalSection => { + match self.lock.load(Ordering::SeqCst) { + 0 => {} + n => { Box::from_raw(n as *mut ReentrantMutex).destroy(); } + } + } + } + } + + unsafe fn remutex(&self) -> *mut ReentrantMutex { + match self.lock.load(Ordering::SeqCst) { + 0 => {} + n => return n as *mut _, + } + let mut re = Box::new(ReentrantMutex::uninitialized()); + re.init(); + let re = Box::into_raw(re); + match self.lock.compare_and_swap(0, re as usize, Ordering::SeqCst) { + 0 => re, + n => { Box::from_raw(re).destroy(); n as *mut _ } + } + } + + unsafe fn flag_locked(&self) -> bool { + if *self.held.get() { + false + } else { + *self.held.get() = true; + true + } + } } -pub struct ReentrantMutex { inner: UnsafeCell } +fn kind() -> Kind { + static KIND: AtomicUsize = AtomicUsize::new(0); + + let val = KIND.load(Ordering::SeqCst); + if val == Kind::SRWLock as usize { + return Kind::SRWLock + } else if val == Kind::CriticalSection as usize { + return Kind::CriticalSection + } + + let ret = match compat::lookup("kernel32", "AcquireSRWLockExclusive") { + None => Kind::CriticalSection, + Some(..) => Kind::SRWLock, + }; + KIND.store(ret as usize, Ordering::SeqCst); + return ret; +} + +pub struct ReentrantMutex { inner: UnsafeCell } unsafe impl Send for ReentrantMutex {} unsafe impl Sync for ReentrantMutex {} @@ -69,23 +166,23 @@ impl ReentrantMutex { } pub unsafe fn init(&mut self) { - ffi::InitializeCriticalSection(self.inner.get()); + c::InitializeCriticalSection(self.inner.get()); } pub unsafe fn lock(&self) { - ffi::EnterCriticalSection(self.inner.get()); + c::EnterCriticalSection(self.inner.get()); } #[inline] pub unsafe fn try_lock(&self) -> bool { - ffi::TryEnterCriticalSection(self.inner.get()) != 0 + c::TryEnterCriticalSection(self.inner.get()) != 0 } pub unsafe fn unlock(&self) { - ffi::LeaveCriticalSection(self.inner.get()); + c::LeaveCriticalSection(self.inner.get()); } pub unsafe fn destroy(&self) { - ffi::DeleteCriticalSection(self.inner.get()); + c::DeleteCriticalSection(self.inner.get()); } } diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs index e727638e3e9b5..25865286db051 100644 --- a/src/libstd/sys/windows/rwlock.rs +++ b/src/libstd/sys/windows/rwlock.rs @@ -11,40 +11,40 @@ use prelude::v1::*; use cell::UnsafeCell; -use sys::sync as ffi; +use sys::c; -pub struct RWLock { inner: UnsafeCell } +pub struct RWLock { inner: UnsafeCell } unsafe impl Send for RWLock {} unsafe impl Sync for RWLock {} impl RWLock { pub const fn new() -> RWLock { - RWLock { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) } + RWLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) } } #[inline] pub unsafe fn read(&self) { - ffi::AcquireSRWLockShared(self.inner.get()) + c::AcquireSRWLockShared(self.inner.get()) } #[inline] pub unsafe fn try_read(&self) -> bool { - ffi::TryAcquireSRWLockShared(self.inner.get()) != 0 + c::TryAcquireSRWLockShared(self.inner.get()) != 0 } #[inline] pub unsafe fn write(&self) { - ffi::AcquireSRWLockExclusive(self.inner.get()) + c::AcquireSRWLockExclusive(self.inner.get()) } #[inline] pub unsafe fn try_write(&self) -> bool { - ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0 + c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 } #[inline] pub unsafe fn read_unlock(&self) { - ffi::ReleaseSRWLockShared(self.inner.get()) + c::ReleaseSRWLockShared(self.inner.get()) } #[inline] pub unsafe fn write_unlock(&self) { - ffi::ReleaseSRWLockExclusive(self.inner.get()) + c::ReleaseSRWLockExclusive(self.inner.get()) } #[inline] diff --git a/src/libstd/sys/windows/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow.rs index 79b7de4f341ac..cf827848db5c9 100644 --- a/src/libstd/sys/windows/stack_overflow.rs +++ b/src/libstd/sys/windows/stack_overflow.rs @@ -8,12 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rt::util::report_overflow; use core::prelude::*; -use ptr; -use mem; + +use libc::types::os::arch::extra::{LPVOID, DWORD, LONG}; use libc; -use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL}; +use mem; +use ptr; +use rt::util::report_overflow; +use sys::c; use sys_common::stack; pub struct Handler { @@ -69,8 +71,12 @@ pub unsafe fn cleanup() { } pub unsafe fn make_handler() -> Handler { - if SetThreadStackGuarantee(&mut 0x5000) == 0 { - panic!("failed to reserve stack space for exception handling"); + // This API isn't available on XP, so don't panic in that case and just pray + // it works out ok. + if c::SetThreadStackGuarantee(&mut 0x5000) == 0 { + if libc::GetLastError() as u32 != libc::ERROR_CALL_NOT_IMPLEMENTED as u32 { + panic!("failed to reserve stack space for exception handling"); + } } Handler { _data: 0 as *mut libc::c_void } @@ -103,5 +109,4 @@ extern "system" { fn AddVectoredExceptionHandler(FirstHandler: ULONG, VectoredHandler: PVECTORED_EXCEPTION_HANDLER) -> LPVOID; - fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL; } diff --git a/src/libstd/sys/windows/sync.rs b/src/libstd/sys/windows/sync.rs deleted file mode 100644 index 5410259540eac..0000000000000 --- a/src/libstd/sys/windows/sync.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 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 libc::{BOOL, DWORD, LPVOID, LONG, HANDLE, c_ulong}; -use libc::types::os::arch::extra::BOOLEAN; - -pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE; -pub type PSRWLOCK = *mut SRWLOCK; -pub type ULONG = c_ulong; -pub type ULONG_PTR = c_ulong; - -#[repr(C)] -pub struct CONDITION_VARIABLE { pub ptr: LPVOID } -#[repr(C)] -pub struct SRWLOCK { pub ptr: LPVOID } -#[repr(C)] -pub struct CRITICAL_SECTION { - CriticalSectionDebug: LPVOID, - LockCount: LONG, - RecursionCount: LONG, - OwningThread: HANDLE, - LockSemaphore: HANDLE, - SpinCount: ULONG_PTR -} - -pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { - ptr: 0 as *mut _, -}; -pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ }; - -extern "system" { - // condition variables - pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE, - SRWLock: PSRWLOCK, - dwMilliseconds: DWORD, - Flags: ULONG) -> BOOL; - pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE); - pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE); - - // slim rwlocks - pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK); - pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK); - pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK); - pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK); - pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN; - pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN; - - pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION); - pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION); - pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN; - pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION); - pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION); -} From 15bc4a30c38e6a4e72bcd05214626933d45018c1 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 26 Jun 2015 12:23:41 -0700 Subject: [PATCH 32/36] Address nits --- src/librustc/middle/astencode.rs | 7 +- src/librustc/middle/infer/mod.rs | 42 +++++++---- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/ty.rs | 78 --------------------- src/librustc_driver/driver.rs | 2 +- src/librustc_trans/trans/common.rs | 5 +- src/librustc_typeck/check/compare_method.rs | 5 +- src/librustc_typeck/check/method/confirm.rs | 3 +- src/librustc_typeck/check/mod.rs | 48 ++----------- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/check/upvar.rs | 8 ++- src/librustc_typeck/check/wf.rs | 25 +++++-- src/librustc_typeck/check/writeback.rs | 6 +- src/librustc_typeck/coherence/mod.rs | 6 +- 14 files changed, 92 insertions(+), 151 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index f2ae396173bc0..d2c79e1d820bf 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1051,7 +1051,12 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, var_id: var_id, closure_expr_id: id }; - let upvar_capture = tcx.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone(); + let upvar_capture = tcx.tables + .borrow() + .upvar_capture_map + .get(&upvar_id) + .unwrap() + .clone(); var_id.encode(rbml_w); upvar_capture.encode(rbml_w); }) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index c21ec9fbbb3bf..c355e8b82a6ef 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -87,6 +87,11 @@ pub struct InferCtxt<'a, 'tcx: 'a> { pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, + // This is a temporary field used for toggling on normalization in the inference context, + // as we move towards the approach described here: + // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293 + // At a point sometime in the future normalization will be done by the typing context + // directly. normalize: bool, err_count_on_creation: usize, @@ -334,7 +339,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, float_unification_table: RefCell::new(UnificationTable::new()), region_vars: RegionVarBindings::new(tcx), parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()), - normalize: true, + normalize: false, err_count_on_creation: tcx.sess.err_count() } } @@ -487,7 +492,8 @@ impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { } fn adjustments(&self) -> Ref>> { - fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) + -> &'a NodeMap> { &tables.adjustments } @@ -524,8 +530,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types + let closure_ty = self.tables .borrow() .closure_tys @@ -534,8 +539,15 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { .subst(self.tcx, substs); if self.normalize { - // NOTE: this flag is *always* set to false currently - panic!("issue XXXX: must finish fulfill refactor") // normalize_associated_type(self.param_env.tcx, &closure_ty) + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // normalize_associated_type(self.param_env.tcx, &closure_ty) + panic!("see issue 26597: fufillment context refactor must occur") } else { closure_ty } @@ -546,13 +558,18 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { substs: &Substs<'tcx>) -> Option>> { - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - let result = ty::ctxt::closure_upvars(self, def_id, substs) + let result = ty::ctxt::closure_upvars(self, def_id, substs); if self.normalize { - // NOTE: this flag is *always* set to false currently - panic!("issue XXXX: must finish fulfill refactor") // monomorphize::normalize_associated_type(self.param_env.tcx, &result) + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // monomorphize::normalize_associated_type(self.param_env.tcx, &result) + panic!("see issue 26597: fufillment context refactor must occur") } else { result } @@ -1004,7 +1021,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match self.tables.borrow().node_types.get(&id) { Some(&t) => t, // FIXME - None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 => self.tcx.types.err, + None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 => + self.tcx.types.err, None => { self.tcx.sess.bug( &format!("no type for node {}: {} in fcx", diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 69b9762b7b982..9df6ed5d68126 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -351,7 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } -// TODO: this is gonna need to be removed ... +// FIXME: this is gonna need to be removed ... /// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>, cause: ObligationCause<'tcx>) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 7616879d10257..489ce7bc4cf78 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3222,84 +3222,6 @@ impl<'tcx> CommonTypes<'tcx> { } } -/// Create a type context and call the closure with a `&ty::ctxt` reference -/// to the context. The closure enforces that the type context and any interned -/// value (types, substs, etc.) can only be used while `ty::tls` has a valid -/// reference to the context, to allow formatting values that need it. -pub fn with_ctxt<'tcx, F, R>(s: Session, - arenas: &'tcx CtxtArenas<'tcx>, - def_map: DefMap, - named_region_map: resolve_lifetime::NamedRegionMap, - map: ast_map::Map<'tcx>, - freevars: RefCell, - region_maps: RegionMaps, - lang_items: middle::lang_items::LanguageItems, - stability: stability::Index<'tcx>, - f: F) -> (Session, R) - where F: FnOnce(&ctxt<'tcx>) -> R -{ - let mut interner = FnvHashMap(); - let common_types = CommonTypes::new(&arenas.type_, &mut interner); - - tls::enter(ctxt { - arenas: arenas, - interner: RefCell::new(interner), - substs_interner: RefCell::new(FnvHashMap()), - bare_fn_interner: RefCell::new(FnvHashMap()), - region_interner: RefCell::new(FnvHashMap()), - stability_interner: RefCell::new(FnvHashMap()), - types: common_types, - named_region_map: named_region_map, - region_maps: region_maps, - free_region_maps: RefCell::new(FnvHashMap()), - item_variance_map: RefCell::new(DefIdMap()), - variance_computed: Cell::new(false), - sess: s, - def_map: def_map, - tables: RefCell::new(Tables::empty()), - impl_trait_refs: RefCell::new(DefIdMap()), - trait_defs: RefCell::new(DefIdMap()), - predicates: RefCell::new(DefIdMap()), - super_predicates: RefCell::new(DefIdMap()), - fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()), - map: map, - freevars: freevars, - tcache: RefCell::new(DefIdMap()), - rcache: RefCell::new(FnvHashMap()), - tc_cache: RefCell::new(FnvHashMap()), - ast_ty_to_ty_cache: RefCell::new(NodeMap()), - enum_var_cache: RefCell::new(DefIdMap()), - impl_or_trait_items: RefCell::new(DefIdMap()), - trait_item_def_ids: RefCell::new(DefIdMap()), - trait_items_cache: RefCell::new(DefIdMap()), - ty_param_defs: RefCell::new(NodeMap()), - normalized_cache: RefCell::new(FnvHashMap()), - lang_items: lang_items, - provided_method_sources: RefCell::new(DefIdMap()), - struct_fields: RefCell::new(DefIdMap()), - destructor_for_type: RefCell::new(DefIdMap()), - destructors: RefCell::new(DefIdSet()), - inherent_impls: RefCell::new(DefIdMap()), - impl_items: RefCell::new(DefIdMap()), - used_unsafe: RefCell::new(NodeSet()), - used_mut_nodes: RefCell::new(NodeSet()), - populated_external_types: RefCell::new(DefIdSet()), - populated_external_primitive_impls: RefCell::new(DefIdSet()), - extern_const_statics: RefCell::new(DefIdMap()), - extern_const_variants: RefCell::new(DefIdMap()), - extern_const_fns: RefCell::new(DefIdMap()), - dependency_formats: RefCell::new(FnvHashMap()), - node_lint_levels: RefCell::new(FnvHashMap()), - transmute_restrictions: RefCell::new(Vec::new()), - stability: RefCell::new(stability), - selection_cache: traits::SelectionCache::new(), - repr_hint_cache: RefCell::new(DefIdMap()), - const_qualif_map: RefCell::new(NodeMap()), - custom_coerce_unsized_kinds: RefCell::new(DefIdMap()), - cast_kinds: RefCell::new(NodeMap()), - }, f) -} - struct FlagComputation { flags: TypeFlags, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ad3f53c328d9..80c4fc28703ac 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -602,7 +602,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session, make_glob_map: resolve::MakeGlobMap, f: F) -> (Session, R) - where F: FnOnce(&ty::ctxt<'tcx>, + where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>, ty::CrateAnalysis) -> R { let time_passes = sess.time_passes(); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index c549d8cd22d64..483d82f508f25 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -649,7 +649,10 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn adjustments<'a>(&'a self) -> Ref>> { - fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + // FIXME (@jroesch): this is becuase we currently have a HR inference problem + // in the snapshot that causes this code not to work. + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> + &'a NodeMap> { &tables.adjustments } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 85f4fdc893201..f62411e85828d 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -240,7 +240,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.into_vec()); let trait_param_env = traits::normalize_param_env_or_error(trait_param_env, normalize_cause.clone()); - // TODO (@jroesch) this seems ugly, but is a temporary change + // FIXME(@jroesch) this seems ugly, but is a temporary change infcx.parameter_environment = trait_param_env; debug!("compare_impl_method: trait_bounds={:?}", @@ -362,7 +362,8 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // anyway, so it shouldn't be needed there either. Anyway, we can // always add more relations later (it's backwards compat). let mut free_regions = FreeRegionMap::new(); - free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds); + free_regions.relate_free_regions_from_predicates(tcx, + &infcx.parameter_environment.caller_bounds); infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 5601888a1f073..9c2d1c4a34df1 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -528,7 +528,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // expects. This is annoying and horrible. We // ought to recode this routine so it doesn't // (ab)use the normal type checking paths. - let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id).cloned(); + let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id) + .cloned(); let (autoderefs, unsize) = match adj { Some(ty::AdjustDerefRef(adr)) => match adr.autoref { None => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2dc0b7d326181..7e87dc6540ea5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -87,8 +87,6 @@ use fmt_macros::{Parser, Piece, Position}; use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS}; use middle::def; use middle::infer; -use middle::mem_categorization as mc; -use middle::mem_categorization::McResult; use middle::pat_util::{self, pat_id_map}; use middle::privacy::{AllPublic, LastMod}; use middle::region::{self, CodeExtent}; @@ -290,32 +288,6 @@ pub struct FnCtxt<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx>, } -impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { - fn node_ty(&self, id: ast::NodeId) -> McResult> { - let ty = self.node_ty(id); - self.resolve_type_vars_or_error(&ty) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { - let ty = self.adjust_expr_ty(expr, self.inh.tables.borrow().adjustments.get(&expr.id)); - self.resolve_type_vars_or_error(&ty) - } - - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - let ty = self.infcx().resolve_type_vars_if_possible(&ty); - !traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) - -> Option> { - self.inh.tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.ty) - .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty)) - } - impl<'a, 'tcx> Inherited<'a, 'tcx> { fn new(tcx: &'a ty::ctxt<'tcx>, tables: &'a RefCell>, @@ -368,7 +340,8 @@ pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, } } -fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, tables: &'a RefCell>) +fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, + tables: &'a RefCell>) -> Inherited<'a, 'tcx> { // It's kind of a kludge to manufacture a fake function context // and statement context, but we might as well do write the code only once @@ -1271,16 +1244,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } - /// Resolves all type variables in `t` and then, if any were left - /// unresolved, substitutes an error type. This is used after the - /// main checking when doing a second pass before writeback. The - /// justification is that writeback will produce an error for - /// these unconstrained type variables. - fn resolve_type_vars_or_error(&self, ty: &Ty<'tcx>) -> mc::McResult> { - let ty = self.infcx().resolve_type_vars_if_possible(ty); - if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } - } - fn record_deferred_call_resolution(&self, closure_def_id: ast::DefId, r: DeferredCallResolutionHandler<'tcx>) { @@ -1614,9 +1577,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn item_substs(&self) -> Ref>> { - // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if it changes - // when we upgrade the snapshot compiler - fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap> { + // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if + // it changes when we upgrade the snapshot compiler + fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) + -> &'a NodeMap> { &tables.item_substs } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 796f6d646939f..a86301907385a 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -125,7 +125,8 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) { pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) { let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id)); let tcx = fcx.tcx(); - rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds); + rcx.free_region_map + .relate_free_regions_from_predicates(tcx, &fcx.infcx().parameter_environment.caller_bounds); rcx.visit_region_obligations(item.id); rcx.resolve_regions_and_report_errors(); } @@ -144,7 +145,8 @@ pub fn regionck_fn(fcx: &FnCtxt, } let tcx = fcx.tcx(); - rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds); + rcx.free_region_map + .relate_free_regions_from_predicates(tcx, &fcx.infcx().parameter_environment.caller_bounds); rcx.resolve_regions_and_report_errors(); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 19a0345e8088f..c7f084e27cda0 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -131,7 +131,8 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { let closure_def_id = ast_util::local_def(expr.id); if !self.fcx.inh.tables.borrow().closure_kinds.contains_key(&closure_def_id) { self.closures_with_inferred_kinds.insert(expr.id); - self.fcx.inh.tables.borrow_mut().closure_kinds.insert(closure_def_id, ty::FnClosureKind); + self.fcx.inh.tables.borrow_mut().closure_kinds + .insert(closure_def_id, ty::FnClosureKind); debug!("check_closure: adding closure_id={:?} to closures_with_inferred_kinds", closure_def_id); } @@ -267,7 +268,10 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // to move out of an upvar, this must be a FnOnce closure self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnOnceClosureKind); - let upvar_capture_map = &mut self.fcx.inh.tables.borrow_mut().upvar_capture_map; + let upvar_capture_map = &mut self.fcx + .inh + .tables.borrow_mut() + .upvar_capture_map; upvar_capture_map.insert(upvar_id, ty::UpvarCapture::ByValue); } mc::NoteClosureEnv(upvar_id) => { diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 18e05cd73fb7d..df01b99fd9b80 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -201,7 +201,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id)); let item_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh.infcx.parameter_environment.free_substs, + &fcx.inh + .infcx + .parameter_environment + .free_substs, &type_scheme.ty); bounds_checker.check_traits_in_ty(item_ty, item.span); @@ -222,7 +225,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // to free. let self_ty = fcx.tcx().node_id_to_type(item.id); let self_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh.infcx.parameter_environment.free_substs, + &fcx.inh + .infcx + .parameter_environment + .free_substs, &self_ty); bounds_checker.check_traits_in_ty(self_ty, item.span); @@ -235,7 +241,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { }; let trait_ref = fcx.instantiate_type_scheme(item.span, - &fcx.inh.infcx.parameter_environment.free_substs, + &fcx.inh + .infcx + .parameter_environment + .free_substs, &trait_ref); // We are stricter on the trait-ref in an impl than the @@ -637,7 +646,10 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, .map(|field| { let field_ty = fcx.tcx().node_id_to_type(field.node.id); let field_ty = fcx.instantiate_type_scheme(field.span, - &fcx.inh.infcx.parameter_environment.free_substs, + &fcx.inh + .infcx + .parameter_environment + .free_substs, &field_ty); AdtField { ty: field_ty, span: field.span } }) @@ -662,7 +674,10 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let arg_ty = arg_tys[index]; let arg_ty = fcx.instantiate_type_scheme(variant.span, - &fcx.inh.infcx.parameter_environment.free_substs, + &fcx.inh + .infcx + .parameter_environment + .free_substs, &arg_ty); AdtField { ty: arg_ty, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index d990697949659..1fc7224737d2d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -217,7 +217,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug!("Upvar capture for {:?} resolved to {:?}", upvar_id, new_upvar_capture); - self.fcx.tcx().tables.borrow_mut().upvar_capture_map.insert(*upvar_id, new_upvar_capture); + self.fcx.tcx() + .tables + .borrow_mut() + .upvar_capture_map + .insert(*upvar_id, new_upvar_capture); } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index af2c3a32150d8..fbabc287342e9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -540,13 +540,15 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { fulfill_cx.register_predicate_obligation(&infcx, predicate); // Check that all transitive obligations are satisfied. - if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { + if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, + &infcx.parameter_environment) { traits::report_fulfillment_errors(&infcx, &errors); } // Finally, resolve all regions. let mut free_regions = FreeRegionMap::new(); - free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds); + free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment + .caller_bounds); infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node); if let Some(kind) = kind { From 5c3753f6b457dbc8e4cf0e8ec2d085d03f310911 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sun, 28 Jun 2015 14:08:50 -0700 Subject: [PATCH 33/36] Fix librustc_driver/test.rs --- src/librustc_driver/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 5ec6e293684cc..fb2f6b2b08db8 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -140,7 +140,7 @@ fn test_env(source_string: &str, lang_items, stability::Index::new(krate), |tcx| { - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID); From 78ec055a148008b6ef9c01ce6fda3c8e6448113d Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Sun, 28 Jun 2015 17:23:53 -0400 Subject: [PATCH 34/36] Add `.write(true)` to append and truncate examples Setting append without write doesn't give you a writeable file. Showing it as an example in the docs is confusing at best. Using truncate on a read-only file is an error on POSIX systems (note however that using create with read-only flags is fine). --- src/libstd/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 2b0f17fb2bb9c..c2d3d2fb0c848 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -419,7 +419,7 @@ impl OpenOptions { /// ```no_run /// use std::fs::OpenOptions; /// - /// let file = OpenOptions::new().append(true).open("foo.txt"); + /// let file = OpenOptions::new().write(true).append(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn append(&mut self, append: bool) -> &mut OpenOptions { @@ -436,7 +436,7 @@ impl OpenOptions { /// ```no_run /// use std::fs::OpenOptions; /// - /// let file = OpenOptions::new().truncate(true).open("foo.txt"); + /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { From 9b6fe6ca368668f3b4950c49546d3d06125b9f01 Mon Sep 17 00:00:00 2001 From: Peter Elmers Date: Sun, 28 Jun 2015 18:49:22 -0700 Subject: [PATCH 35/36] Add tip to do partial compile. --- Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.in b/Makefile.in index d3bb5a541a470..1fe96189632c8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,6 +62,7 @@ # * tidy-basic - show file / line stats # * tidy-errors - show the highest rustc error code # * tidy-features - show the status of language and lib features +# * rustc-stage$(stage) - Only build up to a specific stage # # Then mix in some of these environment variables to harness the # ultimate power of The Rust Build System. From f07b11d07ecdf3fc983b14d68e3d9ecadadf7874 Mon Sep 17 00:00:00 2001 From: Richo Healey Date: Sun, 28 Jun 2015 19:05:09 -0700 Subject: [PATCH 36/36] mk: Fix a typo in the tips --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index d3bb5a541a470..31fa8c8744973 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ # # # Rust recipes for build system success # -# // Modifying libstd? Use this comment to run unit tests just on your change +# // Modifying libstd? Use this command to run unit tests just on your change # make check-stage1-std NO_REBUILD=1 NO_BENCH=1 # # // Added a run-pass test? Use this to test running your test