From 1cf6a8203826cf176eaf093b722b4f5d123f79da Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 17 Jun 2015 22:13:37 +0200 Subject: [PATCH 001/160] README: make it clear rustc is the compiler --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e54473a8b4172..f54c22110b301 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Rust is a systems programming language that is fast, memory safe and multithreaded, but does not employ a garbage collector or otherwise impose significant runtime overhead. -This repo contains the code for `rustc`, the Rust compiler, as well +This repo contains the code for the compiler (`rustc`), as well as standard libraries, tools and documentation for Rust. ## Quick Start From 5ff8e038f447f6c0bfe2ea09c4114684a8add429 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 20 Jun 2015 19:09:56 -0700 Subject: [PATCH 002/160] doc: Make it easier to find the std docs from the index This is usually the link I want when I come to this page. --- src/doc/index.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/index.md b/src/doc/index.md index fba919b711586..c1f9ea6b3b003 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -20,6 +20,13 @@ series of small examples. [rbe]: http://rustbyexample.com/ +# The Standard Library + +We have [API documentation for the entire standard +library](std/index.html). There's a list of crates on the left with more +specific sections, or you can use the search bar at the top to search for +something if you know its name. + # Community & Getting Help If you need help with something, or just want to talk about Rust with others, @@ -75,13 +82,6 @@ There are questions that are asked quite often, so we've made FAQs for them: * [Project FAQ](complement-project-faq.html) * [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports) -# The Standard Library - -We have [API documentation for the entire standard -library](std/index.html). There's a list of crates on the left with more -specific sections, or you can use the search bar at the top to search for -something if you know its name. - # The Error Index If you encounter an error while compiling your code you may be able to look it From b890b7bbc732cd26f13c309573b5a3e45d0748de Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sun, 14 Jun 2015 23:17:17 +0200 Subject: [PATCH 003/160] StrSearcher: Update substring search to use the Two Way algorithm To improve our substring search performance, revive the two way searcher and adapt it to the Pattern API. Fixes #25483, a performance bug: that particular case now completes faster in optimized rust than in ruby (but they share the same order of magnitude). Much thanks to @gereeter who helped me understand the reverse case better and wrote the comment explaining `next_back` in the code. I had quickcheck to fuzz test forward and reverse searching thoroughly. The two way searcher implements both forward and reverse search, but not double ended search. The forward and reverse parts of the two way searcher are completely independent. The two way searcher algorithm has very small, constant space overhead, requiring no dynamic allocation. Our implementation is relatively fast, especially due to the `byteset` addition to the algorithm, which speeds up many no-match cases. A bad case for the two way algorithm is: ``` let haystack = (0..10_000).map(|_| "dac").collect::(); let needle = (0..100).map(|_| "bac").collect::()); ``` For this particular case, two way is not much faster than the naive implementation it replaces. --- src/libcollectionstest/str.rs | 10 +- src/libcore/str/mod.rs | 299 +---------------- src/libcore/str/pattern.rs | 592 ++++++++++++++++++++++++++-------- 3 files changed, 475 insertions(+), 426 deletions(-) diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 3f32136bc2639..87a018ced195a 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -705,7 +705,7 @@ fn test_split_at() { #[should_panic] fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; - let (a, b) = s.split_at(1); + s.split_at(1); } #[test] @@ -1820,6 +1820,14 @@ mod pattern { Match (4, 6), Reject(6, 7), ]); + make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [ + Reject(0, 1), + Match (1, 3), + Reject(3, 4), + Match (4, 6), + Match (6, 8), + Reject(8, 9), + ]); make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [ Match (0, 0), Reject(0, 1), diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 5a621176c4a81..bd6e1a4063abd 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -15,13 +15,12 @@ #![doc(primitive = "str")] #![stable(feature = "rust1", since = "1.0.0")] -use self::OldSearcher::{TwoWay, TwoWayLong}; use self::pattern::Pattern; use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use char::CharExt; use clone::Clone; -use cmp::{self, Eq}; +use cmp::Eq; use convert::AsRef; use default::Default; use fmt; @@ -33,7 +32,6 @@ use option::Option::{self, None, Some}; use raw::{Repr, Slice}; use result::Result::{self, Ok, Err}; use slice::{self, SliceExt}; -use usize; pub mod pattern; @@ -870,301 +868,6 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> { } } -/// The internal state of an iterator that searches for matches of a substring -/// within a larger string using two-way search -#[derive(Clone)] -struct TwoWaySearcher { - // constants - crit_pos: usize, - period: usize, - byteset: u64, - - // variables - position: usize, - memory: usize -} - -/* - This is the Two-Way search algorithm, which was introduced in the paper: - Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675. - - Here's some background information. - - A *word* is a string of symbols. The *length* of a word should be a familiar - notion, and here we denote it for any word x by |x|. - (We also allow for the possibility of the *empty word*, a word of length zero). - - If x is any non-empty word, then an integer p with 0 < p <= |x| is said to be a - *period* for x iff for all i with 0 <= i <= |x| - p - 1, we have x[i] == x[i+p]. - For example, both 1 and 2 are periods for the string "aa". As another example, - the only period of the string "abcd" is 4. - - We denote by period(x) the *smallest* period of x (provided that x is non-empty). - This is always well-defined since every non-empty word x has at least one period, - |x|. We sometimes call this *the period* of x. - - If u, v and x are words such that x = uv, where uv is the concatenation of u and - v, then we say that (u, v) is a *factorization* of x. - - Let (u, v) be a factorization for a word x. Then if w is a non-empty word such - that both of the following hold - - - either w is a suffix of u or u is a suffix of w - - either w is a prefix of v or v is a prefix of w - - then w is said to be a *repetition* for the factorization (u, v). - - Just to unpack this, there are four possibilities here. Let w = "abc". Then we - might have: - - - w is a suffix of u and w is a prefix of v. ex: ("lolabc", "abcde") - - w is a suffix of u and v is a prefix of w. ex: ("lolabc", "ab") - - u is a suffix of w and w is a prefix of v. ex: ("bc", "abchi") - - u is a suffix of w and v is a prefix of w. ex: ("bc", "a") - - Note that the word vu is a repetition for any factorization (u,v) of x = uv, - so every factorization has at least one repetition. - - If x is a string and (u, v) is a factorization for x, then a *local period* for - (u, v) is an integer r such that there is some word w such that |w| = r and w is - a repetition for (u, v). - - We denote by local_period(u, v) the smallest local period of (u, v). We sometimes - call this *the local period* of (u, v). Provided that x = uv is non-empty, this - is well-defined (because each non-empty word has at least one factorization, as - noted above). - - It can be proven that the following is an equivalent definition of a local period - for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for - all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are - defined. (i.e. i > 0 and i + r < |x|). - - Using the above reformulation, it is easy to prove that - - 1 <= local_period(u, v) <= period(uv) - - A factorization (u, v) of x such that local_period(u,v) = period(x) is called a - *critical factorization*. - - The algorithm hinges on the following theorem, which is stated without proof: - - **Critical Factorization Theorem** Any word x has at least one critical - factorization (u, v) such that |u| < period(x). - - The purpose of maximal_suffix is to find such a critical factorization. - -*/ -impl TwoWaySearcher { - #[allow(dead_code)] - fn new(needle: &[u8]) -> TwoWaySearcher { - let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false); - let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true); - - let (crit_pos, period) = - if crit_pos_false > crit_pos_true { - (crit_pos_false, period_false) - } else { - (crit_pos_true, period_true) - }; - - // This isn't in the original algorithm, as far as I'm aware. - let byteset = needle.iter() - .fold(0, |a, &b| (1 << ((b & 0x3f) as usize)) | a); - - // A particularly readable explanation of what's going on here can be found - // in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically - // see the code for "Algorithm CP" on p. 323. - // - // What's going on is we have some critical factorization (u, v) of the - // needle, and we want to determine whether u is a suffix of - // &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use - // "Algorithm CP2", which is optimized for when the period of the needle - // is large. - if &needle[..crit_pos] == &needle[period.. period + crit_pos] { - TwoWaySearcher { - crit_pos: crit_pos, - period: period, - byteset: byteset, - - position: 0, - memory: 0 - } - } else { - TwoWaySearcher { - crit_pos: crit_pos, - period: cmp::max(crit_pos, needle.len() - crit_pos) + 1, - byteset: byteset, - - position: 0, - memory: usize::MAX // Dummy value to signify that the period is long - } - } - } - - // One of the main ideas of Two-Way is that we factorize the needle into - // two halves, (u, v), and begin trying to find v in the haystack by scanning - // left to right. If v matches, we try to match u by scanning right to left. - // How far we can jump when we encounter a mismatch is all based on the fact - // that (u, v) is a critical factorization for the needle. - #[inline] - fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) - -> Option<(usize, usize)> { - 'search: loop { - // Check that we have room to search in - if self.position + needle.len() > haystack.len() { - return None; - } - - // Quickly skip by large portions unrelated to our substring - if (self.byteset >> - ((haystack[self.position + needle.len() - 1] & 0x3f) - as usize)) & 1 == 0 { - self.position += needle.len(); - if !long_period { - self.memory = 0; - } - continue 'search; - } - - // See if the right part of the needle matches - let start = if long_period { self.crit_pos } - else { cmp::max(self.crit_pos, self.memory) }; - for i in start..needle.len() { - if needle[i] != haystack[self.position + i] { - self.position += i - self.crit_pos + 1; - if !long_period { - self.memory = 0; - } - continue 'search; - } - } - - // See if the left part of the needle matches - let start = if long_period { 0 } else { self.memory }; - for i in (start..self.crit_pos).rev() { - if needle[i] != haystack[self.position + i] { - self.position += self.period; - if !long_period { - self.memory = needle.len() - self.period; - } - continue 'search; - } - } - - // We have found a match! - let match_pos = self.position; - self.position += needle.len(); // add self.period for all matches - if !long_period { - self.memory = 0; // set to needle.len() - self.period for all matches - } - return Some((match_pos, match_pos + needle.len())); - } - } - - // Computes a critical factorization (u, v) of `arr`. - // Specifically, returns (i, p), where i is the starting index of v in some - // critical factorization (u, v) and p = period(v) - #[inline] - #[allow(dead_code)] - #[allow(deprecated)] - fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) { - let mut left: usize = !0; // Corresponds to i in the paper - let mut right = 0; // Corresponds to j in the paper - let mut offset = 1; // Corresponds to k in the paper - let mut period = 1; // Corresponds to p in the paper - - while right + offset < arr.len() { - let a; - let b; - if reversed { - a = arr[left.wrapping_add(offset)]; - b = arr[right + offset]; - } else { - a = arr[right + offset]; - b = arr[left.wrapping_add(offset)]; - } - if a < b { - // Suffix is smaller, period is entire prefix so far. - right += offset; - offset = 1; - period = right.wrapping_sub(left); - } else if a == b { - // Advance through repetition of the current period. - if offset == period { - right += offset; - offset = 1; - } else { - offset += 1; - } - } else { - // Suffix is larger, start over from current location. - left = right; - right += 1; - offset = 1; - period = 1; - } - } - (left.wrapping_add(1), period) - } -} - -/// The internal state of an iterator that searches for matches of a substring -/// within a larger string using a dynamically chosen search algorithm -#[derive(Clone)] -// NB: This is kept around for convenience because -// it is planned to be used again in the future -enum OldSearcher { - TwoWay(TwoWaySearcher), - TwoWayLong(TwoWaySearcher), -} - -impl OldSearcher { - #[allow(dead_code)] - fn new(haystack: &[u8], needle: &[u8]) -> OldSearcher { - if needle.is_empty() { - // Handle specially - unimplemented!() - // FIXME: Tune this. - // FIXME(#16715): This unsigned integer addition will probably not - // overflow because that would mean that the memory almost solely - // consists of the needle. Needs #16715 to be formally fixed. - } else if needle.len() + 20 > haystack.len() { - // Use naive searcher - unimplemented!() - } else { - let searcher = TwoWaySearcher::new(needle); - if searcher.memory == usize::MAX { // If the period is long - TwoWayLong(searcher) - } else { - TwoWay(searcher) - } - } - } -} - -#[derive(Clone)] -// NB: This is kept around for convenience because -// it is planned to be used again in the future -struct OldMatchIndices<'a, 'b> { - // constants - haystack: &'a str, - needle: &'b str, - searcher: OldSearcher -} - -impl<'a, 'b> OldMatchIndices<'a, 'b> { - #[inline] - #[allow(dead_code)] - fn next(&mut self) -> Option<(usize, usize)> { - match self.searcher { - TwoWay(ref mut searcher) - => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), false), - TwoWayLong(ref mut searcher) - => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), true), - } - } -} - /* Section: Comparing strings */ diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 8bdbab55211d8..de40a57fe9c17 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -17,6 +17,8 @@ reason = "API not fully fleshed out and ready to be stabilized")] use prelude::*; +use core::cmp; +use usize; // Pattern @@ -345,141 +347,16 @@ impl<'a, C: CharEq> DoubleEndedSearcher<'a> for CharEqSearcher<'a, C> {} // Impl for &str ///////////////////////////////////////////////////////////////////////////// -// Todo: Optimize the naive implementation here - -/// Associated type for `<&str as Pattern<'a>>::Searcher`. -#[derive(Clone)] -pub struct StrSearcher<'a, 'b> { - haystack: &'a str, - needle: &'b str, - start: usize, - end: usize, - state: State, -} - -#[derive(Clone, PartialEq)] -enum State { Done, NotDone, Reject(usize, usize) } -impl State { - #[inline] fn done(&self) -> bool { *self == State::Done } - #[inline] fn take(&mut self) -> State { ::mem::replace(self, State::NotDone) } -} - /// Non-allocating substring search. /// -/// Will handle the pattern `""` as returning empty matches at each utf8 +/// Will handle the pattern `""` as returning empty matches at each character /// boundary. impl<'a, 'b> Pattern<'a> for &'b str { type Searcher = StrSearcher<'a, 'b>; #[inline] fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> { - StrSearcher { - haystack: haystack, - needle: self, - start: 0, - end: haystack.len(), - state: State::NotDone, - } - } -} - -unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { - #[inline] - fn haystack(&self) -> &'a str { - self.haystack - } - - #[inline] - fn next(&mut self) -> SearchStep { - str_search_step(self, - |m: &mut StrSearcher| { - // Forward step for empty needle - let current_start = m.start; - if !m.state.done() { - m.start = m.haystack.char_range_at(current_start).next; - m.state = State::Reject(current_start, m.start); - } - SearchStep::Match(current_start, current_start) - }, - |m: &mut StrSearcher| { - // Forward step for nonempty needle - let current_start = m.start; - // Compare byte window because this might break utf8 boundaries - let possible_match = &m.haystack.as_bytes()[m.start .. m.start + m.needle.len()]; - if possible_match == m.needle.as_bytes() { - m.start += m.needle.len(); - SearchStep::Match(current_start, m.start) - } else { - // Skip a char - let haystack_suffix = &m.haystack[m.start..]; - m.start += haystack_suffix.chars().next().unwrap().len_utf8(); - SearchStep::Reject(current_start, m.start) - } - }) - } -} - -unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { - #[inline] - fn next_back(&mut self) -> SearchStep { - str_search_step(self, - |m: &mut StrSearcher| { - // Backward step for empty needle - let current_end = m.end; - if !m.state.done() { - m.end = m.haystack.char_range_at_reverse(current_end).next; - m.state = State::Reject(m.end, current_end); - } - SearchStep::Match(current_end, current_end) - }, - |m: &mut StrSearcher| { - // Backward step for nonempty needle - let current_end = m.end; - // Compare byte window because this might break utf8 boundaries - let possible_match = &m.haystack.as_bytes()[m.end - m.needle.len() .. m.end]; - if possible_match == m.needle.as_bytes() { - m.end -= m.needle.len(); - SearchStep::Match(m.end, current_end) - } else { - // Skip a char - let haystack_prefix = &m.haystack[..m.end]; - m.end -= haystack_prefix.chars().rev().next().unwrap().len_utf8(); - SearchStep::Reject(m.end, current_end) - } - }) - } -} - -// Helper function for encapsulating the common control flow -// of doing a search step from the front or doing a search step from the back -fn str_search_step(mut m: &mut StrSearcher, - empty_needle_step: F, - nonempty_needle_step: G) -> SearchStep - where F: FnOnce(&mut StrSearcher) -> SearchStep, - G: FnOnce(&mut StrSearcher) -> SearchStep -{ - if m.state.done() { - SearchStep::Done - } else if m.needle.is_empty() && m.start <= m.end { - // Case for needle == "" - if let State::Reject(a, b) = m.state.take() { - SearchStep::Reject(a, b) - } else { - if m.start == m.end { - m.state = State::Done; - } - empty_needle_step(&mut m) - } - } else if m.start + m.needle.len() <= m.end { - // Case for needle != "" - nonempty_needle_step(&mut m) - } else if m.start < m.end { - // Remaining slice shorter than needle, reject it - m.state = State::Done; - SearchStep::Reject(m.start, m.end) - } else { - m.state = State::Done; - SearchStep::Done + StrSearcher::new(haystack, self) } } @@ -633,3 +510,464 @@ impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool { impl<'a, 'b> Pattern<'a> for &'b &'b str { pattern_methods!(StrSearcher<'a, 'b>, |&s| s, |s| s); } + + +///////////////////////////////////////////////////////////////////////////// +// Two Way substring searcher +///////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, Debug)] +/// Associated type for `<&str as Pattern<'a>>::Searcher`. +pub struct StrSearcher<'a, 'b> { + haystack: &'a str, + needle: &'b str, + + searcher: StrSearcherImpl, +} + +#[derive(Clone, Debug)] +enum StrSearcherImpl { + Empty(EmptyNeedle), + TwoWay { + last_match_fw: Option<(usize, usize)>, + last_match_bw: Option<(usize, usize)>, + searcher: TwoWaySearcher, + } +} + +#[derive(Clone, Debug)] +struct EmptyNeedle { + position: usize, + end: usize, + is_match_fw: bool, + is_match_bw: bool, +} + +impl<'a, 'b> StrSearcher<'a, 'b> { + fn new(haystack: &'a str, needle: &'b str) -> StrSearcher<'a, 'b> { + if needle.is_empty() { + StrSearcher { + haystack: haystack, + needle: needle, + searcher: StrSearcherImpl::Empty(EmptyNeedle { + position: 0, + end: haystack.len(), + is_match_fw: true, + is_match_bw: true, + }), + } + } else { + StrSearcher { + haystack: haystack, + needle: needle, + searcher: StrSearcherImpl::TwoWay { + last_match_fw: None, + last_match_bw: None, + searcher: TwoWaySearcher::new(needle.as_bytes(), haystack.len()) + }, + } + } + } +} + +unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { + fn haystack(&self) -> &'a str { self.haystack } + + #[inline] + fn next(&mut self) -> SearchStep { + match self.searcher { + StrSearcherImpl::Empty(ref mut searcher) => { + // empty needle rejects every char and matches every empty string between them + let is_match = searcher.is_match_fw; + searcher.is_match_fw = !searcher.is_match_fw; + let pos = searcher.position; + match self.haystack[pos..].chars().next() { + _ if is_match => SearchStep::Match(pos, pos), + None => SearchStep::Done, + Some(ch) => { + searcher.position += ch.len_utf8(); + SearchStep::Reject(pos, searcher.position) + } + } + } + StrSearcherImpl::TwoWay { ref mut last_match_fw, ref mut searcher, .. } => { + // TwoWaySearcher produces valid *Match* indices that split at char boundaries + // as long as it does correct matching and that haystack and needle are + // valid UTF-8 + // *Rejects* fall on the same indices (the intervals between matches) + // so they are always on character boundaries. + if let Some((a, b)) = last_match_fw.take() { + return SearchStep::Match(a, b); + } + let last_pos = searcher.position; + let is_long = searcher.memory == usize::MAX; + let next_match = searcher.next(self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long); + match next_match { + None => if last_pos != self.haystack.len() { + SearchStep::Reject(last_pos, self.haystack.len()) + } else { + SearchStep::Done + }, + Some((a, b)) => { + if a == last_pos { + SearchStep::Match(a, b) + } else { + *last_match_fw = Some((a, b)); + SearchStep::Reject(last_pos, a) + } + } + } + } + } + } + +} +unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { + #[inline] + fn next_back(&mut self) -> SearchStep { + match self.searcher { + StrSearcherImpl::Empty(ref mut searcher) => { + let is_match = searcher.is_match_bw; + searcher.is_match_bw = !searcher.is_match_bw; + let end = searcher.end; + match self.haystack[..end].chars().next_back() { + _ if is_match => SearchStep::Match(end, end), + None => SearchStep::Done, + Some(ch) => { + searcher.end -= ch.len_utf8(); + SearchStep::Reject(searcher.end, end) + } + } + } + StrSearcherImpl::TwoWay { ref mut last_match_bw, ref mut searcher, .. } => { + if let Some((a, b)) = last_match_bw.take() { + return SearchStep::Match(a, b); + } + let last_end = searcher.end; + let next_match = searcher.next_back(self.haystack.as_bytes(), + self.needle.as_bytes()); + match next_match { + None => if last_end != 0 { + SearchStep::Reject(0, last_end) + } else { + SearchStep::Done + }, + Some((a, b)) => { + if b == last_end { + SearchStep::Match(a, b) + } else { + *last_match_bw = Some((a, b)); + SearchStep::Reject(b, last_end) + } + } + } + } + } + } +} + +/// The internal state of an iterator that searches for matches of a substring +/// within a larger string using two-way search +#[derive(Clone, Debug)] +struct TwoWaySearcher { + // constants + crit_pos: usize, + period: usize, + byteset: u64, + + // variables + position: usize, + end: usize, + memory: usize +} + +/* + This is the Two-Way search algorithm, which was introduced in the paper: + Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675. + + Here's some background information. + + A *word* is a string of symbols. The *length* of a word should be a familiar + notion, and here we denote it for any word x by |x|. + (We also allow for the possibility of the *empty word*, a word of length zero). + + If x is any non-empty word, then an integer p with 0 < p <= |x| is said to be a + *period* for x iff for all i with 0 <= i <= |x| - p - 1, we have x[i] == x[i+p]. + For example, both 1 and 2 are periods for the string "aa". As another example, + the only period of the string "abcd" is 4. + + We denote by period(x) the *smallest* period of x (provided that x is non-empty). + This is always well-defined since every non-empty word x has at least one period, + |x|. We sometimes call this *the period* of x. + + If u, v and x are words such that x = uv, where uv is the concatenation of u and + v, then we say that (u, v) is a *factorization* of x. + + Let (u, v) be a factorization for a word x. Then if w is a non-empty word such + that both of the following hold + + - either w is a suffix of u or u is a suffix of w + - either w is a prefix of v or v is a prefix of w + + then w is said to be a *repetition* for the factorization (u, v). + + Just to unpack this, there are four possibilities here. Let w = "abc". Then we + might have: + + - w is a suffix of u and w is a prefix of v. ex: ("lolabc", "abcde") + - w is a suffix of u and v is a prefix of w. ex: ("lolabc", "ab") + - u is a suffix of w and w is a prefix of v. ex: ("bc", "abchi") + - u is a suffix of w and v is a prefix of w. ex: ("bc", "a") + + Note that the word vu is a repetition for any factorization (u,v) of x = uv, + so every factorization has at least one repetition. + + If x is a string and (u, v) is a factorization for x, then a *local period* for + (u, v) is an integer r such that there is some word w such that |w| = r and w is + a repetition for (u, v). + + We denote by local_period(u, v) the smallest local period of (u, v). We sometimes + call this *the local period* of (u, v). Provided that x = uv is non-empty, this + is well-defined (because each non-empty word has at least one factorization, as + noted above). + + It can be proven that the following is an equivalent definition of a local period + for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for + all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are + defined. (i.e. i > 0 and i + r < |x|). + + Using the above reformulation, it is easy to prove that + + 1 <= local_period(u, v) <= period(uv) + + A factorization (u, v) of x such that local_period(u,v) = period(x) is called a + *critical factorization*. + + The algorithm hinges on the following theorem, which is stated without proof: + + **Critical Factorization Theorem** Any word x has at least one critical + factorization (u, v) such that |u| < period(x). + + The purpose of maximal_suffix is to find such a critical factorization. + +*/ +impl TwoWaySearcher { + fn new(needle: &[u8], end: usize) -> TwoWaySearcher { + let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false); + let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true); + + let (crit_pos, period) = + if crit_pos_false > crit_pos_true { + (crit_pos_false, period_false) + } else { + (crit_pos_true, period_true) + }; + + // This isn't in the original algorithm, as far as I'm aware. + let byteset = needle.iter() + .fold(0, |a, &b| (1 << ((b & 0x3f) as usize)) | a); + + // A particularly readable explanation of what's going on here can be found + // in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically + // see the code for "Algorithm CP" on p. 323. + // + // What's going on is we have some critical factorization (u, v) of the + // needle, and we want to determine whether u is a suffix of + // &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use + // "Algorithm CP2", which is optimized for when the period of the needle + // is large. + if &needle[..crit_pos] == &needle[period.. period + crit_pos] { + // short period case + TwoWaySearcher { + crit_pos: crit_pos, + period: period, + byteset: byteset, + + position: 0, + end: end, + memory: 0 + } + } else { + // long period case + // we have an approximation to the actual period, and don't use memory. + TwoWaySearcher { + crit_pos: crit_pos, + period: cmp::max(crit_pos, needle.len() - crit_pos) + 1, + byteset: byteset, + + position: 0, + end: end, + memory: usize::MAX // Dummy value to signify that the period is long + } + } + } + + #[inline(always)] + fn byteset_contains(&self, byte: u8) -> bool { + (self.byteset >> ((byte & 0x3f) as usize)) & 1 != 0 + } + + // One of the main ideas of Two-Way is that we factorize the needle into + // two halves, (u, v), and begin trying to find v in the haystack by scanning + // left to right. If v matches, we try to match u by scanning right to left. + // How far we can jump when we encounter a mismatch is all based on the fact + // that (u, v) is a critical factorization for the needle. + #[inline] + fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) + -> Option<(usize, usize)> { + // `next()` uses `self.position` as its cursor + 'search: loop { + // Check that we have room to search in + if self.position + needle.len() > haystack.len() { + self.position = haystack.len(); + return None; + } + + // Quickly skip by large portions unrelated to our substring + if !self.byteset_contains(haystack[self.position + needle.len() - 1]) { + self.position += needle.len(); + if !long_period { + self.memory = 0; + } + continue 'search; + } + + // See if the right part of the needle matches + let start = if long_period { self.crit_pos } + else { cmp::max(self.crit_pos, self.memory) }; + for i in start..needle.len() { + if needle[i] != haystack[self.position + i] { + self.position += i - self.crit_pos + 1; + if !long_period { + self.memory = 0; + } + continue 'search; + } + } + + // See if the left part of the needle matches + let start = if long_period { 0 } else { self.memory }; + for i in (start..self.crit_pos).rev() { + if needle[i] != haystack[self.position + i] { + self.position += self.period; + if !long_period { + self.memory = needle.len() - self.period; + } + continue 'search; + } + } + + // We have found a match! + let match_pos = self.position; + + // Note: add self.period instead of needle.len() to have overlapping matches + self.position += needle.len(); + if !long_period { + self.memory = 0; // set to needle.len() - self.period for overlapping matches + } + + return Some((match_pos, match_pos + needle.len())); + } + } + + // Follows the ideas in `next()`. + // + // All the definitions are completely symmetrical, with period(x) = period(reverse(x)) + // and local_period(u, v) = local_period(reverse(v), reverse(u)), so if (u, v) + // is a critical factorization, so is (reverse(v), reverse(u)). Similarly, + // the "period" stored in self.period is the real period if long_period is + // false, and so is still valid for a reversed needle, and if long_period is + // true, all the algorithm requires is that self.period is less than or + // equal to the real period, which must be true for the forward case anyway. + // + // To search in reverse through the haystack, we search forward through + // a reversed haystack with a reversed needle, and the above paragraph shows + // that the precomputed parameters can be left alone. + #[inline] + fn next_back(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(usize, usize)> { + // `next_back()` uses `self.end` as its cursor -- so that `next()` and `next_back()` + // are independent. + 'search: loop { + // Check that we have room to search in + if needle.len() > self.end { + self.end = 0; + return None; + } + + // Quickly skip by large portions unrelated to our substring + if !self.byteset_contains(haystack[self.end - needle.len()]) { + self.end -= needle.len(); + continue 'search; + } + + // See if the left part of the needle matches + for i in (0..self.crit_pos).rev() { + if needle[i] != haystack[self.end - needle.len() + i] { + self.end -= self.crit_pos - i; + continue 'search; + } + } + + // See if the right part of the needle matches + for i in self.crit_pos..needle.len() { + if needle[i] != haystack[self.end - needle.len() + i] { + self.end -= self.period; + continue 'search; + } + } + + // We have found a match! + let match_pos = self.end - needle.len(); + // Note: sub self.period instead of needle.len() to have overlapping matches + self.end -= needle.len(); + + return Some((match_pos, match_pos + needle.len())); + } + } + + // Computes a critical factorization (u, v) of `arr`. + // Specifically, returns (i, p), where i is the starting index of v in some + // critical factorization (u, v) and p = period(v) + #[inline] + fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) { + let mut left: usize = !0; // Corresponds to i in the paper + let mut right = 0; // Corresponds to j in the paper + let mut offset = 1; // Corresponds to k in the paper + let mut period = 1; // Corresponds to p in the paper + + while right + offset < arr.len() { + let a; + let b; + if reversed { + a = arr[left.wrapping_add(offset)]; + b = arr[right + offset]; + } else { + a = arr[right + offset]; + b = arr[left.wrapping_add(offset)]; + } + if a < b { + // Suffix is smaller, period is entire prefix so far. + right += offset; + offset = 1; + period = right.wrapping_sub(left); + } else if a == b { + // Advance through repetition of the current period. + if offset == period { + right += offset; + offset = 1; + } else { + offset += 1; + } + } else { + // Suffix is larger, start over from current location. + left = right; + right += 1; + offset = 1; + period = 1; + } + } + (left.wrapping_add(1), period) + } +} From a6dd2031a363d0b46caea06ef77209f678327719 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 17 Jun 2015 18:35:43 +0200 Subject: [PATCH 004/160] StrSearcher: Specialize is_prefix_of/is_suffix_of for &str --- src/libcore/str/pattern.rs | 50 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index de40a57fe9c17..048bcc0dce53f 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -343,23 +343,6 @@ unsafe impl<'a, C: CharEq> ReverseSearcher<'a> for CharEqSearcher<'a, C> { impl<'a, C: CharEq> DoubleEndedSearcher<'a> for CharEqSearcher<'a, C> {} -///////////////////////////////////////////////////////////////////////////// -// Impl for &str -///////////////////////////////////////////////////////////////////////////// - -/// Non-allocating substring search. -/// -/// Will handle the pattern `""` as returning empty matches at each character -/// boundary. -impl<'a, 'b> Pattern<'a> for &'b str { - type Searcher = StrSearcher<'a, 'b>; - - #[inline] - fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> { - StrSearcher::new(haystack, self) - } -} - ///////////////////////////////////////////////////////////////////////////// macro_rules! pattern_methods { @@ -511,6 +494,39 @@ impl<'a, 'b> Pattern<'a> for &'b &'b str { pattern_methods!(StrSearcher<'a, 'b>, |&s| s, |s| s); } +///////////////////////////////////////////////////////////////////////////// +// Impl for &str +///////////////////////////////////////////////////////////////////////////// + +/// Non-allocating substring search. +/// +/// Will handle the pattern `""` as returning empty matches at each character +/// boundary. +impl<'a, 'b> Pattern<'a> for &'b str { + type Searcher = StrSearcher<'a, 'b>; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> { + StrSearcher::new(haystack, self) + } + + /// Checks whether the pattern matches at the front of the haystack + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + // Use `as_bytes` so that we can slice through a character in the haystack. + // Since self is always valid UTF-8, this can't result in a false positive. + self.len() <= haystack.len() && + self.as_bytes() == &haystack.as_bytes()[..self.len()] + } + + /// Checks whether the pattern matches at the back of the haystack + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool { + self.len() <= haystack.len() && + self.as_bytes() == &haystack.as_bytes()[haystack.len() - self.len()..] + } +} + ///////////////////////////////////////////////////////////////////////////// // Two Way substring searcher From 71006bd6545015d7ae8e4c18589812bc1f6373dd Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sun, 21 Jun 2015 19:44:25 +0200 Subject: [PATCH 005/160] StrSearcher: Use trait to specialize two way algorithm by case Use a trait to be able to implement both the fast search that skips to each match, and the slower search that emits `Reject` intervals regularly. The latter is important for uses of `next_reject`. --- src/libcore/str/pattern.rs | 190 ++++++++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 57 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 048bcc0dce53f..6d68615a8cfd7 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -544,11 +544,7 @@ pub struct StrSearcher<'a, 'b> { #[derive(Clone, Debug)] enum StrSearcherImpl { Empty(EmptyNeedle), - TwoWay { - last_match_fw: Option<(usize, usize)>, - last_match_bw: Option<(usize, usize)>, - searcher: TwoWaySearcher, - } + TwoWay(TwoWaySearcher), } #[derive(Clone, Debug)] @@ -576,11 +572,9 @@ impl<'a, 'b> StrSearcher<'a, 'b> { StrSearcher { haystack: haystack, needle: needle, - searcher: StrSearcherImpl::TwoWay { - last_match_fw: None, - last_match_bw: None, - searcher: TwoWaySearcher::new(needle.as_bytes(), haystack.len()) - }, + searcher: StrSearcherImpl::TwoWay( + TwoWaySearcher::new(needle.as_bytes(), haystack.len()) + ), } } } @@ -606,39 +600,55 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { } } } - StrSearcherImpl::TwoWay { ref mut last_match_fw, ref mut searcher, .. } => { + StrSearcherImpl::TwoWay(ref mut searcher) => { // TwoWaySearcher produces valid *Match* indices that split at char boundaries // as long as it does correct matching and that haystack and needle are // valid UTF-8 - // *Rejects* fall on the same indices (the intervals between matches) - // so they are always on character boundaries. - if let Some((a, b)) = last_match_fw.take() { - return SearchStep::Match(a, b); + // *Rejects* from the algorithm can fall on any indices, but we will walk them + // manually to the next character boundary, so that they are utf-8 safe. + if searcher.position == self.haystack.len() { + return SearchStep::Done; } - let last_pos = searcher.position; let is_long = searcher.memory == usize::MAX; - let next_match = searcher.next(self.haystack.as_bytes(), - self.needle.as_bytes(), - is_long); - match next_match { - None => if last_pos != self.haystack.len() { - SearchStep::Reject(last_pos, self.haystack.len()) - } else { - SearchStep::Done - }, - Some((a, b)) => { - if a == last_pos { - SearchStep::Match(a, b) - } else { - *last_match_fw = Some((a, b)); - SearchStep::Reject(last_pos, a) + match searcher.next::(self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long) + { + SearchStep::Reject(a, mut b) => { + // skip to next char boundary + while !self.haystack.is_char_boundary(b) { + b += 1; } + searcher.position = cmp::max(b, searcher.position); + SearchStep::Reject(a, b) } + otherwise => otherwise, } } } } + #[inline] + fn next_match(&mut self) -> Option<(usize, usize)> { + match self.searcher { + StrSearcherImpl::Empty(..) => { + loop { + match self.next() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => { } + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + let is_long = searcher.memory == usize::MAX; + searcher.next::(self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long) + } + } + } + } unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { #[inline] @@ -657,31 +667,45 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { } } } - StrSearcherImpl::TwoWay { ref mut last_match_bw, ref mut searcher, .. } => { - if let Some((a, b)) = last_match_bw.take() { - return SearchStep::Match(a, b); + StrSearcherImpl::TwoWay(ref mut searcher) => { + if searcher.end == 0 { + return SearchStep::Done; } - let last_end = searcher.end; - let next_match = searcher.next_back(self.haystack.as_bytes(), - self.needle.as_bytes()); - match next_match { - None => if last_end != 0 { - SearchStep::Reject(0, last_end) - } else { - SearchStep::Done - }, - Some((a, b)) => { - if b == last_end { - SearchStep::Match(a, b) - } else { - *last_match_bw = Some((a, b)); - SearchStep::Reject(b, last_end) + match searcher.next_back::(self.haystack.as_bytes(), + self.needle.as_bytes()) + { + SearchStep::Reject(mut a, b) => { + // skip to next char boundary + while !self.haystack.is_char_boundary(a) { + a -= 1; } + searcher.end = cmp::min(a, searcher.end); + SearchStep::Reject(a, b) } + otherwise => otherwise, } } } } + + #[inline] + fn next_match_back(&mut self) -> Option<(usize, usize)> { + match self.searcher { + StrSearcherImpl::Empty(..) => { + loop { + match self.next_back() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => { } + } + } + } + StrSearcherImpl::TwoWay(ref mut searcher) => { + searcher.next_back::(self.haystack.as_bytes(), + self.needle.as_bytes()) + } + } + } } /// The internal state of an iterator that searches for matches of a substring @@ -831,14 +855,21 @@ impl TwoWaySearcher { // How far we can jump when we encounter a mismatch is all based on the fact // that (u, v) is a critical factorization for the needle. #[inline] - fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) - -> Option<(usize, usize)> { + fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) + -> S::Output + where S: TwoWayStrategy + { // `next()` uses `self.position` as its cursor + let old_pos = self.position; 'search: loop { // Check that we have room to search in - if self.position + needle.len() > haystack.len() { + if needle.len() > haystack.len() - self.position { self.position = haystack.len(); - return None; + return S::rejecting(old_pos, self.position); + } + + if S::use_early_reject() && old_pos != self.position { + return S::rejecting(old_pos, self.position); } // Quickly skip by large portions unrelated to our substring @@ -884,7 +915,7 @@ impl TwoWaySearcher { self.memory = 0; // set to needle.len() - self.period for overlapping matches } - return Some((match_pos, match_pos + needle.len())); + return S::matching(match_pos, match_pos + needle.len()); } } @@ -902,14 +933,22 @@ impl TwoWaySearcher { // a reversed haystack with a reversed needle, and the above paragraph shows // that the precomputed parameters can be left alone. #[inline] - fn next_back(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(usize, usize)> { + fn next_back(&mut self, haystack: &[u8], needle: &[u8]) + -> S::Output + where S: TwoWayStrategy + { // `next_back()` uses `self.end` as its cursor -- so that `next()` and `next_back()` // are independent. + let old_end = self.end; 'search: loop { // Check that we have room to search in if needle.len() > self.end { self.end = 0; - return None; + return S::rejecting(0, old_end); + } + + if S::use_early_reject() && old_end != self.end { + return S::rejecting(self.end, old_end); } // Quickly skip by large portions unrelated to our substring @@ -939,7 +978,7 @@ impl TwoWaySearcher { // Note: sub self.period instead of needle.len() to have overlapping matches self.end -= needle.len(); - return Some((match_pos, match_pos + needle.len())); + return S::matching(match_pos, match_pos + needle.len()); } } @@ -987,3 +1026,40 @@ impl TwoWaySearcher { (left.wrapping_add(1), period) } } + +// TwoWayStrategy allows the algorithm to either skip non-matches as quickly +// as possible, or to work in a mode where it emits Rejects relatively quickly. +trait TwoWayStrategy { + type Output; + fn use_early_reject() -> bool; + fn rejecting(usize, usize) -> Self::Output; + fn matching(usize, usize) -> Self::Output; +} + +/// Skip to match intervals as quickly as possible +enum MatchOnly { } + +impl TwoWayStrategy for MatchOnly { + type Output = Option<(usize, usize)>; + + #[inline] + fn use_early_reject() -> bool { false } + #[inline] + fn rejecting(_a: usize, _b: usize) -> Self::Output { None } + #[inline] + fn matching(a: usize, b: usize) -> Self::Output { Some((a, b)) } +} + +/// Emit Rejects regularly +enum RejectAndMatch { } + +impl TwoWayStrategy for RejectAndMatch { + type Output = SearchStep; + + #[inline] + fn use_early_reject() -> bool { true } + #[inline] + fn rejecting(a: usize, b: usize) -> Self::Output { SearchStep::Reject(a, b) } + #[inline] + fn matching(a: usize, b: usize) -> Self::Output { SearchStep::Match(a, b) } +} From 0adda45c04f1c4a950e1e676ae590758c7b827df Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Jun 2015 19:26:51 +0200 Subject: [PATCH 006/160] book: fix sentence --- src/doc/trpl/documentation.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md index 53754e2688dd6..746558b3b9448 100644 --- a/src/doc/trpl/documentation.md +++ b/src/doc/trpl/documentation.md @@ -33,8 +33,10 @@ pub fn new(value: T) -> Rc { ``` This code generates documentation that looks [like this][rc-new]. I've left the -implementation out, with a regular comment in its place. That's the first thing -to notice about this annotation: it uses `///`, instead of `//`. The triple slash +implementation out, with a regular comment in its place. + +The first thing to notice about this annotation is that it uses +`///` instead of `//`. The triple slash indicates a documentation comment. Documentation comments are written in Markdown. From e13077f7f089664a847f9fa1f081f0ff8f413726 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Jun 2015 19:27:31 +0200 Subject: [PATCH 007/160] book: whitespace --- src/doc/trpl/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md index 746558b3b9448..7d9d6aa39f85d 100644 --- a/src/doc/trpl/documentation.md +++ b/src/doc/trpl/documentation.md @@ -382,7 +382,7 @@ $ rustdoc --test path/to/my/crate/root.rs $ cargo test ``` -That's right, `cargo test` tests embedded documentation too. However, +That's right, `cargo test` tests embedded documentation too. However, `cargo test` will not test binary crates, only library ones. This is due to the way `rustdoc` works: it links against the library to be tested, but with a binary, there’s nothing to link to. From 599bf45ac9afc309332388fe4bc42a100e3d1586 Mon Sep 17 00:00:00 2001 From: Theo Belaire Date: Fri, 1 May 2015 21:13:27 +0200 Subject: [PATCH 008/160] Indent code past the widest line number Fixes #11715 --- src/libsyntax/diagnostic.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 14dd9978b876a..6c2e3dc6330ec 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -594,12 +594,18 @@ fn highlight_lines(err: &mut EmitterWriter, let display_line_infos = &lines.lines[..display_lines]; let display_line_strings = &line_strings[..display_lines]; + // Calculate the widest number to format evenly and fix #11715 + assert!(display_line_infos.len() > 0); + let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1; + let mut digits = 0; + while max_line_num > 0 { max_line_num /= 10; digits += 1; } // Print the offending lines for (line_info, line) in display_line_infos.iter().zip(display_line_strings) { - try!(write!(&mut err.dst, "{}:{} {}\n", + try!(write!(&mut err.dst, "{}:{:>width$} {}\n", fm.name, line_info.line_index + 1, - line)); + line, + width=digits)); } // If we elided something, put an ellipsis. From c5dfd34c615b0586a101e9e66770a5c4fd31c852 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 23 Jun 2015 11:43:27 +0200 Subject: [PATCH 009/160] Added unit test for code indent of multi-line errors --- src/libsyntax/diagnostic.rs | 67 ++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 6c2e3dc6330ec..ec93d2c553627 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -598,7 +598,11 @@ fn highlight_lines(err: &mut EmitterWriter, assert!(display_line_infos.len() > 0); let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1; let mut digits = 0; - while max_line_num > 0 { max_line_num /= 10; digits += 1; } + while max_line_num > 0 { + max_line_num /= 10; + digits += 1; + } + // Print the offending lines for (line_info, line) in display_line_infos.iter().zip(display_line_strings) { try!(write!(&mut err.dst, "{}:{:>width$} {}\n", @@ -801,3 +805,64 @@ pub fn expect(diag: &SpanHandler, opt: Option, msg: M) -> T where None => diag.handler().bug(&msg()), } } + +#[cfg(test)] +mod test { + use super::{EmitterWriter, highlight_lines, Level}; + use codemap::{mk_sp, CodeMap, BytePos}; + use std::sync::{Arc, Mutex}; + use std::io::{self, Write}; + use std::str::from_utf8; + + // Diagnostic doesn't align properly in span where line number increases by one digit + #[test] + fn test_hilight_suggestion_issue_11715() { + struct Sink(Arc>>); + impl Write for Sink { + fn write(&mut self, data: &[u8]) -> io::Result { + Write::write(&mut *self.0.lock().unwrap(), data) + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } + } + let data = Arc::new(Mutex::new(Vec::new())); + let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None); + let cm = CodeMap::new(); + let content = "abcdefg + koksi + line3 + line4 + cinq + line6 + line7 + line8 + line9 + line10 + e-lä-vän + tolv + dreizehn + "; + let file = cm.new_filemap("dummy.txt".to_string(), content.to_string()); + for (i, b) in content.bytes().enumerate() { + if b == b'\n' { + file.next_line(BytePos(i as u32)); + } + } + let start = file.lines.borrow()[7]; + let end = file.lines.borrow()[11]; + let sp = mk_sp(start, end); + let lvl = Level::Error; + println!("span_to_lines"); + let lines = cm.span_to_lines(sp); + println!("highlight_lines"); + highlight_lines(&mut ew, &cm, sp, lvl, lines).unwrap(); + println!("done"); + let vec = data.lock().unwrap().clone(); + let vec: &[u8] = &vec; + println!("{}", from_utf8(vec).unwrap()); + assert_eq!(vec, "dummy.txt: 8 \n\ + dummy.txt: 9 \n\ + dummy.txt:10 \n\ + dummy.txt:11 \n\ + dummy.txt:12 \n".as_bytes()); + } +} From 274bb24efdbeed0ab1a91f3c02f86551ef16eac7 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 24 Jun 2015 16:22:09 +0200 Subject: [PATCH 010/160] StrSearcher: Explicitly separate the long and short cases This is needed to not drop performance, after the trait-based changes. Force separate versions of the next method to be generated for the short and long period cases. --- src/libcore/str/pattern.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 6d68615a8cfd7..dccdaa9120d10 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -628,7 +628,7 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { } } - #[inline] + #[inline(always)] fn next_match(&mut self) -> Option<(usize, usize)> { match self.searcher { StrSearcherImpl::Empty(..) => { @@ -642,9 +642,15 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { } StrSearcherImpl::TwoWay(ref mut searcher) => { let is_long = searcher.memory == usize::MAX; - searcher.next::(self.haystack.as_bytes(), - self.needle.as_bytes(), - is_long) + if is_long { + searcher.next::(self.haystack.as_bytes(), + self.needle.as_bytes(), + true) + } else { + searcher.next::(self.haystack.as_bytes(), + self.needle.as_bytes(), + false) + } } } } @@ -854,7 +860,7 @@ impl TwoWaySearcher { // left to right. If v matches, we try to match u by scanning right to left. // How far we can jump when we encounter a mismatch is all based on the fact // that (u, v) is a critical factorization for the needle. - #[inline] + #[inline(always)] fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> S::Output where S: TwoWayStrategy From 225b116829ef76b72f01c2ebf718259c20aa7e14 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 20 May 2015 19:18:03 +1000 Subject: [PATCH 011/160] Make `align_of` behave like `min_align_of`. This removes a footgun, since it is a reasonable assumption to make that pointers to `T` will be aligned to `align_of::()`. This also matches the behaviour of C/C++. `min_align_of` is now deprecated. Closes #21611. --- src/liballoc/arc.rs | 6 +++--- src/liballoc/rc.rs | 8 ++++---- src/libarena/lib.rs | 12 ++++++------ src/libcollections/btree/node.rs | 10 +++++----- src/libcollections/vec.rs | 14 +++++++------- src/libcollections/vec_deque.rs | 8 ++++---- src/libcore/mem.rs | 20 +++++++------------- src/libstd/collections/hash/table.rs | 22 +++++++++++----------- 8 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 7bfeaec36d729..dd9c1d1fd1885 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -77,7 +77,7 @@ use core::atomic; use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; use core::fmt; use core::cmp::Ordering; -use core::mem::{min_align_of_val, size_of_val}; +use core::mem::{align_of_val, size_of_val}; use core::intrinsics::drop_in_place; use core::mem; use core::nonzero::NonZero; @@ -241,7 +241,7 @@ impl Arc { if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - deallocate(ptr as *mut u8, size_of_val(&*ptr), min_align_of_val(&*ptr)) + deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr)) } } } @@ -565,7 +565,7 @@ impl Drop for Weak { atomic::fence(Acquire); unsafe { deallocate(ptr as *mut u8, size_of_val(&*ptr), - min_align_of_val(&*ptr)) } + align_of_val(&*ptr)) } } } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d5b6c86ef359a..3dfafd0a378b9 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -162,7 +162,7 @@ use core::fmt; use core::hash::{Hasher, Hash}; use core::intrinsics::{assume, drop_in_place}; use core::marker::{self, Unsize}; -use core::mem::{self, min_align_of, size_of, min_align_of_val, size_of_val, forget}; +use core::mem::{self, align_of, size_of, align_of_val, size_of_val, forget}; use core::nonzero::NonZero; use core::ops::{CoerceUnsized, Deref}; use core::ptr; @@ -246,7 +246,7 @@ impl Rc { // destruct the box and skip our Drop // we can ignore the refcounts because we know we're unique deallocate(*rc._ptr as *mut u8, size_of::>(), - min_align_of::>()); + align_of::>()); forget(rc); Ok(val) } @@ -496,7 +496,7 @@ impl Drop for Rc { if self.weak() == 0 { deallocate(ptr as *mut u8, size_of_val(&*ptr), - min_align_of_val(&*ptr)) + align_of_val(&*ptr)) } } } @@ -805,7 +805,7 @@ impl Drop for Weak { // the strong pointers have disappeared. if self.weak() == 0 { deallocate(ptr as *mut u8, size_of_val(&*ptr), - min_align_of_val(&*ptr)) + align_of_val(&*ptr)) } } } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 109ad8a942c84..4d064b16ad027 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -244,7 +244,7 @@ impl<'longer_than_self> Arena<'longer_than_self> { fn alloc_copy(&self, op: F) -> &mut T where F: FnOnce() -> T { unsafe { let ptr = self.alloc_copy_inner(mem::size_of::(), - mem::min_align_of::()); + mem::align_of::()); let ptr = ptr as *mut T; ptr::write(&mut (*ptr), op()); return &mut *ptr; @@ -300,7 +300,7 @@ impl<'longer_than_self> Arena<'longer_than_self> { let tydesc = get_tydesc::(); let (ty_ptr, ptr) = self.alloc_noncopy_inner(mem::size_of::(), - mem::min_align_of::()); + mem::align_of::()); let ty_ptr = ty_ptr as *mut usize; let ptr = ptr as *mut T; // Write in our tydesc along with a bit indicating that it @@ -393,7 +393,7 @@ struct TypedArenaChunk { fn calculate_size(capacity: usize) -> usize { let mut size = mem::size_of::>(); - size = round_up(size, mem::min_align_of::()); + size = round_up(size, mem::align_of::()); let elem_size = mem::size_of::(); let elems_size = elem_size.checked_mul(capacity).unwrap(); size = size.checked_add(elems_size).unwrap(); @@ -405,7 +405,7 @@ impl TypedArenaChunk { unsafe fn new(next: *mut TypedArenaChunk, capacity: usize) -> *mut TypedArenaChunk { let size = calculate_size::(capacity); - let chunk = allocate(size, mem::min_align_of::>()) + let chunk = allocate(size, mem::align_of::>()) as *mut TypedArenaChunk; if chunk.is_null() { alloc::oom() } (*chunk).next = next; @@ -431,7 +431,7 @@ impl TypedArenaChunk { let size = calculate_size::(self.capacity); let self_ptr: *mut TypedArenaChunk = self; deallocate(self_ptr as *mut u8, size, - mem::min_align_of::>()); + mem::align_of::>()); if !next.is_null() { let capacity = (*next).capacity; (*next).destroy(capacity); @@ -444,7 +444,7 @@ impl TypedArenaChunk { let this: *const TypedArenaChunk = self; unsafe { mem::transmute(round_up(this.offset(1) as usize, - mem::min_align_of::())) + mem::align_of::())) } } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 2d8335d373473..4d76a986700a2 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -163,12 +163,12 @@ fn test_offset_calculation() { } fn calculate_allocation_generic(capacity: usize, is_leaf: bool) -> (usize, usize) { - let (keys_size, keys_align) = (capacity * mem::size_of::(), mem::min_align_of::()); - let (vals_size, vals_align) = (capacity * mem::size_of::(), mem::min_align_of::()); + let (keys_size, keys_align) = (capacity * mem::size_of::(), mem::align_of::()); + let (vals_size, vals_align) = (capacity * mem::size_of::(), mem::align_of::()); let (edges_size, edges_align) = if is_leaf { (0, 1) } else { - ((capacity + 1) * mem::size_of::>(), mem::min_align_of::>()) + ((capacity + 1) * mem::size_of::>(), mem::align_of::>()) }; calculate_allocation( @@ -181,11 +181,11 @@ fn calculate_allocation_generic(capacity: usize, is_leaf: bool) -> (usize, fn calculate_offsets_generic(capacity: usize, is_leaf: bool) -> (usize, usize) { let keys_size = capacity * mem::size_of::(); let vals_size = capacity * mem::size_of::(); - let vals_align = mem::min_align_of::(); + let vals_align = mem::align_of::(); let edges_align = if is_leaf { 1 } else { - mem::min_align_of::>() + mem::align_of::>() }; calculate_offsets( diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 54528c50f1d1e..6918668dcaaec 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -219,7 +219,7 @@ impl Vec { } else { let size = capacity.checked_mul(mem::size_of::()) .expect("capacity overflow"); - let ptr = unsafe { allocate(size, mem::min_align_of::()) }; + let ptr = unsafe { allocate(size, mem::align_of::()) }; if ptr.is_null() { ::alloc::oom() } unsafe { Vec::from_raw_parts(ptr as *mut T, 0, capacity) } } @@ -393,7 +393,7 @@ impl Vec { let ptr = reallocate(*self.ptr as *mut u8, self.cap * mem::size_of::(), self.len * mem::size_of::(), - mem::min_align_of::()) as *mut T; + mem::align_of::()) as *mut T; if ptr.is_null() { ::alloc::oom() } self.ptr = Unique::new(ptr); } @@ -866,9 +866,9 @@ impl Vec { // FIXME: Assert statically that the types `T` and `U` have the // same minimal alignment in case they are not zero-sized. - // These asserts are necessary because the `min_align_of` of the + // These asserts are necessary because the `align_of` of the // types are passed to the allocator by `Vec`. - assert!(mem::min_align_of::() == mem::min_align_of::()); + assert!(mem::align_of::() == mem::align_of::()); // This `as isize` cast is safe, because the size of the elements of the // vector is not 0, and: @@ -1269,9 +1269,9 @@ impl Vec { #[inline(never)] unsafe fn alloc_or_realloc(ptr: *mut T, old_size: usize, size: usize) -> *mut T { if old_size == 0 { - allocate(size, mem::min_align_of::()) as *mut T + allocate(size, mem::align_of::()) as *mut T } else { - reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::()) as *mut T + reallocate(ptr as *mut u8, old_size, size, mem::align_of::()) as *mut T } } @@ -1280,7 +1280,7 @@ unsafe fn dealloc(ptr: *mut T, len: usize) { if mem::size_of::() != 0 { deallocate(ptr as *mut u8, len * mem::size_of::(), - mem::min_align_of::()) + mem::align_of::()) } } diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index edcd1008747fd..ed47c06e7cd08 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -67,7 +67,7 @@ impl Drop for VecDeque { if mem::size_of::() != 0 { heap::deallocate(*self.ptr as *mut u8, self.cap * mem::size_of::(), - mem::min_align_of::()) + mem::align_of::()) } } } @@ -172,7 +172,7 @@ impl VecDeque { let ptr = unsafe { if mem::size_of::() != 0 { - let ptr = heap::allocate(size, mem::min_align_of::()) as *mut T;; + let ptr = heap::allocate(size, mem::align_of::()) as *mut T;; if ptr.is_null() { ::alloc::oom() } Unique::new(ptr) } else { @@ -340,7 +340,7 @@ impl VecDeque { let ptr = heap::reallocate(*self.ptr as *mut u8, old, new, - mem::min_align_of::()) as *mut T; + mem::align_of::()) as *mut T; if ptr.is_null() { ::alloc::oom() } self.ptr = Unique::new(ptr); } @@ -460,7 +460,7 @@ impl VecDeque { let ptr = heap::reallocate(*self.ptr as *mut u8, old, new_size, - mem::min_align_of::()) as *mut T; + mem::align_of::()) as *mut T; if ptr.is_null() { ::alloc::oom() } self.ptr = Unique::new(ptr); } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 15e7cdbde408d..4177e0666e3a5 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -155,6 +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")] pub fn min_align_of() -> usize { unsafe { intrinsics::min_align_of::() } } @@ -170,14 +171,14 @@ 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")] pub fn min_align_of_val(val: &T) -> usize { unsafe { intrinsics::min_align_of_val(val) } } /// Returns the alignment in memory for a type. /// -/// This function will return the alignment, in bytes, of a type in memory. If the alignment -/// returned is adhered to, then the type is guaranteed to function properly. +/// This is the alignment used for struct fields. It may be smaller than the preferred alignment. /// /// # Examples /// @@ -189,17 +190,10 @@ pub fn min_align_of_val(val: &T) -> usize { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn align_of() -> usize { - // We use the preferred alignment as the default alignment for a type. This - // appears to be what clang migrated towards as well: - // - // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html - unsafe { intrinsics::pref_align_of::() } + unsafe { intrinsics::min_align_of::() } } -/// Returns the alignment of the type of the value that `_val` points to. -/// -/// This is similar to `align_of`, but function will properly handle types such as trait objects -/// (in the future), returning the alignment for an arbitrary value at runtime. +/// Returns the ABI-required minimum alignment of the type of the value that `val` points to /// /// # Examples /// @@ -210,8 +204,8 @@ pub fn align_of() -> usize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub fn align_of_val(_val: &T) -> usize { - align_of::() +pub fn align_of_val(val: &T) -> usize { + unsafe { intrinsics::min_align_of_val(val) } } /// Creates a value initialized to zero. diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 2616bc5278589..349462aebe31b 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -15,7 +15,7 @@ use cmp; use hash::{Hash, Hasher}; use iter::{Iterator, ExactSizeIterator}; use marker::{Copy, Send, Sync, Sized, self}; -use mem::{min_align_of, size_of}; +use mem::{align_of, size_of}; use mem; use num::wrapping::OverflowingOps; use ops::{Deref, DerefMut, Drop}; @@ -553,9 +553,9 @@ fn calculate_allocation(hash_size: usize, hash_align: usize, vals_align); let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size); - let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align)); + let align = cmp::max(hash_align, cmp::max(keys_align, vals_align)); - (min_align, hash_offset, end_of_vals, oflo || oflo2) + (align, hash_offset, end_of_vals, oflo || oflo2) } #[test] @@ -597,9 +597,9 @@ impl RawTable { // factored out into a different function. let (malloc_alignment, hash_offset, size, oflo) = calculate_allocation( - hashes_size, min_align_of::(), - keys_size, min_align_of::< K >(), - vals_size, min_align_of::< V >()); + hashes_size, align_of::(), + keys_size, align_of::< K >(), + vals_size, align_of::< V >()); assert!(!oflo, "capacity overflow"); @@ -630,8 +630,8 @@ impl RawTable { let buffer = *self.hashes as *mut u8; let (keys_offset, vals_offset, oflo) = calculate_offsets(hashes_size, - keys_size, min_align_of::(), - min_align_of::()); + keys_size, align_of::(), + align_of::()); debug_assert!(!oflo, "capacity overflow"); unsafe { RawBucket { @@ -1005,9 +1005,9 @@ impl Drop for RawTable { let keys_size = self.capacity * size_of::(); let vals_size = self.capacity * size_of::(); let (align, _, size, oflo) = - calculate_allocation(hashes_size, min_align_of::(), - keys_size, min_align_of::(), - vals_size, min_align_of::()); + calculate_allocation(hashes_size, align_of::(), + keys_size, align_of::(), + vals_size, align_of::()); debug_assert!(!oflo, "should be impossible"); From 1ec520a531b544079690f8178a7660421e8a713a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 19 Jun 2015 14:51:29 -0700 Subject: [PATCH 012/160] 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 013/160] 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 014/160] 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 015/160] 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 016/160] 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 017/160] 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 018/160] 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 35abf86a1b6ac40d6a8478b9a7bc9da1ebf7b96f Mon Sep 17 00:00:00 2001 From: Adam Heins Date: Thu, 25 Jun 2015 19:29:23 -0400 Subject: [PATCH 019/160] Improve sentence flow. --- src/doc/trpl/link-args.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/link-args.md b/src/doc/trpl/link-args.md index ee5159afb8e6f..cdaef6cd9b510 100644 --- a/src/doc/trpl/link-args.md +++ b/src/doc/trpl/link-args.md @@ -17,7 +17,7 @@ Note that this feature is currently hidden behind the `feature(link_args)` gate because this is not a sanctioned way of performing linking. Right now rustc shells out to the system linker, so it makes sense to provide extra command line arguments, but this will not always be the case. In the future rustc may use -LLVM directly to link native libraries in which case `link_args` will have no +LLVM directly to link native libraries, in which case `link_args` will have no meaning. It is highly recommended to *not* use this attribute, and rather use the more From 44bccd88427e0f4b6a24d82462d03949ac54f647 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 23 Jun 2015 11:50:50 -0700 Subject: [PATCH 020/160] Rename AsPredicate to ToPredicate in order to match naming conventions --- src/librustc/metadata/tydecode.rs | 12 ++++---- src/librustc/middle/implicator.rs | 4 +-- src/librustc/middle/traits/error_reporting.rs | 6 ++-- src/librustc/middle/traits/project.rs | 8 ++--- src/librustc/middle/traits/select.rs | 12 ++++---- src/librustc/middle/traits/util.rs | 8 ++--- src/librustc/middle/ty.rs | 30 +++++++++---------- src/librustc_typeck/astconv.rs | 10 +++---- src/librustc_typeck/check/method/mod.rs | 4 +-- src/librustc_typeck/check/method/suggest.rs | 4 +-- src/librustc_typeck/collect.rs | 16 +++++----- 11 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 3907b0624b42e..63afdc8b0fcf1 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, AsPredicate, Ty}; +use middle::ty::{self, ToPredicate, Ty}; use std::str; use syntax::abi; @@ -775,14 +775,14 @@ fn parse_predicate_<'a,'tcx, F>(st: &mut PState<'a, 'tcx>, F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, { match next(st) { - 't' => ty::Binder(parse_trait_ref_(st, conv)).as_predicate(), + 't' => ty::Binder(parse_trait_ref_(st, conv)).to_predicate(), 'e' => ty::Binder(ty::EquatePredicate(parse_ty_(st, conv), - parse_ty_(st, conv))).as_predicate(), + parse_ty_(st, conv))).to_predicate(), 'r' => ty::Binder(ty::OutlivesPredicate(parse_region_(st, conv), - parse_region_(st, conv))).as_predicate(), + parse_region_(st, conv))).to_predicate(), 'o' => ty::Binder(ty::OutlivesPredicate(parse_ty_(st, conv), - parse_region_(st, conv))).as_predicate(), - 'p' => ty::Binder(parse_projection_predicate_(st, conv)).as_predicate(), + parse_region_(st, conv))).to_predicate(), + 'p' => ty::Binder(parse_projection_predicate_(st, conv)).to_predicate(), c => panic!("Encountered invalid character in metadata: {}", c) } } diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index bbfa3c9fdfa3f..f87b121eb224d 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -13,7 +13,7 @@ use middle::infer::{InferCtxt, GenericKind}; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, ToPolyTraitRef, AsPredicate, Ty}; +use middle::ty::{self, RegionEscape, ToPolyTraitRef, ToPredicate, Ty}; use middle::ty_fold::{TypeFoldable, TypeFolder}; use syntax::ast; @@ -445,7 +445,7 @@ pub fn object_region_bounds<'tcx>( let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs))); let mut predicates = others.to_predicates(tcx, open_ty); - predicates.extend(trait_refs.iter().map(|t| t.as_predicate())); + predicates.extend(trait_refs.iter().map(|t| t.to_predicate())); ty::required_region_bounds(tcx, open_ty, predicates) } diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 8618f52152907..dc7e4f9c57114 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, AsPredicate, ReferencesError, ToPolyTraitRef, TraitRef}; +use middle::ty::{self, ToPredicate, ReferencesError, ToPolyTraitRef, TraitRef}; use middle::ty_fold::TypeFoldable; use std::collections::HashMap; use std::fmt; @@ -464,7 +464,7 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, span_note!(tcx.sess, cause_span, "required because it appears within the type `{}`", parent_trait_ref.0.self_ty()); - let parent_predicate = parent_trait_ref.as_predicate(); + let parent_predicate = parent_trait_ref.to_predicate(); note_obligation_cause_code(infcx, &parent_predicate, cause_span, &*data.parent_code); } ObligationCauseCode::ImplDerivedObligation(ref data) => { @@ -473,7 +473,7 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, "required because of the requirements on the impl of `{}` for `{}`", parent_trait_ref, parent_trait_ref.0.self_ty()); - let parent_predicate = parent_trait_ref.as_predicate(); + let parent_predicate = parent_trait_ref.to_predicate(); note_obligation_cause_code(infcx, &parent_predicate, cause_span, &*data.parent_code); } ObligationCauseCode::CompareImplMethodObligation => { diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 3ac58dafa4a7a..cb5440fbf9000 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -23,7 +23,7 @@ use super::util; use middle::infer; use middle::subst::Subst; -use middle::ty::{self, AsPredicate, ReferencesError, RegionEscape, +use middle::ty::{self, ToPredicate, ReferencesError, RegionEscape, HasProjectionTypes, ToPolyTraitRef, Ty}; use middle::ty_fold::{self, TypeFoldable, TypeFolder}; use syntax::parse::token; @@ -336,7 +336,7 @@ pub fn normalize_projection_type<'a,'b,'tcx>( projection_ty: projection_ty, ty: ty_var }); - let obligation = Obligation::with_depth(cause, depth+1, projection.as_predicate()); + let obligation = Obligation::with_depth(cause, depth+1, projection.to_predicate()); Normalized { value: ty_var, obligations: vec!(obligation) @@ -432,7 +432,7 @@ fn normalize_to_error<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, let trait_ref = projection_ty.trait_ref.to_poly_trait_ref(); let trait_obligation = Obligation { cause: cause, recursion_depth: depth, - predicate: trait_ref.as_predicate() }; + predicate: trait_ref.to_predicate() }; Normalized { value: selcx.tcx().types.err, obligations: vec!(trait_obligation) @@ -646,7 +646,7 @@ fn assemble_candidates_from_object_type<'cx,'tcx>( }; let projection_bounds = data.projection_bounds_with_self_ty(selcx.tcx(), object_ty); let env_predicates = projection_bounds.iter() - .map(|p| p.as_predicate()) + .map(|p| p.to_predicate()) .collect(); let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates); assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref, diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 1653cac68e6e0..4246d5f0e83f8 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, AsPredicate, RegionEscape, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty}; use middle::infer; use middle::infer::{InferCtxt, TypeFreshener}; use middle::ty_fold::TypeFoldable; @@ -2465,7 +2465,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { data_b.bounds.region_bound); nested.push(Obligation::with_depth(cause, obligation.recursion_depth + 1, - ty::Binder(outlives).as_predicate())); + ty::Binder(outlives).to_predicate())); } // T -> Trait. @@ -2485,7 +2485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; // Create the obligation for casting from T to Trait. - push(data.principal_trait_ref_with_self_ty(tcx, source).as_predicate()); + push(data.principal_trait_ref_with_self_ty(tcx, source).to_predicate()); // We can only make objects from sized types. let mut builtin_bounds = data.bounds.builtin_bounds; @@ -2497,7 +2497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // for the Send check.) for bound in &builtin_bounds { if let Ok(tr) = util::trait_ref_for_builtin_bound(tcx, bound, source) { - push(tr.as_predicate()); + push(tr.to_predicate()); } else { return Err(Unimplemented); } @@ -2505,14 +2505,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Create obligations for the projection predicates. for bound in data.projection_bounds_with_self_ty(tcx, source) { - push(bound.as_predicate()); + push(bound.to_predicate()); } // If the type is `Foo+'a`, ensures that the type // being cast to `Foo+'a` outlives `'a`: let outlives = ty::OutlivesPredicate(source, data.bounds.region_bound); - push(ty::Binder(outlives).as_predicate()); + push(ty::Binder(outlives).to_predicate()); } // [T; n] -> [T]. diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 54bcd9d7e66ab..7b4a59b5427c1 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -10,7 +10,7 @@ use middle::subst::Substs; use middle::infer::InferCtxt; -use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef}; +use middle::ty::{self, Ty, ToPredicate, ToPolyTraitRef}; use std::fmt; use syntax::ast; use syntax::codemap::Span; @@ -83,7 +83,7 @@ pub fn elaborate_trait_ref<'cx, 'tcx>( trait_ref: ty::PolyTraitRef<'tcx>) -> Elaborator<'cx, 'tcx> { - elaborate_predicates(tcx, vec![trait_ref.as_predicate()]) + elaborate_predicates(tcx, vec![trait_ref.to_predicate()]) } pub fn elaborate_trait_refs<'cx, 'tcx>( @@ -92,7 +92,7 @@ pub fn elaborate_trait_refs<'cx, 'tcx>( -> Elaborator<'cx, 'tcx> { let predicates = trait_refs.iter() - .map(|trait_ref| trait_ref.as_predicate()) + .map(|trait_ref| trait_ref.to_predicate()) .collect(); elaborate_predicates(tcx, predicates) } @@ -347,7 +347,7 @@ pub fn predicate_for_trait_ref<'tcx>( Obligation { cause: cause, recursion_depth: recursion_depth, - predicate: trait_ref.as_predicate(), + predicate: trait_ref.to_predicate(), } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e32da7837ec17..3f84d433e9cb5 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1873,7 +1873,7 @@ impl BuiltinBounds { self_ty: Ty<'tcx>) -> Vec> { self.iter().filter_map(|builtin_bound| match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, self_ty) { - Ok(trait_ref) => Some(trait_ref.as_predicate()), + Ok(trait_ref) => Some(trait_ref.to_predicate()), Err(ErrorReported) => { None } } ).collect() @@ -2390,12 +2390,12 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> { } } -pub trait AsPredicate<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx>; +pub trait ToPredicate<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx>; } -impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx> { // we're about to add a binder, so let's check that we don't // accidentally capture anything, or else that might be some // weird debruijn accounting. @@ -2407,32 +2407,32 @@ impl<'tcx> AsPredicate<'tcx> for TraitRef<'tcx> { } } -impl<'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx> { ty::Predicate::Trait(self.to_poly_trait_predicate()) } } -impl<'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for PolyEquatePredicate<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx> { Predicate::Equate(self.clone()) } } -impl<'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate { + fn to_predicate(&self) -> Predicate<'tcx> { Predicate::RegionOutlives(self.clone()) } } -impl<'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx> { Predicate::TypeOutlives(self.clone()) } } -impl<'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> { - fn as_predicate(&self) -> Predicate<'tcx> { +impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { + fn to_predicate(&self) -> Predicate<'tcx> { Predicate::Projection(self.clone()) } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index da7c262d63a65..d4ecdc65eadb0 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, AsPredicate}; +use middle::ty::{self, RegionEscape, Ty, ToPredicate}; use middle::ty_fold; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope, ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope}; @@ -2213,7 +2213,7 @@ impl<'tcx> Bounds<'tcx> { for builtin_bound in &self.builtin_bounds { match traits::trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty) { - Ok(trait_ref) => { vec.push(trait_ref.as_predicate()); } + Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); } Err(ErrorReported) => { } } } @@ -2222,15 +2222,15 @@ impl<'tcx> Bounds<'tcx> { // account for the binder being introduced below; no need to shift `param_ty` // because, at present at least, it can only refer to early-bound regions let region_bound = ty_fold::shift_region(region_bound, 1); - vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).as_predicate()); + vec.push(ty::Binder(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate()); } for bound_trait_ref in &self.trait_bounds { - vec.push(bound_trait_ref.as_predicate()); + vec.push(bound_trait_ref.to_predicate()); } for projection in &self.projection_bounds { - vec.push(projection.as_predicate()); + vec.push(projection.to_predicate()); } vec diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e5a57fa9c138e..30fb830495e77 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -16,7 +16,7 @@ use middle::def; use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod}; use middle::subst; use middle::traits; -use middle::ty::{self, AsPredicate, ToPolyTraitRef, TraitRef}; +use middle::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef}; use middle::infer; use syntax::ast::DefId; @@ -192,7 +192,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let poly_trait_ref = trait_ref.to_poly_trait_ref(); let obligation = traits::Obligation::misc(span, fcx.body_id, - poly_trait_ref.as_predicate()); + poly_trait_ref.to_predicate()); // Now we want to know if this can be matched let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 2325b9852c73d..a1d1ddff45aae 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, AsPredicate}; +use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate}; use middle::def; use middle::lang_items::FnOnceTraitLangItem; use middle::subst::Substs; @@ -101,7 +101,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let poly_trait_ref = trait_ref.to_poly_trait_ref(); let obligation = Obligation::misc(span, fcx.body_id, - poly_trait_ref.as_predicate()); + poly_trait_ref.to_predicate()); let mut selcx = SelectionContext::new(infcx, fcx); if selcx.evaluate_obligation(&obligation) { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 22926126f7ab3..a873900b5fc60 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -72,7 +72,7 @@ use middle::free_region::FreeRegionMap; use middle::region; use middle::resolve_lifetime; use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace}; -use middle::ty::{AsPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}; +use middle::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}; use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; use middle::infer; @@ -1171,7 +1171,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, let trait_def = trait_def_of_item(ccx, item); let self_predicate = ty::GenericPredicates { predicates: VecPerParamSpace::new(vec![], - vec![trait_def.trait_ref.as_predicate()], + vec![trait_def.trait_ref.to_predicate()], vec![]) }; let scope = &(generics, &self_predicate); @@ -1355,7 +1355,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) // Add in a predicate that `Self:Trait` (where `Trait` is the // current trait). This is needed for builtin bounds. - let self_predicate = trait_def.trait_ref.to_poly_trait_ref().as_predicate(); + let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate(); base_predicates.predicates.push(SelfSpace, self_predicate); // add in the explicit where-clauses @@ -1767,7 +1767,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, for bound in ¶m.bounds { let bound_region = ast_region_to_region(ccx.tcx, bound); let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region)); - result.predicates.push(space, outlives.as_predicate()); + result.predicates.push(space, outlives.to_predicate()); } } @@ -1791,10 +1791,10 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, poly_trait_ref, &mut projections); - result.predicates.push(space, trait_ref.as_predicate()); + result.predicates.push(space, trait_ref.to_predicate()); for projection in &projections { - result.predicates.push(space, projection.as_predicate()); + result.predicates.push(space, projection.to_predicate()); } } @@ -2028,8 +2028,8 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>, let mut projections = Vec::new(); let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections); projections.into_iter() - .map(|p| p.as_predicate()) - .chain(Some(pred.as_predicate())) + .map(|p| p.to_predicate()) + .chain(Some(pred.to_predicate())) .collect() } ast::RegionTyParamBound(ref lifetime) => { From fd9b2caa5f6792a87a4c99bbbd6abed303a8ab5c Mon Sep 17 00:00:00 2001 From: OGINO Masanori Date: Fri, 26 Jun 2015 11:09:15 +0900 Subject: [PATCH 021/160] 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 022/160] 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 023/160] 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 024/160] 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 025/160] 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 026/160] 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 027/160] 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 6c88a2833d6982b1632b623901e3c30245377550 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Jun 2015 13:39:39 +0200 Subject: [PATCH 028/160] Add E0091 error explanation Part of #24407. cc @michaelsproul --- src/librustc_typeck/diagnostics.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 5a7f3026ee0dc..829909db6d686 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -959,6 +959,20 @@ fn main() { ``` "##, +E0091: r##" +You gave an unnecessary type parameter. Erroneous code example: + +``` +type Foo = u32; // error: type parameter `T` is unused +``` + +Please check you didn't write to many type parameter. Example: + +``` +type Foo = u32; // ok! +``` +"##, + E0106: r##" This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the @@ -1587,7 +1601,6 @@ register_diagnostics! { E0086, E0088, E0090, - E0091, E0092, E0093, E0094, 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 029/160] 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 030/160] 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 0d74311e2baa73d883aec065dd300d48d34a0158 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Jun 2015 13:53:01 +0200 Subject: [PATCH 031/160] Add E0088 error explanation --- src/librustc_typeck/diagnostics.rs | 51 ++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 829909db6d686..bf2913c83a152 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -934,6 +934,51 @@ The number of supplied parameters much exactly match the number of defined type parameters. "##, +E0088: r##" +You gave too many lifetime parameters. Erroneous code example: + +``` +fn f() {} + +fn main() { + f::<'static>() // error: too many lifetime parameters provided +} +``` + +Please check you give the right number of lifetime parameters. Example: + +``` +fn f() {} + +fn main() { + f() // ok! +} +``` + +It's also important to note that the Rust compiler can generally +determine the lifetime by itself. Example: + +``` +struct Foo { + value: String +} + +impl Foo { + // it can be written like this + fn get_value<'a>(&'a self) -> &'a str { &self.value } + // but the compiler works fine with this too: + fn without_lifetime(&self) -> &str { &self.value } +} + +fn main() { + let f = Foo { value: "hello".to_owned() }; + + println!("{}", f.get_value()); + println!("{}", f.without_lifetime()); +} +``` +"##, + E0089: r##" Not enough type parameters were supplied for a function. For example: @@ -960,13 +1005,14 @@ fn main() { "##, E0091: r##" -You gave an unnecessary type parameter. Erroneous code example: +You gave an unnecessary type parameter in a type alias. Erroneous code +example: ``` type Foo = u32; // error: type parameter `T` is unused ``` -Please check you didn't write to many type parameter. Example: +Please check you didn't write too many type parameters. Example: ``` type Foo = u32; // ok! @@ -1599,7 +1645,6 @@ register_diagnostics! { E0077, E0085, E0086, - E0088, E0090, E0092, E0093, From c98e46c7cabd44a306ac52c95d961bcebd899b0f Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Fri, 26 Jun 2015 11:44:02 -0700 Subject: [PATCH 032/160] 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 033/160] 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 034/160] 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 035/160] 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 036/160] 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 d73cc565656c76cb5270934caaafa78760cc565b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Jun 2015 14:23:53 +0200 Subject: [PATCH 037/160] Add E0109 error explanation --- src/librustc/diagnostics.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 034d3ee1604a0..b15bcb7b75862 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -360,6 +360,22 @@ integer type: http://doc.rust-lang.org/reference.html#ffi-attributes "##, +E0109: r##" +You tried to give type parameter to a type which doesn't need it. Erroneous +code example: + +``` +type X = u32; // error: type parameters are not allowed on this type +``` + +Please check you actually used the good type or check again its definition. +Example: + +``` +type X = u32; // ok! +``` +"##, + E0133: r##" Using unsafe functionality, such as dereferencing raw pointers and calling functions via FFI or marked as unsafe, is potentially dangerous and disallowed @@ -1055,7 +1071,6 @@ register_diagnostics! { E0017, E0022, E0038, - E0109, E0110, E0134, E0135, From ca0601a1c23793dd4ad3f65441dd1064f1b47545 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 27 Jun 2015 15:25:15 +0200 Subject: [PATCH 038/160] 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 7d0198d5d2cc13d5030e42ccd1109adebea25b34 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 27 Jun 2015 15:45:48 +0200 Subject: [PATCH 039/160] test: fix some indents --- src/test/compile-fail/no-send-res-ports.rs | 2 +- src/test/run-pass/issue-2718.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index b80d15bb6f3c6..60b2d22079e2c 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -20,7 +20,7 @@ fn main() { _x: Port<()>, } - impl Drop for foo { + impl Drop for foo { fn drop(&mut self) {} } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 1a139bdf0fb27..2da2f1e82a693 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -165,7 +165,7 @@ pub mod pipes { p: Option<*const packet>, } - impl Drop for send_packet { + impl Drop for send_packet { fn drop(&mut self) { unsafe { if self.p != None { @@ -194,7 +194,7 @@ pub mod pipes { p: Option<*const packet>, } - impl Drop for recv_packet { + impl Drop for recv_packet { fn drop(&mut self) { unsafe { if self.p != None { From d6159b7fe0ce668b6875d4551019d3946ed8388c Mon Sep 17 00:00:00 2001 From: Christian Persson Date: Sat, 27 Jun 2015 16:58:18 +0200 Subject: [PATCH 040/160] Clarifying deallocation order of resources within same scope --- src/doc/trpl/references-and-borrowing.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md index b27db2ab7bea8..d1d3063138e7e 100644 --- a/src/doc/trpl/references-and-borrowing.md +++ b/src/doc/trpl/references-and-borrowing.md @@ -336,7 +336,9 @@ In other words, `y` is only valid for the scope where `x` exists. As soon as the borrow ‘doesn’t live long enough’ because it’s not valid for the right amount of time. -The same problem occurs when the reference is declared _before_ the variable it refers to: +The same problem occurs when the reference is declared _before_ the variable it +refers to. This is because resources within the same scope are freed in the +opposite order they were declared: ```rust,ignore let y: &i32; @@ -369,3 +371,6 @@ statement 1 at 3:14 println!("{}", y); } ``` + +In the above example, `y` is declared before `x`, meaning that `y` lives longer +than `x`, which is not allowed. From ae36d4f72ad8b34343dba391f2f239ff29840117 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jun 2015 15:30:00 -0700 Subject: [PATCH 041/160] 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 042/160] 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 043/160] 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 044/160] 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 045/160] 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 046/160] 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 047/160] 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 048/160] 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 049/160] 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 050/160] 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 051/160] 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 052/160] 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 053/160] 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 054/160] 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 From 14e3d26b8a19c56c2c2b2b99ee870a9002bb70e0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 28 Jun 2015 00:20:59 +0200 Subject: [PATCH 055/160] Add E0110 error explanation --- src/librustc/diagnostics.rs | 21 +++++++++++++++++++-- src/librustc_typeck/diagnostics.rs | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b15bcb7b75862..8d51674ab13e5 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -361,13 +361,31 @@ http://doc.rust-lang.org/reference.html#ffi-attributes "##, E0109: r##" -You tried to give type parameter to a type which doesn't need it. Erroneous +You tried to give type parameter to a type which doesn't need it. Erroneous code example: ``` type X = u32; // error: type parameters are not allowed on this type ``` +Please check that you used the correct type and recheck its definition. Perhaps +it doesn't need the type parameter. +Example: + +``` +type X = u32; // ok! +``` +"##, + +E0110: r##" +You tried to give a lifetime parameter to a type which doesn't need it. +Erroneous code example: + +``` +type X = u32<'static>; // error: lifetime parameters are not allowed on + // this type +``` + Please check you actually used the good type or check again its definition. Example: @@ -1071,7 +1089,6 @@ register_diagnostics! { E0017, E0022, E0038, - E0110, E0134, E0135, E0136, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index bf2913c83a152..d4977c5d3941c 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1010,12 +1010,15 @@ example: ``` type Foo = u32; // error: type parameter `T` is unused +// or: +type Foo = Box; // error: type parameter `B` is unused ``` Please check you didn't write too many type parameters. Example: ``` type Foo = u32; // ok! +type Foo = Box; // ok! ``` "##, From b44253067165949d0d70db95c21771a6aeac718f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Jun 2015 10:03:02 +0200 Subject: [PATCH 056/160] Add more details in error explanation --- src/librustc/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 8d51674ab13e5..36ec48633dcf1 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -386,8 +386,8 @@ type X = u32<'static>; // error: lifetime parameters are not allowed on // this type ``` -Please check you actually used the good type or check again its definition. -Example: +Please check that you used the correct type and recheck its definition, +perhaps it doesn't need the lifetime parameter. Example: ``` type X = u32; // ok! From 7f830a874ccea9cf0ebfe88fa4074d5c5e9c53b4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Jun 2015 10:21:39 +0200 Subject: [PATCH 057/160] The come back of the "a" eaten by the void --- src/librustc/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 36ec48633dcf1..4673169a7de3e 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -361,7 +361,7 @@ http://doc.rust-lang.org/reference.html#ffi-attributes "##, E0109: r##" -You tried to give type parameter to a type which doesn't need it. Erroneous +You tried to give a type parameter to a type which doesn't need it. Erroneous code example: ``` From b4f3c5878f8ee6f893b148fd4c18d65eb0219db1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 29 Jun 2015 08:08:59 -0700 Subject: [PATCH 058/160] Hide the Rand trait from docs Fixes #26471 --- src/librand/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librand/lib.rs b/src/librand/lib.rs index ec510b4a5bdfb..2f76aa53f83ae 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -66,6 +66,7 @@ pub mod reseeding; mod rand_impls; /// A type that can be randomly generated using an `Rng`. +#[doc(hidden)] pub trait Rand : Sized { /// Generates a random instance of this type using the specified source of /// randomness. From a1110bc3a33e1fd4e08e7532bb9cd28a0216016e Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 29 Jun 2015 21:07:09 +0300 Subject: [PATCH 059/160] Fix off-by-one error in default-type-parameter checking Fixes #18183 --- src/librustc_typeck/collect.rs | 45 ++++++++++++++++------------ src/test/compile-fail/issue-18183.rs | 13 ++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/issue-18183.rs diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ef9dcd56a578b..d4f04987a812f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1860,6 +1860,29 @@ fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, result } +fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, + path: &P, + space: ParamSpace, + index: u32) + -> Ty<'tcx> +{ + let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path); + + for leaf_ty in ty.walk() { + if let ty::TyParam(p) = leaf_ty.sty { + if p.space == space && p.idx >= index { + span_err!(ccx.tcx.sess, path.span, E0128, + "type parameters with a default cannot use \ + forward declared identifiers"); + + return ccx.tcx.types.err + } + } + } + + ty +} + fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ast_generics: &ast::Generics, space: ParamSpace, @@ -1874,25 +1897,9 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, None => { } } - let default = match param.default { - None => None, - Some(ref path) => { - let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &**path); - let cur_idx = index; - - 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) - } - }; + let default = param.default.as_ref().map( + |def| convert_default_type_parameter(ccx, def, space, index) + ); let object_lifetime_default = compute_object_lifetime_default(ccx, param.id, diff --git a/src/test/compile-fail/issue-18183.rs b/src/test/compile-fail/issue-18183.rs new file mode 100644 index 0000000000000..e6f3a2bdd33ad --- /dev/null +++ b/src/test/compile-fail/issue-18183.rs @@ -0,0 +1,13 @@ +// 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. + +pub struct Foo; //~ ERROR E0128 +pub struct Baz(Foo); +fn main() {} From 8d6b5689fb9bb6ea7c5d38e50525b4d02e2b37c3 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 29 Jun 2015 15:17:56 -0400 Subject: [PATCH 060/160] Change removal notice for pointer guide. This is a bit outdated. --- src/doc/guide-pointers.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/doc/guide-pointers.md b/src/doc/guide-pointers.md index 0374166405c62..dc80ec4399131 100644 --- a/src/doc/guide-pointers.md +++ b/src/doc/guide-pointers.md @@ -1,4 +1,7 @@ -% The (old) Rust Pointer Guide +% The Rust Pointer Guide -This content has moved into -[the Rust Programming Language book](book/pointers.html). +This content has been removed, with no direct replacement. Rust only +has two built-in pointer types now, +[references](book/references-and-borrowing.html) and [raw +pointers](book/raw-pointers.html). Older Rusts had many more pointer +types, they’re gone now. From b676e99b605274c48bea04d344ff18c546041a8f Mon Sep 17 00:00:00 2001 From: Lee Jeffery Date: Mon, 29 Jun 2015 20:40:18 +0100 Subject: [PATCH 061/160] Fix incorrect warning about unused repr attributes. --- src/librustc_lint/builtin.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index db48608823d21..16db45c909d86 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -821,10 +821,12 @@ impl LintPass for NonCamelCaseTypes { } fn check_item(&mut self, cx: &Context, it: &ast::Item) { - let has_extern_repr = it.attrs.iter().any(|attr| { + let extern_repr_count = it.attrs.iter().filter(|attr| { attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter() .any(|r| r == &attr::ReprExtern) - }); + }).count(); + let has_extern_repr = extern_repr_count > 0; + if has_extern_repr { return; } From 08b21661c3131297c021768134d4637d62c12dcb Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 29 Jun 2015 21:44:40 +0300 Subject: [PATCH 062/160] Refine Atomic*::compare_and_swap documentation Namely: * Change parameter `old` to read `current` so it is clearer what the argument refers to (originally suggested `expected`, but shot down by Steve); * Add some formatting and fix some mistakes like referring to the method as `swap` rather than `compare_and_swap`. --- src/libcore/atomic.rs | 46 +++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 1b8ee8db5f47a..5e6be49be97ef 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -272,13 +272,13 @@ impl AtomicBool { unsafe { atomic_swap(self.v.get(), val, order) > 0 } } - /// Stores a value into the bool if the current value is the same as the expected value. + /// Stores a value into the `bool` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `old`, then the value was - /// updated. + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. /// - /// `swap` also takes an `Ordering` argument which describes the memory ordering of this - /// operation. + /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of + /// this operation. /// /// # Examples /// @@ -295,11 +295,11 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn compare_and_swap(&self, old: bool, new: bool, order: Ordering) -> bool { - let old = if old { UINT_TRUE } else { 0 }; + pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { + let current = if current { UINT_TRUE } else { 0 }; let new = if new { UINT_TRUE } else { 0 }; - unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) > 0 } + unsafe { atomic_compare_and_swap(self.v.get(), current, new, order) > 0 } } /// Logical "and" with a boolean value. @@ -515,10 +515,10 @@ impl AtomicIsize { unsafe { atomic_swap(self.v.get(), val, order) } } - /// Stores a value into the isize if the current value is the same as the expected value. + /// Stores a value into the `isize` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `old`, then the value was - /// updated. + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. /// /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of /// this operation. @@ -538,8 +538,8 @@ impl AtomicIsize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn compare_and_swap(&self, old: isize, new: isize, order: Ordering) -> isize { - unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } + pub fn compare_and_swap(&self, current: isize, new: isize, order: Ordering) -> isize { + unsafe { atomic_compare_and_swap(self.v.get(), current, new, order) } } /// Add an isize to the current value, returning the previous value. @@ -709,10 +709,10 @@ impl AtomicUsize { unsafe { atomic_swap(self.v.get(), val, order) } } - /// Stores a value into the usize if the current value is the same as the expected value. + /// Stores a value into the `usize` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `old`, then the value was - /// updated. + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. /// /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of /// this operation. @@ -732,8 +732,8 @@ impl AtomicUsize { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn compare_and_swap(&self, old: usize, new: usize, order: Ordering) -> usize { - unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) } + pub fn compare_and_swap(&self, current: usize, new: usize, order: Ordering) -> usize { + unsafe { atomic_compare_and_swap(self.v.get(), current, new, order) } } /// Add to the current usize, returning the previous value. @@ -910,10 +910,10 @@ impl AtomicPtr { unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } - /// Stores a value into the pointer if the current value is the same as the expected value. + /// Stores a value into the pointer if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `old`, then the value was - /// updated. + /// The return value is always the previous value. If it is equal to `current`, then the value + /// was updated. /// /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of /// this operation. @@ -933,9 +933,9 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T { + pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { unsafe { - atomic_compare_and_swap(self.p.get() as *mut usize, old as usize, + atomic_compare_and_swap(self.p.get() as *mut usize, current as usize, new as usize, order) as *mut T } } From 58ff6cc6681c23cbb10311c2bb2d884f00f9bf24 Mon Sep 17 00:00:00 2001 From: Eljay Date: Mon, 29 Jun 2015 21:27:10 +0100 Subject: [PATCH 063/160] Add test for #26646. --- src/test/run-pass/issue-26646.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/run-pass/issue-26646.rs diff --git a/src/test/run-pass/issue-26646.rs b/src/test/run-pass/issue-26646.rs new file mode 100644 index 0000000000000..2bb9611786819 --- /dev/null +++ b/src/test/run-pass/issue-26646.rs @@ -0,0 +1,21 @@ +// 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. + +#![deny(unused_attributes)] + +#[repr(C)] +#[repr(packed)] +pub struct Foo; + +#[repr(packed)] +#[repr(C)] +pub struct Bar; + +fn main() { } \ No newline at end of file From e8fe55f453c0b7c21baba91c219e7df4b6f2db47 Mon Sep 17 00:00:00 2001 From: Eljay Date: Mon, 29 Jun 2015 21:49:15 +0100 Subject: [PATCH 064/160] Add missing trailing newline. --- src/test/run-pass/issue-26646.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/issue-26646.rs b/src/test/run-pass/issue-26646.rs index 2bb9611786819..89c0a11e292f5 100644 --- a/src/test/run-pass/issue-26646.rs +++ b/src/test/run-pass/issue-26646.rs @@ -18,4 +18,4 @@ pub struct Foo; #[repr(C)] pub struct Bar; -fn main() { } \ No newline at end of file +fn main() { } From f758baa5243d832949a6a04f38da6d1d26b03ef1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 29 Jun 2015 16:31:06 -0400 Subject: [PATCH 065/160] Improve doc for std::mem::drop This was pretty misleading, so let's improve. Fixes #26571 --- src/libcore/mem.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index b53b61e517397..3bcb499de47f4 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -365,11 +365,48 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// Disposes of a value. /// -/// This function can be used to destroy any value by allowing `drop` to take ownership of its -/// argument. +/// While this does call the argument's implementation of `Drop`, it will not +/// release any borrows, as borrows are based on lexical scope. /// /// # Examples /// +/// Basic usage: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// +/// drop(v); // explicitly drop the vector +/// ``` +/// +/// Borrows are based on lexical scope, so this produces an error: +/// +/// ```ignore +/// let mut v = vec![1, 2, 3]; +/// let x = &v[0]; +/// +/// drop(x); // explicitly drop the reference, but the borrow still exists +/// +/// v.push(4); // error: cannot borrow `v` as mutable because it is also +/// // borrowed as immutable +/// ``` +/// +/// An inner scope is needed to fix this: +/// +/// ``` +/// let mut v = vec![1, 2, 3]; +/// +/// { +/// let x = &v[0]; +/// +/// drop(x); // this is now redundant, as `x` is going out of scope anyway +/// } +/// +/// v.push(4); // no problems +/// ``` +/// +/// Since `RefCell` enforces the borrow rules at runtime, `drop()` can +/// seemingly release a borrow of one: +/// /// ``` /// use std::cell::RefCell; /// From b1907a04e44d49008e5b25341fb509541fe18ea8 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 29 Jun 2015 15:31:27 -0400 Subject: [PATCH 066/160] Update link to Ousterhout This is his own mirror, so it shouldn't go down, unlike the previous one. Fixes #26661 --- src/doc/trpl/academic-research.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/trpl/academic-research.md b/src/doc/trpl/academic-research.md index dec46de650133..e317f67934498 100644 --- a/src/doc/trpl/academic-research.md +++ b/src/doc/trpl/academic-research.md @@ -12,7 +12,7 @@ Recommended for inspiration and a better understanding of Rust's background. * [Macros that work together](https://www.cs.utah.edu/plt/publications/jfp12-draft-fcdf.pdf) * [Traits: composable units of behavior](http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf) * [Alias burying](http://www.cs.uwm.edu/faculty/boyland/papers/unique-preprint.ps) - We tried something similar and abandoned it. -* [External uniqueness is unique enough](http://www.computingscience.nl/research/techreps/repo/CS-2002/2002-048.pdf) +* [External uniqueness is unique enough](http://www.cs.uu.nl/research/techreps/UU-CS-2002-048.html) * [Uniqueness and Reference Immutability for Safe Parallelism](https://research.microsoft.com/pubs/170528/msr-tr-2012-79.pdf) * [Region Based Memory Management](http://www.cs.ucla.edu/~palsberg/tba/papers/tofte-talpin-iandc97.pdf) @@ -26,10 +26,10 @@ Recommended for inspiration and a better understanding of Rust's background. * [Dynamic circular work stealing deque](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.170.1097&rep=rep1&type=pdf) - The Chase/Lev deque * [Work-first and help-first scheduling policies for async-finish task parallelism](http://www.cs.rice.edu/%7Eyguo/pubs/PID824943.pdf) - More general than fully-strict work stealing * [A Java fork/join calamity](http://www.coopsoft.com/ar/CalamityArticle.html) - critique of Java's fork/join library, particularly its application of work stealing to non-strict computation -* [Scheduling techniques for concurrent systems](http://www.ece.rutgers.edu/%7Eparashar/Classes/ece572-papers/05/ps-ousterhout.pdf) +* [Scheduling techniques for concurrent systems](http://www.stanford.edu/~ouster/cgi-bin/papers/coscheduling.pdf) * [Contention aware scheduling](http://www.blagodurov.net/files/a8-blagodurov.pdf) * [Balanced work stealing for time-sharing multicores](http://www.cse.ohio-state.edu/hpcs/WWW/HTML/publications/papers/TR-12-1.pdf) -* [Three layer cake](http://www.upcrc.illinois.edu/workshops/paraplop10/papers/paraplop10_submission_8.pdf) +* [Three layer cake for shared-memory programming](http://dl.acm.org/citation.cfm?id=1953616&dl=ACM&coll=DL&CFID=524387192&CFTOKEN=44362705) * [Non-blocking steal-half work queues](http://www.cs.bgu.ac.il/%7Ehendlerd/papers/p280-hendler.pdf) * [Reagents: expressing and composing fine-grained concurrency](http://www.mpi-sws.org/~turon/reagents.pdf) * [Algorithms for scalable synchronization of shared-memory multiprocessors](https://www.cs.rochester.edu/u/scott/papers/1991_TOCS_synch.pdf) From bf164bc6e3b81b9999ad4baddb91079a99f49ab4 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 00:32:39 +0300 Subject: [PATCH 067/160] Fix lifetime elision region accounting This merges accumulate_regions_in_type with ty_fold::collect_regions. Fixes #26638 --- .../middle/infer/higher_ranked/mod.rs | 15 +- src/librustc/middle/ty.rs | 67 ++---- src/librustc/middle/ty_fold.rs | 30 ++- src/librustc/middle/ty_walk.rs | 1 + src/librustc_typeck/astconv.rs | 199 +++++++++--------- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/rscope.rs | 29 ++- src/test/compile-fail/issue-26638.rs | 19 ++ 9 files changed, 187 insertions(+), 179 deletions(-) create mode 100644 src/test/compile-fail/issue-26638.rs diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 9005e1b8c53a5..64063623f6776 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -359,7 +359,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, where T: TypeFoldable<'tcx>, F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region, { - unbound_value.fold_with(&mut ty_fold::RegionFolder::new(tcx, &mut |region, current_depth| { + ty_fold::fold_regions(tcx, unbound_value, &mut false, |region, current_depth| { // we should only be encountering "escaping" late-bound regions here, // because the ones at the current level should have been replaced // with fresh variables @@ -369,7 +369,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, }); fldr(region, ty::DebruijnIndex::new(current_depth)) - })) + }) } impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> { @@ -437,11 +437,10 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> { let escaping_types = self.type_variables.borrow().types_escaping_snapshot(&snapshot.type_snapshot); - let escaping_region_vars: FnvHashSet<_> = - escaping_types - .iter() - .flat_map(|&t| ty_fold::collect_regions(self.tcx, &t)) - .collect(); + let mut escaping_region_vars = FnvHashSet(); + for ty in &escaping_types { + ty_fold::collect_regions(self.tcx, ty, &mut escaping_region_vars); + } region_vars.retain(|®ion_vid| { let r = ty::ReInfer(ty::ReVar(region_vid)); @@ -649,7 +648,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, // binder is that we encountered in `value`. The caller is // responsible for ensuring that (a) `value` contains at least one // binder and (b) that binder is the one we want to use. - let result = ty_fold::fold_regions(infcx.tcx, &value, |r, current_depth| { + let result = ty_fold::fold_regions(infcx.tcx, &value, &mut false, |r, current_depth| { match inv_skol_map.get(&r) { None => r, Some(br) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 489ce7bc4cf78..1bed9c4e0a834 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1713,6 +1713,16 @@ impl Region { _ => false, } } + + /// Returns the depth of `self` from the (1-based) binding level `depth` + pub fn from_depth(&self, depth: u32) -> Region { + match *self { + ty::ReLateBound(debruijn, r) => ty::ReLateBound(DebruijnIndex { + depth: debruijn.depth - (depth - 1) + }, r), + r => r + } + } } #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, @@ -6783,60 +6793,6 @@ pub enum ExplicitSelfCategory { ByBoxExplicitSelfCategory, } -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) - } - } - } - } - } -} - /// A free variable referred to in a function. #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct Freevar { @@ -6917,7 +6873,8 @@ impl<'tcx> ctxt<'tcx> { 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| { + let value = ty_fold::fold_regions(self, bound0_value, &mut false, + |region, current_depth| { match region { ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => { // should be true if no escaping regions from bound2_value diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 012f5216ed7e3..284d26b3cd6d7 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -44,7 +44,7 @@ use std::rc::Rc; use syntax::abi; use syntax::ast; use syntax::owned_slice::OwnedSlice; -use util::nodemap::FnvHashMap; +use util::nodemap::{FnvHashMap, FnvHashSet}; /////////////////////////////////////////////////////////////////////////// // Two generic traits @@ -783,38 +783,51 @@ impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where pub struct RegionFolder<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, + skipped_regions: &'a mut bool, current_depth: u32, fld_r: &'a mut (FnMut(ty::Region, u32) -> ty::Region + 'a), } impl<'a, 'tcx> RegionFolder<'a, 'tcx> { - pub fn new(tcx: &'a ty::ctxt<'tcx>, fld_r: &'a mut F) -> RegionFolder<'a, 'tcx> + pub fn new(tcx: &'a ty::ctxt<'tcx>, + skipped_regions: &'a mut bool, + fld_r: &'a mut F) -> RegionFolder<'a, 'tcx> where F : FnMut(ty::Region, u32) -> ty::Region { RegionFolder { tcx: tcx, + skipped_regions: skipped_regions, current_depth: 1, fld_r: fld_r, } } } -pub fn collect_regions<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> Vec +/// Collects the free and escaping regions in `value` into `region_set`. Returns +/// whether any late-bound regions were skipped +pub fn collect_regions<'tcx,T>(tcx: &ty::ctxt<'tcx>, + value: &T, + region_set: &mut FnvHashSet) -> bool where T : TypeFoldable<'tcx> { - let mut vec = Vec::new(); - fold_regions(tcx, value, |r, _| { vec.push(r); r }); - vec + let mut have_bound_regions = false; + fold_regions(tcx, value, &mut have_bound_regions, + |r, d| { region_set.insert(r.from_depth(d)); r }); + have_bound_regions } +/// Folds the escaping and free regions in `value` using `f`, and +/// sets `skipped_regions` to true if any late-bound region was found +/// and skipped. pub fn fold_regions<'tcx,T,F>(tcx: &ty::ctxt<'tcx>, value: &T, + skipped_regions: &mut bool, mut f: F) -> T where F : FnMut(ty::Region, u32) -> ty::Region, T : TypeFoldable<'tcx>, { - value.fold_with(&mut RegionFolder::new(tcx, &mut f)) + value.fold_with(&mut RegionFolder::new(tcx, skipped_regions, &mut f)) } impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> @@ -834,6 +847,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> ty::ReLateBound(debruijn, _) if debruijn.depth < self.current_depth => { debug!("RegionFolder.fold_region({:?}) skipped bound region (current depth={})", r, self.current_depth); + *self.skipped_regions = true; r } _ => { @@ -989,7 +1003,7 @@ pub fn shift_regions<'tcx, T:TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>, debug!("shift_regions(value={:?}, amount={})", value, amount); - value.fold_with(&mut RegionFolder::new(tcx, &mut |region, _current_depth| { + value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| { shift_region(region, amount) })) } diff --git a/src/librustc/middle/ty_walk.rs b/src/librustc/middle/ty_walk.rs index b34eb2ddb1e91..3e9a402f9499c 100644 --- a/src/librustc/middle/ty_walk.rs +++ b/src/librustc/middle/ty_walk.rs @@ -9,6 +9,7 @@ // except according to those terms. //! An iterator over the type substructure. +//! WARNING: this does not keep track of the region depth. use middle::ty::{self, Ty}; use std::iter::Iterator; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2575dc0184f8c..a55a8ff109e66 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -59,7 +59,8 @@ use middle::traits; use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags}; use middle::ty_fold; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope, - ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope}; + ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope, + ElisionFailureInfo, ElidedLifetime}; use util::common::{ErrorReported, FN_OUTPUT_NAME}; use util::nodemap::FnvHashSet; @@ -186,6 +187,58 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime) r } +fn report_elision_failure( + tcx: &ty::ctxt, + default_span: Span, + params: Vec) +{ + let mut m = String::new(); + let len = params.len(); + for (i, info) in params.into_iter().enumerate() { + let ElisionFailureInfo { + name, lifetime_count: n, have_bound_regions + } = info; + + let help_name = if name.is_empty() { + format!("argument {}", i + 1) + } else { + format!("`{}`", name) + }; + + m.push_str(&(if n == 1 { + help_name + } else { + format!("one of {}'s {} elided {}lifetimes", help_name, n, + if have_bound_regions { "free " } else { "" } ) + })[..]); + + if len == 2 && i == 0 { + m.push_str(" or "); + } else if i + 2 == len { + m.push_str(", or "); + } else if i + 1 != len { + m.push_str(", "); + } + } + if len == 1 { + fileline_help!(tcx.sess, default_span, + "this function's return type contains a borrowed value, but \ + the signature does not say which {} it is borrowed from", + m); + } else if len == 0 { + fileline_help!(tcx.sess, default_span, + "this function's return type contains a borrowed value, but \ + there is no value for it to be borrowed from"); + fileline_help!(tcx.sess, default_span, + "consider giving it a 'static lifetime"); + } else { + fileline_help!(tcx.sess, default_span, + "this function's return type contains a borrowed value, but \ + the signature does not say whether it is borrowed from {}", + m); + } +} + pub fn opt_ast_region_to_region<'tcx>( this: &AstConv<'tcx>, rscope: &RegionScope, @@ -197,61 +250,15 @@ pub fn opt_ast_region_to_region<'tcx>( ast_region_to_region(this.tcx(), lifetime) } - None => { - match rscope.anon_regions(default_span, 1) { - Err(v) => { - debug!("optional region in illegal location"); - span_err!(this.tcx().sess, default_span, E0106, - "missing lifetime specifier"); - match v { - Some(v) => { - let mut m = String::new(); - let len = v.len(); - for (i, (name, n)) in v.into_iter().enumerate() { - let help_name = if name.is_empty() { - format!("argument {}", i + 1) - } else { - format!("`{}`", name) - }; - - m.push_str(&(if n == 1 { - help_name - } else { - format!("one of {}'s {} elided lifetimes", help_name, n) - })[..]); - - if len == 2 && i == 0 { - m.push_str(" or "); - } else if i + 2 == len { - m.push_str(", or "); - } else if i + 1 != len { - m.push_str(", "); - } - } - if len == 1 { - fileline_help!(this.tcx().sess, default_span, - "this function's return type contains a borrowed value, but \ - the signature does not say which {} it is borrowed from", - m); - } else if len == 0 { - fileline_help!(this.tcx().sess, default_span, - "this function's return type contains a borrowed value, but \ - there is no value for it to be borrowed from"); - fileline_help!(this.tcx().sess, default_span, - "consider giving it a 'static lifetime"); - } else { - fileline_help!(this.tcx().sess, default_span, - "this function's return type contains a borrowed value, but \ - the signature does not say whether it is borrowed from {}", - m); - } - } - None => {}, - } - ty::ReStatic + None => match rscope.anon_regions(default_span, 1) { + Ok(rs) => rs[0], + Err(params) => { + span_err!(this.tcx().sess, default_span, E0106, + "missing lifetime specifier"); + if let Some(params) = params { + report_elision_failure(this.tcx(), default_span, params); } - - Ok(rs) => rs[0], + ty::ReStatic } } }; @@ -505,48 +512,54 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>, /// Returns the appropriate lifetime to use for any output lifetimes /// (if one exists) and a vector of the (pattern, number of lifetimes) /// corresponding to each input type/pattern. -fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec) - -> (Option, Vec<(String, usize)>) +fn find_implied_output_region<'tcx>(tcx: &ty::ctxt<'tcx>, + input_tys: &[Ty<'tcx>], + input_pats: Vec) -> ElidedLifetime { - let mut lifetimes_for_params: Vec<(String, usize)> = Vec::new(); + let mut lifetimes_for_params = Vec::new(); let mut possible_implied_output_region = None; for (input_type, input_pat) in input_tys.iter().zip(input_pats) { - let mut accumulator = Vec::new(); - input_type.accumulate_lifetimes_in_type(&mut accumulator); + let mut regions = FnvHashSet(); + let have_bound_regions = ty_fold::collect_regions(tcx, + input_type, + &mut regions); - if accumulator.len() == 1 { + debug!("find_implied_output_regions: collected {:?} from {:?} \ + have_bound_regions={:?}", ®ions, input_type, have_bound_regions); + + if regions.len() == 1 { // there's a chance that the unique lifetime of this // iteration will be the appropriate lifetime for output // parameters, so lets store it. - possible_implied_output_region = Some(accumulator[0]) + possible_implied_output_region = regions.iter().cloned().next(); } - lifetimes_for_params.push((input_pat, accumulator.len())); + lifetimes_for_params.push(ElisionFailureInfo { + name: input_pat, + lifetime_count: regions.len(), + have_bound_regions: have_bound_regions + }); } - let implied_output_region = - if lifetimes_for_params.iter().map(|&(_, n)| n).sum::() == 1 { - assert!(possible_implied_output_region.is_some()); - possible_implied_output_region - } else { - None - }; - (implied_output_region, lifetimes_for_params) + if lifetimes_for_params.iter().map(|e| e.lifetime_count).sum::() == 1 { + Ok(possible_implied_output_region.unwrap()) + } else { + Err(Some(lifetimes_for_params)) + } } fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>, - implied_output_region: Option, - param_lifetimes: Vec<(String, usize)>, + elided_lifetime: ElidedLifetime, ty: &ast::Ty) -> Ty<'tcx> { - match implied_output_region { - Some(implied_output_region) => { + match elided_lifetime { + Ok(implied_output_region) => { let rb = ElidableRscope::new(implied_output_region); ast_ty_to_ty(this, &rb, ty) } - None => { + Err(param_lifetimes) => { // All regions must be explicitly specified in the output // if the lifetime elision rules do not apply. This saves // the user from potentially-confusing errors. @@ -576,8 +589,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>, .collect::>>(); let input_params: Vec<_> = repeat(String::new()).take(inputs.len()).collect(); - let (implied_output_region, - params_lifetimes) = find_implied_output_region(&*inputs, input_params); + let implied_output_region = find_implied_output_region(this.tcx(), &inputs, input_params); let input_ty = this.tcx().mk_tup(inputs); @@ -585,8 +597,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>, Some(ref output_ty) => { (convert_ty_with_lifetime_elision(this, implied_output_region, - params_lifetimes, - &**output_ty), + &output_ty), output_ty.span) } None => { @@ -1705,7 +1716,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // here), if self is by-reference, then the implied output region is the // region of the self parameter. let mut explicit_self_category_result = None; - let (self_ty, mut implied_output_region) = match opt_self_info { + let (self_ty, implied_output_region) = match opt_self_info { None => (None, None), Some(self_info) => { // This type comes from an impl or trait; no late-bound @@ -1756,19 +1767,18 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, // Second, if there was exactly one lifetime (either a substitution or a // reference) in the arguments, then any anonymous regions in the output // have that lifetime. - let lifetimes_for_params = if implied_output_region.is_none() { - let input_tys = if self_ty.is_some() { - // Skip the first argument if `self` is present. - &self_and_input_tys[1..] - } else { - &self_and_input_tys[..] - }; + let implied_output_region = match implied_output_region { + Some(r) => Ok(r), + None => { + let input_tys = if self_ty.is_some() { + // Skip the first argument if `self` is present. + &self_and_input_tys[1..] + } else { + &self_and_input_tys[..] + }; - let (ior, lfp) = find_implied_output_region(input_tys, input_pats); - implied_output_region = ior; - lfp - } else { - vec![] + find_implied_output_region(this.tcx(), input_tys, input_pats) + } }; let output_ty = match decl.output { @@ -1777,8 +1787,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>, ast::Return(ref output) => ty::FnConverging(convert_ty_with_lifetime_elision(this, implied_output_region, - lifetimes_for_params, - &**output)), + &output)), ast::DefaultReturn(..) => ty::FnConverging(this.tcx().mk_nil()), ast::NoReturn(..) => ty::FnDiverging }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7e87dc6540ea5..2db1598db4bee 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,7 @@ use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; use middle::ty::{MethodCall, MethodCallee}; use middle::ty_fold::{TypeFolder, TypeFoldable}; -use rscope::RegionScope; +use rscope::{ElisionFailureInfo, RegionScope}; use session::Session; use {CrateCtxt, lookup_full_def, require_same_types}; use TypeAndSubsts; @@ -1796,7 +1796,7 @@ impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> { } fn anon_regions(&self, span: Span, count: usize) - -> Result, Option>> { + -> Result, Option>> { Ok((0..count).map(|_| { self.infcx().next_region_var(infer::MiscVariable(span)) }).collect()) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d4f04987a812f..7909908079fb3 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2248,7 +2248,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( * before we really have a `ParameterEnvironment` to check. */ - ty_fold::fold_regions(tcx, value, |region, _| { + ty_fold::fold_regions(tcx, value, &mut false, |region, _| { match region { ty::ReEarlyBound(data) => { let def_id = local_def(data.param_id); diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index c908e21626e56..b416026ba0134 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -16,6 +16,15 @@ use std::cell::Cell; use std::iter::repeat; use syntax::codemap::Span; +#[derive(Clone)] +pub struct ElisionFailureInfo { + pub name: String, + pub lifetime_count: usize, + pub have_bound_regions: bool +} + +pub type ElidedLifetime = Result>>; + /// Defines strategies for handling regions that are omitted. For /// example, if one writes the type `&Foo`, then the lifetime of /// this reference has been omitted. When converting this @@ -30,7 +39,7 @@ pub trait RegionScope { fn anon_regions(&self, span: Span, count: usize) - -> Result, Option>>; + -> Result, Option>>; /// If an object omits any explicit lifetime bound, and none can /// be derived from the object traits, what should we use? If @@ -51,16 +60,16 @@ impl RegionScope for ExplicitRscope { fn anon_regions(&self, _span: Span, _count: usize) - -> Result, Option>> { + -> Result, Option>> { Err(None) } } // Same as `ExplicitRscope`, but provides some extra information for diagnostics -pub struct UnelidableRscope(Vec<(String, usize)>); +pub struct UnelidableRscope(Option>); impl UnelidableRscope { - pub fn new(v: Vec<(String, usize)>) -> UnelidableRscope { + pub fn new(v: Option>) -> UnelidableRscope { UnelidableRscope(v) } } @@ -73,9 +82,9 @@ impl RegionScope for UnelidableRscope { fn anon_regions(&self, _span: Span, _count: usize) - -> Result, Option>> { + -> Result, Option>> { let UnelidableRscope(ref v) = *self; - Err(Some(v.clone())) + Err(v.clone()) } } @@ -104,7 +113,7 @@ impl RegionScope for ElidableRscope { fn anon_regions(&self, _span: Span, count: usize) - -> Result, Option>> + -> Result, Option>> { Ok(repeat(self.default).take(count).collect()) } @@ -141,7 +150,7 @@ impl RegionScope for BindingRscope { fn anon_regions(&self, _: Span, count: usize) - -> Result, Option>> + -> Result, Option>> { Ok((0..count).map(|_| self.next_region()).collect()) } @@ -177,7 +186,7 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> { fn anon_regions(&self, span: Span, count: usize) - -> Result, Option>> + -> Result, Option>> { self.base_scope.anon_regions(span, count) } @@ -204,7 +213,7 @@ impl<'r> RegionScope for ShiftedRscope<'r> { fn anon_regions(&self, span: Span, count: usize) - -> Result, Option>> + -> Result, Option>> { match self.base_scope.anon_regions(span, count) { Ok(mut v) => { diff --git a/src/test/compile-fail/issue-26638.rs b/src/test/compile-fail/issue-26638.rs new file mode 100644 index 0000000000000..edb9ab47fc611 --- /dev/null +++ b/src/test/compile-fail/issue-26638.rs @@ -0,0 +1,19 @@ +// 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. + +fn parse_type(iter: Box+'static>) -> &str { iter.next() } +//~^ ERROR missing lifetime specifier [E0106] +//~^^ HELP 2 elided lifetimes + +fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } +//~^ ERROR missing lifetime specifier [E0106] +//~^^ HELP 0 elided free lifetimes + +fn main() {} From 336f81215eb166aad4f8759be0cf284f3321212f Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 01:34:17 +0300 Subject: [PATCH 068/160] Remove type_needs_unwind_cleanup After the last @dinosaur went extinct, the check became redundant with type_needs_drop, except for its bugginess. Fixes #26655. --- src/librustc_trans/trans/cleanup.rs | 9 ++---- src/librustc_trans/trans/common.rs | 45 +---------------------------- src/test/run-pass/issue-26655.rs | 34 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 51 deletions(-) create mode 100644 src/test/run-pass/issue-26655.rs diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index b7e761fa4b991..0b4d7e602be80 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -389,7 +389,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { if !self.type_needs_drop(ty) { return; } let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -415,7 +414,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: true, @@ -447,7 +445,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { let drop = box DropValue { is_immediate: false, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -473,7 +470,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { if !self.type_needs_drop(ty) { return; } let drop = box DropValue { is_immediate: true, - must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty), val: val, ty: ty, fill_on_drop: false, @@ -1031,7 +1027,6 @@ impl EarlyExitLabel { #[derive(Copy, Clone)] pub struct DropValue<'tcx> { is_immediate: bool, - must_unwind: bool, val: ValueRef, ty: Ty<'tcx>, fill_on_drop: bool, @@ -1040,11 +1035,11 @@ pub struct DropValue<'tcx> { impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> { fn must_unwind(&self) -> bool { - self.must_unwind + true } fn clean_on_unwind(&self) -> bool { - self.must_unwind + true } fn is_lifetime_end(&self) -> bool { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 483d82f508f25..9c2aea1e67adf 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -25,7 +25,7 @@ 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 middle::subst::{self, Substs}; use trans::base; use trans::build; use trans::cleanup; @@ -54,8 +54,6 @@ use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; use syntax::parse::token::InternedString; use syntax::parse::token; -use util::common::memoized; -use util::nodemap::FnvHashSet; pub use trans::context::CrateContext; @@ -136,47 +134,6 @@ pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { } } -// Some things don't need cleanups during unwinding because the -// thread can free them all at once later. Currently only things -// that only contain scalars and shared boxes can avoid unwind -// cleanups. -pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { - return memoized(ccx.needs_unwind_cleanup_cache(), ty, |ty| { - type_needs_unwind_cleanup_(ccx.tcx(), ty, &mut FnvHashSet()) - }); - - fn type_needs_unwind_cleanup_<'tcx>(tcx: &ty::ctxt<'tcx>, - ty: Ty<'tcx>, - tycache: &mut FnvHashSet>) - -> bool - { - // Prevent infinite recursion - if !tycache.insert(ty) { - return false; - } - - let mut needs_unwind_cleanup = false; - ty.maybe_walk(|ty| { - needs_unwind_cleanup |= match ty.sty { - ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | - ty::TyFloat(_) | ty::TyTuple(_) | ty::TyRawPtr(_) => false, - - ty::TyEnum(did, substs) => - 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) - }) - ), - - _ => true - }; - !needs_unwind_cleanup - }); - needs_unwind_cleanup - } -} - /// If `type_needs_drop` returns true, then `ty` is definitely /// non-copy and *might* have a destructor attached; if it returns /// false, then `ty` definitely has no destructor (i.e. no drop glue). diff --git a/src/test/run-pass/issue-26655.rs b/src/test/run-pass/issue-26655.rs new file mode 100644 index 0000000000000..bdd3a80d74cf4 --- /dev/null +++ b/src/test/run-pass/issue-26655.rs @@ -0,0 +1,34 @@ +// 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. + +#![feature(const_fn)] + +// Check that the destructors of simple enums are run on unwinding + +use std::sync::atomic::{Ordering, AtomicUsize}; +use std::thread; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +enum WithDtor { Val } +impl Drop for WithDtor { + fn drop(&mut self) { + LOG.store(LOG.load(Ordering::SeqCst)+1,Ordering::SeqCst); + } +} + +pub fn main() { + thread::spawn(move|| { + let _e: WithDtor = WithDtor::Val; + panic!("fail"); + }).join().unwrap_err(); + + assert_eq!(LOG.load(Ordering::SeqCst), 1); +} From b1931e48a01b418b4b1ba6c747f2c99a5b10d96f Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 29 Jun 2015 14:51:56 -0700 Subject: [PATCH 069/160] lint: only consider actual calls as unconditional recursion. Specifically, just mentioning the function name as a value is fine, as long as it isn't called, e.g. `fn main() { let _ = main; }`. Closes #21705. --- src/librustc_lint/builtin.rs | 9 +++++++-- src/test/compile-fail/lint-unconditional-recursion.rs | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index db48608823d21..3d5eb422b634b 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1973,8 +1973,13 @@ impl LintPass for UnconditionalRecursion { fn_id: ast::NodeId, _: ast::Ident, id: ast::NodeId) -> bool { - tcx.def_map.borrow().get(&id) - .map_or(false, |def| def.def_id() == local_def(fn_id)) + match tcx.map.get(id) { + ast_map::NodeExpr(&ast::Expr { node: ast::ExprCall(ref callee, _), .. }) => { + tcx.def_map.borrow().get(&callee.id) + .map_or(false, |def| def.def_id() == local_def(fn_id)) + } + _ => false + } } // check if the method call `id` refers to method `method_id` diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs index 0c3d1c6adea40..0cd71aebd63fb 100644 --- a/src/test/compile-fail/lint-unconditional-recursion.rs +++ b/src/test/compile-fail/lint-unconditional-recursion.rs @@ -63,4 +63,8 @@ impl Baz { } } +fn all_fine() { + let _f = all_fine; +} + fn main() {} From 900af2c6d9b21ca1b1db35b7b09b0fb59cf78b84 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 29 Jun 2015 15:56:00 -0700 Subject: [PATCH 070/160] lint: default methods must be called on Self to unconditionally recur. This catches the case when a trait defines a default method that calls itself, but on a type that isn't necessarily `Self`, e.g. there's no reason that `T = Self` in the following, so the call isn't necessarily recursive (`T` may override the call). trait Bar { fn method(&self, x: &T) { x.method(x) } } Fixes #26333. --- src/librustc_lint/builtin.rs | 9 +++++++++ src/test/compile-fail/lint-unconditional-recursion.rs | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3d5eb422b634b..190e2965e76ce 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -2007,6 +2007,15 @@ impl LintPass for UnconditionalRecursion { // method instead. ty::MethodTypeParam( ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => { + + let on_self = m.substs.self_ty().map_or(false, |t| t.is_self()); + if !on_self { + // we can only be recurring in a default + // method if we're being called literally + // on the `Self` type. + return false + } + tcx.trait_item(trait_ref.def_id, method_num).def_id() } diff --git a/src/test/compile-fail/lint-unconditional-recursion.rs b/src/test/compile-fail/lint-unconditional-recursion.rs index 0cd71aebd63fb..47bb7f948a786 100644 --- a/src/test/compile-fail/lint-unconditional-recursion.rs +++ b/src/test/compile-fail/lint-unconditional-recursion.rs @@ -67,4 +67,11 @@ fn all_fine() { let _f = all_fine; } +// issue 26333 +trait Bar { + fn method(&self, x: &T) { + x.method(x) + } +} + fn main() {} From a5e21daa1909f538ddd696f7baffad4603f38a5d Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 02:24:46 +0300 Subject: [PATCH 071/160] Kill count_late_bound_regions No, it didn't show up in my profiler. It still needs to die. --- src/librustc/middle/traits/fulfill.rs | 24 ++++++++--------- src/librustc/middle/ty.rs | 39 ++++++++++++++++----------- src/librustc_typeck/astconv.rs | 8 +++--- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 5e274dcec70e4..dc3ccd417b8f7 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -421,16 +421,18 @@ 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 selcx.tcx().count_late_bound_regions(binder) != 0 { - errors.push( - FulfillmentError::new( - obligation.clone(), - CodeSelectionError(Unimplemented))); - } else { - let ty::OutlivesPredicate(t_a, r_b) = binder.0; - register_region_obligation(t_a, r_b, - obligation.cause.clone(), - region_obligations); + match selcx.tcx().no_late_bound_regions(binder) { + None => { + errors.push( + FulfillmentError::new( + obligation.clone(), + CodeSelectionError(Unimplemented))) + } + Some(ty::OutlivesPredicate(t_a, r_b)) => { + register_region_obligation(t_a, r_b, + obligation.cause.clone(), + region_obligations); + } } true } @@ -501,5 +503,3 @@ impl<'tcx> FulfilledPredicates<'tcx> { !self.set.insert(p.clone()) } } - - diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 1bed9c4e0a834..fe52fba49c6e5 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -6853,19 +6853,6 @@ impl<'tcx> ctxt<'tcx> { |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).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() - } - - 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>) @@ -6890,9 +6877,9 @@ impl<'tcx> ctxt<'tcx> { } pub fn no_late_bound_regions(&self, value: &Binder) -> Option - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + RegionEscape { - if self.binds_late_bound_regions(value) { + if value.0.has_escaping_regions() { None } else { Some(value.0.clone()) @@ -7052,6 +7039,19 @@ impl<'tcx> RegionEscape for Substs<'tcx> { } } +impl RegionEscape for Vec { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.iter().any(|t| t.has_regions_escaping_depth(depth)) + } +} + +impl<'tcx> RegionEscape for FnSig<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.inputs.has_regions_escaping_depth(depth) || + self.output.has_regions_escaping_depth(depth) + } +} + impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.iter_enumerated().any(|(space, _, t)| { @@ -7124,6 +7124,15 @@ impl<'tcx,T:RegionEscape> RegionEscape for Binder { } } +impl<'tcx> RegionEscape for FnOutput<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + match *self { + FnConverging(t) => t.has_regions_escaping_depth(depth), + FnDiverging => false + } + } +} + impl<'tcx> RegionEscape for EquatePredicate<'tcx> { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a55a8ff109e66..00b7f42061405 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -125,14 +125,14 @@ pub trait AstConv<'tcx> { item_name: ast::Name) -> Ty<'tcx> { - if self.tcx().binds_late_bound_regions(&poly_trait_ref) { + if let Some(trait_ref) = self.tcx().no_late_bound_regions(&poly_trait_ref) { + self.projected_ty(span, trait_ref, item_name) + } else { + // no late-bound regions, we can just ignore the binder span_err!(self.tcx().sess, span, E0212, "cannot extract an associated type from a higher-ranked trait bound \ in this context"); self.tcx().types.err - } else { - // no late-bound regions, we can just ignore the binder - self.projected_ty(span, poly_trait_ref.0.clone(), item_name) } } From fb5dd398f677213e8f0943638c9205172a634efe Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 02:31:07 +0300 Subject: [PATCH 072/160] Remove now-useless code --- src/librustc_trans/trans/cleanup.rs | 52 +++++++---------------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 0b4d7e602be80..588e4cea5048b 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -199,7 +199,6 @@ pub struct CachedEarlyExit { pub trait Cleanup<'tcx> { fn must_unwind(&self) -> bool; - fn clean_on_unwind(&self) -> bool; fn is_lifetime_end(&self) -> bool; fn trans<'blk>(&self, bcx: Block<'blk, 'tcx>, @@ -776,29 +775,19 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx // // At this point, `popped_scopes` is empty, and so the final block // that we return to the user is `Cleanup(AST 24)`. - while !popped_scopes.is_empty() { - let mut scope = popped_scopes.pop().unwrap(); - - if scope.cleanups.iter().any(|c| cleanup_is_suitable_for(&**c, label)) - { - let name = scope.block_name("clean"); - debug!("generating cleanups for {}", name); - let bcx_in = self.new_block(label.is_unwind(), - &name[..], - None); - let mut bcx_out = bcx_in; - for cleanup in scope.cleanups.iter().rev() { - if cleanup_is_suitable_for(&**cleanup, label) { - bcx_out = cleanup.trans(bcx_out, - scope.debug_loc); - } - } - build::Br(bcx_out, prev_llbb, DebugLoc::None); - prev_llbb = bcx_in.llbb; - } else { - debug!("no suitable cleanups in {}", - scope.block_name("clean")); + while let Some(mut scope) = popped_scopes.pop() { + let name = scope.block_name("clean"); + debug!("generating cleanups for {}", name); + let bcx_in = self.new_block(label.is_unwind(), + &name[..], + None); + let mut bcx_out = bcx_in; + for cleanup in scope.cleanups.iter().rev() { + bcx_out = cleanup.trans(bcx_out, + scope.debug_loc); } + build::Br(bcx_out, prev_llbb, DebugLoc::None); + prev_llbb = bcx_in.llbb; scope.add_cached_early_exit(label, prev_llbb); self.push_scope(scope); @@ -1038,10 +1027,6 @@ impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> { true } - fn clean_on_unwind(&self) -> bool { - true - } - fn is_lifetime_end(&self) -> bool { false } @@ -1085,10 +1070,6 @@ impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> { true } - fn clean_on_unwind(&self) -> bool { - true - } - fn is_lifetime_end(&self) -> bool { false } @@ -1118,10 +1099,6 @@ impl<'tcx> Cleanup<'tcx> for LifetimeEnd { false } - fn clean_on_unwind(&self) -> bool { - true - } - fn is_lifetime_end(&self) -> bool { true } @@ -1160,11 +1137,6 @@ pub fn var_scope(tcx: &ty::ctxt, r } -fn cleanup_is_suitable_for(c: &Cleanup, - label: EarlyExitLabel) -> bool { - !label.is_unwind() || c.clean_on_unwind() -} - /////////////////////////////////////////////////////////////////////////// // These traits just exist to put the methods into this file. From d8680f6534ef1ffcb1affda7a1e1ea2bfc4749c2 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 29 Jun 2015 17:10:53 -0700 Subject: [PATCH 073/160] Add regression test for #17756 Closes #17756 --- src/test/run-pass/issue-17756.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/run-pass/issue-17756.rs diff --git a/src/test/run-pass/issue-17756.rs b/src/test/run-pass/issue-17756.rs new file mode 100644 index 0000000000000..1b108463c748e --- /dev/null +++ b/src/test/run-pass/issue-17756.rs @@ -0,0 +1,14 @@ +// 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. + +const count : usize = 2 as usize; +fn main() { + let larger : [usize; count*2]; +} From e834c0348fe094da4f32594278fee6b0446cb41c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 29 Jun 2015 17:23:02 -0700 Subject: [PATCH 074/160] Link to docs from error explanations via HTTPS --- src/librustc/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4673169a7de3e..68ca0eac37a5d 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -357,7 +357,7 @@ Ensure that the expressions given can be evaluated as the desired integer type. See the FFI section of the Reference for more information about using a custom integer type: -http://doc.rust-lang.org/reference.html#ffi-attributes +https://doc.rust-lang.org/reference.html#ffi-attributes "##, E0109: r##" @@ -408,7 +408,7 @@ fn main() { } ``` -See also http://doc.rust-lang.org/book/unsafe.html +See also https://doc.rust-lang.org/book/unsafe.html "##, E0137: r##" From 6419acee34373ffe28600cdff67cfc398a3fb23c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 29 Jun 2015 17:28:21 -0700 Subject: [PATCH 075/160] Add regression test for #13902 Closes #13902 --- src/test/run-pass/issue-13902.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/run-pass/issue-13902.rs diff --git a/src/test/run-pass/issue-13902.rs b/src/test/run-pass/issue-13902.rs new file mode 100644 index 0000000000000..14019aaacd4c4 --- /dev/null +++ b/src/test/run-pass/issue-13902.rs @@ -0,0 +1,22 @@ +// 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. + +const JSVAL_TAG_CLEAR: u32 = 0xFFFFFF80; +const JSVAL_TYPE_INT32: u8 = 0x01; +const JSVAL_TYPE_UNDEFINED: u8 = 0x02; +#[repr(u32)] +enum ValueTag { + JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | (JSVAL_TYPE_INT32 as u32), + JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | (JSVAL_TYPE_UNDEFINED as u32), +} + +fn main() { + let _ = ValueTag::JSVAL_TAG_INT32; +} From bbf0daa19276354d5759d0b0bd7d31bcd3cc301c Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 16 Jun 2015 21:56:33 +1200 Subject: [PATCH 076/160] Add parent_node to ast_map --- src/librustc/ast_map/mod.rs | 200 ++++++++++++++++++++++++------------ 1 file changed, 133 insertions(+), 67 deletions(-) diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index 06d87f5333ad3..39ad2022183e4 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -121,27 +121,28 @@ pub enum Node<'ast> { NodeLifetime(&'ast Lifetime), } -/// Represents an entry and its parent Node ID +/// Represents an entry and its parent NodeID and parent_node NodeID, see +/// get_parent_node for the distinction. /// The odd layout is to bring down the total size. #[derive(Copy, Debug)] enum MapEntry<'ast> { /// Placeholder for holes in the map. NotPresent, - /// All the node types, with a parent ID. - EntryItem(NodeId, &'ast Item), - EntryForeignItem(NodeId, &'ast ForeignItem), - EntryTraitItem(NodeId, &'ast TraitItem), - EntryImplItem(NodeId, &'ast ImplItem), - EntryVariant(NodeId, &'ast Variant), - EntryExpr(NodeId, &'ast Expr), - EntryStmt(NodeId, &'ast Stmt), - EntryArg(NodeId, &'ast Pat), - EntryLocal(NodeId, &'ast Pat), - EntryPat(NodeId, &'ast Pat), - EntryBlock(NodeId, &'ast Block), - EntryStructCtor(NodeId, &'ast StructDef), - EntryLifetime(NodeId, &'ast Lifetime), + /// All the node types, with a parent and scope ID. + EntryItem(NodeId, NodeId, &'ast Item), + EntryForeignItem(NodeId, NodeId, &'ast ForeignItem), + EntryTraitItem(NodeId, NodeId, &'ast TraitItem), + EntryImplItem(NodeId, NodeId, &'ast ImplItem), + EntryVariant(NodeId, NodeId, &'ast Variant), + EntryExpr(NodeId, NodeId, &'ast Expr), + EntryStmt(NodeId, NodeId, &'ast Stmt), + EntryArg(NodeId, NodeId, &'ast Pat), + EntryLocal(NodeId, NodeId, &'ast Pat), + EntryPat(NodeId, NodeId, &'ast Pat), + EntryBlock(NodeId, NodeId, &'ast Block), + EntryStructCtor(NodeId, NodeId, &'ast StructDef), + EntryLifetime(NodeId, NodeId, &'ast Lifetime), /// Roots for node trees. RootCrate, @@ -161,58 +162,77 @@ struct InlinedParent { } impl<'ast> MapEntry<'ast> { - fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { + fn from_node(p: NodeId, s: NodeId, node: Node<'ast>) -> MapEntry<'ast> { match node { - NodeItem(n) => EntryItem(p, n), - NodeForeignItem(n) => EntryForeignItem(p, n), - NodeTraitItem(n) => EntryTraitItem(p, n), - NodeImplItem(n) => EntryImplItem(p, n), - NodeVariant(n) => EntryVariant(p, n), - NodeExpr(n) => EntryExpr(p, n), - NodeStmt(n) => EntryStmt(p, n), - NodeArg(n) => EntryArg(p, n), - NodeLocal(n) => EntryLocal(p, n), - NodePat(n) => EntryPat(p, n), - NodeBlock(n) => EntryBlock(p, n), - NodeStructCtor(n) => EntryStructCtor(p, n), - NodeLifetime(n) => EntryLifetime(p, n) + NodeItem(n) => EntryItem(p, s, n), + NodeForeignItem(n) => EntryForeignItem(p, s, n), + NodeTraitItem(n) => EntryTraitItem(p, s, n), + NodeImplItem(n) => EntryImplItem(p, s, n), + NodeVariant(n) => EntryVariant(p, s, n), + NodeExpr(n) => EntryExpr(p, s, n), + NodeStmt(n) => EntryStmt(p, s, n), + NodeArg(n) => EntryArg(p, s, n), + NodeLocal(n) => EntryLocal(p, s, n), + NodePat(n) => EntryPat(p, s, n), + NodeBlock(n) => EntryBlock(p, s, n), + NodeStructCtor(n) => EntryStructCtor(p, s, n), + NodeLifetime(n) => EntryLifetime(p, s, n) } } fn parent(self) -> Option { Some(match self { - EntryItem(id, _) => id, - EntryForeignItem(id, _) => id, - EntryTraitItem(id, _) => id, - EntryImplItem(id, _) => id, - EntryVariant(id, _) => id, - EntryExpr(id, _) => id, - EntryStmt(id, _) => id, - EntryArg(id, _) => id, - EntryLocal(id, _) => id, - EntryPat(id, _) => id, - EntryBlock(id, _) => id, - EntryStructCtor(id, _) => id, - EntryLifetime(id, _) => id, + EntryItem(id, _, _) => id, + EntryForeignItem(id, _, _) => id, + EntryTraitItem(id, _, _) => id, + EntryImplItem(id, _, _) => id, + EntryVariant(id, _, _) => id, + EntryExpr(id, _, _) => id, + EntryStmt(id, _, _) => id, + EntryArg(id, _, _) => id, + EntryLocal(id, _, _) => id, + EntryPat(id, _, _) => id, + EntryBlock(id, _, _) => id, + EntryStructCtor(id, _, _) => id, + EntryLifetime(id, _, _) => id, + _ => return None + }) + } + + fn parent_node(self) -> Option { + Some(match self { + EntryItem(_, id, _) => id, + EntryForeignItem(_, id, _) => id, + EntryTraitItem(_, id, _) => id, + EntryImplItem(_, id, _) => id, + EntryVariant(_, id, _) => id, + EntryExpr(_, id, _) => id, + EntryStmt(_, id, _) => id, + EntryArg(_, id, _) => id, + EntryLocal(_, id, _) => id, + EntryPat(_, id, _) => id, + EntryBlock(_, id, _) => id, + EntryStructCtor(_, id, _) => id, + EntryLifetime(_, id, _) => id, _ => return None }) } fn to_node(self) -> Option> { Some(match self { - EntryItem(_, n) => NodeItem(n), - EntryForeignItem(_, n) => NodeForeignItem(n), - EntryTraitItem(_, n) => NodeTraitItem(n), - EntryImplItem(_, n) => NodeImplItem(n), - EntryVariant(_, n) => NodeVariant(n), - EntryExpr(_, n) => NodeExpr(n), - EntryStmt(_, n) => NodeStmt(n), - EntryArg(_, n) => NodeArg(n), - EntryLocal(_, n) => NodeLocal(n), - EntryPat(_, n) => NodePat(n), - EntryBlock(_, n) => NodeBlock(n), - EntryStructCtor(_, n) => NodeStructCtor(n), - EntryLifetime(_, n) => NodeLifetime(n), + EntryItem(_, _, n) => NodeItem(n), + EntryForeignItem(_, _, n) => NodeForeignItem(n), + EntryTraitItem(_, _, n) => NodeTraitItem(n), + EntryImplItem(_, _, n) => NodeImplItem(n), + EntryVariant(_, _, n) => NodeVariant(n), + EntryExpr(_, _, n) => NodeExpr(n), + EntryStmt(_, _, n) => NodeStmt(n), + EntryArg(_, _, n) => NodeArg(n), + EntryLocal(_, _, n) => NodeLocal(n), + EntryPat(_, _, n) => NodePat(n), + EntryBlock(_, _, n) => NodeBlock(n), + EntryStructCtor(_, _, n) => NodeStructCtor(n), + EntryLifetime(_, _, n) => NodeLifetime(n), _ => return None }) } @@ -289,6 +309,18 @@ impl<'ast> Map<'ast> { self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id) } + /// Similar to get_parent, returns the parent node id or id if there is no + /// parent. + /// This function returns the most direct parent in the AST, whereas get_parent + /// returns the enclosing item. Note that this might not be the actual parent + /// node in the AST - some kinds of nodes are not in the map and these will + /// never appear as the parent_node. So you can always walk the parent_nodes + /// from a node to the root of the ast (unless you get the same id back here + /// that can happen if the id is not in the map itself or is just weird). + pub fn get_parent_node(&self, id: NodeId) -> NodeId { + self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) + } + pub fn get_parent_did(&self, id: NodeId) -> DefId { let parent = self.get_parent(id); match self.find_entry(parent) { @@ -301,7 +333,7 @@ impl<'ast> Map<'ast> { pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi { let parent = self.get_parent(id); let abi = match self.find_entry(parent) { - Some(EntryItem(_, i)) => { + Some(EntryItem(_, _, i)) => { match i.node { ItemForeignMod(ref nm) => Some(nm.abi), _ => None @@ -591,11 +623,11 @@ impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> { } self.idx += 1; let (p, name) = match self.map.find_entry(idx) { - Some(EntryItem(p, n)) => (p, n.name()), - Some(EntryForeignItem(p, n))=> (p, n.name()), - Some(EntryTraitItem(p, n)) => (p, n.name()), - Some(EntryImplItem(p, n)) => (p, n.name()), - Some(EntryVariant(p, n)) => (p, n.name()), + Some(EntryItem(p, _, n)) => (p, n.name()), + Some(EntryForeignItem(p, _, n))=> (p, n.name()), + Some(EntryTraitItem(p, _, n)) => (p, n.name()), + Some(EntryImplItem(p, _, n)) => (p, n.name()), + Some(EntryVariant(p, _, n)) => (p, n.name()), _ => continue, }; if self.matches_names(p, name) { @@ -648,7 +680,8 @@ impl Folder for IdAndSpanUpdater { struct NodeCollector<'ast> { map: Vec>, /// The node in which we are currently mapping (an item or a method). - parent: NodeId + parent: NodeId, + parent_node: NodeId, } impl<'ast> NodeCollector<'ast> { @@ -662,7 +695,7 @@ impl<'ast> NodeCollector<'ast> { } fn insert(&mut self, id: NodeId, node: Node<'ast>) { - let entry = MapEntry::from_node(self.parent, node); + let entry = MapEntry::from_node(self.parent, self.parent_node, node); self.insert_entry(id, entry); } @@ -678,6 +711,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert(i.id, NodeItem(i)); let parent = self.parent; self.parent = i.id; + let parent_node = self.parent_node; + self.parent_node = i.id; match i.node { ItemImpl(_, _, _, _, _, ref impl_items) => { for ii in impl_items { @@ -728,48 +763,70 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } visit::walk_item(self, i); self.parent = parent; + self.parent_node = parent_node; } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { let parent = self.parent; self.parent = ti.id; + let parent_node = self.parent_node; + self.parent_node = ti.id; visit::walk_trait_item(self, ti); self.parent = parent; + self.parent_node = parent_node; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { let parent = self.parent; self.parent = ii.id; + let parent_node = self.parent_node; + self.parent_node = ii.id; visit::walk_impl_item(self, ii); self.parent = parent; + self.parent_node = parent_node; } fn visit_pat(&mut self, pat: &'ast Pat) { + let parent_node = self.parent_node; + self.parent_node = pat.id; self.insert(pat.id, match pat.node { // Note: this is at least *potentially* a pattern... PatIdent(..) => NodeLocal(pat), _ => NodePat(pat) }); visit::walk_pat(self, pat); + self.parent_node = parent_node; } fn visit_expr(&mut self, expr: &'ast Expr) { + let parent_node = self.parent_node; + self.parent_node = expr.id; self.insert(expr.id, NodeExpr(expr)); visit::walk_expr(self, expr); + self.parent_node = parent_node; } fn visit_stmt(&mut self, stmt: &'ast Stmt) { - self.insert(ast_util::stmt_id(stmt), NodeStmt(stmt)); + let id = ast_util::stmt_id(stmt); + let parent_node = self.parent_node; + self.parent_node = id; + self.insert(id, NodeStmt(stmt)); visit::walk_stmt(self, stmt); + self.parent_node = parent_node; } fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl, - b: &'ast Block, s: Span, _: NodeId) { + b: &'ast Block, s: Span, id: NodeId) { + let parent_node = self.parent_node; + self.parent_node = id; self.visit_fn_decl(fd); visit::walk_fn(self, fk, fd, b, s); + self.parent_node = parent_node; } fn visit_ty(&mut self, ty: &'ast Ty) { + let parent_node = self.parent_node; + self.parent_node = ty.id; match ty.node { TyBareFn(ref fd) => { self.visit_fn_decl(&*fd.decl); @@ -777,15 +834,22 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { _ => {} } visit::walk_ty(self, ty); + self.parent_node = parent_node; } fn visit_block(&mut self, block: &'ast Block) { + let parent_node = self.parent_node; + self.parent_node = block.id; self.insert(block.id, NodeBlock(block)); visit::walk_block(self, block); + self.parent_node = parent_node; } fn visit_lifetime_ref(&mut self, lifetime: &'ast Lifetime) { + let parent_node = self.parent_node; + self.parent_node = lifetime.id; self.insert(lifetime.id, NodeLifetime(lifetime)); + self.parent_node = parent_node; } fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { @@ -809,7 +873,8 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map let mut collector = NodeCollector { map: vec![], - parent: CRATE_NODE_ID + parent: CRATE_NODE_ID, + parent_node: CRATE_NODE_ID, }; collector.insert_entry(CRATE_NODE_ID, RootCrate); visit::walk_crate(&mut collector, &forest.krate); @@ -866,7 +931,8 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let mut collector = NodeCollector { map: mem::replace(&mut *map.map.borrow_mut(), vec![]), - parent: fld.new_id(DUMMY_NODE_ID) + parent: fld.new_id(DUMMY_NODE_ID), + parent_node: fld.new_id(DUMMY_NODE_ID), }; let ii_parent_id = collector.parent; collector.insert_entry(ii_parent_id, RootInlinedParent(ii_parent)); From b23ddc60e9fcb188421060a83f1af2b815fc60e2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 16 Jun 2015 22:20:30 +1200 Subject: [PATCH 077/160] Implement get_enclosing_scope and use it in save-analysis --- src/librustc/ast_map/mod.rs | 28 ++++++++++++++++++++++++++++ src/librustc_trans/save/mod.rs | 16 ++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index 39ad2022183e4..7c80ba376c368 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -321,6 +321,34 @@ impl<'ast> Map<'ast> { self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) } + /// Returns the nearest enclosing scope. A scope is an item or block. + /// FIXME it is not clear to me that all items qualify as scopes - statics + /// and associated types probably shouldn't, for example. Behaviour in this + /// regard should be expected to be highly unstable. + pub fn get_enclosing_scope(&self, id: NodeId) -> Option { + let mut last_id = id; + // Walk up the chain of parents until we find a 'scope'. + loop { + let cur_id = self.get_parent_node(last_id); + if cur_id == last_id { + return None; + } + + match self.get(cur_id) { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) | + NodeBlock(_) => { + return Some(cur_id); + } + _ => {} + } + + last_id = cur_id; + } + } + pub fn get_parent_did(&self, id: NodeId) -> DefId { let parent = self.get_parent(id); match self.find_entry(parent) { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 27805b9d8330b..e9c91f4f4c194 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -172,7 +172,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname: qualname, declaration: None, span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(item.id), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), }) } ast::ItemStatic(ref typ, mt, ref expr) => { @@ -191,7 +191,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(item.id), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), value: value, type_value: ty_to_string(&typ), }) @@ -205,7 +205,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(item.id), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), value: self.span_utils.snippet(expr.span), type_value: ty_to_string(&typ), }) @@ -223,7 +223,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(item.id), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), filename: filename, }) }, @@ -237,14 +237,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { value: val, span: sub_span.unwrap(), qualname: enum_name, - scope: self.tcx.map.get_parent(item.id), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), }) }, ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => { let mut type_data = None; let sub_span; - let parent = self.tcx.map.get_parent(item.id); + let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap(); match typ.node { // Common case impl for a struct or something basic. @@ -337,7 +337,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { return Some(Data::VariableRefData(VariableRefData { name: get_ident(ident.node).to_string(), span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(expr.id), + scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(), ref_id: f.id, })); } @@ -360,7 +360,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let sub_span = self.span_utils.span_for_last_ident(path.span); Some(Data::TypeRefData(TypeRefData { span: sub_span.unwrap(), - scope: self.tcx.map.get_parent(expr.id), + scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(), ref_id: def_id, })) } From 15dcb5bfc51753aad5527888ec5a1c9381e8d1e1 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 25 Jun 2015 15:48:59 -0700 Subject: [PATCH 078/160] Alternate method --- src/librustc/ast_map/mod.rs | 214 +++++++++++++++++---------------- src/librustc_trans/save/mod.rs | 16 +-- 2 files changed, 117 insertions(+), 113 deletions(-) diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index 7c80ba376c368..800cd7e8aeea7 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -130,19 +130,19 @@ enum MapEntry<'ast> { NotPresent, /// All the node types, with a parent and scope ID. - EntryItem(NodeId, NodeId, &'ast Item), - EntryForeignItem(NodeId, NodeId, &'ast ForeignItem), - EntryTraitItem(NodeId, NodeId, &'ast TraitItem), - EntryImplItem(NodeId, NodeId, &'ast ImplItem), - EntryVariant(NodeId, NodeId, &'ast Variant), - EntryExpr(NodeId, NodeId, &'ast Expr), - EntryStmt(NodeId, NodeId, &'ast Stmt), - EntryArg(NodeId, NodeId, &'ast Pat), - EntryLocal(NodeId, NodeId, &'ast Pat), - EntryPat(NodeId, NodeId, &'ast Pat), - EntryBlock(NodeId, NodeId, &'ast Block), - EntryStructCtor(NodeId, NodeId, &'ast StructDef), - EntryLifetime(NodeId, NodeId, &'ast Lifetime), + EntryItem(NodeId, &'ast Item), + EntryForeignItem(NodeId, &'ast ForeignItem), + EntryTraitItem(NodeId, &'ast TraitItem), + EntryImplItem(NodeId, &'ast ImplItem), + EntryVariant(NodeId, &'ast Variant), + EntryExpr(NodeId, &'ast Expr), + EntryStmt(NodeId, &'ast Stmt), + EntryArg(NodeId, &'ast Pat), + EntryLocal(NodeId, &'ast Pat), + EntryPat(NodeId, &'ast Pat), + EntryBlock(NodeId, &'ast Block), + EntryStructCtor(NodeId, &'ast StructDef), + EntryLifetime(NodeId, &'ast Lifetime), /// Roots for node trees. RootCrate, @@ -162,77 +162,58 @@ struct InlinedParent { } impl<'ast> MapEntry<'ast> { - fn from_node(p: NodeId, s: NodeId, node: Node<'ast>) -> MapEntry<'ast> { + fn from_node(s: NodeId, node: Node<'ast>) -> MapEntry<'ast> { match node { - NodeItem(n) => EntryItem(p, s, n), - NodeForeignItem(n) => EntryForeignItem(p, s, n), - NodeTraitItem(n) => EntryTraitItem(p, s, n), - NodeImplItem(n) => EntryImplItem(p, s, n), - NodeVariant(n) => EntryVariant(p, s, n), - NodeExpr(n) => EntryExpr(p, s, n), - NodeStmt(n) => EntryStmt(p, s, n), - NodeArg(n) => EntryArg(p, s, n), - NodeLocal(n) => EntryLocal(p, s, n), - NodePat(n) => EntryPat(p, s, n), - NodeBlock(n) => EntryBlock(p, s, n), - NodeStructCtor(n) => EntryStructCtor(p, s, n), - NodeLifetime(n) => EntryLifetime(p, s, n) + NodeItem(n) => EntryItem(s, n), + NodeForeignItem(n) => EntryForeignItem(s, n), + NodeTraitItem(n) => EntryTraitItem(s, n), + NodeImplItem(n) => EntryImplItem(s, n), + NodeVariant(n) => EntryVariant(s, n), + NodeExpr(n) => EntryExpr(s, n), + NodeStmt(n) => EntryStmt(s, n), + NodeArg(n) => EntryArg(s, n), + NodeLocal(n) => EntryLocal(s, n), + NodePat(n) => EntryPat(s, n), + NodeBlock(n) => EntryBlock(s, n), + NodeStructCtor(n) => EntryStructCtor(s, n), + NodeLifetime(n) => EntryLifetime(s, n) } } - fn parent(self) -> Option { - Some(match self { - EntryItem(id, _, _) => id, - EntryForeignItem(id, _, _) => id, - EntryTraitItem(id, _, _) => id, - EntryImplItem(id, _, _) => id, - EntryVariant(id, _, _) => id, - EntryExpr(id, _, _) => id, - EntryStmt(id, _, _) => id, - EntryArg(id, _, _) => id, - EntryLocal(id, _, _) => id, - EntryPat(id, _, _) => id, - EntryBlock(id, _, _) => id, - EntryStructCtor(id, _, _) => id, - EntryLifetime(id, _, _) => id, - _ => return None - }) - } - fn parent_node(self) -> Option { Some(match self { - EntryItem(_, id, _) => id, - EntryForeignItem(_, id, _) => id, - EntryTraitItem(_, id, _) => id, - EntryImplItem(_, id, _) => id, - EntryVariant(_, id, _) => id, - EntryExpr(_, id, _) => id, - EntryStmt(_, id, _) => id, - EntryArg(_, id, _) => id, - EntryLocal(_, id, _) => id, - EntryPat(_, id, _) => id, - EntryBlock(_, id, _) => id, - EntryStructCtor(_, id, _) => id, - EntryLifetime(_, id, _) => id, + EntryItem(id, _) => id, + EntryForeignItem(id, _) => id, + EntryTraitItem(id, _) => id, + EntryImplItem(id, _) => id, + EntryVariant(id, _) => id, + EntryExpr(id, _) => id, + EntryStmt(id, _) => id, + EntryArg(id, _) => id, + EntryLocal(id, _) => id, + EntryPat(id, _) => id, + EntryBlock(id, _) => id, + EntryStructCtor(id, _) => id, + EntryLifetime(id, _) => id, _ => return None }) } fn to_node(self) -> Option> { Some(match self { - EntryItem(_, _, n) => NodeItem(n), - EntryForeignItem(_, _, n) => NodeForeignItem(n), - EntryTraitItem(_, _, n) => NodeTraitItem(n), - EntryImplItem(_, _, n) => NodeImplItem(n), - EntryVariant(_, _, n) => NodeVariant(n), - EntryExpr(_, _, n) => NodeExpr(n), - EntryStmt(_, _, n) => NodeStmt(n), - EntryArg(_, _, n) => NodeArg(n), - EntryLocal(_, _, n) => NodeLocal(n), - EntryPat(_, _, n) => NodePat(n), - EntryBlock(_, _, n) => NodeBlock(n), - EntryStructCtor(_, _, n) => NodeStructCtor(n), - EntryLifetime(_, _, n) => NodeLifetime(n), + EntryItem(_, n) => NodeItem(n), + EntryForeignItem(_, n) => NodeForeignItem(n), + EntryTraitItem(_, n) => NodeTraitItem(n), + EntryImplItem(_, n) => NodeImplItem(n), + EntryVariant(_, n) => NodeVariant(n), + EntryExpr(_, n) => NodeExpr(n), + EntryStmt(_, n) => NodeStmt(n), + EntryArg(_, n) => NodeArg(n), + EntryLocal(_, n) => NodeLocal(n), + EntryPat(_, n) => NodePat(n), + EntryBlock(_, n) => NodeBlock(n), + EntryStructCtor(_, n) => NodeStructCtor(n), + EntryLifetime(_, n) => NodeLifetime(n), _ => return None }) } @@ -306,7 +287,37 @@ impl<'ast> Map<'ast> { /// Retrieve the parent NodeId for `id`, or `id` itself if no /// parent is registered in this map. pub fn get_parent(&self, id: NodeId) -> NodeId { - self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id) + let mut id = id; + loop { + let parent_node = self.get_parent_node(id); + if parent_node == 0 { + return parent_node; + } + if parent_node == id { + return id; + } + + let node = self.find_entry(parent_node); + if node.is_none() { + return id; + } + let node = node.unwrap().to_node(); + match node { + Some(node) => match node { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) => { + return parent_node; + } + _ => {} + }, + None => { + return parent_node; + } + } + id = parent_node; + } } /// Similar to get_parent, returns the parent node id or id if there is no @@ -334,6 +345,10 @@ impl<'ast> Map<'ast> { return None; } + if cur_id == 0 { + return Some(0); + } + match self.get(cur_id) { NodeItem(_) | NodeForeignItem(_) | @@ -361,7 +376,7 @@ impl<'ast> Map<'ast> { pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi { let parent = self.get_parent(id); let abi = match self.find_entry(parent) { - Some(EntryItem(_, _, i)) => { + Some(EntryItem(_, i)) => { match i.node { ItemForeignMod(ref nm) => Some(nm.abi), _ => None @@ -650,15 +665,15 @@ impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> { return None; } self.idx += 1; - let (p, name) = match self.map.find_entry(idx) { - Some(EntryItem(p, _, n)) => (p, n.name()), - Some(EntryForeignItem(p, _, n))=> (p, n.name()), - Some(EntryTraitItem(p, _, n)) => (p, n.name()), - Some(EntryImplItem(p, _, n)) => (p, n.name()), - Some(EntryVariant(p, _, n)) => (p, n.name()), + let name = match self.map.find_entry(idx) { + Some(EntryItem(_, n)) => n.name(), + Some(EntryForeignItem(_, n))=> n.name(), + Some(EntryTraitItem(_, n)) => n.name(), + Some(EntryImplItem(_, n)) => n.name(), + Some(EntryVariant(_, n)) => n.name(), _ => continue, }; - if self.matches_names(p, name) { + if self.matches_names(self.map.get_parent(idx), name) { return Some(idx) } } @@ -707,8 +722,6 @@ impl Folder for IdAndSpanUpdater { /// A Visitor that walks over an AST and collects Node's into an AST Map. struct NodeCollector<'ast> { map: Vec>, - /// The node in which we are currently mapping (an item or a method). - parent: NodeId, parent_node: NodeId, } @@ -723,7 +736,7 @@ impl<'ast> NodeCollector<'ast> { } fn insert(&mut self, id: NodeId, node: Node<'ast>) { - let entry = MapEntry::from_node(self.parent, self.parent_node, node); + let entry = MapEntry::from_node(self.parent_node, node); self.insert_entry(id, entry); } @@ -737,10 +750,10 @@ impl<'ast> NodeCollector<'ast> { impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_item(&mut self, i: &'ast Item) { self.insert(i.id, NodeItem(i)); - let parent = self.parent; - self.parent = i.id; + let parent_node = self.parent_node; self.parent_node = i.id; + match i.node { ItemImpl(_, _, _, _, _, ref impl_items) => { for ii in impl_items { @@ -790,55 +803,51 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { _ => {} } visit::walk_item(self, i); - self.parent = parent; self.parent_node = parent_node; } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { - let parent = self.parent; - self.parent = ti.id; let parent_node = self.parent_node; self.parent_node = ti.id; visit::walk_trait_item(self, ti); - self.parent = parent; self.parent_node = parent_node; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { - let parent = self.parent; - self.parent = ii.id; let parent_node = self.parent_node; self.parent_node = ii.id; + visit::walk_impl_item(self, ii); - self.parent = parent; + self.parent_node = parent_node; } fn visit_pat(&mut self, pat: &'ast Pat) { - let parent_node = self.parent_node; - self.parent_node = pat.id; self.insert(pat.id, match pat.node { // Note: this is at least *potentially* a pattern... PatIdent(..) => NodeLocal(pat), _ => NodePat(pat) }); + + let parent_node = self.parent_node; + self.parent_node = pat.id; visit::walk_pat(self, pat); self.parent_node = parent_node; } fn visit_expr(&mut self, expr: &'ast Expr) { + self.insert(expr.id, NodeExpr(expr)); let parent_node = self.parent_node; self.parent_node = expr.id; - self.insert(expr.id, NodeExpr(expr)); visit::walk_expr(self, expr); self.parent_node = parent_node; } fn visit_stmt(&mut self, stmt: &'ast Stmt) { let id = ast_util::stmt_id(stmt); + self.insert(id, NodeStmt(stmt)); let parent_node = self.parent_node; self.parent_node = id; - self.insert(id, NodeStmt(stmt)); visit::walk_stmt(self, stmt); self.parent_node = parent_node; } @@ -866,18 +875,15 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_block(&mut self, block: &'ast Block) { + self.insert(block.id, NodeBlock(block)); let parent_node = self.parent_node; self.parent_node = block.id; - self.insert(block.id, NodeBlock(block)); visit::walk_block(self, block); self.parent_node = parent_node; } fn visit_lifetime_ref(&mut self, lifetime: &'ast Lifetime) { - let parent_node = self.parent_node; - self.parent_node = lifetime.id; self.insert(lifetime.id, NodeLifetime(lifetime)); - self.parent_node = parent_node; } fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { @@ -901,7 +907,6 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map let mut collector = NodeCollector { map: vec![], - parent: CRATE_NODE_ID, parent_node: CRATE_NODE_ID, }; collector.insert_entry(CRATE_NODE_ID, RootCrate); @@ -957,12 +962,11 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, ii: ii }); + let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let mut collector = NodeCollector { map: mem::replace(&mut *map.map.borrow_mut(), vec![]), - parent: fld.new_id(DUMMY_NODE_ID), - parent_node: fld.new_id(DUMMY_NODE_ID), + parent_node: ii_parent_id, }; - let ii_parent_id = collector.parent; collector.insert_entry(ii_parent_id, RootInlinedParent(ii_parent)); visit::walk_inlined_item(&mut collector, &ii_parent.ii); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index e9c91f4f4c194..9d66e99df3057 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -172,7 +172,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname: qualname, declaration: None, span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0), }) } ast::ItemStatic(ref typ, mt, ref expr) => { @@ -191,7 +191,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0), value: value, type_value: ty_to_string(&typ), }) @@ -205,7 +205,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0), value: self.span_utils.snippet(expr.span), type_value: ty_to_string(&typ), }) @@ -223,7 +223,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: get_ident(item.ident).to_string(), qualname: qualname, span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0), filename: filename, }) }, @@ -237,14 +237,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { value: val, span: sub_span.unwrap(), qualname: enum_name, - scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0), }) }, ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => { let mut type_data = None; let sub_span; - let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap(); + let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0); match typ.node { // Common case impl for a struct or something basic. @@ -337,7 +337,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { return Some(Data::VariableRefData(VariableRefData { name: get_ident(ident.node).to_string(), span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0), ref_id: f.id, })); } @@ -360,7 +360,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let sub_span = self.span_utils.span_for_last_ident(path.span); Some(Data::TypeRefData(TypeRefData { span: sub_span.unwrap(), - scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(), + scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0), ref_id: def_id, })) } From 6947948b4df98b82a9e8f6847db442921edfc37b Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Fri, 26 Jun 2015 12:23:41 -0700 Subject: [PATCH 079/160] Move FufillmentContext into InferContext --- src/librustc/middle/infer/mod.rs | 13 ++++++++++- src/librustc/middle/traits/mod.rs | 2 +- src/librustc_trans/trans/common.rs | 4 ++-- src/librustc_trans/trans/monomorphize.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 ++-- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 25 ++++++++++++--------- src/librustc_typeck/check/regionck.rs | 12 ++++++---- src/librustc_typeck/coherence/mod.rs | 5 +++-- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- 13 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index c355e8b82a6ef..4617d3860a3a6 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -87,6 +87,8 @@ pub struct InferCtxt<'a, 'tcx: 'a> { pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, + pub fulfillment_cx: RefCell>, + // 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 @@ -327,9 +329,16 @@ pub fn fixup_err_to_string(f: fixup_err) -> String { } } +/// errors_will_be_reported is required to proxy to the fulfillment context +/// FIXME -- a better option would be to hold back on modifying +/// the global cache until we know that all dependent obligations +/// are also satisfied. In that case, we could actually remove +/// this boolean flag, and we'd also avoid the problem of squelching +/// duplicate errors that occur across fns. pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, tables: &'a RefCell>, - param_env: Option>) + param_env: Option>, + errors_will_be_reported: bool) -> InferCtxt<'a, 'tcx> { InferCtxt { tcx: tcx, @@ -339,6 +348,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()), + fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)), normalize: false, err_count_on_creation: tcx.sess.err_count() } @@ -1009,6 +1019,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { raw_ty.adjust(self.tcx, expr.span, expr.id, + raw_ty, adjustment, |method_call| self.tables .borrow() diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 9df6ed5d68126..c5afb7dd3db25 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, &tcx.tables, Some(elaborated_env)); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env), false); let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 9c2aea1e67adf..32a1f74063bba 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -957,7 +957,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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -1019,7 +1019,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, &tcx.tables, None); + let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); 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 67ccf64621a85..6ad164719cf6f 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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); 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/closure.rs b/src/librustc_typeck/check/closure.rs index b5ee46ece94be..6d1e9dfacf281 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -125,7 +125,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>( expected_vid: ty::TyVid) -> (Option>, Option) { - let fulfillment_cx = fcx.inh.fulfillment_cx.borrow(); + let fulfillment_cx = fcx.inh.infcx.fulfillment_cx.borrow(); // Here `expected_ty` is known to be a type inference variable. let expected_sig = diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index f62411e85828d..6375926298f3c 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, &tcx.tables, None); + let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); let mut fulfillment_cx = traits::FulfillmentContext::new(true); let trait_to_impl_substs = &impl_trait_ref.substs; @@ -419,7 +419,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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); 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 6f0fbfebf46cc..7d911cf8b03bc 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -93,7 +93,7 @@ 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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); infcx.commit_if_ok(|snapshot| { let (named_type_to_skolem, skol_map) = diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2db1598db4bee..76286cfe9ba04 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -159,7 +159,7 @@ pub struct Inherited<'a, 'tcx: 'a> { fn_sig_map: RefCell>>>, // Tracks trait obligations incurred during this function body. - fulfillment_cx: RefCell>, + // fulfillment_cx: RefCell>, // When we process a call like `c()` where `c` is a closure type, // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or @@ -295,11 +295,11 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { -> Inherited<'a, 'tcx> { Inherited { - infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)), + // I'm probably screwed here ... more boolean prop ... + infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), false), locals: RefCell::new(NodeMap()), tables: tables, fn_sig_map: RefCell::new(NodeMap()), - fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)), deferred_call_resolutions: RefCell::new(DefIdMap()), deferred_cast_checks: RefCell::new(Vec::new()), } @@ -313,7 +313,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { -> T where T : TypeFoldable<'tcx> + HasTypeFlags { - let mut fulfillment_cx = self.fulfillment_cx.borrow_mut(); + let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, typer, &mut *fulfillment_cx, span, @@ -1389,7 +1389,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = traits::ObligationCause::new(span, self.body_id, traits::ObligationCauseCode::MiscObligation); - self.inh.fulfillment_cx + self.inh + .infcx + .fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), self.infcx(), @@ -1513,7 +1515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { builtin_bound: ty::BuiltinBound, cause: traits::ObligationCause<'tcx>) { - self.inh.fulfillment_cx.borrow_mut() + self.inh.infcx.fulfillment_cx.borrow_mut() .register_builtin_bound(self.infcx(), ty, builtin_bound, cause); } @@ -1522,7 +1524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { debug!("register_predicate({:?})", obligation); - self.inh.fulfillment_cx + self.inh.infcx.fulfillment_cx .borrow_mut() .register_predicate_obligation(self.infcx(), obligation); } @@ -1558,6 +1560,7 @@ 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| { + .method_map self.inh.tables.borrow().method_map.get(&method_call) .map(|method| resolve_ty(method.ty)) }) @@ -1648,7 +1651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { region: ty::Region, cause: traits::ObligationCause<'tcx>) { - let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut(); + let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut(); fulfillment_cx.register_region_obligation(ty, region, cause); } @@ -1747,7 +1750,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { assert!(self.inh.deferred_call_resolutions.borrow().is_empty()); self.select_all_obligations_and_apply_defaults(); - let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut(); + let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut(); match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -1757,7 +1760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Select as many obligations as we can at present. fn select_obligations_where_possible(&self) { match - self.inh.fulfillment_cx + self.inh.infcx.fulfillment_cx .borrow_mut() .select_where_possible(self.infcx(), self.infcx()) { @@ -1772,7 +1775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// work. fn select_new_obligations(&self) { match - self.inh.fulfillment_cx + self.inh.infcx.fulfillment_cx .borrow_mut() .select_new_obligations(self.infcx(), self.infcx()) { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a86301907385a..661e1856ce8cd 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -318,9 +318,13 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { // Make a copy of the region obligations vec because we'll need // to be able to borrow the fulfillment-cx below when projecting. let region_obligations = - self.fcx.inh.fulfillment_cx.borrow() - .region_obligations(node_id) - .to_vec(); + self.fcx + .inh + .infcx + .fulfillment_cx + .borrow() + .region_obligations(node_id) + .to_vec(); for r_o in ®ion_obligations { debug!("visit_region_obligations: r_o={:?}", @@ -332,7 +336,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { // Processing the region obligations should not cause the list to grow further: assert_eq!(region_obligations.len(), - self.fcx.inh.fulfillment_cx.borrow().region_obligations(node_id).len()); + self.fcx.inh.infcx.fulfillment_cx.borrow().region_obligations(node_id).len()); } /// This method populates the region map's `free_region_map`. It walks over the transformed diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fbabc287342e9..23336c4399566 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, &tcx.tables, Some(param_env)); + let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env), true); let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>, mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| { @@ -632,7 +632,8 @@ 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, &crate_context.tcx.tables, None), + // XXXJAREDXXX: not sure if the bool is right here? + inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, false), 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 3495714fcc736..42c6bcbfbb999 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, &self.tcx.tables, None); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false); 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 7909908079fb3..c45fbb70002d1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2211,7 +2211,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>( base_type, base_type_free); - let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); drop(::require_same_types(tcx, Some(&infcx), false, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 48a64675c708a..8c3ef4ae631c3 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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2) } Some(infcx) => { From 64f1a59daf4b7b5cbab1730f3b10fb73745d3b5e Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 17:37:13 -0700 Subject: [PATCH 080/160] Update all uses of FulfillmentContext Update all uses of FulfillmentContext to be ones obtained via an InferCtxt. This is another step of flattening the type checking context into a single piece of state. --- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/traits/mod.rs | 5 +++-- src/librustc_trans/trans/common.rs | 6 +++--- src/librustc_trans/trans/monomorphize.rs | 3 ++- src/librustc_typeck/check/compare_method.rs | 4 ++-- src/librustc_typeck/coherence/mod.rs | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 8bbb6ae757fc1..16193e11b4142 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -284,8 +284,8 @@ 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, &self.tcx.tables, None); - let mut fulfill_cx = traits::FulfillmentContext::new(false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { Ok(()) => { }, diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index c5afb7dd3db25..ff84c1755a4d6 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -322,7 +322,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty, bound); - let mut fulfill_cx = FulfillmentContext::new(false); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any @@ -438,7 +438,8 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); - let mut fulfill_cx = FulfillmentContext::new(false); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); debug!("normalize_param_env: normalized_value={:?} obligations={:?}", diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 32a1f74063bba..92aeb9f7b720e 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -994,7 +994,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Currently, we use a fulfillment context to completely resolve // all nested obligations. This is because they can inform the // inference of the impl's type parameters. - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let vtable = selection.map(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); @@ -1019,10 +1019,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, predicates); let tcx = ccx.tcx(); - let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); - let mut fulfill_cx = traits::FulfillmentContext::new(false); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = traits::normalize(&mut selcx, cause.clone(), &predicates); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 6ad164719cf6f..b88251c69a0a9 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -335,7 +335,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T result, obligations); - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + for obligation in obligations { fulfill_cx.register_predicate_obligation(&infcx, obligation); } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 6375926298f3c..85478945e1cfc 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -44,7 +44,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_trait_ref); let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut fulfillment_cx = traits::FulfillmentContext::new(true); + let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut(); let trait_to_impl_substs = &impl_trait_ref.substs; @@ -420,7 +420,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, impl_trait_ref); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut fulfillment_cx = traits::FulfillmentContext::new(true); + let mut fulfillment_cx = infcx.fulfillment_cx.borrow_mut(); // The below is for the most part highly similar to the procedure // for methods above. It is simpler in many respects, especially diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 23336c4399566..9705cfae4d3e9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }; - let mut fulfill_cx = traits::FulfillmentContext::new(true); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_did.node); From 0f13a3f361384c278041c95e9a2ba9975e6cde71 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 17:37:22 -0700 Subject: [PATCH 081/160] Use fresh FulfillmentContexts in select locations --- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/mod.rs | 1 - src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/traits/mod.rs | 14 ++++++++++++-- src/librustc/middle/ty.rs | 2 +- src/librustc_typeck/check/mod.rs | 7 +++---- src/librustc_typeck/coherence/mod.rs | 4 ++-- 8 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 16193e11b4142..95a598ad115ae 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, &self.tcx.tables, None); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None, false); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); 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 a6b7d7f832a3c..7d4553c8b146a 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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); 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 4617d3860a3a6..04c29aaeb5a6f 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1019,7 +1019,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { raw_ty.adjust(self.tcx, expr.span, expr.id, - raw_ty, adjustment, |method_call| self.tables .borrow() diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index dc3ccd417b8f7..a769ef8233e68 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -85,7 +85,7 @@ pub struct FulfillmentContext<'tcx> { // particular node-id). region_obligations: NodeMap>>, - errors_will_be_reported: bool, + pub errors_will_be_reported: bool, } #[derive(Clone)] diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index ff84c1755a4d6..c398a24f4f67c 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -322,7 +322,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty, bound); - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let mut fulfill_cx = FulfillmentContext::new(false); // We can use a dummy node-id here because we won't pay any mind // to region obligations that arise (there shouldn't really be any @@ -438,7 +438,17 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + // FIXME (@jroesch): I'm not sure if this is a bug or not, needs + // further investigation. It appears that by reusing the fulfillment_cx + // here we incur more obligations and later trip an asssertion on + // regionck.rs line 337. The two possibilities I see is that + // normalization is not actually fully happening and we + // have a bug else where or that we are adding a duplicate + // bound into the list causing its size to change. I think + // we should probably land this refactor and then come + // back to this is a follow-up patch. + let mut fulfill_cx = FulfillmentContext::new(false); + // let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index fe52fba49c6e5..8e5b6f4d4507f 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4401,7 +4401,7 @@ impl<'tcx> TyS<'tcx> { -> bool { let tcx = param_env.tcx(); - let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone())); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, self, bound, span); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 76286cfe9ba04..806bcb2306bd1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -295,8 +295,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { -> Inherited<'a, 'tcx> { Inherited { - // I'm probably screwed here ... more boolean prop ... - infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), false), + infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env), true), locals: RefCell::new(NodeMap()), tables: tables, fn_sig_map: RefCell::new(NodeMap()), @@ -316,7 +315,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, typer, - &mut *fulfillment_cx, span, + &mut fulfillment_cx, + span, body_id, value) } @@ -1560,7 +1560,6 @@ 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| { - .method_map self.inh.tables.borrow().method_map.get(&method_call) .map(|method| resolve_ty(method.ty)) }) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 9705cfae4d3e9..1219f2928c1c8 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } }; - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); // Register an obligation for `A: Trait`. let cause = traits::ObligationCause::misc(span, impl_did.node); @@ -633,7 +633,7 @@ pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, // XXXJAREDXXX: not sure if the bool is right here? - inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, false), + inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, true), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); unsafety::check(crate_context.tcx); From fb295a60b37fc2bc60fab29fad1863a174fa587c Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sat, 27 Jun 2015 22:04:15 -0700 Subject: [PATCH 082/160] Remove NormalizingClosureTyper --- src/librustc/middle/infer/mod.rs | 164 +++++++++++++++++- src/librustc_trans/trans/adt.rs | 9 +- src/librustc_trans/trans/attributes.rs | 5 +- src/librustc_trans/trans/base.rs | 5 +- src/librustc_trans/trans/closure.rs | 10 +- src/librustc_trans/trans/common.rs | 81 ++------- .../trans/debuginfo/metadata.rs | 11 +- src/librustc_trans/trans/declare.rs | 6 +- src/librustc_trans/trans/monomorphize.rs | 7 +- 9 files changed, 204 insertions(+), 94 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 04c29aaeb5a6f..91fee77f0a7a3 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -19,6 +19,7 @@ pub use self::TypeOrigin::*; pub use self::ValuePairs::*; pub use self::fixup_err::*; pub use middle::ty::IntVarValue; +use middle::ty::ClosureTyper; pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; @@ -29,7 +30,8 @@ use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; -use middle::traits; +use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, + SelectionContext, ObligationCause}; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; @@ -39,7 +41,7 @@ use std::cell::{RefCell, Ref}; use std::fmt; use syntax::ast; use syntax::codemap; -use syntax::codemap::Span; +use syntax::codemap::{Span, DUMMY_SP}; use util::nodemap::{FnvHashMap, NodeMap}; use self::combine::CombineFields; @@ -354,6 +356,14 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, } } +pub fn normalizing_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, + tables: &'a RefCell>) + -> InferCtxt<'a, 'tcx> { + let mut infcx = new_infer_ctxt(tcx, tables, None, false); + infcx.normalize = true; + infcx +} + /// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and /// returns ty::err. pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, @@ -557,7 +567,8 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { // 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") + normalize_associated_type(&self.tcx, &closure_ty) + // panic!("see issue 26597: fufillment context refactor must occur") } else { closure_ty } @@ -579,13 +590,158 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { // 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") + // panic!("see issue 26597: fufillment context refactor must occur") + normalize_associated_type(&self.tcx, &result) } else { result } } } +pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T + where T : TypeFoldable<'tcx> + HasTypeFlags +{ + debug!("normalize_associated_type(t={:?})", value); + + let value = erase_regions(tcx, value); + + if !value.has_projection_types() { + return value; + } + + let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let cause = traits::ObligationCause::dummy(); + let traits::Normalized { value: result, obligations } = + traits::normalize(&mut selcx, cause, &value); + + debug!("normalize_associated_type: result={:?} obligations={:?}", + result, + obligations); + + let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); + + for obligation in obligations { + fulfill_cx.register_predicate_obligation(&infcx, obligation); + } + + let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result); + + result +} + +pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, + infcx: &InferCtxt<'a,'tcx>, + fulfill_cx: &mut traits::FulfillmentContext<'tcx>, + result: &T) + -> T + where T : TypeFoldable<'tcx> +{ + match drain_fulfillment_cx(infcx, fulfill_cx, result) { + Ok(v) => v, + Err(errors) => { + infcx.tcx.sess.span_bug( + span, + &format!("Encountered errors `{:?}` fulfilling during trans", + errors)); + } + } +} + +/// Finishes processes any obligations that remain in the fulfillment +/// context, and then "freshens" and returns `result`. This is +/// primarily used during normalization and other cases where +/// processing the obligations in `fulfill_cx` may cause type +/// inference variables that appear in `result` to be unified, and +/// hence we need to process those obligations to get the complete +/// picture of the type. +pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, + fulfill_cx: &mut traits::FulfillmentContext<'tcx>, + result: &T) + -> Result>> + where T : TypeFoldable<'tcx> +{ + debug!("drain_fulfillment_cx(result={:?})", + result); + // this is stupid but temporary + let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` + // contains unbound type parameters. It could be a slight + // optimization to stop iterating early. + match fulfill_cx.select_all_or_error(infcx, typer) { + Ok(()) => { } + Err(errors) => { + return Err(errors); + } + } + + // Use freshen to simultaneously replace all type variables with + // their bindings and replace all regions with 'static. This is + // sort of overkill because we do not expect there to be any + // unbound type variables, hence no `TyFresh` types should ever be + // inserted. + Ok(result.fold_with(&mut infcx.freshener())) +} + +/// Returns an equivalent value with all free regions removed (note +/// that late-bound regions remain, because they are important for +/// subtyping, but they are anonymized and normalized as well). This +/// is a stronger, caching version of `ty_fold::erase_regions`. +pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T + where T : TypeFoldable<'tcx> +{ + let value1 = value.fold_with(&mut RegionEraser(cx)); + debug!("erase_regions({:?}) = {:?}", + value, value1); + return value1; + + struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>); + + impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { + fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match self.tcx().normalized_cache.borrow().get(&ty).cloned() { + None => {} + Some(u) => return u + } + + let t_norm = ty_fold::super_fold_ty(self, ty); + self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); + return t_norm; + } + + fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder + where T : TypeFoldable<'tcx> + { + let u = self.tcx().anonymize_late_bound_regions(t); + ty_fold::super_fold_binder(self, &u) + } + + fn fold_region(&mut self, r: ty::Region) -> ty::Region { + // because late-bound regions affect subtyping, we can't + // erase the bound/free distinction, but we can replace + // all free regions with 'static. + // + // Note that we *CAN* replace early-bound regions -- the + // type system never "sees" those, they get substituted + // away. In trans, they will always be erased to 'static + // whenever a substitution occurs. + match r { + ty::ReLateBound(..) => r, + _ => ty::ReStatic + } + } + + fn fold_substs(&mut self, + substs: &subst::Substs<'tcx>) + -> subst::Substs<'tcx> { + subst::Substs { regions: subst::ErasedRegions, + types: substs.types.fold_with(self) } + } + } +} + impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn freshen>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 3ce76167e8517..b96dcf940a895 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -50,6 +50,7 @@ use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; use back::abi::FAT_PTR_ADDR; use middle::subst; +use middle::infer; use middle::ty::{self, Ty, ClosureTyper}; use middle::ty::Disr; use syntax::ast; @@ -223,8 +224,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor)) } ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); Univariant(mk_struct(cx, &upvar_types[..], false, t), 0) } @@ -443,8 +444,8 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, // Perhaps one of the upvars of this struct is non-zero // Let's recurse and find out! ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(tcx); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::>(); for (j, &ty) in upvar_types.iter().enumerate() { diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index b432560bc4b3c..fd704ed2d378b 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -12,6 +12,7 @@ use libc::{c_uint, c_ulonglong}; use llvm::{self, ValueRef, AttrHelper}; use middle::ty::{self, ClosureTyper}; +use middle::infer; use session::config::NoDebugInfo; use syntax::abi; use syntax::ast; @@ -145,8 +146,8 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx let (fn_sig, abi, env_ty) = match fn_type.sty { ty::TyBareFn(_, ref f) => (&f.sig, f.abi, None), ty::TyClosure(closure_did, substs) => { - let typer = common::NormalizingClosureTyper::new(ccx.tcx()); - function_type = typer.closure_type(closure_did, substs); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); (&function_type.sig, abi::RustCall, Some(self_type)) } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 0cd6bbad03aa9..088df7288bec5 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -37,6 +37,7 @@ use llvm; use metadata::{csearch, encoder, loader}; use middle::astencode; use middle::cfg; +use middle::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; @@ -434,8 +435,8 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, } ty::TyClosure(def_id, substs) => { let repr = adt::represent_type(cx.ccx(), t); - let typer = common::NormalizingClosureTyper::new(cx.tcx()); - let upvars = typer.closure_upvars(def_id, substs).unwrap(); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let upvars = infcx.closure_upvars(def_id, substs).unwrap(); for (i, upvar) in upvars.iter().enumerate() { let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i); cx = f(cx, llupvar, upvar.ty); diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index b637806285540..c9bab6861ca05 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -12,6 +12,7 @@ use arena::TypedArena; use back::link::{self, mangle_internal_name_by_path_and_seq}; use llvm::{ValueRef, get_params}; use middle::mem_categorization::Typer; +use middle::infer; use trans::adt; use trans::attributes; use trans::base::*; @@ -214,8 +215,9 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>, // takes the same set of type arguments as the enclosing fn, and // this function (`trans_closure`) is invoked at the point // of the closure expression. - let typer = NormalizingClosureTyper::new(tcx); - let function_type = typer.closure_type(closure_id, param_substs); + + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + let function_type = infcx.closure_type(closure_id, param_substs); let freevars: Vec = tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); @@ -358,7 +360,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( ccx.tn().val_to_string(llreffn)); let tcx = ccx.tcx(); - let typer = NormalizingClosureTyper::new(tcx); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); // Find a version of the closure type. Substitute static for the // region since it doesn't really matter. @@ -367,7 +369,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( 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); + let ty::ClosureTy { unsafety, abi, mut sig } = infcx.closure_type(closure_def_id, substs); sig.0.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety, abi: abi, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 92aeb9f7b720e..1fc68790db07a 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -24,6 +24,7 @@ use middle::infer; use middle::lang_items::LangItem; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; +use middle::ty::ClosureTyper; use middle::region; use middle::subst::{self, Substs}; use trans::base; @@ -642,8 +643,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { def_id: ast::DefId) -> Option { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_kind(def_id) + let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); + infcx.closure_kind(def_id) } fn closure_type(&self, @@ -651,8 +652,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_type(def_id, substs) + let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); + infcx.closure_type(def_id, substs) } fn closure_upvars(&self, @@ -660,8 +661,8 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { substs: &Substs<'tcx>) -> Option>> { - let typer = NormalizingClosureTyper::new(self.tcx()); - typer.closure_upvars(def_id, substs) + let infcx = infer::new_infer_ctxt(self.tcx(), &self.tcx().tables, None, true); + infcx.closure_upvars(def_id, substs) } } @@ -957,12 +958,12 @@ 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, &tcx.tables, None, true); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID), trait_ref.to_poly_trait_predicate()); @@ -1019,9 +1020,8 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, predicates); let tcx = ccx.tcx(); - let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = @@ -1036,57 +1036,6 @@ 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> -} - -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: tcx.empty_parameter_environment() } - } -} - -impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - &self.param_env - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - self.param_env.closure_kind(def_id) - } - - fn closure_type(&self, - def_id: ast::DefId, - 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.param_env.tcx.closure_type(def_id, substs); - monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - // the substitutions in `substs` are already monomorphized, - // but we still must normalize associated types - let result = self.param_env.closure_upvars(def_id, substs); - monomorphize::normalize_associated_type(self.param_env.tcx, &result) - } -} - pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, infcx: &infer::InferCtxt<'a,'tcx>, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, @@ -1120,12 +1069,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - + // this is stupid but temporary + let typer: &ClosureTyper<'tcx> = infcx; // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - let typer = NormalizingClosureTyper::new(infcx.tcx); - match fulfill_cx.select_all_or_error(infcx, &typer) { + match fulfill_cx.select_all_or_error(infcx, typer) { Ok(()) => { } Err(errors) => { return Err(errors); diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 1fbbf0763aa53..12892c87b4687 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -26,9 +26,10 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType}; use metadata::csearch; use middle::pat_util; use middle::subst::{self, Substs}; +use middle::infer; use rustc::ast_map; use trans::{type_of, adt, machine, monomorphize}; -use trans::common::{self, CrateContext, FunctionContext, NormalizingClosureTyper, Block}; +use trans::common::{self, CrateContext, FunctionContext, Block}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; use trans::type_::Type; use middle::ty::{self, Ty, ClosureTyper}; @@ -287,8 +288,8 @@ impl<'tcx> TypeMap<'tcx> { } }, ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let closure_ty = typer.closure_type(def_id, substs); + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let closure_ty = infcx.closure_type(def_id, substs); self.get_unique_type_id_of_closure_type(cx, closure_ty, &mut unique_type_id); @@ -796,8 +797,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span) } ty::TyClosure(def_id, substs) => { - let typer = NormalizingClosureTyper::new(cx.tcx()); - let sig = typer.closure_type(def_id, substs).sig; + let infcx = infer::normalizing_infer_ctxt(cx.tcx(), &cx.tcx().tables); + let sig = infcx.closure_type(def_id, substs).sig; subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span) } ty::TyStruct(def_id, substs) => { diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index 646ca6733c3b6..0eaaaaa5b3414 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -21,10 +21,10 @@ //! * When in doubt, define. use llvm::{self, ValueRef}; use middle::ty::{self, ClosureTyper}; +use middle::infer; use syntax::abi; use trans::attributes; use trans::base; -use trans::common; use trans::context::CrateContext; use trans::monomorphize; use trans::type_::Type; @@ -117,8 +117,8 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, (&f.sig, f.abi, None) } ty::TyClosure(closure_did, substs) => { - let typer = common::NormalizingClosureTyper::new(ccx.tcx()); - function_type = typer.closure_type(closure_did, substs); + let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); + function_type = infcx.closure_type(closure_did, substs); let self_type = base::self_type_for_closure(ccx, closure_did, fn_type); let llenvironment_type = type_of::type_of_explicit_arg(ccx, self_type); debug!("declare_rust_fn function_type={:?} self_type={:?}", diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index b88251c69a0a9..b297a731d29e7 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -324,9 +324,8 @@ 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, &tcx.tables, None, true); - let typer = NormalizingClosureTyper::new(tcx); - let mut selcx = traits::SelectionContext::new(&infcx, &typer); + let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); @@ -336,7 +335,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T obligations); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); - + for obligation in obligations { fulfill_cx.register_predicate_obligation(&infcx, obligation); } From e2d7e904ca621b72a7445e666baba4b282d2bb7d Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Sun, 28 Jun 2015 23:03:47 -0700 Subject: [PATCH 083/160] Remove Typer + ClosureTyper impls for ParameterEnv --- src/librustc/middle/check_const.rs | 9 +- src/librustc/middle/check_match.rs | 10 +- src/librustc/middle/check_rvalues.rs | 7 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc/middle/traits/coherence.rs | 3 +- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/ty.rs | 91 +++---------------- src/librustc_borrowck/borrowck/check_loans.rs | 6 +- .../borrowck/gather_loans/mod.rs | 9 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_trans/trans/_match.rs | 3 +- src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/datum.rs | 5 +- src/librustc_typeck/check/compare_method.rs | 12 +-- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 2 +- 18 files changed, 60 insertions(+), 117 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 95a598ad115ae..139750af6284a 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -111,13 +111,16 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { fn with_euv<'b, F, R>(&'b mut self, item_id: Option, f: F) -> R where F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'tcx, - ty::ParameterEnvironment<'a, 'tcx>>) -> R, + infer::InferCtxt<'a, 'tcx>>) -> R, { let param_env = match item_id { Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id), None => self.tcx.empty_parameter_environment() }; - f(&mut euv::ExprUseVisitor::new(self, ¶m_env)) + + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); + + f(&mut euv::ExprUseVisitor::new(self, &infcx)) } fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif { @@ -287,7 +290,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) { + match fulfill_cx.select_all_or_error(&infcx, &infcx) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index f61884e213666..900a231835e59 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -20,6 +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::infer; use middle::mem_categorization::{cmt, Typer}; use middle::pat_util::*; use middle::ty::*; @@ -1111,7 +1112,9 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, match p.node { ast::PatIdent(ast::BindByValue(_), _, ref sub) => { let pat_ty = tcx.node_id_to_type(p.id); - if cx.param_env.type_moves_by_default(pat_ty, pat.span) { + //FIXME: (@jroesch) this code should be floated up as well + let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(cx.param_env.clone()), false); + if infcx.type_moves_by_default(pat_ty, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } } @@ -1139,8 +1142,9 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, let mut checker = MutationChecker { cx: cx, }; - let mut visitor = ExprUseVisitor::new(&mut checker, - &checker.cx.param_env); + + let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(checker.cx.param_env.clone()), false); + let mut visitor = ExprUseVisitor::new(&mut checker, &infcx); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 1489e946fe2ce..23accf88dc9d3 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -12,6 +12,7 @@ // is the public starting point. use middle::expr_use_visitor as euv; +use middle::infer; use middle::mem_categorization as mc; use middle::ty::ParameterEnvironment; use middle::ty; @@ -38,9 +39,11 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { s: Span, fn_id: ast::NodeId) { { + // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; - let mut euv = euv::ExprUseVisitor::new(&mut delegate, ¶m_env); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); + let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &infcx.parameter_environment }; + let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); } visit::walk_fn(self, fk, fd, b, s) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 7d4553c8b146a..b98864304d25e 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1033,7 +1033,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); 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/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 91fee77f0a7a3..31bfc01886c0f 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { } fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.parameter_environment.temporary_scope(rvalue_id) + self.tcx.region_maps.temporary_scope(rvalue_id) } fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 371b5c309a850..25b336f0c7a6a 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -38,8 +38,7 @@ pub fn overlapping_impls(infcx: &InferCtxt, impl1_def_id, impl2_def_id); - let param_env = &infcx.tcx.empty_parameter_environment(); - let selcx = &mut SelectionContext::intercrate(infcx, param_env); + let selcx = &mut SelectionContext::intercrate(infcx, infcx); infcx.probe(|_| { overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) }) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index c398a24f4f67c..8c065e182cd41 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -398,7 +398,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, &tcx.tables, Some(elaborated_env), false); - let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause, + let predicates = match fully_normalize(&infcx, &infcx, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, Err(errors) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8e5b6f4d4507f..23aa840703bbf 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,6 @@ use middle::dependency_format; use middle::fast_reject; use middle::free_region::FreeRegionMap; 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; @@ -2919,11 +2918,14 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { -> Result<(),CopyImplementationError> { let tcx = self.tcx; + // FIXME: (@jroesch) float this code up + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(self.clone()), false); + 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) { + if infcx.type_moves_by_default(field.mt.ty, span) { return Err(FieldDoesNotImplementCopy(field.name)) } } @@ -2935,7 +2937,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { 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) { + if infcx.type_moves_by_default(substd_arg_type, span) { return Err(VariantDoesNotImplementCopy(variant.name)) } } @@ -4272,7 +4274,8 @@ impl<'tcx> TyS<'tcx> { 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(); + let infcx = infer::new_infer_ctxt(cx, &cx.tables, Some(param_env), false); + let upvars = infcx.closure_upvars(did, substs).unwrap(); TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache)) } @@ -4400,10 +4403,10 @@ impl<'tcx> TyS<'tcx> { span: Span) -> bool { - let tcx = param_env.tcx(); + let tcx = param_env.tcx; let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); - let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, + let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, &infcx, self, bound, span); debug!("Ty::impls_bound({:?}, {:?}) = {:?}", @@ -4412,7 +4415,8 @@ impl<'tcx> TyS<'tcx> { is_impld } - fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, + // temp hack, probably should be private + pub 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); @@ -6711,79 +6715,6 @@ impl<'tcx> ctxt<'tcx> { } } -impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> { - fn node_ty(&self, id: ast::NodeId) -> mc::McResult> { - Ok(self.tcx.node_id_to_type(id)) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult> { - Ok(self.tcx.expr_ty_adjusted(expr)) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - 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.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone()) - } - - 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 { - self.tcx.is_method_call(id) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx.region_maps.temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.tcx.upvar_capture(upvar_id) - } - - fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - ty.moves_by_default(self, span) - } -} - -impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> { - fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { - self - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - Some(self.tcx.closure_kind(def_id)) - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.tcx.closure_type(def_id, substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> { - ctxt::closure_upvars(self, def_id, substs) - } -} - - /// The category of explicit self. #[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum ExplicitSelfCategory { diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 9d4fb4c994d40..7c2318eef9cdd 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -21,6 +21,7 @@ use self::UseError::*; use borrowck::*; use borrowck::InteriorKind::{InteriorElement, InteriorField}; use rustc::middle::expr_use_visitor as euv; +use rustc::middle::infer; use rustc::middle::mem_categorization as mc; use rustc::middle::region; use rustc::middle::ty; @@ -198,17 +199,18 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, debug!("check_loans(body id={})", body.id); let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); + let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false); let mut clcx = CheckLoanCtxt { bccx: bccx, dfcx_loans: dfcx_loans, move_data: move_data, all_loans: all_loans, - param_env: ¶m_env, + param_env: &infcx.parameter_environment }; { - let mut euv = euv::ExprUseVisitor::new(&mut clcx, ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut clcx, &infcx); euv.walk_fn(decl, body); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 44a4a0d250402..432d6289efec5 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -19,6 +19,7 @@ use borrowck::*; use borrowck::move_data::MoveData; use rustc::middle::expr_use_visitor as euv; +use rustc::middle::infer; use rustc::middle::mem_categorization as mc; use rustc::middle::region; use rustc::middle::ty; @@ -49,9 +50,9 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, }; let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); - + let infcx = infer::new_infer_ctxt(bccx.tcx, &bccx.tcx.tables, Some(param_env), false); { - let mut euv = euv::ExprUseVisitor::new(&mut glcx, ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut glcx, &infcx); euv.walk_fn(decl, body); } @@ -490,8 +491,8 @@ 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 = self.bccx.tcx.empty_parameter_environment(); - let mc = mc::MemCategorizationContext::new(¶m_env); + let infcx = infer::new_infer_ctxt(self.bccx.tcx, &self.bccx.tcx.tables, None, false); + let mc = mc::MemCategorizationContext::new(&infcx); let base_cmt = mc.cat_expr(&**base).unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4f726044a1bac..3cf2a62b3b674 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -747,7 +747,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { -> (&'static str, &'static str) { match ty.sty { _ => { - if param_env.type_moves_by_default(ty, span) { + if ty.moves_by_default(param_env, span) { ("non-copyable", "perhaps you meant to use `clone()`?") } else { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 190e2965e76ce..5661109ab4555 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1704,7 +1704,9 @@ impl LintPass for MissingCopyImplementations { _ => return, }; let parameter_environment = cx.tcx.empty_parameter_environment(); - if !parameter_environment.type_moves_by_default(ty, item.span) { + // FIXME (@jroesch) should probably inver this so that the parameter env still impls this + // method + if !ty.moves_by_default(¶meter_environment, item.span) { return; } if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() { diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 47c2a5e579d94..9b293f7b1a783 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -197,7 +197,6 @@ 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::*; @@ -1416,7 +1415,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, let trmode; match bm { ast::BindByValue(_) - if !param_env.type_moves_by_default(variable_ty, span) || reassigned => + if !variable_ty.moves_by_default(¶m_env, span) || reassigned => { llmatch = alloca_no_lifetime(bcx, llvariable_ty.ptr_to(), diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 1fc68790db07a..d4f318a4258c3 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -154,7 +154,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 = !param_env.type_moves_by_default(ty, DUMMY_SP); + let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP); if implements_copy { return false; } @@ -630,7 +630,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { - self.fcx.param_env.type_moves_by_default(ty, span) + ty.moves_by_default(&self.fcx.param_env, span) } } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 2c539b67cb627..c0ebffb58afcf 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -101,7 +101,6 @@ use trans::cleanup::CleanupMethods; use trans::expr; use trans::tvec; use trans::type_of; -use middle::mem_categorization::Typer; use middle::ty::Ty; use std::fmt; @@ -606,8 +605,8 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> { * affine values (since they must never be duplicated). */ - assert!(!bcx.tcx().empty_parameter_environment() - .type_moves_by_default(self.ty, DUMMY_SP)); + assert!(!self.ty + .moves_by_default(&bcx.tcx().empty_parameter_environment(), DUMMY_SP)); self.shallow_copy_raw(bcx, dst) } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 85478945e1cfc..c05b95f4aeb25 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -246,7 +246,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: trait_bounds={:?}", infcx.parameter_environment.caller_bounds); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment); + let mut selcx = traits::SelectionContext::new(&infcx, &infcx); for predicate in impl_pred.fns { let traits::Normalized { value: predicate, .. } = @@ -293,7 +293,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_sig.subst(tcx, impl_to_skol_substs); let impl_sig = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -312,7 +312,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, trait_sig.subst(tcx, &trait_to_skol_substs); let trait_sig = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -347,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, &infcx.parameter_environment) { + match fulfillment_cx.select_all_or_error(&infcx, &infcx) { Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) } Ok(_) => {} } @@ -456,7 +456,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, // There is no "body" here, so just pass dummy id. let impl_ty = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_c_span, 0, @@ -466,7 +466,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, let trait_ty = assoc::normalize_associated_types_in(&infcx, - &impl_param_env, + &infcx, &mut fulfillment_cx, impl_c_span, 0, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 806bcb2306bd1..4d750f88093f5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -431,7 +431,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(&inh.infcx.parameter_environment, + inh.normalize_associated_types_in(&inh.infcx, body.span, body.id, &fn_sig); @@ -1504,7 +1504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> bool { traits::type_known_to_meet_builtin_bound(self.infcx(), - self.param_env(), + self.infcx(), ty, ty::BoundSized, span) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 1219f2928c1c8..0650f7deb06f4 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -541,7 +541,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Check that all transitive obligations are satisfied. if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, - &infcx.parameter_environment) { + &infcx) { traits::report_fulfillment_errors(&infcx, &errors); } From 05c57e0e6a667422c8a9159febbf0476f039f4fc Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Mon, 29 Jun 2015 17:46:24 -0700 Subject: [PATCH 084/160] Remove Typer + ClosureTyper impls for BlockS --- src/librustc/middle/check_const.rs | 3 +- src/librustc/middle/check_rvalues.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 15 ++-- src/librustc/middle/infer/mod.rs | 6 +- src/librustc/middle/mem_categorization.rs | 26 +++---- src/librustc_trans/lib.rs | 1 - src/librustc_trans/trans/_match.rs | 4 +- src/librustc_trans/trans/common.rs | 92 +---------------------- src/librustc_typeck/check/regionck.rs | 4 +- 9 files changed, 32 insertions(+), 123 deletions(-) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 139750af6284a..2798cfa43ddb7 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -110,8 +110,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { } fn with_euv<'b, F, R>(&'b mut self, item_id: Option, f: F) -> R where - F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'tcx, - infer::InferCtxt<'a, 'tcx>>) -> R, + F: for<'t> FnOnce(&mut euv::ExprUseVisitor<'b, 't, 'b, 'tcx>) -> R, { let param_env = match item_id { Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id), diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 23accf88dc9d3..731e49192a82a 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -41,8 +41,8 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { { // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), false); - let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: &infcx.parameter_environment }; + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env.clone()), false); + let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 25728c50c61f4..c8555d28e40a7 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -21,9 +21,10 @@ use self::TrackMatchMode::*; use self::OverloadedCallType::*; use middle::{def, region, pat_util}; +use middle::infer; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; -use middle::ty::{self}; +use middle::ty::{self, ClosureTyper}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; @@ -291,9 +292,9 @@ impl OverloadedCallType { // supplies types from the tree. After type checking is complete, you // can just use the tcx as the typer. -pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> { - typer: &'t TYPER, - mc: mc::MemCategorizationContext<'t,TYPER>, +pub struct ExprUseVisitor<'d,'t,'a: 't, 'tcx:'a> { + typer: &'t infer::InferCtxt<'a, 'tcx>, + mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, delegate: &'d mut (Delegate<'tcx>+'d), } @@ -319,10 +320,10 @@ enum PassArgs { ByRef, } -impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { +impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { pub fn new(delegate: &'d mut Delegate<'tcx>, - typer: &'t TYPER) - -> ExprUseVisitor<'d,'t,'tcx,TYPER> { + typer: &'t infer::InferCtxt<'a, 'tcx>) + -> ExprUseVisitor<'d,'t,'a, 'tcx> { ExprUseVisitor { typer: typer, mc: mc::MemCategorizationContext::new(typer), diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 31bfc01886c0f..6ca1c22a2c22f 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -30,7 +30,7 @@ use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; -use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, +use middle::traits::{self, FulfillmentContext, Normalized, SelectionContext, ObligationCause}; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; @@ -477,7 +477,7 @@ pub struct CombinedSnapshot { impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { fn node_ty(&self, id: ast::NodeId) -> McResult> { - let ty = self.node_ty(id); + let ty = self.node_type(id); self.resolve_type_vars_or_error(&ty) } @@ -1183,7 +1183,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .map(|method| resolve_ty(method.ty))) } - pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { + pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> { match self.tables.borrow().node_types.get(&id) { Some(&t) => t, // FIXME diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 13e127e912613..867174ffbc5ba 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -73,10 +73,11 @@ pub use self::categorization::*; use self::Aliasability::*; use ast_map; +use middle::infer; use middle::check_const; use middle::def; use middle::region; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, ClosureTyper}; use util::nodemap::NodeMap; use syntax::ast::{MutImmutable, MutMutable}; @@ -255,13 +256,10 @@ impl ast_node for ast::Pat { fn span(&self) -> Span { self.span } } -pub struct MemCategorizationContext<'t,TYPER:'t> { - typer: &'t TYPER -} - -impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {} -impl<'t,TYPER:'t> Clone for MemCategorizationContext<'t,TYPER> { - fn clone(&self) -> MemCategorizationContext<'t,TYPER> { *self } +#[derive(Copy, Clone)] +pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { + pub typer: &'t infer::InferCtxt<'a, 'tcx>, + // pub monomorphize: bool, } pub type McResult = Result; @@ -391,13 +389,13 @@ impl MutabilityCategory { } } -impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { - pub fn new(typer: &'t TYPER) -> MemCategorizationContext<'t,TYPER> { +impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> { + pub fn new(typer: &'t infer::InferCtxt<'a, 'tcx>) -> MemCategorizationContext<'t, 'a, 'tcx> { MemCategorizationContext { typer: typer } } - fn tcx(&self) -> &'t ty::ctxt<'tcx> { - self.typer.tcx() + fn tcx(&self) -> &'a ty::ctxt<'tcx> { + self.typer.tcx } fn expr_ty(&self, expr: &ast::Expr) -> McResult> { @@ -1175,7 +1173,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } pub fn cat_pattern(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()> - where F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat), + where F: FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat), { self.cat_pattern_(cmt, pat, &mut op) } @@ -1183,7 +1181,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // FIXME(#19596) This is a workaround, but there should be a better way to do this fn cat_pattern_(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F) -> McResult<()> - where F : FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat), + where F : FnMut(&MemCategorizationContext<'t, 'a, 'tcx>, cmt<'tcx>, &ast::Pat), { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index dc692b0e765dd..bb7e95cd4ae44 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,7 +43,6 @@ #![feature(unicode)] #![feature(unicode)] #![feature(vec_push_all)] -#![feature(cell_extras)] #![allow(trivial_casts)] diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 9b293f7b1a783..a9617bd17c097 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -195,6 +195,7 @@ use middle::check_match; use middle::const_eval; use middle::def::{self, DefMap}; use middle::expr_use_visitor as euv; +use middle::infer; use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; use middle::pat_util::*; @@ -1350,7 +1351,8 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool reassigned: false }; { - let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx); + let infcx = infer::new_infer_ctxt(bcx.tcx(), &bcx.tcx().tables, None, false); + let mut visitor = euv::ExprUseVisitor::new(&mut rc, &infcx); visitor.walk_expr(body); } rc.reassigned diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index d4f318a4258c3..598029b842b64 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,7 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::mem_categorization as mc; use middle::mem_categorization::Typer; use middle::ty::ClosureTyper; use middle::region; @@ -48,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, Ref}; +use std::cell::{Cell, RefCell}; use std::result::Result as StdResult; use std::vec::Vec; use syntax::ast; @@ -577,95 +576,6 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { } } -impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { - fn node_ty(&self, id: ast::NodeId) -> mc::McResult> { - Ok(node_id_type(self, id)) - } - - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult> { - Ok(expr_ty_adjusted(self, expr)) - } - - fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - self.tcx() - .tables - .borrow() - .method_map - .get(&method_call) - .map(|method| monomorphize_type(self, method.ty)) - } - - fn node_method_origin(&self, method_call: ty::MethodCall) - -> Option> - { - self.tcx() - .tables - .borrow() - .method_map - .get(&method_call) - .map(|method| method.origin.clone()) - } - - fn adjustments<'a>(&'a self) -> Ref>> { - // 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 - } - - Ref::map(self.tcx().tables.borrow(), project_adjustments) - } - - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) - } - - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.tcx().region_maps.temporary_scope(rvalue_id) - } - - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - 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 { - ty.moves_by_default(&self.fcx.param_env, span) - } -} - -impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> { - fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> { - &self.fcx.param_env - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); - infcx.closure_kind(def_id) - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - let infcx = infer::normalizing_infer_ctxt(self.tcx(), &self.tcx().tables); - infcx.closure_type(def_id, substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - let infcx = infer::new_infer_ctxt(self.tcx(), &self.tcx().tables, None, true); - infcx.closure_upvars(def_id, substs) - } -} - pub struct Result<'blk, 'tcx: 'blk> { pub bcx: Block<'blk, 'tcx>, pub val: ValueRef diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 661e1856ce8cd..a98bcc247edd5 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1101,8 +1101,8 @@ 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>, +fn link_pattern<'t, 'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, + mc: mc::MemCategorizationContext<'t, 'a, 'tcx>, discr_cmt: mc::cmt<'tcx>, root_pat: &ast::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", From 9faae6a5ca1c5579a8185138b1e534285324db87 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 30 Jun 2015 02:18:03 -0700 Subject: [PATCH 085/160] Remove Typer and ClosureTyper This commit finalizes the work of the past commits by fully moving the fulfillment context into the InferCtxt, cleaning up related context interfaces, removing the Typer and ClosureTyper traits and cleaning up related intefaces --- src/librustc/middle/astencode.rs | 1 - src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 13 +- src/librustc/middle/implicator.rs | 6 +- src/librustc/middle/infer/mod.rs | 250 +++++++++--------- src/librustc/middle/liveness.rs | 2 - src/librustc/middle/mem_categorization.rs | 33 +-- src/librustc/middle/traits/coherence.rs | 2 +- src/librustc/middle/traits/fulfill.rs | 18 +- src/librustc/middle/traits/mod.rs | 10 +- src/librustc/middle/traits/select.rs | 24 +- src/librustc/middle/ty.rs | 36 +-- src/librustc_borrowck/borrowck/mod.rs | 1 - src/librustc_lint/builtin.rs | 1 - src/librustc_trans/trans/adt.rs | 2 +- src/librustc_trans/trans/attributes.rs | 2 +- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/closure.rs | 3 +- src/librustc_trans/trans/common.rs | 11 +- src/librustc_trans/trans/debuginfo/gdb.rs | 1 - .../trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/debuginfo/mod.rs | 2 +- .../trans/debuginfo/namespace.rs | 1 - .../trans/debuginfo/type_names.rs | 3 +- src/librustc_trans/trans/declare.rs | 2 +- src/librustc_trans/trans/expr.rs | 1 - src/librustc_trans/trans/meth.rs | 1 - src/librustc_trans/trans/monomorphize.rs | 4 +- src/librustc_typeck/check/assoc.rs | 6 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 10 +- src/librustc_typeck/check/method/confirm.rs | 1 - 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 | 15 +- src/librustc_typeck/check/regionck.rs | 7 +- src/librustc_typeck/check/wf.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 3 +- 42 files changed, 194 insertions(+), 304 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index d2c79e1d820bf..ad87643e550c9 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -26,7 +26,6 @@ use metadata::tydecode::{RegionParameter, ClosureSource}; use metadata::tyencode; use middle::cast; use middle::check_const::ConstQualif; -use middle::mem_categorization::Typer; use middle::privacy::{AllPublic, LastMod}; use middle::subst; use middle::subst::VecPerParamSpace; diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 2798cfa43ddb7..19b688e5ccfb4 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - match fulfill_cx.select_all_or_error(&infcx, &infcx) { + match fulfill_cx.select_all_or_error(&infcx) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 900a231835e59..8e315901db212 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -21,7 +21,7 @@ use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode}; use middle::expr_use_visitor::WriteAndRead; use middle::expr_use_visitor as euv; use middle::infer; -use middle::mem_categorization::{cmt, Typer}; +use middle::mem_categorization::{cmt}; use middle::pat_util::*; use middle::ty::*; use middle::ty; diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index b98864304d25e..7d54b8c284f1f 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -1033,7 +1033,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>, tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); 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/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c8555d28e40a7..3edf0490214b9 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -23,8 +23,7 @@ use self::OverloadedCallType::*; use middle::{def, region, pat_util}; use middle::infer; use middle::mem_categorization as mc; -use middle::mem_categorization::Typer; -use middle::ty::{self, ClosureTyper}; +use middle::ty::{self}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticClosure}; @@ -356,7 +355,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } fn tcx(&self) -> &'t ty::ctxt<'tcx> { - self.typer.tcx() + self.typer.tcx } fn delegate_consume(&mut self, @@ -691,7 +690,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { match local.init { None => { let delegate = &mut self.delegate; - pat_util::pat_bindings(&self.typer.tcx().def_map, &*local.pat, + pat_util::pat_bindings(&self.typer.tcx.def_map, &*local.pat, |_, id, span, _| { delegate.decl_without_init(id, span); }) @@ -1053,7 +1052,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { let delegate = &mut self.delegate; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| { if pat_util::pat_is_binding(def_map, pat) { - let tcx = typer.tcx(); + let tcx = typer.tcx; debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, @@ -1140,7 +1139,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { // the leaves of the pattern tree structure. return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { let def_map = def_map.borrow(); - let tcx = typer.tcx(); + let tcx = typer.tcx; match pat.node { ast::PatEnum(_, _) | ast::PatQPath(..) | @@ -1279,7 +1278,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } } -fn copy_or_move<'tcx>(typer: &mc::Typer<'tcx>, +fn copy_or_move<'a, 'tcx>(typer: &infer::InferCtxt<'a, 'tcx>, cmt: &mc::cmt<'tcx>, move_reason: MoveReason) -> ConsumeMode diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index d5fa885b16ab5..3e097578857e9 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -34,7 +34,6 @@ pub enum Implication<'tcx> { struct Implicator<'a, 'tcx: 'a> { infcx: &'a InferCtxt<'a,'tcx>, - closure_typer: &'a (ty::ClosureTyper<'tcx>+'a), body_id: ast::NodeId, stack: Vec<(ty::Region, Option>)>, span: Span, @@ -46,7 +45,6 @@ struct Implicator<'a, 'tcx: 'a> { /// appear in a context with lifetime `outer_region` pub fn implications<'a,'tcx>( infcx: &'a InferCtxt<'a,'tcx>, - closure_typer: &ty::ClosureTyper<'tcx>, body_id: ast::NodeId, ty: Ty<'tcx>, outer_region: ty::Region, @@ -60,8 +58,7 @@ pub fn implications<'a,'tcx>( let mut stack = Vec::new(); stack.push((outer_region, None)); - let mut wf = Implicator { closure_typer: closure_typer, - infcx: infcx, + let mut wf = Implicator { infcx: infcx, body_id: body_id, span: span, stack: stack, @@ -404,7 +401,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { { let value = traits::fully_normalize(self.infcx, - self.closure_typer, traits::ObligationCause::misc(self.span, self.body_id), value); match value { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 6ca1c22a2c22f..a64fe8b91282b 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -19,7 +19,6 @@ pub use self::TypeOrigin::*; pub use self::ValuePairs::*; pub use self::fixup_err::*; pub use middle::ty::IntVarValue; -use middle::ty::ClosureTyper; pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; @@ -475,129 +474,6 @@ 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_type(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.tcx.region_maps.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> - { - - let closure_ty = self.tables - .borrow() - .closure_tys - .get(&def_id) - .unwrap() - .subst(self.tcx, substs); - - if self.normalize { - // 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) - normalize_associated_type(&self.tcx, &closure_ty) - // panic!("see issue 26597: fufillment context refactor must occur") - } else { - closure_ty - } - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> - { - let result = ty::ctxt::closure_upvars(self, def_id, substs); - - if self.normalize { - // 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") - normalize_associated_type(&self.tcx, &result) - } else { - result - } - } -} - pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T where T : TypeFoldable<'tcx> + HasTypeFlags { @@ -610,7 +486,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T } let infcx = new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); @@ -663,12 +539,11 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - // this is stupid but temporary - let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { } Err(errors) => { return Err(errors); @@ -1429,6 +1304,125 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.equate(true, trace).relate(a, b) }).map(|_| ()) } + + pub fn node_ty(&self, id: ast::NodeId) -> McResult> { + let ty = self.node_type(id); + self.resolve_type_vars_or_error(&ty) + } + + pub 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) + } + + pub 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, ty, ty::BoundCopy, span) + } + + pub 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)) + } + + pub fn node_method_origin(&self, method_call: ty::MethodCall) + -> Option> + { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.origin.clone()) + } + + pub 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) + } + + pub fn is_method_call(&self, id: ast::NodeId) -> bool { + self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) + } + + pub fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { + self.tcx.region_maps.temporary_scope(rvalue_id) + } + + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { + self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() + } + + pub fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.parameter_environment + } + + pub fn closure_kind(&self, + def_id: ast::DefId) + -> Option + { + self.tables.borrow().closure_kinds.get(&def_id).cloned() + } + + pub fn closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + + let closure_ty = self.tables + .borrow() + .closure_tys + .get(&def_id) + .unwrap() + .subst(self.tcx, substs); + + if self.normalize { + // 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) + normalize_associated_type(&self.tcx, &closure_ty) + // panic!("see issue 26597: fufillment context refactor must occur") + } else { + closure_ty + } + } + + pub fn closure_upvars(&self, + def_id: ast::DefId, + substs: &Substs<'tcx>) + -> Option>> + { + let result = ty::ctxt::closure_upvars(self, def_id, substs); + + if self.normalize { + // 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") + normalize_associated_type(&self.tcx, &result) + } else { + result + } + } } impl<'tcx> TypeTrace<'tcx> { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 7d237a511c4a1..68001ae1564ab 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -110,11 +110,9 @@ use self::LiveNodeKind::*; use self::VarKind::*; use middle::def::*; -use middle::mem_categorization::Typer; use middle::pat_util; use middle::region; use middle::ty; -use middle::ty::ClosureTyper; use lint; use util::nodemap::NodeMap; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 867174ffbc5ba..32fbd7739005e 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -77,14 +77,12 @@ use middle::infer; use middle::check_const; use middle::def; use middle::region; -use middle::ty::{self, Ty, ClosureTyper}; -use util::nodemap::NodeMap; +use middle::ty::{self, Ty}; use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap::Span; -use std::cell::Ref; use std::fmt; use std::rc::Rc; @@ -264,35 +262,6 @@ pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { pub type McResult = Result; -/// The `Typer` trait provides the interface for the mem-categorization -/// module to the results of the type check. It can be used to query -/// the type assigned to an expression node, to inquire after adjustments, -/// and so on. -/// -/// This interface is needed because mem-categorization is used from -/// two places: `regionck` and `borrowck`. `regionck` executes before -/// type inference is complete, and hence derives types and so on from -/// intermediate tables. This also implies that type errors can occur, -/// and hence `node_ty()` and friends return a `Result` type -- any -/// error will propagate back up through the mem-categorization -/// routines. -/// -/// In the borrow checker, in contrast, type checking is complete and we -/// know that no errors have occurred, so we simply consult the tcx and we -/// can be sure that only `Ok` results will occur. -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, 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>; - 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; -} - impl MutabilityCategory { pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory { let ret = match m { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 25b336f0c7a6a..977d0577e480f 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 selcx = &mut SelectionContext::intercrate(infcx, infcx); + let selcx = &mut SelectionContext::intercrate(infcx); infcx.probe(|_| { overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) }) diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index a769ef8233e68..08cb3e5701569 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -132,7 +132,6 @@ impl<'tcx> FulfillmentContext<'tcx> { /// `projection_ty` again. pub fn normalize_projection_type<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>, projection_ty: ty::ProjectionTy<'tcx>, cause: ObligationCause<'tcx>) -> Ty<'tcx> @@ -144,7 +143,7 @@ impl<'tcx> FulfillmentContext<'tcx> { // FIXME(#20304) -- cache - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0); for obligation in normalized.obligations { @@ -208,11 +207,10 @@ impl<'tcx> FulfillmentContext<'tcx> { } pub fn select_all_or_error<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - try!(self.select_where_possible(infcx, typer)); + try!(self.select_where_possible(infcx)); // Anything left is ambiguous. let errors: Vec = @@ -233,20 +231,18 @@ impl<'tcx> FulfillmentContext<'tcx> { /// gaining type information. It'd be equally valid to use `select_where_possible` but it /// results in `O(n^2)` performance (#18208). pub fn select_new_obligations<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); self.select(&mut selcx, true) } pub fn select_where_possible<'a>(&mut self, - infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>) + infcx: &InferCtxt<'a,'tcx>) -> Result<(),Vec>> { - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); self.select(&mut selcx, false) } diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 8c065e182cd41..a39fe45366436 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -312,7 +312,6 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>, /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, - typer: &ty::ClosureTyper<'tcx>, ty: Ty<'tcx>, bound: ty::BuiltinBound, span: Span) @@ -334,7 +333,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, // Note: we only assume something is `Copy` if we can // *definitively* show that it implements `Copy`. Otherwise, // assume it is move; linear is always ok. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { debug!("type_known_to_meet_builtin_bound: ty={:?} bound={:?} success", ty, @@ -398,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, &tcx.tables, Some(elaborated_env), false); - let predicates = match fully_normalize(&infcx, &infcx, cause, + let predicates = match fully_normalize(&infcx, cause, &infcx.parameter_environment.caller_bounds) { Ok(predicates) => predicates, Err(errors) => { @@ -429,7 +428,6 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi } pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, - closure_typer: &ty::ClosureTyper<'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Result>> @@ -437,7 +435,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { debug!("normalize_param_env(value={:?})", value); - let mut selcx = &mut SelectionContext::new(infcx, closure_typer); + let mut selcx = &mut SelectionContext::new(infcx); // FIXME (@jroesch): I'm not sure if this is a bug or not, needs // further investigation. It appears that by reusing the fulfillment_cx // here we incur more obligations and later trip an asssertion on @@ -458,7 +456,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } - try!(fulfill_cx.select_all_or_error(infcx, closure_typer)); + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); Ok(resolved_value) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ae15c8aa8e028..3bc4fd0c0a14e 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -55,8 +55,6 @@ 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 /// obligation stack. This ensures that all entries on the stack /// at one time will have the same set of skolemized entries, @@ -244,23 +242,19 @@ enum EvaluationResult<'tcx> { } impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { - pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>, - closure_typer: &'cx ty::ClosureTyper<'tcx>) + pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: false, } } - pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>, - closure_typer: &'cx ty::ClosureTyper<'tcx>) + pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: true, } @@ -275,11 +269,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'cx, 'tcx> { - self.closure_typer.param_env() + self.infcx.param_env() } - pub fn closure_typer(&self) -> &'cx (ty::ClosureTyper<'tcx>+'cx) { - self.closure_typer + pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'tcx> { + self.infcx } /////////////////////////////////////////////////////////////////////////// @@ -1163,7 +1157,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { kind, obligation); - match self.closure_typer.closure_kind(closure_def_id) { + match self.infcx.closure_kind(closure_def_id) { Some(closure_kind) => { debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind); if closure_kind.extends(kind) { @@ -1727,7 +1721,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return ok_if(Vec::new()); } - match self.closure_typer.closure_upvars(def_id, substs) { + match self.infcx.closure_upvars(def_id, substs) { Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()), None => { debug!("assemble_builtin_bound_candidates: no upvar types available yet"); @@ -1865,7 +1859,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::TyClosure(def_id, substs) => { assert_eq!(def_id.krate, ast::LOCAL_CRATE); - match self.closure_typer.closure_upvars(def_id, substs) { + match self.infcx.closure_upvars(def_id, substs) { Some(upvars) => { Some(upvars.iter().map(|c| c.ty).collect()) } @@ -2844,7 +2838,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { substs: &Substs<'tcx>) -> ty::PolyTraitRef<'tcx> { - let closure_type = self.closure_typer.closure_type(closure_def_id, substs); + let closure_type = self.infcx.closure_type(closure_def_id, substs); let ty::Binder((trait_ref, _)) = util::closure_trait_ref_and_return_type(self.tcx(), obligation.predicate.def_id(), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 23aa840703bbf..e20df807c8784 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,6 @@ use middle::dependency_format; use middle::fast_reject; use middle::free_region::FreeRegionMap; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; -use middle::mem_categorization::Typer; use middle::region; use middle::resolve_lifetime; use middle::infer; @@ -3179,35 +3178,6 @@ impl ClosureKind { } } -pub trait ClosureTyper<'tcx> { - fn tcx(&self) -> &ctxt<'tcx> { - self.param_env().tcx - } - - fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>; - - /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck, - /// returns `None` if the kind of this closure has not yet been - /// inferred. - fn closure_kind(&self, - def_id: ast::DefId) - -> Option; - - /// Returns the argument/return types of this closure. - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx>; - - /// Returns the set of all upvars and their transformed - /// types. During typeck, maybe return `None` if the upvar types - /// have not yet been inferred. - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>>; -} - impl<'tcx> CommonTypes<'tcx> { fn new(arena: &'tcx TypedArena>, interner: &mut FnvHashMap, Ty<'tcx>>) @@ -4406,7 +4376,7 @@ impl<'tcx> TyS<'tcx> { let tcx = param_env.tcx; let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()), false); - let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, &infcx, + let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, self, bound, span); debug!("Ty::impls_bound({:?}, {:?}) = {:?}", @@ -6116,7 +6086,7 @@ impl<'tcx> ctxt<'tcx> { } // Returns a list of `ClosureUpvar`s for each upvar. - pub fn closure_upvars(typer: &Typer<'tcx>, + pub fn closure_upvars<'a>(typer: &infer::InferCtxt<'a, 'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>) -> Option>> @@ -6127,7 +6097,7 @@ impl<'tcx> ctxt<'tcx> { // This may change if abstract return types of some sort are // implemented. assert!(closure_id.krate == ast::LOCAL_CRATE); - let tcx = typer.tcx(); + let tcx = typer.tcx; match tcx.freevars.borrow().get(&closure_id.node) { None => Some(vec![]), Some(ref freevars) => { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 3cf2a62b3b674..3a4318527fb40 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -30,7 +30,6 @@ use rustc::middle::dataflow::KillFrom; use rustc::middle::expr_use_visitor as euv; use rustc::middle::free_region::FreeRegionMap; use rustc::middle::mem_categorization as mc; -use rustc::middle::mem_categorization::Typer; use rustc::middle::region; use rustc::middle::ty::{self, Ty}; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5661109ab4555..2e812a0a78072 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -30,7 +30,6 @@ 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}; diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index b96dcf940a895..eca9891c57cb7 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -51,7 +51,7 @@ use llvm::{ValueRef, True, IntEQ, IntNE}; use back::abi::FAT_PTR_ADDR; use middle::subst; use middle::infer; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use middle::ty::Disr; use syntax::ast; use syntax::attr; diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs index fd704ed2d378b..25cde149df109 100644 --- a/src/librustc_trans/trans/attributes.rs +++ b/src/librustc_trans/trans/attributes.rs @@ -11,7 +11,7 @@ use libc::{c_uint, c_ulonglong}; use llvm::{self, ValueRef, AttrHelper}; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::infer; use session::config::NoDebugInfo; use syntax::abi; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 088df7288bec5..156d591b909f4 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -41,7 +41,7 @@ use middle::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::Substs; -use middle::ty::{self, Ty, ClosureTyper, HasTypeFlags}; +use middle::ty::{self, Ty, HasTypeFlags}; use rustc::ast_map; use session::config::{self, NoDebugInfo}; use session::Session; diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index c9bab6861ca05..5fd0f92400f84 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -11,7 +11,6 @@ use arena::TypedArena; use back::link::{self, mangle_internal_name_by_path_and_seq}; use llvm::{ValueRef, get_params}; -use middle::mem_categorization::Typer; use middle::infer; use trans::adt; use trans::attributes; @@ -26,7 +25,7 @@ use trans::declare; use trans::expr; use trans::monomorphize::{self, MonoId}; use trans::type_of::*; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::subst::Substs; use session::config::FullDebugInfo; diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 598029b842b64..6dffb3fe2a713 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,8 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::mem_categorization::Typer; -use middle::ty::ClosureTyper; use middle::region; use middle::subst::{self, Substs}; use trans::base; @@ -872,7 +870,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID), @@ -931,7 +929,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let tcx = ccx.tcx(); let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, true); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: predicates, obligations } = @@ -979,12 +977,11 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>, { debug!("drain_fulfillment_cx(result={:?})", result); - // this is stupid but temporary - let typer: &ClosureTyper<'tcx> = infcx; + // In principle, we only need to do this so long as `result` // contains unbound type parameters. It could be a slight // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(infcx, typer) { + match fulfill_cx.select_all_or_error(infcx) { Ok(()) => { } Err(errors) => { return Err(errors); diff --git a/src/librustc_trans/trans/debuginfo/gdb.rs b/src/librustc_trans/trans/debuginfo/gdb.rs index a6f1199d0ffe7..f7b0f37c9ff78 100644 --- a/src/librustc_trans/trans/debuginfo/gdb.rs +++ b/src/librustc_trans/trans/debuginfo/gdb.rs @@ -16,7 +16,6 @@ use llvm::ValueRef; use trans::common::{C_bytes, CrateContext}; use trans::declare; use trans::type_::Type; -use middle::ty::ClosureTyper; use session::config::NoDebugInfo; use std::ffi::CString; diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 12892c87b4687..45349969a0b3e 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -32,7 +32,7 @@ use trans::{type_of, adt, machine, monomorphize}; use trans::common::{self, CrateContext, FunctionContext, Block}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; use trans::type_::Type; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use session::config::{self, FullDebugInfo}; use util::nodemap::FnvHashMap; use util::common::path2cstr; diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 7487e8d331bf5..ebe5e832e6fb2 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::{Ty, ClosureTyper}; +use middle::ty::Ty; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; diff --git a/src/librustc_trans/trans/debuginfo/namespace.rs b/src/librustc_trans/trans/debuginfo/namespace.rs index 2e5943a248a5f..8b33acdee8e25 100644 --- a/src/librustc_trans/trans/debuginfo/namespace.rs +++ b/src/librustc_trans/trans/debuginfo/namespace.rs @@ -16,7 +16,6 @@ use llvm; use llvm::debuginfo::DIScope; use rustc::ast_map; use trans::common::CrateContext; -use middle::ty::ClosureTyper; use std::ffi::CString; use std::ptr; diff --git a/src/librustc_trans/trans/debuginfo/type_names.rs b/src/librustc_trans/trans/debuginfo/type_names.rs index 6ea43d7392c94..f411688319981 100644 --- a/src/librustc_trans/trans/debuginfo/type_names.rs +++ b/src/librustc_trans/trans/debuginfo/type_names.rs @@ -14,7 +14,7 @@ use super::namespace::crate_root_namespace; use trans::common::CrateContext; use middle::subst::{self, Substs}; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use syntax::ast; use syntax::parse::token; @@ -225,4 +225,3 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push('>'); } } - diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index 0eaaaaa5b3414..b29da9d560fea 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -20,7 +20,7 @@ //! * Use define_* family of methods when you might be defining the ValueRef. //! * When in doubt, define. use llvm::{self, ValueRef}; -use middle::ty::{self, ClosureTyper}; +use middle::ty; use middle::infer; use syntax::abi; use trans::attributes; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 045cc69bf954b..39bb9b25be76e 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -56,7 +56,6 @@ use llvm::{self, ValueRef, TypeKind}; use middle::check_const; use middle::def; use middle::lang_items::CoerceUnsizedTraitLangItem; -use middle::mem_categorization::Typer; use middle::subst::{Substs, VecPerParamSpace}; use middle::traits; use trans::{_match, adt, asm, base, callee, closure, consts, controlflow}; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index e46c3b5fab1f7..1b01fb6c7f86d 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -17,7 +17,6 @@ use middle::subst::{Subst, Substs}; use middle::subst::VecPerParamSpace; use middle::subst; use middle::traits; -use middle::ty::ClosureTyper; use rustc::ast_map; use trans::base::*; use trans::build::*; diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index b297a731d29e7..3ef72e2c4af3a 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -322,10 +322,8 @@ 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::normalizing_infer_ctxt(tcx, &tcx.tables); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, &value); diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 4eafbaaf794d2..75263c35d5958 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -11,13 +11,13 @@ use middle::infer::InferCtxt; use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, SelectionContext, ObligationCause}; -use middle::ty::{self, HasTypeFlags}; +use middle::ty::HasTypeFlags; use middle::ty_fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; +//FIME(@jroesch): Refactor this pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, - typer: &(ty::ClosureTyper<'tcx>+'a), fulfillment_cx: &mut FulfillmentContext<'tcx>, span: Span, body_id: ast::NodeId, @@ -26,7 +26,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("normalize_associated_types_in(value={:?})", value); - let mut selcx = SelectionContext::new(infcx, typer); + let mut selcx = SelectionContext::new(infcx); let cause = ObligationCause::new(span, body_id, MiscObligation); let Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value); debug!("normalize_associated_types_in: result={:?} predicates={:?}", diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index d29c0494572cb..f32a4fe43d696 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -27,7 +27,7 @@ use super::write_call; use CrateCtxt; use middle::infer; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty}; use syntax::ast; use syntax::codemap::Span; use syntax::parse::token; diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index b38b6884a98ad..a0abef7490703 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.infcx()); + let mut selcx = traits::SelectionContext::new(self.fcx.infcx()); // Use a FIFO queue for this custom fulfillment procedure. let mut queue = VecDeque::new(); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index c05b95f4aeb25..7926394ebb517 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -246,7 +246,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, debug!("compare_impl_method: trait_bounds={:?}", infcx.parameter_environment.caller_bounds); - let mut selcx = traits::SelectionContext::new(&infcx, &infcx); + let mut selcx = traits::SelectionContext::new(&infcx); for predicate in impl_pred.fns { let traits::Normalized { value: predicate, .. } = @@ -293,7 +293,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, impl_sig.subst(tcx, impl_to_skol_substs); let impl_sig = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -312,7 +311,6 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, trait_sig.subst(tcx, &trait_to_skol_substs); let trait_sig = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -347,7 +345,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, &infcx) { + match fulfillment_cx.select_all_or_error(&infcx) { Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) } Ok(_) => {} } @@ -456,21 +454,21 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>, // There is no "body" here, so just pass dummy id. let impl_ty = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_c_span, 0, &impl_ty); + debug!("compare_const_impl: impl_ty={:?}", impl_ty); let trait_ty = assoc::normalize_associated_types_in(&infcx, - &infcx, &mut fulfillment_cx, impl_c_span, 0, &trait_ty); + debug!("compare_const_impl: trait_ty={:?}", trait_ty); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 9c2d1c4a34df1..7a887fac9d402 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -12,7 +12,6 @@ use super::probe; use check::{self, FnCtxt, NoPreference, PreferMutLvalue, callee, demand}; use check::UnresolvedTypeAction; -use middle::mem_categorization::Typer; use middle::subst::{self}; use middle::traits; use middle::ty::{self, Ty}; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f312db9c4dcf2..7ed5c69ad6157 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.infcx()); + let mut selcx = traits::SelectionContext::new(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 94a2050829dfa..8eb4716cb2a69 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.infcx()); + let mut selcx = &mut traits::SelectionContext::new(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.infcx()); + let mut selcx = &mut traits::SelectionContext::new(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.infcx()); + let selcx = &mut traits::SelectionContext::new(self.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 b81b672e684a5..d6a8b3583f8ca 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.infcx()); + let mut selcx = SelectionContext::new(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 4d750f88093f5..477b6e9825689 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -305,7 +305,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { } fn normalize_associated_types_in(&self, - typer: &ty::ClosureTyper<'tcx>, span: Span, body_id: ast::NodeId, value: &T) @@ -314,7 +313,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { { let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, - typer, &mut fulfillment_cx, span, body_id, @@ -431,8 +429,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(&inh.infcx, - body.span, + inh.normalize_associated_types_in(body.span, body.id, &fn_sig); @@ -1377,7 +1374,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.infcx(), span, self.body_id, value) + self.inh.normalize_associated_types_in(span, self.body_id, value) } fn normalize_associated_type(&self, @@ -1394,7 +1391,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), - self.infcx(), ty::ProjectionTy { trait_ref: trait_ref, item_name: item_name, @@ -1504,7 +1500,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { -> bool { traits::type_known_to_meet_builtin_bound(self.infcx(), - self.infcx(), ty, ty::BoundSized, span) @@ -1750,7 +1745,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.select_all_obligations_and_apply_defaults(); let mut fulfillment_cx = self.inh.infcx.fulfillment_cx.borrow_mut(); - match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) { + match fulfillment_cx.select_all_or_error(self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } } @@ -1761,7 +1756,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.infcx.fulfillment_cx .borrow_mut() - .select_where_possible(self.infcx(), self.infcx()) + .select_where_possible(self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -1776,7 +1771,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.infcx.fulfillment_cx .borrow_mut() - .select_new_obligations(self.infcx(), self.infcx()) + .select_new_obligations(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 a98bcc247edd5..bb3c9f9fb5425 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -86,13 +86,12 @@ 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; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall, HasTypeFlags}; +use middle::ty::{self, ReScope, Ty, MethodCall, HasTypeFlags}; use middle::infer::{self, GenericKind}; use middle::pat_util; @@ -360,7 +359,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.infcx(), body_id, + let implications = implicator::implications(self.fcx.infcx(), body_id, ty, body_scope, span); // Record any relations between free regions that we observe into the free-region-map. @@ -1409,7 +1408,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, ty, region); - let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx.infcx(), rcx.body_id, + let implications = implicator::implications(rcx.fcx.infcx(), rcx.body_id, ty, region, origin.span()); for implication in implications { debug!("implication: {:?}", implication); diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index df01b99fd9b80..7cf7d73a5668c 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -268,7 +268,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.infcx()); + let selcx = &mut traits::SelectionContext::new(fcx.infcx()); traits::normalize(selcx, cause.clone(), &predicates) }; for predicate in predicates.value.predicates { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 0650f7deb06f4..fca23a1b029a8 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -540,8 +540,7 @@ 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) { + if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) { traits::report_fulfillment_errors(&infcx, &errors); } From 7a8f83a6e59abb53adaafe7a9f70ff7069feefae Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Tue, 30 Jun 2015 02:39:47 -0700 Subject: [PATCH 086/160] Clean up patch --- src/librustc/middle/infer/mod.rs | 18 ------------------ src/librustc/middle/mem_categorization.rs | 1 - src/librustc/middle/traits/mod.rs | 22 +++++++++++++--------- src/librustc_typeck/check/assoc.rs | 2 +- src/librustc_typeck/check/mod.rs | 3 --- src/librustc_typeck/coherence/mod.rs | 1 - 6 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index a64fe8b91282b..43be1beba91d0 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1386,16 +1386,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .subst(self.tcx, substs); if self.normalize { - // 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) normalize_associated_type(&self.tcx, &closure_ty) - // panic!("see issue 26597: fufillment context refactor must occur") } else { closure_ty } @@ -1409,15 +1400,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let result = ty::ctxt::closure_upvars(self, def_id, substs); if self.normalize { - // 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") normalize_associated_type(&self.tcx, &result) } else { result diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 32fbd7739005e..f506de525ff9c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -257,7 +257,6 @@ impl ast_node for ast::Pat { #[derive(Copy, Clone)] pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { pub typer: &'t infer::InferCtxt<'a, 'tcx>, - // pub monomorphize: bool, } pub type McResult = Result; diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index a39fe45366436..47002497acca5 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -436,17 +436,20 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx); - // FIXME (@jroesch): I'm not sure if this is a bug or not, needs - // further investigation. It appears that by reusing the fulfillment_cx - // here we incur more obligations and later trip an asssertion on - // regionck.rs line 337. The two possibilities I see is that - // normalization is not actually fully happening and we - // have a bug else where or that we are adding a duplicate - // bound into the list causing its size to change. I think - // we should probably land this refactor and then come + // FIXME (@jroesch): + // I'm not sure if this is a bug or not, needs further investigation. + // It appears that by reusing the fulfillment_cx here we incur more + // obligations and later trip an asssertion on regionck.rs line 337. + // + // The two possibilities I see is: + // - normalization is not actually fully happening and we + // have a bug else where + // - we are adding a duplicate bound into the list causing + // its size to change. + // + // I think we should probably land this refactor and then come // back to this is a follow-up patch. let mut fulfill_cx = FulfillmentContext::new(false); - // let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, cause, value); @@ -456,6 +459,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 75263c35d5958..c80c48a96922d 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -16,7 +16,7 @@ use middle::ty_fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; -//FIME(@jroesch): Refactor this +//FIXME(@jroesch): Ideally we should be able to drop the fulfillment_cx argument. pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, fulfillment_cx: &mut FulfillmentContext<'tcx>, span: Span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 477b6e9825689..b7ebf1abd2d22 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -158,9 +158,6 @@ pub struct Inherited<'a, 'tcx: 'a> { // one is never copied into the tcx: it is only used by regionck. fn_sig_map: RefCell>>>, - // Tracks trait obligations incurred during this function body. - // fulfillment_cx: RefCell>, - // When we process a call like `c()` where `c` is a closure type, // we may not have decided yet whether `c` is a `Fn`, `FnMut`, or // `FnOnce` closure. In that case, we defer full resolution of the diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fca23a1b029a8..a1c5ad51dcdf7 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -631,7 +631,6 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, pub fn check_coherence(crate_context: &CrateCtxt) { CoherenceChecker { crate_context: crate_context, - // XXXJAREDXXX: not sure if the bool is right here? inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None, true), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); From 516941b74f61f058625fab936ad0fd2c97943e22 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Tue, 30 Jun 2015 14:10:24 +0200 Subject: [PATCH 087/160] fmt: Update docs and mention :#? pretty-printing --- src/libcollections/fmt.rs | 45 ++++++++++++++++++++------------------- src/libcore/fmt/mod.rs | 5 ++++- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 72d0ca85357a4..7df259e9b36a8 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -128,15 +128,15 @@ //! This allows multiple actual types to be formatted via `{:x}` (like `i8` as //! well as `isize`). The current mapping of types to traits is: //! -//! * *nothing* ⇒ `Display` -//! * `?` ⇒ `Debug` -//! * `o` ⇒ `Octal` -//! * `x` ⇒ `LowerHex` -//! * `X` ⇒ `UpperHex` -//! * `p` ⇒ `Pointer` -//! * `b` ⇒ `Binary` -//! * `e` ⇒ `LowerExp` -//! * `E` ⇒ `UpperExp` +//! * *nothing* ⇒ [`Display`](trait.Display.html) +//! * `?` ⇒ [`Debug`](trait.Debug.html) +//! * `o` ⇒ [`Octal`](trait.Octal.html) +//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html) +//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html) +//! * `p` ⇒ [`Pointer`](trait.Pointer.html) +//! * `b` ⇒ [`Binary`](trait.Binary.html) +//! * `e` ⇒ [`LowerExp`](trait.LowerExp.html) +//! * `E` ⇒ [`UpperExp`](trait.UpperExp.html) //! //! What this means is that any type of argument which implements the //! `fmt::Binary` trait can then be formatted with `{:b}`. Implementations @@ -367,11 +367,11 @@ //! should always be printed. //! * '-' - Currently not used //! * '#' - This flag is indicates that the "alternate" form of printing should -//! be used. For array slices, the alternate form omits the brackets. -//! For the integer formatting traits, the alternate forms are: +//! be used. The alternate forms are: +//! * `#?` - pretty-print the `Debug` formatting //! * `#x` - precedes the argument with a "0x" //! * `#X` - precedes the argument with a "0x" -//! * `#t` - precedes the argument with a "0b" +//! * `#b` - precedes the argument with a "0b" //! * `#o` - precedes the argument with a "0o" //! * '0' - This is used to indicate for integer formats that the padding should //! both be done with a `0` character as well as be sign-aware. A format @@ -408,19 +408,20 @@ //! //! There are three possible ways to specify the desired `precision`: //! -//! There are three possible ways to specify the desired `precision`: -//! 1. An integer `.N`, -//! 2. an integer followed by dollar sign `.N$`, or -//! 3. an asterisk `.*`. +//! 1. An integer `.N`: +//! +//! the integer `N` itself is the precision. +//! +//! 2. An integer followed by dollar sign `.N$`: //! -//! The first specification, `.N`, means the integer `N` itself is the precision. +//! use format *argument* `N` (which must be a `usize`) as the precision. //! -//! The second, `.N$`, means use format *argument* `N` (which must be a `usize`) as the precision. +//! 3. An asterisk `.*`: //! -//! Finally, `.*` means that this `{...}` is associated with *two* format inputs rather than one: -//! the first input holds the `usize` precision, and the second holds the value to print. Note -//! that in this case, if one uses the format string `{:.*}`, then the `` part -//! refers to the *value* to print, and the `precision` must come in the input preceding ``. +//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the +//! first input holds the `usize` precision, and the second holds the value to print. Note that +//! in this case, if one uses the format string `{:.*}`, then the `` part refers +//! to the *value* to print, and the `precision` must come in the input preceding ``. //! //! For example, these: //! diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index cbbb186af7609..35dea6d15f0e9 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -267,7 +267,7 @@ impl<'a> Display for Arguments<'a> { } } -/// Format trait for the `:?` format. Useful for debugging, all types +/// Format trait for the `?` character. Useful for debugging, all types /// should implement this. /// /// Generally speaking, you should just `derive` a `Debug` implementation. @@ -312,6 +312,9 @@ impl<'a> Display for Arguments<'a> { /// There are a number of `debug_*` methods on `Formatter` to help you with manual /// implementations, such as [`debug_struct`][debug_struct]. /// +/// `Debug` implementations using either `derive` or the debug builder API +/// on `Formatter` support pretty printing using the alternate flag: `{:#?}`. +/// /// [debug_struct]: ../std/fmt/struct.Formatter.html#method.debug_struct #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ From c158be082f07c2b2ed0a5f1db33627709396ac63 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 29 Jun 2015 16:00:57 +0200 Subject: [PATCH 088/160] Add E0195 error explanation --- src/librustc_typeck/diagnostics.rs | 39 +++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index d4977c5d3941c..1e83c1b6900a4 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1250,6 +1250,44 @@ information see the [opt-in builtin traits RFC](https://github.com/rust-lang/ rfcs/blob/master/text/0019-opt-in-builtin-traits.md). "##, +E0195: r##" +Your method's lifetime parameters do not match the trait declaration. +Erroneous code example: + +``` +trait Trait { + fn t<'a,'b:'a>(x: &'a str, y: &'b str); +} + +struct Foo; + +impl Trait for Foo { + fn t<'a,'b>(x: &'a str, y: &'b str) { // error: lifetime parameters + // or bounds on method `t` + // do not match the trait + // declaration + } +} +``` + +The 'b lifetime constraints for `t` implementation does not match the +trait declaration. Ensure lifetime declarations match exactly in both trait +declaration and implementation. Example: + +``` +trait Trait { + fn t<'a,'b:'a>(x: &'a str, y: &'b str); +} + +struct Foo; + +impl Trait for Foo { + fn t<'a,'b:'a>(x: &'a str, y: &'b str) { // ok! + } +} +``` +"##, + E0197: r##" Inherent implementations (one that do not implement a trait but provide methods associated with a type) are always safe because they are not @@ -1686,7 +1724,6 @@ register_diagnostics! { E0193, // cannot bound type where clause bounds may only be attached to types // involving type parameters E0194, - E0195, // lifetime parameters or bounds on method do not match the trait declaration E0196, // cannot determine a type for this closure E0203, // type parameter has more than one relaxed default bound, // and only one is supported From 20f22b7f0e29068414933dd6d41c6a5785d3fd75 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 10:35:46 +0200 Subject: [PATCH 089/160] Add E0093 error explanation --- src/librustc_typeck/diagnostics.rs | 37 +++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 1e83c1b6900a4..57fbd52f71f4e 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1022,6 +1022,42 @@ type Foo = Box; // ok! ``` "##, +E0093: r##" +You called an unknown intrinsic function. Erroneous code example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn foo(); +} + +fn main() { + unsafe { + foo(); + } +} +``` + +Please check you didn't make a mistake in the function's name. All intrinsic +functions are defined in librustc_trans/trans/intrinsic.rs and in +libcore/intrinsics.rs. Example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn atomic_fence(); +} + +fn main() { + unsafe { + atomic_fence(); + } +} +``` +"##, + E0106: r##" This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the @@ -1688,7 +1724,6 @@ register_diagnostics! { E0086, E0090, E0092, - E0093, E0094, E0101, E0102, From ed6940fd384b1e42c3e3ad229e022af2e13b79c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 10:44:20 +0200 Subject: [PATCH 090/160] Add E0094 error explanation --- src/librustc_typeck/diagnostics.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 57fbd52f71f4e..4d3d18cb16c02 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1029,7 +1029,7 @@ You called an unknown intrinsic function. Erroneous code example: #![feature(intrinsics)] extern "rust-intrinsic" { - fn foo(); + fn foo(); // error: unrecognized intrinsic function: `foo` } fn main() { @@ -1047,7 +1047,7 @@ libcore/intrinsics.rs. Example: #![feature(intrinsics)] extern "rust-intrinsic" { - fn atomic_fence(); + fn atomic_fence(); // ok! } fn main() { @@ -1058,6 +1058,31 @@ fn main() { ``` "##, +E0094: r##" +You gave an invalid number of type parameters to an intrinsic function. +Erroneous code example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn size_of() -> usize; // error: intrinsic has wrong number + // of type parameters +} +``` + +Please check you give the right number of lifetime parameters and/or the +function definition. Example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn size_of() -> usize; // ok! +} +``` +"##, + E0106: r##" This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the @@ -1724,7 +1749,6 @@ register_diagnostics! { E0086, E0090, E0092, - E0094, E0101, E0102, E0103, From 0ba2db5fde29bfac76a69cff819cb8388be90392 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 10:47:49 +0200 Subject: [PATCH 091/160] Add E0211 error explanation --- src/librustc_typeck/diagnostics.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 4d3d18cb16c02..e81acc497b1b4 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1528,6 +1528,29 @@ impl Copy for &'static Bar { } // error ``` "##, +E0211: r##" +You used an intrinsic function which doesn't correspond to its +definition. Erroneous code example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn size_of(); // error: intrinsic has wrong type +} +``` + +Please check the function definition. Example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn size_of() -> usize; +} +``` +"##, + E0243: r##" This error indicates that not enough type parameters were found in a type or trait. @@ -1790,7 +1813,6 @@ register_diagnostics! { E0208, E0209, // builtin traits can only be implemented on structs or enums E0210, // type parameter is not constrained by any local type - E0211, E0212, // cannot extract an associated type from a higher-ranked trait bound E0213, // associated types are not accepted in this context E0214, // parenthesized parameters may only be used with a trait From 758ea34146f4651cb78e2167de3c335007a8f26d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 10:58:52 +0200 Subject: [PATCH 092/160] Add E0092 error explanation --- src/librustc_typeck/diagnostics.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index e81acc497b1b4..49f58d0d9e9de 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1022,6 +1022,32 @@ type Foo = Box; // ok! ``` "##, +E0092: r##" +You tried to call an undefined atomic operation function. +Erroneous code example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn atomic_foo(); // error: unrecognized atomic operation + // function +} +``` + +Please check you didn't make a mistake in the function's name. All intrinsic +functions are defined in librustc_trans/trans/intrinsic.rs and in +libcore/intrinsics.rs. Example: + +``` +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn atomic_fence(); // ok! +} +``` +"##, + E0093: r##" You called an unknown intrinsic function. Erroneous code example: @@ -1771,7 +1797,6 @@ register_diagnostics! { E0085, E0086, E0090, - E0092, E0101, E0102, E0103, From edf6132be88fa2a51176f84d5fbee45046880717 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 11:19:16 +0200 Subject: [PATCH 093/160] Add E0101 error explanation --- src/librustc_typeck/diagnostics.rs | 51 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 49f58d0d9e9de..affa0768697da 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1023,7 +1023,7 @@ type Foo = Box; // ok! "##, E0092: r##" -You tried to call an undefined atomic operation function. +You tried to declare an undefined atomic operation function. Erroneous code example: ``` @@ -1037,7 +1037,7 @@ extern "rust-intrinsic" { Please check you didn't make a mistake in the function's name. All intrinsic functions are defined in librustc_trans/trans/intrinsic.rs and in -libcore/intrinsics.rs. Example: +libcore/intrinsics.rs in the Rust source code. Example: ``` #![feature(intrinsics)] @@ -1049,7 +1049,7 @@ extern "rust-intrinsic" { "##, E0093: r##" -You called an unknown intrinsic function. Erroneous code example: +You declared an unknown intrinsic function. Erroneous code example: ``` #![feature(intrinsics)] @@ -1067,7 +1067,7 @@ fn main() { Please check you didn't make a mistake in the function's name. All intrinsic functions are defined in librustc_trans/trans/intrinsic.rs and in -libcore/intrinsics.rs. Example: +libcore/intrinsics.rs in the Rust source code. Example: ``` #![feature(intrinsics)] @@ -1097,8 +1097,9 @@ extern "rust-intrinsic" { } ``` -Please check you give the right number of lifetime parameters and/or the -function definition. Example: +Please check that you provided the right number of lifetime parameters +and verify with the function declaration in the Rust source code. +Example: ``` #![feature(intrinsics)] @@ -1109,6 +1110,32 @@ extern "rust-intrinsic" { ``` "##, +E0101: r##" +You hit this error because the compiler the compiler lacks information +to determine a type for this expression. Erroneous code example: + +``` +fn main() { + let x = |_| {}; // error: cannot determine a type for this expression +} +``` + +You have two possibilities to solve this situation: + * Give an explicit definition of the expression + * Infer the expression + +Examples: + +``` +fn main() { + let x = |_ : u32| {}; // ok! + // or: + let x = |_| {}; + x(0u32); +} +``` +"##, + E0106: r##" This error indicates that a lifetime is missing from a type. If it is an error inside a function signature, the problem may be with failing to adhere to the @@ -1343,21 +1370,20 @@ Erroneous code example: ``` trait Trait { - fn t<'a,'b:'a>(x: &'a str, y: &'b str); + fn bar<'a,'b:'a>(x: &'a str, y: &'b str); } struct Foo; impl Trait for Foo { - fn t<'a,'b>(x: &'a str, y: &'b str) { // error: lifetime parameters - // or bounds on method `t` - // do not match the trait - // declaration + fn bar<'a,'b>(x: &'a str, y: &'b str) { + // error: lifetime parameters or bounds on method `bar` + // do not match the trait declaration } } ``` -The 'b lifetime constraints for `t` implementation does not match the +The `'b` lifetime constraint for bar() implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: @@ -1797,7 +1823,6 @@ register_diagnostics! { E0085, E0086, E0090, - E0101, E0102, E0103, E0104, From a481c4ecdc95bf9247f262334f288ff78001ff6c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 11:57:47 +0200 Subject: [PATCH 094/160] Add E0117 error explanation --- src/librustc_typeck/diagnostics.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index affa0768697da..7cc13a1a07737 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1244,6 +1244,26 @@ impl Bytes { ... } // error, same as above ``` "##, +E0117: r##" +You tried to implement a trait on a type which isn't defined in your crate. +Erroneous code example: + +``` +impl Drop for u32 {} +``` + +The type on which you want to implement the trait has to be defined in +your crate. Example: + +``` +pub struct Foo; // you define your type in your crate + +impl Drop for Foo { // and you can implement the trait on it! + // code of trait implementation here +} +``` +"##, + E0121: r##" In order to be consistent with Rust's lack of global type inference, type placeholders are disallowed by design in item signatures. @@ -1826,7 +1846,6 @@ register_diagnostics! { E0102, E0103, E0104, - E0117, E0118, E0119, E0120, From 2881e83c96c6f35fdc6741bbb3f951507ef74ca5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 12:12:45 +0200 Subject: [PATCH 095/160] Add E0207 error explanation --- src/librustc_typeck/diagnostics.rs | 37 +++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 7cc13a1a07737..83e6ea74d83dc 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1600,6 +1600,42 @@ impl Copy for &'static Bar { } // error ``` "##, +E0207: r##" +You passed an unused type parameter when implementing a trait +on an object. Erroneous code example: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +struct Foo; + +impl MyTrait for Foo { + fn get(&self) -> usize { + 0 + } +} +``` + +Please check your object definition and remove unused type +parameter(s). Example: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +struct Foo; + +impl MyTrait for Foo { + fn get(&self) -> usize { + 0 + } +} +``` +"##, + E0211: r##" You used an intrinsic function which doesn't correspond to its definition. Erroneous code example: @@ -1878,7 +1914,6 @@ register_diagnostics! { E0196, // cannot determine a type for this closure E0203, // type parameter has more than one relaxed default bound, // and only one is supported - E0207, // type parameter is not constrained by the impl trait, self type, or predicate E0208, E0209, // builtin traits can only be implemented on structs or enums E0210, // type parameter is not constrained by any local type From be38926b6941f13b1f03c2e3523b98dd256b3c7b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Jun 2015 12:35:01 +0200 Subject: [PATCH 096/160] Add E0119 error explanation Add more explanations --- src/librustc_typeck/diagnostics.rs | 85 +++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 83e6ea74d83dc..05ddfe89bcf5c 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1245,15 +1245,16 @@ impl Bytes { ... } // error, same as above "##, E0117: r##" -You tried to implement a trait on a type which isn't defined in your crate. -Erroneous code example: +You got this error because because you tried to implement a foreign +trait for a foreign type (with maybe a foreign type parameter). Erroneous +code example: ``` impl Drop for u32 {} ``` -The type on which you want to implement the trait has to be defined in -your crate. Example: +The type, trait or the type parameter (or all of them) has to be defined +in your crate. Example: ``` pub struct Foo; // you define your type in your crate @@ -1261,6 +1262,75 @@ pub struct Foo; // you define your type in your crate impl Drop for Foo { // and you can implement the trait on it! // code of trait implementation here } + +trait Bar { // or define your trait in your crate + fn get(&self) -> usize; +} + +impl Bar for u32 { // and then you implement it on a foreign type + fn get(&self) -> usize { 0 } +} + +impl From for i32 { // or you use a type from your crate as + // a type parameter + fn from(i: Foo) -> i32 { + 0 + } +} +``` +"##, + +E0119: r##" +There are conflicting trait implementations for the same type. +Erroneous code example: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct Foo { + value: usize +} + +impl MyTrait for Foo { // error: conflicting implementations for trait + // `MyTrait` + fn get(&self) -> usize { self.value } +} +``` + +When you write: + +``` +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} +``` + +This makes the trait implemented on all types in the scope. So if you +try to implement it on another one after that, the implementations will +conflict. Example: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct Foo; + +fn main() { + let f = Foo; + + f.get(); // the trait is implemented so we can use it +} ``` "##, @@ -1403,7 +1473,7 @@ impl Trait for Foo { } ``` -The `'b` lifetime constraint for bar() implementation does not match the +The lifetime constraint `'b` for bar() implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: @@ -1601,8 +1671,8 @@ impl Copy for &'static Bar { } // error "##, E0207: r##" -You passed an unused type parameter when implementing a trait -on an object. Erroneous code example: +You declared an unused type parameter when implementing a trait on an object. +Erroneous code example: ``` trait MyTrait { @@ -1883,7 +1953,6 @@ register_diagnostics! { E0103, E0104, E0118, - E0119, E0120, E0122, E0123, From 8b25086f3dba6d2a452de009914ab5ae058a6d28 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Fri, 5 Jun 2015 12:43:32 -0700 Subject: [PATCH 097/160] Deprecate BitSet and BitVec in favour of bit-vec and bit-set crates in cargo --- src/libcollections/bit.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 51914900fdd99..7e7481e4f2fde 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -8,6 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deprecated(reason = "BitVec and BitSet have been migrated to cargo as bit-vec and bit-set", + since = "1.2.0")] +#![unstable(feature = "collections", reason = "deprecated")] +#![allow(deprecated)] + // FIXME(Gankro): BitVec and BitSet are very tightly coupled. Ideally (for // maintenance), they should be in separate files/modules, with BitSet only // using BitVec's public API. This will be hard for performance though, because From bc1b43cd0bbd14c72aebb81f3496cbe287241f7c Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 27 Jun 2015 22:58:49 +0200 Subject: [PATCH 098/160] doc: add example for Stdin::read_line --- src/libstd/io/stdio.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 9fd48f6795039..2a64d0f6e8c19 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -204,6 +204,28 @@ impl Stdin { /// /// For detailed semantics of this method, see the documentation on /// `BufRead::read_line`. + /// + /// # Examples + /// + /// ```no_run + /// use std::io; + /// + /// let mut input = String::new(); + /// match io::stdin().read_line(&mut input) { + /// Ok(n) => { + /// println!("{} bytes read", n); + /// println!("{}", input); + /// } + /// Err(error) => println!("error: {}", error), + /// } + /// ``` + /// + /// You can run the example one of two ways: + /// + /// - Pipe some text to it, e.g. `printf foo | path/to/executable` + /// - Give it text interactively by running the executable directly, + // in which case it will wait for the Enter key to be pressed before + /// continuing #[stable(feature = "rust1", since = "1.0.0")] pub fn read_line(&mut self, buf: &mut String) -> io::Result { self.lock().read_line(buf) From cebb118bff991c47de08461d0d319c3d99b92bcd Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Tue, 30 Jun 2015 22:03:25 +0300 Subject: [PATCH 099/160] Actually encode default associated types Fixes #26636 --- src/librustc/metadata/encoder.rs | 4 ++++ src/librustc/middle/traits/project.rs | 3 +++ .../xcrate_associated_type_defaults.rs | 16 ++++++++++++++++ .../xcrate-associated-type-defaults.rs | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 src/test/auxiliary/xcrate_associated_type_defaults.rs create mode 100644 src/test/run-pass/xcrate-associated-type-defaults.rs diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index b844717e61388..b677e7b85703b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1451,6 +1451,10 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_item_sort(rbml_w, 't'); encode_family(rbml_w, 'y'); + if let Some(ty) = associated_type.ty { + encode_type(ecx, rbml_w, ty); + } + is_nonstatic_method = false; } } diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 184de682c67db..e5f7542aa84c9 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -904,6 +904,9 @@ fn confirm_impl_candidate<'cx,'tcx>( // ought to be reported by the type checker method // `check_impl_items_against_trait`, so here we // just return TyError. + debug!("confirm_impl_candidate: no associated type {:?} for {:?}", + assoc_ty.name, + trait_ref); return (selcx.tcx().types.err, vec!()); } } diff --git a/src/test/auxiliary/xcrate_associated_type_defaults.rs b/src/test/auxiliary/xcrate_associated_type_defaults.rs new file mode 100644 index 0000000000000..a6b70bf974f95 --- /dev/null +++ b/src/test/auxiliary/xcrate_associated_type_defaults.rs @@ -0,0 +1,16 @@ +// 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. + +pub trait Foo { + type Input = usize; + fn bar(&self, _: Self::Input) {} +} + +impl Foo for () {} diff --git a/src/test/run-pass/xcrate-associated-type-defaults.rs b/src/test/run-pass/xcrate-associated-type-defaults.rs new file mode 100644 index 0000000000000..1b6de3b2f7bcf --- /dev/null +++ b/src/test/run-pass/xcrate-associated-type-defaults.rs @@ -0,0 +1,18 @@ +// 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. + +// aux-build:xcrate_associated_type_defaults.rs + +extern crate xcrate_associated_type_defaults; +use xcrate_associated_type_defaults::Foo; + +fn main() { + ().bar(5); +} From 8b81f76593ce044b0d822f07061c93b515f7dc01 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 30 Jun 2015 18:46:31 -0400 Subject: [PATCH 100/160] Make note of Ord's derive ordering Fixes #26620 --- src/libcore/cmp.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 0269499ad5414..52ed29c1b61f4 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -166,6 +166,8 @@ impl Ordering { /// /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. +/// +/// When this trait is `derive`d, it produces a lexicographic ordering. #[stable(feature = "rust1", since = "1.0.0")] pub trait Ord: Eq + PartialOrd { /// This method returns an `Ordering` between `self` and `other`. From 2f45294a506904f2768a8f991b0cf33b7cb0bcd2 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 17 Jun 2015 21:54:22 +0300 Subject: [PATCH 101/160] Clean-up assignment checking in borrowck --- src/librustc_borrowck/borrowck/check_loans.rs | 207 ++---------------- .../borrowck/gather_loans/lifetime.rs | 2 +- .../borrowck/gather_loans/mod.rs | 155 ++++++++----- .../borrowck/gather_loans/restrictions.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 35 +-- 5 files changed, 137 insertions(+), 264 deletions(-) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 9d4fb4c994d40..f06dc105d9cc1 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -565,13 +565,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { true } - fn is_local_variable_or_arg(&self, cmt: mc::cmt<'tcx>) -> bool { - match cmt.cat { - mc::cat_local(_) => true, - _ => false - } - } - fn consume_common(&self, id: ast::NodeId, span: Span, @@ -793,198 +786,40 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { mode: euv::MutateMode) { debug!("check_assignment(assignee_cmt={:?})", assignee_cmt); - // Mutable values can be assigned, as long as they obey loans - // and aliasing restrictions: - if assignee_cmt.mutbl.is_mutable() { - if check_for_aliasable_mutable_writes(self, assignment_span, assignee_cmt.clone()) { - if mode != euv::Init { - check_for_assignment_to_borrowed_path( - self, assignment_id, assignment_span, assignee_cmt.clone()); - mark_variable_as_used_mut(self, assignee_cmt); - } - } - - return; - } - - // Initializations are OK if and only if they aren't partial - // reinitialization of a partially-uninitialized structure. + // Initializations never cause borrow errors as they only + // affect a fresh local. if mode == euv::Init { return } - // For immutable local variables, assignments are legal - // if they cannot already have been assigned - if self.is_local_variable_or_arg(assignee_cmt.clone()) { - assert!(assignee_cmt.mutbl.is_immutable()); // no "const" locals - let lp = opt_loan_path(&assignee_cmt).unwrap(); - self.move_data.each_assignment_of(assignment_id, &lp, |assign| { - self.bccx.report_reassigned_immutable_variable( - assignment_span, - &*lp, - assign); + // Check that we don't invalidate any outstanding loans + if let Some(loan_path) = opt_loan_path(&assignee_cmt) { + let scope = region::CodeExtent::from_node_id(assignment_id); + self.each_in_scope_loan_affecting_path(scope, &*loan_path, |loan| { + self.report_illegal_mutation(assignment_span, &*loan_path, loan); false }); - return; - } - - // Otherwise, just a plain error. - match assignee_cmt.note { - mc::NoteClosureEnv(upvar_id) => { - // If this is an `Fn` closure, it simply can't mutate upvars. - // If it's an `FnMut` closure, the original variable was declared immutable. - // We need to determine which is the case here. - let kind = match assignee_cmt.upvar().unwrap().cat { - mc::cat_upvar(mc::Upvar { kind, .. }) => kind, - _ => unreachable!() - }; - if kind == ty::FnClosureKind { - self.bccx.span_err( - assignment_span, - &format!("cannot assign to {}", - self.bccx.cmt_to_string(&*assignee_cmt))); - self.bccx.span_help( - self.tcx().map.span(upvar_id.closure_expr_id), - "consider changing this closure to take self by mutable reference"); - } else { - self.bccx.span_err( - assignment_span, - &format!("cannot assign to {} {}", - assignee_cmt.mutbl.to_user_str(), - self.bccx.cmt_to_string(&*assignee_cmt))); - } - } - _ => match opt_loan_path(&assignee_cmt) { - Some(lp) => { - self.bccx.span_err( - assignment_span, - &format!("cannot assign to {} {} `{}`", - assignee_cmt.mutbl.to_user_str(), - self.bccx.cmt_to_string(&*assignee_cmt), - self.bccx.loan_path_to_string(&*lp))); - } - None => { - self.bccx.span_err( - assignment_span, - &format!("cannot assign to {} {}", - assignee_cmt.mutbl.to_user_str(), - self.bccx.cmt_to_string(&*assignee_cmt))); - } - } - } - return; - - fn mark_variable_as_used_mut<'a, 'tcx>(this: &CheckLoanCtxt<'a, 'tcx>, - mut cmt: mc::cmt<'tcx>) { - //! If the mutability of the `cmt` being written is inherited - //! from a local variable, liveness will - //! not have been able to detect that this variable's mutability - //! is important, so we must add the variable to the - //! `used_mut_nodes` table here. - - loop { - debug!("mark_variable_as_used_mut(cmt={:?})", cmt); - match cmt.cat.clone() { - mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: id, .. }, .. }) | - mc::cat_local(id) => { - this.tcx().used_mut_nodes.borrow_mut().insert(id); - return; - } - - mc::cat_rvalue(..) | - mc::cat_static_item | - mc::cat_deref(_, _, mc::UnsafePtr(..)) | - mc::cat_deref(_, _, mc::Implicit(..)) => { - assert_eq!(cmt.mutbl, mc::McDeclared); - return; - } - - mc::cat_deref(_, _, mc::BorrowedPtr(..)) => { - assert_eq!(cmt.mutbl, mc::McDeclared); - // We need to drill down to upvar if applicable - match cmt.upvar() { - Some(b) => cmt = b, - None => return - } - } - - mc::cat_deref(b, _, mc::Unique) => { - assert_eq!(cmt.mutbl, mc::McInherited); - cmt = b; - } - - mc::cat_downcast(b, _) | - mc::cat_interior(b, _) => { - assert_eq!(cmt.mutbl, mc::McInherited); - cmt = b; - } - } - } } - fn check_for_aliasable_mutable_writes<'a, 'tcx>(this: &CheckLoanCtxt<'a, 'tcx>, - span: Span, - cmt: mc::cmt<'tcx>) -> bool { - //! Safety checks related to writes to aliasable, mutable locations - - let guarantor = cmt.guarantor(); - debug!("check_for_aliasable_mutable_writes(cmt={:?}, guarantor={:?})", - cmt, guarantor); - if let mc::cat_deref(ref b, _, mc::BorrowedPtr(ty::MutBorrow, _)) = guarantor.cat { - // Statically prohibit writes to `&mut` when aliasable - check_for_aliasability_violation(this, span, b.clone()); + // Local variables can always be assigned to, expect for reassignments + // of immutable variables (or assignments that invalidate loans, + // of course). + if let mc::cat_local(local_id) = assignee_cmt.cat { + if assignee_cmt.mutbl.is_mutable() { + self.tcx().used_mut_nodes.borrow_mut().insert(local_id); } - return true; // no errors reported - } - - fn check_for_aliasability_violation<'a, 'tcx>(this: &CheckLoanCtxt<'a, 'tcx>, - span: Span, - cmt: mc::cmt<'tcx>) - -> bool { - match cmt.freely_aliasable(this.tcx()) { - mc::Aliasability::NonAliasable => { - return true; - } - mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut(..)) => { - return true; - } - mc::Aliasability::ImmutableUnique(_) => { - this.bccx.report_aliasability_violation( - span, - MutabilityViolation, - mc::AliasableReason::UnaliasableImmutable); - return false; - } - mc::Aliasability::FreelyAliasable(cause) => { - this.bccx.report_aliasability_violation( - span, - MutabilityViolation, - cause); - return false; + let lp = opt_loan_path(&assignee_cmt).unwrap(); + self.move_data.each_assignment_of(assignment_id, &lp, |assign| { + if !assignee_cmt.mutbl.is_mutable() { + self.bccx.report_reassigned_immutable_variable( + assignment_span, + &*lp, + assign); } - } - } - - fn check_for_assignment_to_borrowed_path<'a, 'tcx>( - this: &CheckLoanCtxt<'a, 'tcx>, - assignment_id: ast::NodeId, - assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>) - { - //! Check for assignments that violate the terms of an - //! outstanding loan. - - let loan_path = match opt_loan_path(&assignee_cmt) { - Some(lp) => lp, - None => { return; /* no loan path, can't be any loans */ } - }; - - let scope = region::CodeExtent::from_node_id(assignment_id); - this.each_in_scope_loan_affecting_path(scope, &*loan_path, |loan| { - this.report_illegal_mutation(assignment_span, &*loan_path, loan); false }); + return } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 427d78e89b3e2..919bc45f00ddf 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -137,7 +137,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { fn report_error(&self, code: bckerr_code) { self.bccx.report(BckError { cmt: self.cmt_original.clone(), span: self.span, - cause: self.cause, + cause: BorrowViolation(self.cause), code: code }); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 44a4a0d250402..39b9f07604353 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -151,22 +151,10 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { assignee_cmt: mc::cmt<'tcx>, mode: euv::MutateMode) { - let opt_lp = opt_loan_path(&assignee_cmt); - debug!("mutate(assignment_id={}, assignee_cmt={:?}) opt_lp={:?}", - assignment_id, assignee_cmt, opt_lp); - - match opt_lp { - Some(lp) => { - gather_moves::gather_assignment(self.bccx, &self.move_data, - assignment_id, assignment_span, - lp, assignee_cmt.id, mode); - } - None => { - // This can occur with e.g. `*foo() = 5`. In such - // cases, there is no need to check for conflicts - // with moves etc, just ignore. - } - } + self.guarantee_assignment_valid(assignment_id, + assignment_span, + assignee_cmt, + mode); } fn decl_without_init(&mut self, id: ast::NodeId, span: Span) { @@ -177,7 +165,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> { /// Implements the A-* rules in README.md. fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, borrow_span: Span, - loan_cause: euv::LoanCause, + loan_cause: AliasableViolationKind, cmt: mc::cmt<'tcx>, req_kind: ty::BorrowKind) -> Result<(),()> { @@ -203,7 +191,7 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, (mc::Aliasability::ImmutableUnique(_), ty::MutBorrow) => { bccx.report_aliasability_violation( borrow_span, - BorrowViolation(loan_cause), + loan_cause, mc::AliasableReason::UnaliasableImmutable); Err(()) } @@ -211,7 +199,7 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, (mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => { bccx.report_aliasability_violation( borrow_span, - BorrowViolation(loan_cause), + loan_cause, alias_cause); Err(()) } @@ -221,9 +209,94 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, } } +/// Implements the M-* rules in README.md. +fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, + borrow_span: Span, + cause: AliasableViolationKind, + cmt: mc::cmt<'tcx>, + req_kind: ty::BorrowKind) + -> Result<(),()> { + debug!("check_mutability(cause={:?} cmt={:?} req_kind={:?}", + cause, cmt, req_kind); + match req_kind { + ty::UniqueImmBorrow | ty::ImmBorrow => { + match cmt.mutbl { + // I am intentionally leaving this here to help + // refactoring if, in the future, we should add new + // kinds of mutability. + mc::McImmutable | mc::McDeclared | mc::McInherited => { + // both imm and mut data can be lent as imm; + // for mutable data, this is a freeze + Ok(()) + } + } + } + + ty::MutBorrow => { + // Only mutable data can be lent as mutable. + if !cmt.mutbl.is_mutable() { + Err(bccx.report(BckError { span: borrow_span, + cause: cause, + cmt: cmt, + code: err_mutbl })) + } else { + Ok(()) + } + } + } +} + impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx } + /// Guarantees that `cmt` is assignable, or reports an error. + fn guarantee_assignment_valid(&mut self, + assignment_id: ast::NodeId, + assignment_span: Span, + cmt: mc::cmt<'tcx>, + mode: euv::MutateMode) { + + let opt_lp = opt_loan_path(&cmt); + debug!("guarantee_assignment_valid(assignment_id={}, cmt={:?}) opt_lp={:?}", + assignment_id, cmt, opt_lp); + + if let mc::cat_local(..) = cmt.cat { + // Only re-assignments to locals require it to be + // mutable - this is checked in check_loans. + } else { + // Check that we don't allow assignments to non-mutable data. + if check_mutability(self.bccx, assignment_span, MutabilityViolation, + cmt.clone(), ty::MutBorrow).is_err() { + return; // reported an error, no sense in reporting more. + } + } + + // Check that we don't allow assignments to aliasable data + if check_aliasability(self.bccx, assignment_span, MutabilityViolation, + cmt.clone(), ty::MutBorrow).is_err() { + return; // reported an error, no sense in reporting more. + } + + match opt_lp { + Some(lp) => { + if let mc::cat_local(..) = cmt.cat { + // Only re-assignments to locals require it to be + // mutable - this is checked in check_loans. + } else { + self.mark_loan_path_as_mutated(&lp); + } + gather_moves::gather_assignment(self.bccx, &self.move_data, + assignment_id, assignment_span, + lp, cmt.id, mode); + } + None => { + // This can occur with e.g. `*foo() = 5`. In such + // cases, there is no need to check for conflicts + // with moves etc, just ignore. + } + } + } + /// Guarantees that `addr_of(cmt)` will be valid for the duration of `static_scope_r`, or /// reports an error. This may entail taking out loans, which will be added to the /// `req_loan_map`. @@ -256,13 +329,13 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { } // Check that we don't allow mutable borrows of non-mutable data. - if check_mutability(self.bccx, borrow_span, cause, + if check_mutability(self.bccx, borrow_span, BorrowViolation(cause), cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of aliasable data. - if check_aliasability(self.bccx, borrow_span, cause, + if check_aliasability(self.bccx, borrow_span, BorrowViolation(cause), cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } @@ -368,43 +441,6 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { // restrictions: restrictions // } // } - - fn check_mutability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, - borrow_span: Span, - cause: euv::LoanCause, - cmt: mc::cmt<'tcx>, - req_kind: ty::BorrowKind) - -> Result<(),()> { - //! Implements the M-* rules in README.md. - debug!("check_mutability(cause={:?} cmt={:?} req_kind={:?}", - cause, cmt, req_kind); - match req_kind { - ty::UniqueImmBorrow | ty::ImmBorrow => { - match cmt.mutbl { - // I am intentionally leaving this here to help - // refactoring if, in the future, we should add new - // kinds of mutability. - mc::McImmutable | mc::McDeclared | mc::McInherited => { - // both imm and mut data can be lent as imm; - // for mutable data, this is a freeze - Ok(()) - } - } - } - - ty::MutBorrow => { - // Only mutable data can be lent as mutable. - if !cmt.mutbl.is_mutable() { - Err(bccx.report(BckError { span: borrow_span, - cause: cause, - cmt: cmt, - code: err_mutbl })) - } else { - Ok(()) - } - } - } - } } pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) { @@ -495,7 +531,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { let base_cmt = mc.cat_expr(&**base).unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. - if check_aliasability(self.bccx, ex.span, euv::AddrOf, + if check_aliasability(self.bccx, ex.span, + BorrowViolation(euv::AddrOf), base_cmt, borrow_kind).is_err() { return; // reported an error, no sense in reporting more. } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index 345f5378f69e1..4c186dd840610 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { self.bccx.report( BckError { span: self.span, - cause: self.cause, + cause: BorrowViolation(self.cause), cmt: cmt_base, code: err_borrowed_pointer_too_short( self.loan_region, lt)}); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4f726044a1bac..65e3e443e7de2 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -546,12 +546,12 @@ pub enum bckerr_code { #[derive(PartialEq)] pub struct BckError<'tcx> { span: Span, - cause: euv::LoanCause, + cause: AliasableViolationKind, cmt: mc::cmt<'tcx>, code: bckerr_code } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug, PartialEq)] pub enum AliasableViolationKind { MutabilityViolation, BorrowViolation(euv::LoanCause) @@ -576,8 +576,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { pub fn report(&self, err: BckError<'tcx>) { // Catch and handle some particular cases. match (&err.code, &err.cause) { - (&err_out_of_scope(ty::ReScope(_), ty::ReStatic), &euv::ClosureCapture(span)) | - (&err_out_of_scope(ty::ReScope(_), ty::ReFree(..)), &euv::ClosureCapture(span)) => { + (&err_out_of_scope(ty::ReScope(_), ty::ReStatic), + &BorrowViolation(euv::ClosureCapture(span))) | + (&err_out_of_scope(ty::ReScope(_), ty::ReFree(..)), + &BorrowViolation(euv::ClosureCapture(span))) => { return self.report_out_of_scope_escaping_closure_capture(&err, span); } _ => { } @@ -796,10 +798,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.sess.span_end_note(s, m); } - pub fn span_help(&self, s: Span, m: &str) { - self.tcx.sess.span_help(s, m); - } - pub fn fileline_help(&self, s: Span, m: &str) { self.tcx.sess.fileline_help(s, m); } @@ -827,19 +825,22 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { }; match err.cause { - euv::ClosureCapture(_) => { + MutabilityViolation => { + format!("cannot assign to {}", descr) + } + BorrowViolation(euv::ClosureCapture(_)) => { format!("closure cannot assign to {}", descr) } - euv::OverloadedOperator | - euv::AddrOf | - euv::RefBinding | - euv::AutoRef | - euv::AutoUnsafe | - euv::ForLoop | - euv::MatchDiscriminant => { + BorrowViolation(euv::OverloadedOperator) | + BorrowViolation(euv::AddrOf) | + BorrowViolation(euv::RefBinding) | + BorrowViolation(euv::AutoRef) | + BorrowViolation(euv::AutoUnsafe) | + BorrowViolation(euv::ForLoop) | + BorrowViolation(euv::MatchDiscriminant) => { format!("cannot borrow {} as mutable", descr) } - euv::ClosureInvocation => { + BorrowViolation(euv::ClosureInvocation) => { self.tcx.sess.span_bug(err.span, "err_mutbl with a closure invocation"); } From a18d9842ed94ecca3e7161945bb2f749d98d18ee Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 18 Jun 2015 01:02:58 +0300 Subject: [PATCH 102/160] Make the unused_mut lint smarter with respect to locals. Fixes #26332 --- src/libcore/iter.rs | 4 +-- src/libfmt_macros/lib.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 2 +- src/librustc_borrowck/borrowck/check_loans.rs | 25 ++++++------------- src/librustc_trans/save/dump_csv.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 2 +- .../compile-fail/lint-unused-mut-variables.rs | 9 +++++++ 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 3026f91e853ee..4c8511eb1902c 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2655,8 +2655,8 @@ macro_rules! step_impl_signed { #[allow(trivial_numeric_casts)] fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { if *by == 0 { return None; } - let mut diff: usize; - let mut by_u: usize; + let diff: usize; + let by_u: usize; if *by > 0 { if *start >= *end { return Some(0); diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index c2b28bd134d47..7ca89cfd0c9cc 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -399,7 +399,7 @@ impl<'a> Parser<'a> { } Some(..) | None => { return &self.input[..0]; } }; - let mut end; + let end; loop { match self.cur.clone().next() { Some((_, c)) if c.is_xid_continue() => { diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 17075c0cba6ca..6d5b47d8ed980 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1854,7 +1854,7 @@ impl LifeGiver { } fn give_lifetime(&self) -> ast::Lifetime { - let mut lifetime; + let lifetime; loop { let mut s = String::from("'"); s.push_str(&num_to_string(self.counter.get())); diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index f06dc105d9cc1..237add6ff860e 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -182,7 +182,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { None => { } } - self.check_assignment(assignment_id, assignment_span, assignee_cmt, mode); + self.check_assignment(assignment_id, assignment_span, assignee_cmt); } fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) { } @@ -782,16 +782,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { fn check_assignment(&self, assignment_id: ast::NodeId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, - mode: euv::MutateMode) { + assignee_cmt: mc::cmt<'tcx>) { debug!("check_assignment(assignee_cmt={:?})", assignee_cmt); - // Initializations never cause borrow errors as they only - // affect a fresh local. - if mode == euv::Init { - return - } - // Check that we don't invalidate any outstanding loans if let Some(loan_path) = opt_loan_path(&assignee_cmt) { let scope = region::CodeExtent::from_node_id(assignment_id); @@ -801,17 +794,15 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }); } - // Local variables can always be assigned to, expect for reassignments - // of immutable variables (or assignments that invalidate loans, - // of course). + // Check for reassignments to (immutable) local variables. This + // needs to be done here instead of in check_loans because we + // depend on move data. if let mc::cat_local(local_id) = assignee_cmt.cat { - if assignee_cmt.mutbl.is_mutable() { - self.tcx().used_mut_nodes.borrow_mut().insert(local_id); - } - let lp = opt_loan_path(&assignee_cmt).unwrap(); self.move_data.each_assignment_of(assignment_id, &lp, |assign| { - if !assignee_cmt.mutbl.is_mutable() { + if assignee_cmt.mutbl.is_mutable() { + self.tcx().used_mut_nodes.borrow_mut().insert(local_id); + } else { self.bccx.report_reassigned_immutable_variable( assignment_span, &*lp, diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index d86242f39cea7..f747f2deec415 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -308,7 +308,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { debug!("process_method: {}:{}", id, token::get_name(name)); - let mut scope_id; + let 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 self.tcx.impl_of_method(ast_util::local_def(id)) { diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b6b5ac5c01eee..507bd9de2a11a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -598,7 +598,7 @@ impl<'a> StringReader<'a> { /// Lex a LIT_INTEGER or a LIT_FLOAT fn scan_number(&mut self, c: char) -> token::Lit { - let mut num_digits; + let num_digits; let mut base = 10; let start_bpos = self.last_pos; diff --git a/src/test/compile-fail/lint-unused-mut-variables.rs b/src/test/compile-fail/lint-unused-mut-variables.rs index dcc82b8920ff5..8165dd0fa29c0 100644 --- a/src/test/compile-fail/lint-unused-mut-variables.rs +++ b/src/test/compile-fail/lint-unused-mut-variables.rs @@ -23,6 +23,15 @@ fn main() { let mut b = 3; //~ ERROR: variable does not need to be mutable let mut a = vec!(3); //~ ERROR: variable does not need to be mutable let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable + let mut a; //~ ERROR: variable does not need to be mutable + a = 3; + + let mut b; //~ ERROR: variable does not need to be mutable + if true { + b = 3; + } else { + b = 4; + } match 30 { mut x => {} //~ ERROR: variable does not need to be mutable From 98566ea951fec6d359e2d98367d34c06e2243ee2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 30 Jun 2015 19:26:03 -0700 Subject: [PATCH 103/160] std: Fix formatting flags for chars This recently regressed in #24689, and this updates the `Display` implementation to take formatting flags into account. Closes #26625 --- src/libcore/fmt/mod.rs | 9 ++++++++- src/libcoretest/fmt/mod.rs | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index cbbb186af7609..343772c764f81 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -980,7 +980,14 @@ impl Debug for char { #[stable(feature = "rust1", since = "1.0.0")] impl Display for char { fn fmt(&self, f: &mut Formatter) -> Result { - f.write_char(*self) + if f.width.is_none() && f.precision.is_none() { + f.write_char(*self) + } else { + let mut utf8 = [0; 4]; + let amt = self.encode_utf8(&mut utf8).unwrap_or(0); + let s: &str = unsafe { mem::transmute(&utf8[..amt]) }; + f.pad(s) + } } } diff --git a/src/libcoretest/fmt/mod.rs b/src/libcoretest/fmt/mod.rs index cdb9c38f027f7..42872589bb01f 100644 --- a/src/libcoretest/fmt/mod.rs +++ b/src/libcoretest/fmt/mod.rs @@ -16,4 +16,6 @@ fn test_format_flags() { // No residual flags left by pointer formatting let p = "".as_ptr(); assert_eq!(format!("{:p} {:x}", p, 16), format!("{:p} 10", p)); + + assert_eq!(format!("{: >3}", 'a'), " a"); } From a1d40c81f95107a5233db2c0059b8b7652592edd Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 1 Jul 2015 15:53:08 +1200 Subject: [PATCH 104/160] save-analysis: skip generated content in patterns --- src/librustc_trans/save/dump_csv.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index d86242f39cea7..c0bfd6fbcb713 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -937,7 +937,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { fn process_pat(&mut self, p:&ast::Pat) { if generated_code(p.span) { - return + return; } match p.node { @@ -963,6 +963,10 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { if let Some(struct_def) = struct_def { let struct_fields = self.tcx.lookup_struct_fields(struct_def); for &Spanned { node: ref field, span } in fields { + if generated_code(span) { + continue; + } + let sub_span = self.span.span_for_first_ident(span); for f in &struct_fields { if f.name == field.ident.name { @@ -974,7 +978,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { break; } } - self.visit_pat(&*field.pat); + self.visit_pat(&field.pat); } } } From 88900895562e0ab5e0642724fe9dd71eeda79a7a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 29 Jun 2015 09:46:35 -0700 Subject: [PATCH 105/160] std: Avoid the WSA_FLAG_NO_HANDLE_INHERIT option This was added after Windows 7 SP1, so it's not always available. Instead use the `SetHandleInformation` function to flag a socket as not inheritable. This is not atomic with respect to creating new processes, but it mirrors what Unix does with respect to possibly using the atomic option in the future. Closes #26543 --- src/libstd/sys/windows/c.rs | 5 ++++ src/libstd/sys/windows/net.rs | 45 ++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 7f89ea979391e..2ddf685729bcb 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -64,6 +64,8 @@ pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD; pub const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD; pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD; +pub const HANDLE_FLAG_INHERIT: libc::DWORD = 0x00000001; + #[repr(C)] #[cfg(target_arch = "x86")] pub struct WSADATA { @@ -408,6 +410,9 @@ extern "system" { pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE, lpProfileDir: libc::LPCWSTR, lpcchSize: *mut libc::DWORD) -> libc::BOOL; + pub fn SetHandleInformation(hObject: libc::HANDLE, + dwMask: libc::DWORD, + dwFlags: libc::DWORD) -> libc::BOOL; } // Functions that aren't available on Windows XP, but we still use them and just diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 0b9052672369d..b765bc6e50085 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -82,26 +82,31 @@ impl Socket { SocketAddr::V4(..) => libc::AF_INET, SocketAddr::V6(..) => libc::AF_INET6, }; - let socket = unsafe { - c::WSASocketW(fam, ty, 0, 0 as *mut _, 0, - c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT) - }; - match socket { - INVALID_SOCKET => Err(last_error()), - n => Ok(Socket(n)), - } + let socket = try!(unsafe { + match c::WSASocketW(fam, ty, 0, 0 as *mut _, 0, + c::WSA_FLAG_OVERLAPPED) { + INVALID_SOCKET => Err(last_error()), + n => Ok(Socket(n)), + } + }); + try!(socket.set_no_inherit()); + Ok(socket) } pub fn accept(&self, storage: *mut libc::sockaddr, len: *mut libc::socklen_t) -> io::Result { - match unsafe { libc::accept(self.0, storage, len) } { - INVALID_SOCKET => Err(last_error()), - n => Ok(Socket(n)), - } + let socket = try!(unsafe { + match libc::accept(self.0, storage, len) { + INVALID_SOCKET => Err(last_error()), + n => Ok(Socket(n)), + } + }); + try!(socket.set_no_inherit()); + Ok(socket) } pub fn duplicate(&self) -> io::Result { - unsafe { + let socket = try!(unsafe { let mut info: c::WSAPROTOCOL_INFO = mem::zeroed(); try!(cvt(c::WSADuplicateSocketW(self.0, c::GetCurrentProcessId(), @@ -110,12 +115,13 @@ impl Socket { info.iSocketType, info.iProtocol, &mut info, 0, - c::WSA_FLAG_OVERLAPPED | - c::WSA_FLAG_NO_HANDLE_INHERIT) { + c::WSA_FLAG_OVERLAPPED) { INVALID_SOCKET => Err(last_error()), n => Ok(Socket(n)), } - } + }); + try!(socket.set_no_inherit()); + Ok(socket) } pub fn read(&self, buf: &mut [u8]) -> io::Result { @@ -156,6 +162,13 @@ impl Socket { Ok(Some(Duration::new(secs as u64, nsec as u32))) } } + + fn set_no_inherit(&self) -> io::Result<()> { + sys::cvt(unsafe { + c::SetHandleInformation(self.0 as libc::HANDLE, + c::HANDLE_FLAG_INHERIT, 0) + }).map(|_| ()) + } } impl Drop for Socket { From 49b73e46d68f96e8afc8346c5d3a0ccb38f7c634 Mon Sep 17 00:00:00 2001 From: Mathieu David Date: Tue, 30 Jun 2015 09:32:15 +0200 Subject: [PATCH 106/160] In js from the docs, change keyboard eventlistener to be compatible with non-english keyboard layouts. Fixes #26016 Fixes #16572 --- src/librustdoc/html/static/main.js | 39 +++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index fb8f511795e87..4a03345277466 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -76,17 +76,46 @@ highlightSourceLines(null); $(window).on('hashchange', highlightSourceLines); - $(document).on('keyup', function handleKeyboardShortcut(e) { + // Helper function for Keyboard events, + // Get's the char from the keypress event + // + // This method is used because e.wich === x is not + // compatible with non-english keyboard layouts + // + // Note: event.type must be keypress ! + function getChar(event) { + if (event.which == null) { + return String.fromCharCode(event.keyCode) // IE + } else if (event.which!=0 && event.charCode!=0) { + return String.fromCharCode(event.which) // the rest + } else { + return null // special key + } + } + + $(document).on('keypress', function handleKeyboardShortcut(e) { if (document.activeElement.tagName === 'INPUT') { return; } - if (e.which === 191) { // question mark + if (getChar(e) === '?') { if (e.shiftKey && $('#help').hasClass('hidden')) { e.preventDefault(); $('#help').removeClass('hidden'); } - } else if (e.which === 27) { // esc + } else if (getChar(e) === 's' || getChar(e) === 'S') { + e.preventDefault(); + $('.search-input').focus(); + } + }).on('keydown', function(e) { + // The escape key event has to be captured with the keydown event. + // Because keypressed has no keycode for the escape key + // (and other special keys in general)... + if (document.activeElement.tagName === 'INPUT') { + return; + } + + if (e.keyCode === 27) { // escape key if (!$('#help').hasClass('hidden')) { e.preventDefault(); $('#help').addClass('hidden'); @@ -95,9 +124,6 @@ $('#search').addClass('hidden'); $('#main').removeClass('hidden'); } - } else if (e.which === 83) { // S - e.preventDefault(); - $('.search-input').focus(); } }).on('click', function(e) { if (!$(e.target).closest('#help').length) { @@ -105,6 +131,7 @@ } }); + $('.version-selector').on('change', function() { var i, match, url = document.location.href, From 7dc50b1a075da8cbfb707ea02f935c872c2652cc Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Wed, 1 Jul 2015 12:05:57 +0200 Subject: [PATCH 107/160] Hide SampleRange trait from docs --- src/librand/distributions/range.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index 4916e305b70e3..dce114d1fc21b 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -58,6 +58,7 @@ impl IndependentSample for Range { /// The helper trait for types that have a sensible way to sample /// uniformly between two values. This should not be used directly, /// and is only to facilitate `Range`. +#[doc(hidden)] pub trait SampleRange { /// Construct the `Range` object that `sample_range` /// requires. This should not ever be called directly, only via From d2e6ddabc4bdc041d2545896cfe4a642a9569664 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Jul 2015 13:07:29 +0200 Subject: [PATCH 108/160] Add E0124 error explanation --- src/librustc_typeck/diagnostics.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 05ddfe89bcf5c..e95145c3760e6 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1347,6 +1347,27 @@ static BAR: _ = "test"; // error, explicitly write out the type instead ``` "##, +E0124: r##" +You declared two fields of a struct with the same name. Erroneous code +example: + +``` +struct Foo { + field1: i32, + field1: i32 // error: field is already declared +} +``` + +Please check you didn't mispelled one field. Example: + +``` +struct Foo { + field1: i32, + field2: i32 // ok! +} +``` +"##, + E0131: r##" It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. @@ -1956,7 +1977,6 @@ register_diagnostics! { E0120, E0122, E0123, - E0124, E0127, E0128, E0129, From 55641720aa29aab8a82ff907f6ac513180337f93 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 1 Jul 2015 11:58:51 -0400 Subject: [PATCH 109/160] Expand docs for recv Add an example, plus some text that covers the buffering nature of channels. Fixes #26497 --- src/libstd/sync/mpsc/mod.rs | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 77aeeca796809..1453c91fd4d1d 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -768,6 +768,48 @@ impl Receiver { /// If the corresponding `Sender` has disconnected, or it disconnects while /// this call is blocking, this call will wake up and return `Err` to /// indicate that no more messages can ever be received on this channel. + /// However, since channels are buffered, messages sent before the disconnect + /// will still be properly received. + /// + /// # Examples + /// + /// ``` + /// use std::sync::mpsc; + /// use std::thread; + /// + /// let (send, recv) = mpsc::channel(); + /// let handle = thread::spawn(move || { + /// send.send(1u8).unwrap(); + /// }); + /// + /// handle.join().unwrap(); + /// + /// assert_eq!(Ok(1), recv.recv()); + /// ``` + /// + /// Buffering behavior: + /// + /// ``` + /// use std::sync::mpsc; + /// use std::thread; + /// use std::sync::mpsc::RecvError; + /// + /// let (send, recv) = mpsc::channel(); + /// let handle = thread::spawn(move || { + /// send.send(1u8).unwrap(); + /// send.send(2).unwrap(); + /// send.send(3).unwrap(); + /// drop(send); + /// }); + /// + /// // wait for the thread to join so we ensure the sender is dropped + /// handle.join().unwrap(); + /// + /// assert_eq!(Ok(1), recv.recv()); + /// assert_eq!(Ok(2), recv.recv()); + /// assert_eq!(Ok(3), recv.recv()); + /// assert_eq!(Err(RecvError), recv.recv()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn recv(&self) -> Result { loop { From 0ca7699837ff3302f65418d5bd0fc54c5fb2da4d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Jul 2015 13:37:02 +0200 Subject: [PATCH 110/160] Add examples in error explanation E0267 and E0268 --- src/librustc/diagnostics.rs | 40 +++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 68ca0eac37a5d..08ff692fd46a0 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -602,15 +602,47 @@ const Y: u32 = X; E0267: r##" This error indicates the use of a loop keyword (`break` or `continue`) inside a -closure but outside of any loop. Break and continue can be used as normal inside -closures as long as they are also contained within a loop. To halt the execution -of a closure you should instead use a return statement. +closure but outside of any loop. Erroneous code example: + +``` +let w = || { break; }; // error: `break` inside of a closure +``` + +`break` and `continue` keywords can be used as normal inside closures as long as +they are also contained within a loop. To halt the execution of a closure you +should instead use a return statement. Example: + +``` +let w = || { + for _ in 0..10 { + break; + } +}; + +w(); +``` "##, E0268: r##" This error indicates the use of a loop keyword (`break` or `continue`) outside of a loop. Without a loop to break out of or continue in, no sensible action can -be taken. +be taken. Erroneous code example: + +``` +fn some_func() { + break; // error: `break` outside of loop +} +``` + +Please verify that you are using `break` and `continue` only in loops. Example: + +``` +fn some_func() { + for _ in 0..10 { + break; // ok! + } +} +``` "##, E0271: r##" From 28d2b39f45298b16240455039358d2a4d304fd61 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 1 Jul 2015 13:28:26 +0200 Subject: [PATCH 111/160] Add E0277 error explanation --- src/librustc/diagnostics.rs | 49 +++++++++++++++++++++++++++++- src/librustc_typeck/diagnostics.rs | 2 +- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 68ca0eac37a5d..2eb26e760f9f8 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -749,6 +749,54 @@ for v in &vs { ``` "##, +E0277: r##" +You tried to use a type which doesn't implement some trait in a place which +expected that trait. Erroneous code example: + +``` +// here we declare the Foo trait with a bar method +trait Foo { + fn bar(&self); +} + +// we now declare a function which takes an object with Foo trait implemented +// as parameter +fn some_func(foo: T) { + foo.bar(); +} + +fn main() { + // we now call the method with the i32 type, which doesn't implement + // the Foo trait + some_func(5i32); // error: the trait `Foo` is not implemented for the + // type `i32` +} +``` + +In order to fix this error, verify that the type you're using does implement +the trait. Example: + +``` +trait Foo { + fn bar(&self); +} + +fn some_func(foo: T) { + foo.bar(); // we can now use this method since i32 implements the + // Foo trait +} + +// we implement the trait on the i32 type +impl Foo for i32 { + fn bar(&self) {} +} + +fn main() { + some_func(5i32); // ok! +} +``` +"##, + E0282: r##" This error indicates that type inference did not result in one unique possible type, and extra information is required. In most cases this can be provided @@ -1103,7 +1151,6 @@ register_diagnostics! { E0274, // rustc_on_unimplemented must have a value E0275, // overflow evaluating requirement E0276, // requirement appears on impl method but not on corresponding trait method - E0277, // trait is not implemented for type E0278, // requirement is not satisfied E0279, // requirement is not satisfied E0280, // requirement is not satisfied diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index e95145c3760e6..2c948a45f8c80 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1358,7 +1358,7 @@ struct Foo { } ``` -Please check you didn't mispelled one field. Example: +Please verify that the field names have been correctly spelled. Example: ``` struct Foo { From c9c5ea7c138af6c57da0da53517a4b5f6ccf4915 Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 1 Jul 2015 12:22:42 -0500 Subject: [PATCH 112/160] Add a regression test for #8640. This doesn't add a test for the main problem in #8640 since it seems that was already fixed (including a test) in PR #19522. This just adds a test for a program mentioned in the comments that used to erroneously compile. Closes #8640. --- src/test/compile-fail/issue-8640.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/compile-fail/issue-8640.rs diff --git a/src/test/compile-fail/issue-8640.rs b/src/test/compile-fail/issue-8640.rs new file mode 100644 index 0000000000000..5c1592e65473c --- /dev/null +++ b/src/test/compile-fail/issue-8640.rs @@ -0,0 +1,20 @@ +// 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. + +#[allow(unused_imports)] + +mod foo { + use baz::bar; + //~^ ERROR import `bar` conflicts with existing submodule + mod bar {} +} +mod baz { pub mod bar {} } + +fn main() {} From 7850c8d0aa14cd561fcdce816c94532a3d54ff60 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Tue, 30 Jun 2015 16:41:00 -0700 Subject: [PATCH 113/160] fallout of bitvec/bitset deprecation --- src/libcollections/bit.rs | 2 +- src/libcollections/lib.rs | 4 ++++ src/librustc_lint/builtin.rs | 3 +++ src/libsyntax/attr.rs | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 7e7481e4f2fde..a8d638028be3a 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -9,7 +9,7 @@ // except according to those terms. #![deprecated(reason = "BitVec and BitSet have been migrated to cargo as bit-vec and bit-set", - since = "1.2.0")] + since = "1.3.0")] #![unstable(feature = "collections", reason = "deprecated")] #![allow(deprecated)] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 8d0f57de4c595..42adbe10e5051 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -77,7 +77,9 @@ extern crate alloc; #[cfg(test)] extern crate test; pub use binary_heap::BinaryHeap; +#[allow(deprecated)] pub use bit_vec::BitVec; +#[allow(deprecated)] pub use bit_set::BitSet; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; @@ -111,11 +113,13 @@ pub mod vec_map; #[unstable(feature = "bitvec", reason = "RFC 509")] pub mod bit_vec { + #![allow(deprecated)] pub use bit::{BitVec, Iter}; } #[unstable(feature = "bitset", reason = "RFC 509")] pub mod bit_set { + #![allow(deprecated)] pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference}; pub use bit::SetIter as Iter; } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 190e2965e76ce..577fe3979ddc0 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -28,6 +28,9 @@ //! Use the former for unit-like structs and the latter for structs with //! a `pub fn new()`. +// BitSet +#![allow(deprecated)] + use metadata::{csearch, decoder}; use middle::def::*; use middle::mem_categorization::Typer; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 3ee8ffe3636a7..3cc141106bb16 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -10,6 +10,9 @@ // Functions dealing with attributes and meta items +// BitSet +#![allow(deprecated)] + pub use self::StabilityLevel::*; pub use self::ReprAttr::*; pub use self::IntType::*; From 8bf4651e2cbe04511c7e92279073e46e33d3b0fc Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Wed, 1 Jul 2015 15:51:17 -0400 Subject: [PATCH 114/160] Implement CoerceUnsized for rc::Weak Fixes #26704 --- src/liballoc/rc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 3dfafd0a378b9..d461eeea0b7eb 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -734,6 +734,8 @@ pub struct Weak { impl !marker::Send for Weak {} impl !marker::Sync for Weak {} +impl, U: ?Sized> CoerceUnsized> for Weak {} + #[unstable(feature = "rc_weak", reason = "Weak pointers may not belong in this module.")] impl Weak { From ce089e50a4caa5ec583e79de32d94fb2934ca8df Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 1 Jul 2015 13:08:25 -0700 Subject: [PATCH 115/160] Address nits --- src/librustc/middle/check_match.rs | 11 +++++++++-- src/librustc/middle/check_rvalues.rs | 5 ++++- src/librustc/middle/infer/mod.rs | 2 ++ src/librustc/middle/traits/mod.rs | 4 ++-- src/librustc/middle/ty.rs | 2 +- src/librustc_trans/trans/common.rs | 1 - src/librustc_trans/trans/debuginfo/mod.rs | 2 +- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 8e315901db212..a303c49bf8db7 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -1113,7 +1113,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, ast::PatIdent(ast::BindByValue(_), _, ref sub) => { let pat_ty = tcx.node_id_to_type(p.id); //FIXME: (@jroesch) this code should be floated up as well - let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(cx.param_env.clone()), false); + let infcx = infer::new_infer_ctxt(cx.tcx, + &cx.tcx.tables, + Some(cx.param_env.clone()), + false); if infcx.type_moves_by_default(pat_ty, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); } @@ -1143,7 +1146,11 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, cx: cx, }; - let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(checker.cx.param_env.clone()), false); + let infcx = infer::new_infer_ctxt(cx.tcx, + &cx.tcx.tables, + Some(checker.cx.param_env.clone()), + false); + let mut visitor = ExprUseVisitor::new(&mut checker, &infcx); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 731e49192a82a..c9017432473a7 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -41,7 +41,10 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { { // FIXME (@jroesch) change this to be an inference context let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); - let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env.clone()), false); + let infcx = infer::new_infer_ctxt(self.tcx, + &self.tcx.tables, + Some(param_env.clone()), + false); let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; let mut euv = euv::ExprUseVisitor::new(&mut delegate, &infcx); euv.walk_fn(fd, b); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 43be1beba91d0..7df37bdae07db 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1318,6 +1318,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub 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, ty, ty::BoundCopy, span) + // FIXME(@jroesch): should be able to use: + // ty.moves_by_default(&self.parameter_environment, span) } pub fn node_method_ty(&self, method_call: ty::MethodCall) diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 47002497acca5..5126a549887ed 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -436,7 +436,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, debug!("normalize_param_env(value={:?})", value); let mut selcx = &mut SelectionContext::new(infcx); - // FIXME (@jroesch): + // FIXME (@jroesch) ISSUE 26721 // I'm not sure if this is a bug or not, needs further investigation. // It appears that by reusing the fulfillment_cx here we incur more // obligations and later trip an asssertion on regionck.rs line 337. @@ -459,7 +459,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, for obligation in obligations { fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation); } - + try!(fulfill_cx.select_all_or_error(infcx)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); debug!("normalize_param_env: resolved_value={:?}", resolved_value); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e20df807c8784..b1b0097cbf654 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4385,7 +4385,7 @@ impl<'tcx> TyS<'tcx> { is_impld } - // temp hack, probably should be private + // FIXME (@jroesch): I made this public to use it, not sure if should be private pub fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>, span: Span) -> bool { if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 6dffb3fe2a713..96564277cdc1d 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -22,7 +22,6 @@ use middle::cfg; use middle::def; use middle::infer; use middle::lang_items::LangItem; -use middle::region; use middle::subst::{self, Substs}; use trans::base; use trans::build; diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index ebe5e832e6fb2..3d1b384c2d915 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::Ty; +use middle::ty::Ty; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}; From 2fc85718615a4261eba5ef0e696e1d995cdfd375 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Wed, 1 Jul 2015 23:07:26 +0300 Subject: [PATCH 116/160] Fix deadlocks with RUST_LOG=rustc::middle::ty These are RefCell deadlocks that cause the rustc task to die with the stderr lock held, causing a real deadlock. Fixes #26717. --- src/librustc/middle/astencode.rs | 2 +- src/librustc/middle/ty.rs | 50 +++++++++++++----------- src/librustc/util/ppaux.rs | 11 +++++- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 57 ++++++++++++++-------------- 6 files changed, 68 insertions(+), 56 deletions(-) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index d2c79e1d820bf..a0efc50d0d781 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1656,7 +1656,7 @@ fn decode_side_tables(dcx: &DecodeContext, c::tag_table_tcache => { let type_scheme = val_dsr.read_type_scheme(dcx); let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id }; - dcx.tcx.tcache.borrow_mut().insert(lid, type_scheme); + dcx.tcx.register_item_type(lid, type_scheme); } c::tag_table_param_defs => { let bounds = val_dsr.read_type_param_def(dcx); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 489ce7bc4cf78..4ec59926eaef2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3198,10 +3198,10 @@ pub trait ClosureTyper<'tcx> { impl<'tcx> CommonTypes<'tcx> { fn new(arena: &'tcx TypedArena>, - interner: &mut FnvHashMap, Ty<'tcx>>) + interner: &RefCell, Ty<'tcx>>>) -> CommonTypes<'tcx> { - let mut mk = |sty| ctxt::intern_ty(arena, interner, sty); + let mk = |sty| ctxt::intern_ty(arena, interner, sty); CommonTypes { bool: mk(TyBool), char: mk(TyChar), @@ -3430,12 +3430,12 @@ impl<'tcx> ctxt<'tcx> { f: F) -> (Session, R) where F: FnOnce(&ctxt<'tcx>) -> R { - let mut interner = FnvHashMap(); - let common_types = CommonTypes::new(&arenas.type_, &mut interner); + let interner = RefCell::new(FnvHashMap()); + let common_types = CommonTypes::new(&arenas.type_, &interner); tls::enter(ctxt { arenas: arenas, - interner: RefCell::new(interner), + interner: interner, substs_interner: RefCell::new(FnvHashMap()), bare_fn_interner: RefCell::new(FnvHashMap()), region_interner: RefCell::new(FnvHashMap()), @@ -3563,35 +3563,37 @@ impl<'tcx> ctxt<'tcx> { } fn intern_ty(type_arena: &'tcx TypedArena>, - interner: &mut FnvHashMap, Ty<'tcx>>, + interner: &RefCell, Ty<'tcx>>>, st: TypeVariants<'tcx>) -> Ty<'tcx> { - match interner.get(&st) { - Some(ty) => return *ty, - _ => () - } + let ty: Ty /* don't be &mut TyS */ = { + let mut interner = interner.borrow_mut(); + match interner.get(&st) { + Some(ty) => return *ty, + _ => () + } - let flags = FlagComputation::for_sty(&st); + let flags = FlagComputation::for_sty(&st); + + let ty = match () { + () => type_arena.alloc(TyS { sty: st, + flags: Cell::new(flags.flags), + region_depth: flags.depth, }), + }; - let ty = match () { - () => type_arena.alloc(TyS { sty: st, - flags: Cell::new(flags.flags), - region_depth: flags.depth, }), + interner.insert(InternedTy { ty: ty }, ty); + ty }; 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(); - ctxt::intern_ty(&self.arenas.type_, &mut *interner, st) + ctxt::intern_ty(&self.arenas.type_, &self.interner, st) } pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> { @@ -5930,6 +5932,10 @@ impl<'tcx> ctxt<'tcx> { .clone() } + // Register a given item type + pub fn register_item_type(&self, did: ast::DefId, ty: TypeScheme<'tcx>) { + self.tcache.borrow_mut().insert(did, ty); + } // 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. @@ -6006,8 +6012,8 @@ impl<'tcx> ctxt<'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 + memoized(&self.tcache, id, + |id| csearch::get_field_type(self, struct_id, id)).ty } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index de2f33e8a4ac9..91b547e967952 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -680,8 +680,15 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyError => write!(f, "[type error]"), TyParam(ref param_ty) => write!(f, "{}", param_ty), TyEnum(did, substs) | TyStruct(did, substs) => { - parameterized(f, substs, did, &[], - |tcx| tcx.lookup_item_type(did).generics) + ty::tls::with(|tcx| { + if did.krate == ast::LOCAL_CRATE && + !tcx.tcache.borrow().contains_key(&did) { + write!(f, "{}<..>", tcx.item_path_str(did)) + } else { + parameterized(f, substs, did, &[], + |tcx| tcx.lookup_item_type(did).generics) + } + }) } TyTrait(ref data) => write!(f, "{}", data), ty::TyProjection(ref data) => write!(f, "{}", data), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7e87dc6540ea5..020aac2c197af 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4007,7 +4007,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, 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; + let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty; check_const_with_ty(&fcx, sp, e, declty); } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fbabc287342e9..da7851b18f9d0 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { }; debug!("new_polytype={:?}", new_polytype); - tcx.tcache.borrow_mut().insert(new_did, new_polytype); + tcx.register_item_type(new_did, new_polytype); tcx.predicates.borrow_mut().insert(new_did, new_method_ty.predicates.clone()); tcx.impl_or_trait_items .borrow_mut() diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ef9dcd56a578b..4ac100f4c1012 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -596,7 +596,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty: result_ty }; - tcx.tcache.borrow_mut().insert(variant_def_id, variant_scheme.clone()); + tcx.register_item_type(variant_def_id, variant_scheme.clone()); tcx.predicates.borrow_mut().insert(variant_def_id, enum_predicates.clone()); write_ty_to_tcx(tcx, variant.node.id, result_ty); } @@ -635,7 +635,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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 { + ccx.tcx.register_item_type(def_id, TypeScheme { generics: ty_method.generics.clone(), ty: fty }); @@ -661,11 +661,11 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, write_ty_to_tcx(ccx.tcx, v.node.id, tt); /* add the field to the tcache */ - ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id), - ty::TypeScheme { - generics: struct_generics.clone(), - ty: tt - }); + ccx.tcx.register_item_type(local_def(v.node.id), + ty::TypeScheme { + generics: struct_generics.clone(), + ty: tt + }); ccx.tcx.predicates.borrow_mut().insert(local_def(v.node.id), struct_predicates.clone()); @@ -841,9 +841,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty); write_ty_to_tcx(tcx, it.id, selfty); - tcx.tcache.borrow_mut().insert(local_def(it.id), - TypeScheme { generics: ty_generics.clone(), - ty: selfty }); + tcx.register_item_type(local_def(it.id), + TypeScheme { generics: ty_generics.clone(), + ty: selfty }); tcx.predicates.borrow_mut().insert(local_def(it.id), ty_predicates.clone()); @@ -863,11 +863,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node { let ty = ccx.icx(&ty_predicates) .to_ty(&ExplicitRscope, &*ty); - tcx.tcache.borrow_mut().insert(local_def(impl_item.id), - TypeScheme { - generics: ty_generics.clone(), - ty: ty, - }); + tcx.register_item_type(local_def(impl_item.id), + TypeScheme { + generics: ty_generics.clone(), + ty: ty, + }); convert_associated_const(ccx, ImplContainer(local_def(it.id)), impl_item.ident, impl_item.id, impl_item.vis.inherit_from(parent_visibility), @@ -954,11 +954,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { ast::ConstTraitItem(ref ty, ref default) => { let ty = ccx.icx(&trait_predicates) .to_ty(&ExplicitRscope, ty); - tcx.tcache.borrow_mut().insert(local_def(trait_item.id), - TypeScheme { - generics: trait_def.generics.clone(), - ty: ty, - }); + tcx.register_item_type(local_def(trait_item.id), + TypeScheme { + generics: trait_def.generics.clone(), + ty: ty, + }); convert_associated_const(ccx, TraitContainer(local_def(it.id)), trait_item.ident, trait_item.id, ast::Public, ty, default.as_ref().map(|d| &**d)); @@ -1099,26 +1099,25 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Enum-like. write_ty_to_tcx(tcx, ctor_id, selfty); - tcx.tcache.borrow_mut().insert(local_def(ctor_id), scheme); + tcx.register_item_type(local_def(ctor_id), scheme); tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates); } else if struct_def.fields[0].node.kind.is_unnamed() { // Tuple-like. let inputs: Vec<_> = struct_def.fields .iter() - .map(|field| tcx.tcache.borrow().get(&local_def(field.node.id)) - .unwrap() - .ty) + .map(|field| tcx.lookup_item_type( + local_def(field.node.id)).ty) .collect(); let ctor_fn_ty = tcx.mk_ctor_fn(local_def(ctor_id), &inputs[..], selfty); write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty); - tcx.tcache.borrow_mut().insert(local_def(ctor_id), - TypeScheme { - generics: scheme.generics, - ty: ctor_fn_ty - }); + tcx.register_item_type(local_def(ctor_id), + TypeScheme { + generics: scheme.generics, + ty: ctor_fn_ty + }); tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates); } } From 8261599e62a7930cec372e637e5ab58f5a26532c Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 1 Jul 2015 08:58:48 +1200 Subject: [PATCH 117/160] Refactoring --- src/librustc/ast_map/mod.rs | 137 ++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 67 deletions(-) diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs index 800cd7e8aeea7..3205141e604c2 100644 --- a/src/librustc/ast_map/mod.rs +++ b/src/librustc/ast_map/mod.rs @@ -121,15 +121,14 @@ pub enum Node<'ast> { NodeLifetime(&'ast Lifetime), } -/// Represents an entry and its parent NodeID and parent_node NodeID, see -/// get_parent_node for the distinction. +/// Represents an entry and its parent NodeID. /// The odd layout is to bring down the total size. #[derive(Copy, Debug)] enum MapEntry<'ast> { /// Placeholder for holes in the map. NotPresent, - /// All the node types, with a parent and scope ID. + /// All the node types, with a parent ID. EntryItem(NodeId, &'ast Item), EntryForeignItem(NodeId, &'ast ForeignItem), EntryTraitItem(NodeId, &'ast TraitItem), @@ -162,21 +161,21 @@ struct InlinedParent { } impl<'ast> MapEntry<'ast> { - fn from_node(s: NodeId, node: Node<'ast>) -> MapEntry<'ast> { + fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { match node { - NodeItem(n) => EntryItem(s, n), - NodeForeignItem(n) => EntryForeignItem(s, n), - NodeTraitItem(n) => EntryTraitItem(s, n), - NodeImplItem(n) => EntryImplItem(s, n), - NodeVariant(n) => EntryVariant(s, n), - NodeExpr(n) => EntryExpr(s, n), - NodeStmt(n) => EntryStmt(s, n), - NodeArg(n) => EntryArg(s, n), - NodeLocal(n) => EntryLocal(s, n), - NodePat(n) => EntryPat(s, n), - NodeBlock(n) => EntryBlock(s, n), - NodeStructCtor(n) => EntryStructCtor(s, n), - NodeLifetime(n) => EntryLifetime(s, n) + NodeItem(n) => EntryItem(p, n), + NodeForeignItem(n) => EntryForeignItem(p, n), + NodeTraitItem(n) => EntryTraitItem(p, n), + NodeImplItem(n) => EntryImplItem(p, n), + NodeVariant(n) => EntryVariant(p, n), + NodeExpr(n) => EntryExpr(p, n), + NodeStmt(n) => EntryStmt(p, n), + NodeArg(n) => EntryArg(p, n), + NodeLocal(n) => EntryLocal(p, n), + NodePat(n) => EntryPat(p, n), + NodeBlock(n) => EntryBlock(p, n), + NodeStructCtor(n) => EntryStructCtor(p, n), + NodeLifetime(n) => EntryLifetime(p, n) } } @@ -284,52 +283,70 @@ impl<'ast> Map<'ast> { self.find_entry(id).and_then(|x| x.to_node()) } - /// Retrieve the parent NodeId for `id`, or `id` itself if no - /// parent is registered in this map. - pub fn get_parent(&self, id: NodeId) -> NodeId { - let mut id = id; + /// Similar to get_parent, returns the parent node id or id if there is no + /// parent. + /// This function returns the immediate parent in the AST, whereas get_parent + /// returns the enclosing item. Note that this might not be the actual parent + /// node in the AST - some kinds of nodes are not in the map and these will + /// never appear as the parent_node. So you can always walk the parent_nodes + /// from a node to the root of the ast (unless you get the same id back here + /// that can happen if the id is not in the map itself or is just weird). + pub fn get_parent_node(&self, id: NodeId) -> NodeId { + self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) + } + + /// If there is some error when walking the parents (e.g., a node does not + /// have a parent in the map or a node can't be found), then we return the + /// last good node id we found. Note that reaching the crate root (id == 0), + /// is not an error, since items in the crate module have the crate root as + /// parent. + fn walk_parent_nodes(&self, start_id: NodeId, found: F) -> Result + where F: Fn(&Node<'ast>) -> bool + { + let mut id = start_id; loop { let parent_node = self.get_parent_node(id); if parent_node == 0 { - return parent_node; + return Ok(0); } if parent_node == id { - return id; + return Err(id); } let node = self.find_entry(parent_node); if node.is_none() { - return id; + return Err(id); } let node = node.unwrap().to_node(); match node { - Some(node) => match node { - NodeItem(_) | - NodeForeignItem(_) | - NodeTraitItem(_) | - NodeImplItem(_) => { - return parent_node; + Some(ref node) => { + if found(node) { + return Ok(parent_node); } - _ => {} - }, + } None => { - return parent_node; + return Err(parent_node); } } id = parent_node; } } - /// Similar to get_parent, returns the parent node id or id if there is no - /// parent. - /// This function returns the most direct parent in the AST, whereas get_parent - /// returns the enclosing item. Note that this might not be the actual parent - /// node in the AST - some kinds of nodes are not in the map and these will - /// never appear as the parent_node. So you can always walk the parent_nodes - /// from a node to the root of the ast (unless you get the same id back here - /// that can happen if the id is not in the map itself or is just weird). - pub fn get_parent_node(&self, id: NodeId) -> NodeId { - self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) + /// Retrieve the NodeId for `id`'s parent item, or `id` itself if no + /// parent item is in this map. The "parent item" is the closest parent node + /// in the AST which is recorded by the map and is an item, either an item + /// in a module, trait, or impl. + pub fn get_parent(&self, id: NodeId) -> NodeId { + match self.walk_parent_nodes(id, |node| match *node { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) => true, + _ => false, + }) { + Ok(id) => id, + Err(id) => id, + } } /// Returns the nearest enclosing scope. A scope is an item or block. @@ -337,30 +354,16 @@ impl<'ast> Map<'ast> { /// and associated types probably shouldn't, for example. Behaviour in this /// regard should be expected to be highly unstable. pub fn get_enclosing_scope(&self, id: NodeId) -> Option { - let mut last_id = id; - // Walk up the chain of parents until we find a 'scope'. - loop { - let cur_id = self.get_parent_node(last_id); - if cur_id == last_id { - return None; - } - - if cur_id == 0 { - return Some(0); - } - - match self.get(cur_id) { - NodeItem(_) | - NodeForeignItem(_) | - NodeTraitItem(_) | - NodeImplItem(_) | - NodeBlock(_) => { - return Some(cur_id); - } - _ => {} - } - - last_id = cur_id; + match self.walk_parent_nodes(id, |node| match *node { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) | + NodeBlock(_) => true, + _ => false, + }) { + Ok(id) => Some(id), + Err(_) => None, } } From 5976355b67a05be3096e35d6467a057f920ea799 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 1 Jul 2015 23:05:06 +0200 Subject: [PATCH 118/160] doc: there is just one trait in here Also, the info is repeated in the following paragraph --- src/libcore/any.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index f0c77ae866d59..8d86e6fb194db 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Traits for dynamic typing of any `'static` type (through runtime reflection) -//! //! This module implements the `Any` trait, which enables dynamic typing //! of any `'static` type through runtime reflection. //! From b643a0b67942a0f2bd9450c43749aa9beac43895 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 1 Jul 2015 23:08:50 +0200 Subject: [PATCH 119/160] doc: add missing space --- src/libcore/any.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index f0c77ae866d59..38221f76c4de5 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -16,7 +16,7 @@ //! `Any` itself can be used to get a `TypeId`, and has more features when used //! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and //! `as_ref` methods, to test if the contained value is of a given type, and to -//! get a reference to the inner value as a type. As`&mut Any`, there is also +//! get a reference to the inner value as a type. As `&mut Any`, there is also //! the `as_mut` method, for getting a mutable reference to the inner value. //! `Box` adds the `move` method, which will unwrap a `Box` from the //! object. See the extension traits (`*Ext`) for the full details. From 7713e141b714adc6416994b7783b51f56996a7ba Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sat, 27 Jun 2015 18:37:33 -0700 Subject: [PATCH 120/160] Report memory use in time-passes Reports the resident set size after each pass (linux-only). --- src/librustc/lib.rs | 1 + src/librustc/util/common.rs | 40 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2cec42b76bce3..e4e7459f8c605 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -62,6 +62,7 @@ #![feature(vec_push_all)] #![feature(wrapping)] #![feature(cell_extras)] +#![feature(page_size)] #![cfg_attr(test, feature(test))] #![allow(trivial_casts)] diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 8d5357fa6e417..162bf6ed9a97f 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -59,14 +59,50 @@ pub fn time(do_it: bool, what: &str, u: U, f: F) -> T where const NANOS_PER_SEC: f64 = 1_000_000_000.0; let secs = dur.secs() as f64; let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC; - println!("{}time: {:.3} \t{}", repeat(" ").take(old).collect::(), - secs, what); + + let mem_string = match get_resident() { + Some(n) => { + let mb = n as f64 / 1_000_000.0; + format!("; rss: {}MB", mb.round() as usize) + } + None => "".to_owned(), + }; + println!("{}time: {:.3}{}\t{}", repeat(" ").take(old).collect::(), + secs, mem_string, what); DEPTH.with(|slot| slot.set(old)); rv } +// Memory reporting +fn get_resident() -> Option { + if cfg!(unix) { + get_proc_self_statm_field(1) + } else { + None + } +} + +// Like std::macros::try!, but for Option<>. +macro_rules! option_try( + ($e:expr) => (match $e { Some(e) => e, None => return None }) +); + +fn get_proc_self_statm_field(field: usize) -> Option { + use std::fs::File; + use std::io::Read; + + assert!(cfg!(unix)); + + let mut f = option_try!(File::open("/proc/self/statm").ok()); + let mut contents = String::new(); + option_try!(f.read_to_string(&mut contents).ok()); + let s = option_try!(contents.split_whitespace().nth(field)); + let npages = option_try!(s.parse::().ok()); + Some(npages * ::std::env::page_size()) +} + pub fn indent(op: F) -> R where R: Debug, F: FnOnce() -> R, From 50421827ae6bff8085e499eae1427e6c037d76d1 Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Wed, 1 Jul 2015 17:54:54 -0400 Subject: [PATCH 121/160] Add test to dst-coerce-rc.rs --- src/test/run-pass/dst-coerce-rc.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/run-pass/dst-coerce-rc.rs b/src/test/run-pass/dst-coerce-rc.rs index 67dd4021cb5c8..f147a2dca6343 100644 --- a/src/test/run-pass/dst-coerce-rc.rs +++ b/src/test/run-pass/dst-coerce-rc.rs @@ -10,10 +10,10 @@ // Test a very simple custom DST coercion. -#![feature(core)] +#![feature(core, rc_weak)] use std::cell::RefCell; -use std::rc::Rc; +use std::rc::{Rc, Weak}; trait Baz { fn get(&self) -> i32; @@ -36,9 +36,13 @@ fn main() { let b: Rc = a.clone(); assert_eq!(b.get(), 42); + let c: Weak = a.downgrade(); + let d: Weak = c.clone(); + let _c = b.clone(); let a: Rc> = Rc::new(RefCell::new(42)); let b: Rc> = a.clone(); assert_eq!(b.borrow().get(), 42); + let c: Weak> = a.downgrade(); } From 3278e793b2d0332c6659b732178892aab11654ee Mon Sep 17 00:00:00 2001 From: Remi Rampin Date: Wed, 1 Jul 2015 17:58:05 -0400 Subject: [PATCH 122/160] Implement CoerceUnsized for arc::Weak --- src/liballoc/arc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index dd9c1d1fd1885..c84649f92e7ff 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -145,6 +145,8 @@ pub struct Weak { unsafe impl Send for Weak { } unsafe impl Sync for Weak { } +impl, U: ?Sized> CoerceUnsized> for Weak {} + #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 0b7c4f57f6ba59dabe4db2808fe45e8bd8bbce22 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Tue, 30 Jun 2015 20:37:11 -0700 Subject: [PATCH 123/160] Add netbsd amd64 support --- configure | 4 ++ mk/cfg/x86_64-unknown-netbsd.mk | 22 ++++++ src/compiletest/util.rs | 1 + src/doc/reference.md | 2 +- src/etc/snapshot.py | 11 +-- src/liblibc/lib.rs | 28 +++++--- src/librustc_back/arm.rs | 2 +- src/librustc_back/mips.rs | 2 +- src/librustc_back/mipsel.rs | 2 +- src/librustc_back/target/mod.rs | 2 + src/librustc_back/target/netbsd_base.rs | 32 +++++++++ .../target/x86_64_unknown_netbsd.rs | 29 ++++++++ src/librustc_back/x86.rs | 2 +- src/librustc_back/x86_64.rs | 2 +- src/librustdoc/flock.rs | 1 + src/libstd/dynamic_lib.rs | 2 + src/libstd/env.rs | 12 ++++ src/libstd/net/tcp.rs | 2 +- src/libstd/net/udp.rs | 4 +- src/libstd/os/mod.rs | 1 + src/libstd/os/netbsd/mod.rs | 20 ++++++ src/libstd/os/netbsd/raw.rs | 71 +++++++++++++++++++ src/libstd/rt/args.rs | 1 + src/libstd/rt/libunwind.rs | 2 +- src/libstd/rtdeps.rs | 1 + src/libstd/sys/common/stack.rs | 2 + src/libstd/sys/unix/backtrace.rs | 1 + src/libstd/sys/unix/c.rs | 10 ++- src/libstd/sys/unix/mod.rs | 1 + src/libstd/sys/unix/os.rs | 15 +--- src/libstd/sys/unix/process.rs | 1 + src/libstd/sys/unix/stack_overflow.rs | 2 + src/libstd/sys/unix/sync.rs | 1 + src/libstd/sys/unix/thread.rs | 6 +- src/libstd/sys/unix/thread_local.rs | 2 + src/libstd/sys/unix/time.rs | 1 + src/libstd/thread/scoped_tls.rs | 3 + src/libsyntax/abi.rs | 2 + src/test/parse-fail/issue-5806.rs | 1 + src/test/run-pass/intrinsic-alignment.rs | 1 + src/test/run-pass/rec-align-u64.rs | 1 + src/test/run-pass/tcp-stress.rs | 3 +- src/test/run-pass/x86stdcall.rs | 1 + 43 files changed, 271 insertions(+), 41 deletions(-) create mode 100644 mk/cfg/x86_64-unknown-netbsd.mk create mode 100644 src/librustc_back/target/netbsd_base.rs create mode 100644 src/librustc_back/target/x86_64_unknown_netbsd.rs create mode 100644 src/libstd/os/netbsd/mod.rs create mode 100644 src/libstd/os/netbsd/raw.rs diff --git a/configure b/configure index 5d4a017b6fbfa..1d3611f88f0a9 100755 --- a/configure +++ b/configure @@ -405,6 +405,10 @@ case $CFG_OSTYPE in CFG_OSTYPE=unknown-openbsd ;; + NetBSD) + CFG_OSTYPE=unknown-netbsd + ;; + Darwin) CFG_OSTYPE=apple-darwin ;; diff --git a/mk/cfg/x86_64-unknown-netbsd.mk b/mk/cfg/x86_64-unknown-netbsd.mk new file mode 100644 index 0000000000000..401b0fb7ab008 --- /dev/null +++ b/mk/cfg/x86_64-unknown-netbsd.mk @@ -0,0 +1,22 @@ +# x86_64-unknown-netbsd configuration +CC_x86_64-unknown-netbsd=$(CC) +CXX_x86_64-unknown-netbsd=$(CXX) +CPP_x86_64-unknown-netbsd=$(CPP) +AR_x86_64-unknown-netbsd=$(AR) +CFG_LIB_NAME_x86_64-unknown-netbsd=lib$(1).so +CFG_STATIC_LIB_NAME_x86_64-unknown-netbsd=lib$(1).a +CFG_LIB_GLOB_x86_64-unknown-netbsd=lib$(1)-*.so +CFG_LIB_DSYM_GLOB_x86_64-unknown-netbsd=$(1)-*.dylib.dSYM +CFG_JEMALLOC_CFLAGS_x86_64-unknown-netbsd := -I/usr/local/include $(CFLAGS) +CFG_GCCISH_CFLAGS_x86_64-unknown-netbsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS) +CFG_GCCISH_LINK_FLAGS_x86_64-unknown-netbsd := -shared -fPIC -g -pthread -lrt +CFG_GCCISH_DEF_FLAG_x86_64-unknown-netbsd := -Wl,--export-dynamic,--dynamic-list= +CFG_LLC_FLAGS_x86_64-unknown-netbsd := +CFG_INSTALL_NAME_x86_64-unknown-netbsd = +CFG_EXE_SUFFIX_x86_64-unknown-netbsd := +CFG_WINDOWSY_x86_64-unknown-netbsd := +CFG_UNIXY_x86_64-unknown-netbsd := 1 +CFG_LDPATH_x86_64-unknown-netbsd := +CFG_RUN_x86_64-unknown-netbsd=$(2) +CFG_RUN_TARG_x86_64-unknown-netbsd=$(call CFG_RUN_x86_64-unknown-netbsd,,$(2)) +CFG_GNU_TRIPLE_x86_64-unknown-netbsd := x86_64-unknown-netbsd diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index 184d62db45114..13d6c029ff584 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -21,6 +21,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("ios", "ios"), ("linux", "linux"), ("mingw32", "windows"), + ("netbsd", "netbsd"), ("openbsd", "openbsd"), ("win32", "windows"), ("windows", "windows"), diff --git a/src/doc/reference.md b/src/doc/reference.md index 7e28651c6aafb..650e1d5541ecf 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2023,7 +2023,7 @@ The following configurations must be defined by the implementation: as a configuration itself, like `unix` or `windows`. * `target_os = "..."`. Operating system of the target, examples include `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`, - `"bitrig"` or `"openbsd"`. + `"bitrig"` , `"openbsd"` or `"netbsd"`. * `target_pointer_width = "..."`. Target pointer width in bits. This is set to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for 64-bit pointers. diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 0349ccf9b6640..6d62a45c703a2 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -41,13 +41,14 @@ def scrub(b): download_unpack_base = os.path.join(download_dir_base, "unpack") snapshot_files = { + "bitrig": ["bin/rustc"], + "dragonfly": ["bin/rustc"], + "freebsd": ["bin/rustc"], "linux": ["bin/rustc"], "macos": ["bin/rustc"], - "winnt": ["bin/rustc.exe"], - "freebsd": ["bin/rustc"], - "dragonfly": ["bin/rustc"], - "bitrig": ["bin/rustc"], + "netbsd": ["bin/rustc"], "openbsd": ["bin/rustc"], + "winnt": ["bin/rustc.exe"], } winnt_runtime_deps_32 = ["libgcc_s_dw2-1.dll", "libstdc++-6.dll"] @@ -103,6 +104,8 @@ def get_kernel(triple): return "dragonfly" if os_name == "bitrig": return "bitrig" + if os_name == "netbsd": + return "netbsd" if os_name == "openbsd": return "openbsd" return "linux" diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 6e01796ad8227..f66811e561adf 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -1322,7 +1322,7 @@ pub mod types { } } - #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] + #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os ="openbsd"))] pub mod os { pub mod common { pub mod posix01 { @@ -1351,7 +1351,7 @@ pub mod types { pub __unused7: *mut c_void, } - #[cfg(target_os = "openbsd")] + #[cfg(any(target_os = "netbsd", target_os="openbsd"))] #[repr(C)] #[derive(Copy, Clone)] pub struct glob_t { pub gl_pathc: c_int, @@ -4323,7 +4323,7 @@ pub mod consts { } } - #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] + #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] pub mod os { pub mod c95 { use types::os::arch::c95::{c_int, c_uint}; @@ -5568,6 +5568,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "nacl"))] pub mod posix88 { @@ -5584,6 +5585,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "ios", @@ -5602,6 +5604,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "ios", @@ -5889,6 +5892,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "nacl"))] pub mod posix01 { @@ -5901,6 +5905,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "ios", @@ -6019,16 +6024,17 @@ pub mod funcs { } - #[cfg(any(target_os = "windows", - target_os = "linux", - target_os = "android", - target_os = "macos", + #[cfg(any(target_os = "android", + target_os = "bitrig", + target_os = "dragonfly", target_os = "ios", target_os = "freebsd", - target_os = "dragonfly", - target_os = "bitrig", + target_os = "linux", + target_os = "macos", + target_os = "nacl", + target_os = "netbsd", target_os = "openbsd", - target_os = "nacl"))] + target_os = "windows"))] pub mod posix08 { pub mod unistd { } @@ -6115,6 +6121,7 @@ pub mod funcs { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub mod bsd44 { use types::common::c95::{c_void}; @@ -6192,6 +6199,7 @@ pub mod funcs { #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub mod extra { } diff --git a/src/librustc_back/arm.rs b/src/librustc_back/arm.rs index 7325e4e7a2ece..9e288f6ddb2bf 100644 --- a/src/librustc_back/arm.rs +++ b/src/librustc_back/arm.rs @@ -61,7 +61,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs -a:0:64-n32".to_string() } - abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => { + abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd | abi::OsNetbsd => { "e-p:32:32:32\ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ -f32:32:32-f64:64:64\ diff --git a/src/librustc_back/mips.rs b/src/librustc_back/mips.rs index b46150f75d084..e1edff817d6c1 100644 --- a/src/librustc_back/mips.rs +++ b/src/librustc_back/mips.rs @@ -56,7 +56,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs -a:0:64-n32".to_string() } - abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => { + abi::OsBitrig | abi::OsDragonfly | abi::OsFreebsd | abi::OsNetbsd | abi::OsOpenbsd => { "E-p:32:32:32\ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ -f32:32:32-f64:64:64\ diff --git a/src/librustc_back/mipsel.rs b/src/librustc_back/mipsel.rs index c7fa7aa879ac2..ca52a9e56ff52 100644 --- a/src/librustc_back/mipsel.rs +++ b/src/librustc_back/mipsel.rs @@ -56,7 +56,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs -a:0:64-n32".to_string() } - abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => { + abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd | abi::OsNetbsd => { "e-p:32:32:32\ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ -f32:32:32-f64:64:64\ diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index a42f861d19056..bc5f306cd3568 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -58,6 +58,7 @@ mod dragonfly_base; mod freebsd_base; mod linux_base; mod openbsd_base; +mod netbsd_base; mod windows_base; mod windows_msvc_base; @@ -368,6 +369,7 @@ impl Target { x86_64_unknown_bitrig, x86_64_unknown_openbsd, + x86_64_unknown_netbsd, x86_64_apple_darwin, i686_apple_darwin, diff --git a/src/librustc_back/target/netbsd_base.rs b/src/librustc_back/target/netbsd_base.rs new file mode 100644 index 0000000000000..0f2ab32be2431 --- /dev/null +++ b/src/librustc_back/target/netbsd_base.rs @@ -0,0 +1,32 @@ +// Copyright 2014-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::TargetOptions; +use std::default::Default; + +pub fn opts() -> TargetOptions { + TargetOptions { + linker: "cc".to_string(), + dynamic_linking: true, + executables: true, + morestack: false, + linker_is_gnu: true, + has_rpath: true, + pre_link_args: vec!( + // GNU-style linkers will use this to omit linking to libraries + // which don't actually fulfill any relocations, but only for + // libraries which follow this flag. Thus, use it before + // specifying libraries to link to. + "-Wl,--as-needed".to_string(), + ), + position_independent_executables: true, + .. Default::default() + } +} diff --git a/src/librustc_back/target/x86_64_unknown_netbsd.rs b/src/librustc_back/target/x86_64_unknown_netbsd.rs new file mode 100644 index 0000000000000..3f5bd39949ab6 --- /dev/null +++ b/src/librustc_back/target/x86_64_unknown_netbsd.rs @@ -0,0 +1,29 @@ +// Copyright 2014-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::netbsd_base::opts(); + base.pre_link_args.push("-m64".to_string()); + + Target { + data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\ + f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\ + s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(), + llvm_target: "x86_64-unknown-netbsd".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + arch: "x86_64".to_string(), + target_os: "netbsd".to_string(), + target_env: "".to_string(), + options: base, + } +} diff --git a/src/librustc_back/x86.rs b/src/librustc_back/x86.rs index 1c6eacc355947..46e0a83ac033b 100644 --- a/src/librustc_back/x86.rs +++ b/src/librustc_back/x86.rs @@ -45,7 +45,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string() } - abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => { + abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd | abi::OsNetbsd => { "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string() } diff --git a/src/librustc_back/x86_64.rs b/src/librustc_back/x86_64.rs index d016bd12c698f..abdcd56444213 100644 --- a/src/librustc_back/x86_64.rs +++ b/src/librustc_back/x86_64.rs @@ -47,7 +47,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs s0:64:64-f80:128:128-n8:16:32:64-S128".to_string() } - abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => { + abi::OsBitrig | abi::OsDragonfly | abi::OsFreebsd | abi::OsNetbsd | abi::OsOpenbsd => { "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string() diff --git a/src/librustdoc/flock.rs b/src/librustdoc/flock.rs index 760fa329fd986..847e28d2bc510 100644 --- a/src/librustdoc/flock.rs +++ b/src/librustdoc/flock.rs @@ -68,6 +68,7 @@ mod imp { #[cfg(any(target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod os { use libc; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index a17d121e60a2a..3621d18daed81 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -160,6 +160,7 @@ mod tests { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] fn test_errors_do_not_crash() { // Open /dev/null as a library to get an error, and make sure @@ -179,6 +180,7 @@ mod tests { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod dl { use prelude::v1::*; diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 2e00e126e2378..7c2cd615303c0 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -633,6 +633,7 @@ pub mod consts { /// - freebsd /// - dragonfly /// - bitrig + /// - netbsd /// - openbsd /// - android /// - windows @@ -759,6 +760,17 @@ mod os { pub const EXE_EXTENSION: &'static str = ""; } +#[cfg(target_os = "netbsd")] +mod os { + pub const FAMILY: &'static str = "unix"; + pub const OS: &'static str = "netbsd"; + pub const DLL_PREFIX: &'static str = "lib"; + pub const DLL_SUFFIX: &'static str = ".so"; + pub const DLL_EXTENSION: &'static str = "so"; + pub const EXE_SUFFIX: &'static str = ""; + pub const EXE_EXTENSION: &'static str = ""; +} + #[cfg(target_os = "openbsd")] mod os { pub const FAMILY: &'static str = "unix"; diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 222059e4c0e6a..085ba286dc3d9 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -904,7 +904,7 @@ mod tests { // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code // no longer has rounding errors. - #[cfg_attr(any(target_os = "bitrig", target_os = "openbsd"), ignore)] + #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)] #[test] fn timeouts() { let addr = next_test_ip4(); diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index c3cf9895205e4..0545175d9aee9 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -360,9 +360,9 @@ mod tests { assert_eq!(format!("{:?}", udpsock), compare); } - // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code + // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code // no longer has rounding errors. - #[cfg_attr(any(target_os = "bitrig", target_os = "openbsd"), ignore)] + #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)] #[test] fn timeouts() { let addr = next_test_ip4(); diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index cc4b1c944e786..859cb900460c5 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -24,6 +24,7 @@ #[cfg(target_os = "linux")] pub mod linux; #[cfg(target_os = "macos")] pub mod macos; #[cfg(target_os = "nacl")] pub mod nacl; +#[cfg(target_os = "netbsd")] pub mod netbsd; #[cfg(target_os = "openbsd")] pub mod openbsd; pub mod raw; diff --git a/src/libstd/os/netbsd/mod.rs b/src/libstd/os/netbsd/mod.rs new file mode 100644 index 0000000000000..bdb003b877bab --- /dev/null +++ b/src/libstd/os/netbsd/mod.rs @@ -0,0 +1,20 @@ +// 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. + +//! OpenBSD-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod raw; + +pub mod fs { + #![stable(feature = "raw_ext", since = "1.1.0")] + pub use sys::fs::MetadataExt; +} diff --git a/src/libstd/os/netbsd/raw.rs b/src/libstd/os/netbsd/raw.rs new file mode 100644 index 0000000000000..f9898dfbdb537 --- /dev/null +++ b/src/libstd/os/netbsd/raw.rs @@ -0,0 +1,71 @@ +// 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. + +//! NetBSD/OpenBSD-specific raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +use os::raw::c_long; +use os::unix::raw::{uid_t, gid_t}; + +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; +#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; + +#[repr(C)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_flags: fflags_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gen: u32, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_birthtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_birthtime_nsec: c_long, +} diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index d23a124a6ecda..52697f00264be 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -44,6 +44,7 @@ pub fn clone() -> Option>> { imp::clone() } target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod imp { use prelude::v1::*; diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs index 8f75ae5ef5cc8..d99b31c9f2b43 100644 --- a/src/libstd/rt/libunwind.rs +++ b/src/libstd/rt/libunwind.rs @@ -106,7 +106,7 @@ extern {} #[link(name = "unwind", kind = "static")] extern {} -#[cfg(any(target_os = "android", target_os = "openbsd"))] +#[cfg(any(target_os = "android", target_os = "netbsd", target_os = "openbsd"))] #[link(name = "gcc")] extern {} diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs index be674c83e2213..a395dbf8995c6 100644 --- a/src/libstd/rtdeps.rs +++ b/src/libstd/rtdeps.rs @@ -39,6 +39,7 @@ extern {} #[cfg(any(target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] #[link(name = "pthread")] extern {} diff --git a/src/libstd/sys/common/stack.rs b/src/libstd/sys/common/stack.rs index 11982ebc572e5..002e3b20c3542 100644 --- a/src/libstd/sys/common/stack.rs +++ b/src/libstd/sys/common/stack.rs @@ -202,6 +202,7 @@ pub unsafe fn record_sp_limit(limit: usize) { target_arch = "powerpc", all(target_arch = "arm", target_os = "ios"), target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] unsafe fn target_record_sp_limit(_: usize) { } @@ -299,6 +300,7 @@ pub unsafe fn get_sp_limit() -> usize { target_arch = "powerpc", all(target_arch = "arm", target_os = "ios"), target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] #[inline(always)] unsafe fn target_get_sp_limit() -> usize { diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index b23a3eee1a173..a5d1595cfeb1f 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -363,6 +363,7 @@ fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, let selfname = if cfg!(target_os = "freebsd") || cfg!(target_os = "dragonfly") || cfg!(target_os = "bitrig") || + cfg!(target_os = "netbsd") || cfg!(target_os = "openbsd") { env::current_exe().ok() } else { diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index 99a6731c57d95..eeecf7f50f79a 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -34,6 +34,7 @@ use libc; target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub const FIOCLEX: libc::c_ulong = 0x20006601; @@ -60,6 +61,7 @@ pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70; target_os = "dragonfly"))] pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71; #[cfg(any(target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101; #[cfg(target_os = "android")] @@ -82,6 +84,7 @@ pub struct passwd { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub struct passwd { pub pw_name: *mut libc::c_char, @@ -321,6 +324,7 @@ mod signal_os { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod signal_os { use libc; @@ -348,7 +352,7 @@ mod signal_os { pub struct sigset_t { bits: [u32; 4], } - #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] + #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] pub type sigset_t = libc::c_uint; // This structure has more fields, but we're not all that interested in @@ -365,7 +369,7 @@ mod signal_os { pub _status: libc::c_int, pub si_addr: *mut libc::c_void } - #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] + #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] #[repr(C)] pub struct siginfo { pub si_signo: libc::c_int, @@ -375,7 +379,7 @@ mod signal_os { } #[cfg(any(target_os = "macos", target_os = "ios", - target_os = "bitrig", target_os = "openbsd"))] + target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] #[repr(C)] pub struct sigaction { pub sa_sigaction: sighandler_t, diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index c1a4e8cee9ed4..6fd20b940bb52 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -26,6 +26,7 @@ use ops::Neg; #[cfg(target_os = "linux")] pub use os::linux as platform; #[cfg(target_os = "macos")] pub use os::macos as platform; #[cfg(target_os = "nacl")] pub use os::nacl as platform; +#[cfg(target_os = "netbsd")] pub use os::netbsd as platform; #[cfg(target_os = "openbsd")] pub use os::openbsd as platform; pub mod backtrace; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 5178d7b8fb1a0..334dd6b5f18c1 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -51,23 +51,13 @@ pub fn errno() -> i32 { __error() } - #[cfg(target_os = "bitrig")] - fn errno_location() -> *const c_int { - extern { - fn __errno() -> *const c_int; - } - unsafe { - __errno() - } - } - #[cfg(target_os = "dragonfly")] unsafe fn errno_location() -> *const c_int { extern { fn __dfly_error() -> *const c_int; } __dfly_error() } - #[cfg(target_os = "openbsd")] + #[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] unsafe fn errno_location() -> *const c_int { extern { fn __errno() -> *const c_int; } __errno() @@ -214,7 +204,7 @@ pub fn current_exe() -> io::Result { ::fs::read_link("/proc/curproc/file") } -#[cfg(any(target_os = "bitrig", target_os = "openbsd"))] +#[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))] pub fn current_exe() -> io::Result { use sync::StaticMutex; static LOCK: StaticMutex = StaticMutex::new(); @@ -356,6 +346,7 @@ pub fn args() -> Args { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub fn args() -> Args { use rt; diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 695d0ddfaaf61..cc78dd4e5ef12 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -423,6 +423,7 @@ fn translate_status(status: c_int) -> ExitStatus { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod imp { pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 } diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 52494a17b9d24..62689c39255e3 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -35,6 +35,7 @@ impl Drop for Handler { #[cfg(any(target_os = "linux", target_os = "macos", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod imp { use sys_common::stack; @@ -149,6 +150,7 @@ mod imp { #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd")))] mod imp { use libc; diff --git a/src/libstd/sys/unix/sync.rs b/src/libstd/sys/unix/sync.rs index 41e1e206a423a..9c8a1f4ca40ec 100644 --- a/src/libstd/sys/unix/sync.rs +++ b/src/libstd/sys/unix/sync.rs @@ -55,6 +55,7 @@ extern { #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] mod os { use libc; diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index bb0e12e8df899..17804c8d81ffb 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -105,6 +105,7 @@ impl Thread { #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] pub fn set_name(name: &str) { extern { @@ -162,6 +163,7 @@ impl Drop for Thread { #[cfg(all(not(target_os = "linux"), not(target_os = "macos"), not(target_os = "bitrig"), + not(target_os = "netbsd"), not(target_os = "openbsd")))] pub mod guard { pub unsafe fn current() -> usize { 0 } @@ -173,6 +175,7 @@ pub mod guard { #[cfg(any(target_os = "linux", target_os = "macos", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] #[allow(unused_imports)] pub mod guard { @@ -193,6 +196,7 @@ pub mod guard { #[cfg(any(target_os = "macos", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] unsafe fn get_stack_start() -> *mut libc::c_void { current() as *mut libc::c_void @@ -258,7 +262,7 @@ pub mod guard { pthread_get_stacksize_np(pthread_self())) as usize } - #[cfg(any(target_os = "openbsd", target_os = "bitrig"))] + #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "bitrig"))] pub unsafe fn current() -> usize { #[repr(C)] struct stack_t { diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs index 3afe84b25804c..7238adfcc566d 100644 --- a/src/libstd/sys/unix/thread_local.rs +++ b/src/libstd/sys/unix/thread_local.rs @@ -46,6 +46,7 @@ type pthread_key_t = ::libc::c_ulong; #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd"))] type pthread_key_t = ::libc::c_int; @@ -54,6 +55,7 @@ type pthread_key_t = ::libc::c_int; target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd")))] type pthread_key_t = ::libc::c_uint; diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index 6b84baeca7dc9..db0d0f1506139 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -80,6 +80,7 @@ mod inner { // OpenBSD provide it via libc #[cfg(not(any(target_os = "android", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_env = "musl")))] #[link(name = "rt")] diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs index 679902ec7abdb..c2fad0aa89c93 100644 --- a/src/libstd/thread/scoped_tls.rs +++ b/src/libstd/thread/scoped_tls.rs @@ -104,6 +104,7 @@ macro_rules! __scoped_thread_local_inner { #[cfg_attr(not(any(windows, target_os = "android", target_os = "ios", + target_os = "netbsd", target_os = "openbsd", target_arch = "aarch64")), thread_local)] @@ -215,6 +216,7 @@ impl ScopedKey { #[cfg(not(any(windows, target_os = "android", target_os = "ios", + target_os = "netbsd", target_os = "openbsd", target_arch = "aarch64", no_elf_tls)))] @@ -238,6 +240,7 @@ mod imp { #[cfg(any(windows, target_os = "android", target_os = "ios", + target_os = "netbsd", target_os = "openbsd", target_arch = "aarch64", no_elf_tls))] diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 27e331893e5d7..50c86a80b4ab5 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -25,6 +25,7 @@ pub enum Os { OsiOS, OsDragonfly, OsBitrig, + OsNetbsd, OsOpenbsd, } @@ -138,6 +139,7 @@ impl fmt::Display for Os { OsFreebsd => "freebsd".fmt(f), OsDragonfly => "dragonfly".fmt(f), OsBitrig => "bitrig".fmt(f), + OsNetbsd => "netbsd".fmt(f), OsOpenbsd => "openbsd".fmt(f), } } diff --git a/src/test/parse-fail/issue-5806.rs b/src/test/parse-fail/issue-5806.rs index f54423139049e..f6606a58ecaf1 100644 --- a/src/test/parse-fail/issue-5806.rs +++ b/src/test/parse-fail/issue-5806.rs @@ -11,6 +11,7 @@ // ignore-windows // ignore-freebsd // ignore-openbsd +// ignore-netbsd // ignore-bitrig // compile-flags: -Z parse-only diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs index fa97ef8fcd394..ef69946d7aa2a 100644 --- a/src/test/run-pass/intrinsic-alignment.rs +++ b/src/test/run-pass/intrinsic-alignment.rs @@ -22,6 +22,7 @@ mod rusti { target_os = "macos", target_os = "freebsd", target_os = "dragonfly", + target_os = "netbsd", target_os = "openbsd"))] mod m { #[main] diff --git a/src/test/run-pass/rec-align-u64.rs b/src/test/run-pass/rec-align-u64.rs index bae95bcb50f50..fc032aa3ff0cd 100644 --- a/src/test/run-pass/rec-align-u64.rs +++ b/src/test/run-pass/rec-align-u64.rs @@ -40,6 +40,7 @@ struct Outer { target_os = "macos", target_os = "freebsd", target_os = "dragonfly", + target_os = "netbsd", target_os = "openbsd"))] mod m { #[cfg(target_arch = "x86")] diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index c47b95bec2b52..dca65f03f690a 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -9,8 +9,9 @@ // except according to those terms. // ignore-android needs extra network permissions -// ignore-openbsd system ulimit (Too many open files) // ignore-bitrig system ulimit (Too many open files) +// ignore-netbsd system ulimit (Too many open files) +// ignore-openbsd system ulimit (Too many open files) use std::io::prelude::*; use std::net::{TcpListener, TcpStream}; diff --git a/src/test/run-pass/x86stdcall.rs b/src/test/run-pass/x86stdcall.rs index b0bfb5c29c18c..62cbb76c30950 100644 --- a/src/test/run-pass/x86stdcall.rs +++ b/src/test/run-pass/x86stdcall.rs @@ -35,6 +35,7 @@ pub fn main() { target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", + target_os = "netbsd", target_os = "openbsd", target_os = "android"))] pub fn main() { } From c64bda322764792c272d65bb14e033974ea1f287 Mon Sep 17 00:00:00 2001 From: Jared Roesch Date: Wed, 1 Jul 2015 19:29:17 -0700 Subject: [PATCH 124/160] Update 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 fb2f6b2b08db8..128b0b7baabc0 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, &tcx.tables, None); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None, false); body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID); From b51aea325646a506340d85b511ba1495673c5410 Mon Sep 17 00:00:00 2001 From: Nick Howell Date: Wed, 1 Jul 2015 23:52:40 -0400 Subject: [PATCH 125/160] rustdoc: Update jQuery from 2.1.0 to 2.1.4 --- src/librustdoc/html/render.rs | 4 ++-- src/librustdoc/html/static/jquery-2.1.0.min.js | 4 ---- src/librustdoc/html/static/jquery-2.1.4.min.js | 4 ++++ 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 src/librustdoc/html/static/jquery-2.1.0.min.js create mode 100644 src/librustdoc/html/static/jquery-2.1.4.min.js diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 0080b5e5f223f..5b0109290e6c3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1,4 +1,4 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -552,7 +552,7 @@ fn write_shared(cx: &Context, // Add all the static files. These may already exist, but we just // overwrite them anyway to make sure that they're fresh and up-to-date. try!(write(cx.dst.join("jquery.js"), - include_bytes!("static/jquery-2.1.0.min.js"))); + include_bytes!("static/jquery-2.1.4.min.js"))); try!(write(cx.dst.join("main.js"), include_bytes!("static/main.js"))); try!(write(cx.dst.join("playpen.js"), include_bytes!("static/playpen.js"))); try!(write(cx.dst.join("main.css"), include_bytes!("static/main.css"))); diff --git a/src/librustdoc/html/static/jquery-2.1.0.min.js b/src/librustdoc/html/static/jquery-2.1.0.min.js deleted file mode 100644 index cbe6abe59a815..0000000000000 --- a/src/librustdoc/html/static/jquery-2.1.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="
","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length; -while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("