From 840a5769b0879f39e21d973a60ac0b0db172f050 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Fri, 27 Mar 2020 22:02:18 -0400 Subject: [PATCH 01/33] Move raw string tests into the raw directory --- src/test/ui/parser/{ => raw}/raw-byte-string-eof.rs | 0 src/test/ui/parser/{ => raw}/raw-byte-string-eof.stderr | 0 src/test/ui/parser/{ => raw}/raw-byte-string-literals.rs | 0 src/test/ui/parser/{ => raw}/raw-byte-string-literals.stderr | 0 src/test/ui/parser/{ => raw}/raw-str-delim.rs | 0 src/test/ui/parser/{ => raw}/raw-str-delim.stderr | 0 src/test/ui/parser/{ => raw}/raw-str-unbalanced.rs | 0 src/test/ui/parser/{ => raw}/raw-str-unbalanced.stderr | 0 src/test/ui/parser/{ => raw}/raw-str-unterminated.rs | 0 src/test/ui/parser/{ => raw}/raw-str-unterminated.stderr | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/parser/{ => raw}/raw-byte-string-eof.rs (100%) rename src/test/ui/parser/{ => raw}/raw-byte-string-eof.stderr (100%) rename src/test/ui/parser/{ => raw}/raw-byte-string-literals.rs (100%) rename src/test/ui/parser/{ => raw}/raw-byte-string-literals.stderr (100%) rename src/test/ui/parser/{ => raw}/raw-str-delim.rs (100%) rename src/test/ui/parser/{ => raw}/raw-str-delim.stderr (100%) rename src/test/ui/parser/{ => raw}/raw-str-unbalanced.rs (100%) rename src/test/ui/parser/{ => raw}/raw-str-unbalanced.stderr (100%) rename src/test/ui/parser/{ => raw}/raw-str-unterminated.rs (100%) rename src/test/ui/parser/{ => raw}/raw-str-unterminated.stderr (100%) diff --git a/src/test/ui/parser/raw-byte-string-eof.rs b/src/test/ui/parser/raw/raw-byte-string-eof.rs similarity index 100% rename from src/test/ui/parser/raw-byte-string-eof.rs rename to src/test/ui/parser/raw/raw-byte-string-eof.rs diff --git a/src/test/ui/parser/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr similarity index 100% rename from src/test/ui/parser/raw-byte-string-eof.stderr rename to src/test/ui/parser/raw/raw-byte-string-eof.stderr diff --git a/src/test/ui/parser/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs similarity index 100% rename from src/test/ui/parser/raw-byte-string-literals.rs rename to src/test/ui/parser/raw/raw-byte-string-literals.rs diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr similarity index 100% rename from src/test/ui/parser/raw-byte-string-literals.stderr rename to src/test/ui/parser/raw/raw-byte-string-literals.stderr diff --git a/src/test/ui/parser/raw-str-delim.rs b/src/test/ui/parser/raw/raw-str-delim.rs similarity index 100% rename from src/test/ui/parser/raw-str-delim.rs rename to src/test/ui/parser/raw/raw-str-delim.rs diff --git a/src/test/ui/parser/raw-str-delim.stderr b/src/test/ui/parser/raw/raw-str-delim.stderr similarity index 100% rename from src/test/ui/parser/raw-str-delim.stderr rename to src/test/ui/parser/raw/raw-str-delim.stderr diff --git a/src/test/ui/parser/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs similarity index 100% rename from src/test/ui/parser/raw-str-unbalanced.rs rename to src/test/ui/parser/raw/raw-str-unbalanced.rs diff --git a/src/test/ui/parser/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr similarity index 100% rename from src/test/ui/parser/raw-str-unbalanced.stderr rename to src/test/ui/parser/raw/raw-str-unbalanced.stderr diff --git a/src/test/ui/parser/raw-str-unterminated.rs b/src/test/ui/parser/raw/raw-str-unterminated.rs similarity index 100% rename from src/test/ui/parser/raw-str-unterminated.rs rename to src/test/ui/parser/raw/raw-str-unterminated.rs diff --git a/src/test/ui/parser/raw-str-unterminated.stderr b/src/test/ui/parser/raw/raw-str-unterminated.stderr similarity index 100% rename from src/test/ui/parser/raw-str-unterminated.stderr rename to src/test/ui/parser/raw/raw-str-unterminated.stderr From 4d099e63083b4730f57d1ccb5d27c251dbddfb56 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 28 Mar 2020 14:05:59 -0700 Subject: [PATCH 02/33] Add `-Z dump-mir-dataflow` --- src/librustc_interface/tests.rs | 2 ++ src/librustc_session/options.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index 6a6d0a8f061eb..00d9f8df8ff81 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -566,6 +566,8 @@ fn test_debugging_options_tracking_hash() { assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts.debugging_opts.dump_mir_graphviz = true; assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + opts.debugging_opts.dump_mir_dataflow = true; + assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); // Make sure changing a [TRACKED] option changes the hash opts = reference.clone(); diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 72c720d09b0bf..700ecd7d6135e 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -837,6 +837,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "the directory the MIR is dumped into"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], "in addition to `.mir` files, create graphviz `.dot` files"), + dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED], + "in addition to `.mir` files, create graphviz `.dot` files with dataflow results"), dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], "if set, exclude the pass number when dumping MIR (used in tests)"), mir_emit_retag: bool = (false, parse_bool, [TRACKED], From edbd7c86027c7205076832924ee7999796c2405f Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 28 Mar 2020 14:07:07 -0700 Subject: [PATCH 03/33] `dump_enabled` takes a `DefId` instead of `MirSource` --- src/librustc_mir/borrow_check/nll.rs | 2 +- src/librustc_mir/transform/dump_mir.rs | 2 +- src/librustc_mir/util/liveness.rs | 2 +- src/librustc_mir/util/pretty.rs | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 8e929a4fa22f4..14a8f13909574 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -317,7 +317,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>( regioncx: &RegionInferenceContext<'_>, closure_region_requirements: &Option>, ) { - if !mir_util::dump_enabled(infcx.tcx, "nll", source) { + if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) { return; } diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 795bcb57d0678..fd6de0324a0ea 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -46,7 +46,7 @@ pub fn on_mir_pass<'tcx>( body: &Body<'tcx>, is_after: bool, ) { - if mir_util::dump_enabled(tcx, pass_name, source) { + if mir_util::dump_enabled(tcx, pass_name, source.def_id()) { mir_util::dump_mir( tcx, Some(pass_num), diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index f6c6f55549593..e4de97dfd25e6 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -265,7 +265,7 @@ pub fn dump_mir<'tcx>( body: &Body<'tcx>, result: &LivenessResult, ) { - if !dump_enabled(tcx, pass_name, source) { + if !dump_enabled(tcx, pass_name, source.def_id()) { return; } let node_path = ty::print::with_forced_impl_filename_line(|| { diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 0368a73832d75..399714c3880ef 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -76,21 +76,21 @@ pub fn dump_mir<'tcx, F>( ) where F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { - if !dump_enabled(tcx, pass_name, source) { + if !dump_enabled(tcx, pass_name, source.def_id()) { return; } dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, source, body, extra_data); } -pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, source: MirSource<'tcx>) -> bool { +pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool { let filters = match tcx.sess.opts.debugging_opts.dump_mir { None => return false, Some(ref filters) => filters, }; let node_path = ty::print::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.def_path_str(source.def_id()) + tcx.def_path_str(def_id) }); filters.split('|').any(|or_filter| { or_filter.split('&').all(|and_filter| { From c8004027ba11a7611ead54275ab14f58a8b0edb8 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 28 Mar 2020 14:09:12 -0700 Subject: [PATCH 04/33] Dump graphviz dataflow results with flag --- src/librustc_mir/dataflow/framework/engine.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs index d32072125b3b9..54263287e0228 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/src/librustc_mir/dataflow/framework/engine.rs @@ -15,6 +15,7 @@ use rustc_span::symbol::{sym, Symbol}; use super::graphviz; use super::{Analysis, GenKillAnalysis, GenKillSet, Results}; +use crate::util::pretty::dump_enabled; /// A solver for dataflow problems. pub struct Engine<'a, 'tcx, A> @@ -400,12 +401,25 @@ where let attrs = match RustcMirAttrs::parse(tcx, def_id) { Ok(attrs) => attrs, - // Invalid `rustc_mir` attrs will be reported using `span_err`. + // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse` Err(()) => return Ok(()), }; let path = match attrs.output_path(A::NAME) { Some(path) => path, + + None if tcx.sess.opts.debugging_opts.dump_mir_dataflow + && dump_enabled(tcx, A::NAME, def_id) => + { + let mut path = PathBuf::from(&tcx.sess.opts.debugging_opts.dump_mir_dir); + + let item_name = ty::print::with_forced_impl_filename_line(|| { + tcx.def_path(def_id).to_filename_friendly_no_crate() + }); + path.push(format!("rustc.{}.{}.dot", item_name, A::NAME)); + path + } + None => return Ok(()), }; From 4d1194c31a8548f554212abb8fa724319631e2fc Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sat, 28 Mar 2020 14:09:34 -0700 Subject: [PATCH 05/33] Ensure output dir for dataflow results exists --- src/librustc_mir/dataflow/framework/engine.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs index 54263287e0228..6d3b453bfc022 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/src/librustc_mir/dataflow/framework/engine.rs @@ -444,7 +444,12 @@ where let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter); dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?; + + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } fs::write(&path, buf)?; + Ok(()) } From 629e97a5a02edb3d8dc63c5157962c093217d441 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Sat, 28 Mar 2020 01:46:20 -0400 Subject: [PATCH 06/33] Improve error messages for raw strings (#60762) This diff improves error messages around raw strings in a few ways: - Catch extra trailing `#` in the parser. This can't be handled in the lexer because we could be in a macro that actually expects another # (see test) - Refactor & unify error handling in the lexer between ByteStrings and RawByteStrings - Detect potentially intended terminators (longest sequence of "#*" is suggested) --- src/librustc_lexer/src/cursor.rs | 2 +- src/librustc_lexer/src/lib.rs | 131 +++++++++++++++--- src/librustc_lexer/src/tests.rs | 119 ++++++++++++++++ src/librustc_parse/lexer/mod.rs | 94 ++++++++----- src/librustc_parse/parser/diagnostics.rs | 31 ++++- .../ui/parser/raw/raw-byte-string-eof.stderr | 4 +- .../ui/parser/raw/raw-str-in-macro-call.rs | 14 ++ src/test/ui/parser/raw/raw-str-unbalanced.rs | 2 +- .../ui/parser/raw/raw-str-unbalanced.stderr | 6 +- src/test/ui/parser/raw/raw_string.stderr | 4 +- 10 files changed, 344 insertions(+), 63 deletions(-) create mode 100644 src/librustc_lexer/src/tests.rs create mode 100644 src/test/ui/parser/raw/raw-str-in-macro-call.rs diff --git a/src/librustc_lexer/src/cursor.rs b/src/librustc_lexer/src/cursor.rs index ed0911379c4b3..13d0b07d98bae 100644 --- a/src/librustc_lexer/src/cursor.rs +++ b/src/librustc_lexer/src/cursor.rs @@ -41,7 +41,7 @@ impl<'a> Cursor<'a> { /// If requested position doesn't exist, `EOF_CHAR` is returned. /// However, getting `EOF_CHAR` doesn't always mean actual end of file, /// it should be checked with `is_eof` method. - fn nth_char(&self, n: usize) -> char { + pub(crate) fn nth_char(&self, n: usize) -> char { self.chars().nth(n).unwrap_or(EOF_CHAR) } diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index d3ac58a49c8d5..70df6d210f4a1 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -17,9 +17,13 @@ mod cursor; pub mod unescape; +#[cfg(test)] +mod tests; + use self::LiteralKind::*; use self::TokenKind::*; use crate::cursor::{Cursor, EOF_CHAR}; +use std::convert::TryInto; /// Parsed token. /// It doesn't contain information about data that has been parsed, @@ -132,9 +136,65 @@ pub enum LiteralKind { /// "b"abc"", "b"abc" ByteStr { terminated: bool }, /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a" - RawStr { n_hashes: usize, started: bool, terminated: bool }, + RawStr(UnvalidatedRawStr), /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a" - RawByteStr { n_hashes: usize, started: bool, terminated: bool }, + RawByteStr(UnvalidatedRawStr), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct UnvalidatedRawStr { + valid_start: bool, + n_start_hashes: usize, + n_end_hashes: usize, + possible_terminator_offset: Option, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum LexRawStrError { + /// Non # characters between `r` and `"` eg. `r#~"..` + InvalidStarter, + /// The string was never terminated. `possible_terminator_offset` is the best guess of where they + /// may have intended to terminate it. + NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option }, + /// More than 65536 # signs + TooManyDelimiters, +} + +#[derive(Debug, Eq, PartialEq, Copy, Clone)] +pub struct ValidatedRawStr { + n_hashes: u16, +} + +impl ValidatedRawStr { + pub fn num_hashes(&self) -> u16 { + self.n_hashes + } +} + +impl UnvalidatedRawStr { + pub fn started(&self) -> bool { + self.valid_start + } + + pub fn validate(self) -> Result { + if !self.valid_start { + return Err(LexRawStrError::InvalidStarter); + } + + let n_start_safe: u16 = + self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?; + match (self.n_start_hashes, self.n_end_hashes) { + (n_start, n_end) if n_start > n_end => Err(LexRawStrError::NoTerminator { + expected: n_start, + found: self.n_end_hashes, + possible_terminator_offset: self.possible_terminator_offset, + }), + (n_start, n_end) => { + debug_assert_eq!(n_start, n_end); + Ok(ValidatedRawStr { n_hashes: n_start_safe }) + } + } + } } /// Base of numeric literal encoding according to its prefix. @@ -209,7 +269,7 @@ pub fn is_whitespace(c: char) -> bool { // Dedicated whitespace characters from Unicode | '\u{2028}' // LINE SEPARATOR | '\u{2029}' // PARAGRAPH SEPARATOR - => true, + => true, _ => false, } } @@ -258,12 +318,12 @@ impl Cursor<'_> { 'r' => match (self.first(), self.second()) { ('#', c1) if is_id_start(c1) => self.raw_ident(), ('#', _) | ('"', _) => { - let (n_hashes, started, terminated) = self.raw_double_quoted_string(); + let raw_str_i = self.raw_double_quoted_string(1); let suffix_start = self.len_consumed(); - if terminated { + if raw_str_i.n_end_hashes == raw_str_i.n_start_hashes { self.eat_literal_suffix(); } - let kind = RawStr { n_hashes, started, terminated }; + let kind = RawStr(raw_str_i); Literal { kind, suffix_start } } _ => self.ident(), @@ -293,12 +353,14 @@ impl Cursor<'_> { } ('r', '"') | ('r', '#') => { self.bump(); - let (n_hashes, started, terminated) = self.raw_double_quoted_string(); + let raw_str_i = self.raw_double_quoted_string(2); let suffix_start = self.len_consumed(); + let terminated = raw_str_i.n_start_hashes == raw_str_i.n_end_hashes; if terminated { self.eat_literal_suffix(); } - let kind = RawByteStr { n_hashes, started, terminated }; + + let kind = RawByteStr(raw_str_i); Literal { kind, suffix_start } } _ => self.ident(), @@ -594,29 +656,41 @@ impl Cursor<'_> { false } - /// Eats the double-quoted string and returns a tuple of - /// (amount of the '#' symbols, raw string started, raw string terminated) - fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) { + /// Eats the double-quoted string an UnvalidatedRawStr + fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr { debug_assert!(self.prev() == 'r'); - let mut started: bool = false; - let mut finished: bool = false; + let mut valid_start: bool = false; + let start_pos = self.len_consumed(); + let (mut possible_terminator_offset, mut max_hashes) = (None, 0); // Count opening '#' symbols. - let n_hashes = self.eat_while(|c| c == '#'); + let n_start_hashes = self.eat_while(|c| c == '#'); // Check that string is started. match self.bump() { - Some('"') => started = true, - _ => return (n_hashes, started, finished), + Some('"') => valid_start = true, + _ => { + return UnvalidatedRawStr { + valid_start, + n_start_hashes, + n_end_hashes: 0, + possible_terminator_offset, + }; + } } // Skip the string contents and on each '#' character met, check if this is // a raw string termination. - while !finished { + loop { self.eat_while(|c| c != '"'); if self.is_eof() { - return (n_hashes, started, finished); + return UnvalidatedRawStr { + valid_start, + n_start_hashes, + n_end_hashes: max_hashes, + possible_terminator_offset, + }; } // Eat closing double quote. @@ -624,7 +698,7 @@ impl Cursor<'_> { // Check that amount of closing '#' symbols // is equal to the amount of opening ones. - let mut hashes_left = n_hashes; + let mut hashes_left = n_start_hashes; let is_closing_hash = |c| { if c == '#' && hashes_left != 0 { hashes_left -= 1; @@ -633,10 +707,23 @@ impl Cursor<'_> { false } }; - finished = self.eat_while(is_closing_hash) == n_hashes; + let n_end_hashes = self.eat_while(is_closing_hash); + + if n_end_hashes == n_start_hashes { + return UnvalidatedRawStr { + valid_start, + n_start_hashes, + n_end_hashes, + possible_terminator_offset: None, + }; + } else if n_end_hashes > 0 && n_end_hashes > max_hashes { + // Keep track of possible terminators to give a hint about where there might be + // a missing terminator + possible_terminator_offset = + Some(self.len_consumed() - start_pos - n_end_hashes + prefix_len); + max_hashes = n_end_hashes; + } } - - (n_hashes, started, finished) } fn eat_decimal_digits(&mut self) -> bool { diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs new file mode 100644 index 0000000000000..ba5897c5d4218 --- /dev/null +++ b/src/librustc_lexer/src/tests.rs @@ -0,0 +1,119 @@ +#[cfg(test)] +mod tests { + use crate::*; + + fn check_raw_str( + s: &str, + expected: UnvalidatedRawStr, + validated: Result, + ) { + let mut cursor = Cursor::new(s); + let tok = cursor.raw_double_quoted_string(0); + assert_eq!(tok, expected); + assert_eq!(tok.validate(), validated); + } + + #[test] + fn test_naked_raw_str() { + check_raw_str( + r#""abc""#, + UnvalidatedRawStr { + n_start_hashes: 0, + n_end_hashes: 0, + valid_start: true, + possible_terminator_offset: None, + }, + Ok(ValidatedRawStr { n_hashes: 0 }), + ); + } + + #[test] + fn test_raw_no_start() { + check_raw_str( + r##""abc"#"##, + UnvalidatedRawStr { + n_start_hashes: 0, + n_end_hashes: 0, + valid_start: true, + possible_terminator_offset: None, + }, + Ok(ValidatedRawStr { n_hashes: 0 }), + ); + } + + #[test] + fn test_too_many_terminators() { + // this error is handled in the parser later + check_raw_str( + r###"#"abc"##"###, + UnvalidatedRawStr { + n_start_hashes: 1, + n_end_hashes: 1, + valid_start: true, + possible_terminator_offset: None, + }, + Ok(ValidatedRawStr { n_hashes: 1 }), + ); + } + + #[test] + fn test_unterminated() { + check_raw_str( + r#"#"abc"#, + UnvalidatedRawStr { + n_start_hashes: 1, + n_end_hashes: 0, + valid_start: true, + possible_terminator_offset: None, + }, + Err(LexRawStrError::NoTerminator { + expected: 1, + found: 0, + possible_terminator_offset: None, + }), + ); + check_raw_str( + r###"##"abc"#"###, + UnvalidatedRawStr { + n_start_hashes: 2, + n_end_hashes: 1, + valid_start: true, + possible_terminator_offset: Some(7), + }, + Err(LexRawStrError::NoTerminator { + expected: 2, + found: 1, + possible_terminator_offset: Some(7), + }), + ); + // We're looking for "# not just any # + check_raw_str( + r###"##"abc#"###, + UnvalidatedRawStr { + n_start_hashes: 2, + n_end_hashes: 0, + valid_start: true, + possible_terminator_offset: None, + }, + Err(LexRawStrError::NoTerminator { + expected: 2, + found: 0, + possible_terminator_offset: None, + }), + ) + } + + #[test] + fn test_invalid_start() { + check_raw_str( + r##"#~"abc"#"##, + UnvalidatedRawStr { + n_start_hashes: 1, + n_end_hashes: 0, + valid_start: false, + possible_terminator_offset: None, + }, + Err(LexRawStrError::InvalidStarter), + ); + } +} diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index ac58cbb9e8dae..2f720d95c6d2f 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -1,20 +1,20 @@ use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::util::comments; use rustc_data_structures::sync::Lrc; -use rustc_errors::{error_code, DiagnosticBuilder, FatalError}; -use rustc_lexer::unescape; +use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError}; use rustc_lexer::Base; +use rustc_lexer::{unescape, LexRawStrError, UnvalidatedRawStr, ValidatedRawStr}; use rustc_session::parse::ParseSess; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Pos, Span}; use log::debug; use std::char; -use std::convert::TryInto; mod tokentrees; mod unescape_error_reporting; mod unicode_chars; + use unescape_error_reporting::{emit_unescape_error, push_escaped_char}; #[derive(Clone, Debug)] @@ -376,30 +376,22 @@ impl<'a> StringReader<'a> { let id = self.symbol_from_to(content_start, content_end); (token::ByteStr, id) } - rustc_lexer::LiteralKind::RawStr { n_hashes, started, terminated } => { - if !started { - self.report_non_started_raw_string(start); - } - if !terminated { - self.report_unterminated_raw_string(start, n_hashes) - } - let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes); + rustc_lexer::LiteralKind::RawStr(unvalidated_raw_str) => { + let valid_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str); + let n_hashes = valid_raw_str.num_hashes(); let n = u32::from(n_hashes); + let content_start = start + BytePos(2 + n); let content_end = suffix_start - BytePos(1 + n); self.validate_raw_str_escape(content_start, content_end); let id = self.symbol_from_to(content_start, content_end); (token::StrRaw(n_hashes), id) } - rustc_lexer::LiteralKind::RawByteStr { n_hashes, started, terminated } => { - if !started { - self.report_non_started_raw_string(start); - } - if !terminated { - self.report_unterminated_raw_string(start, n_hashes) - } - let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes); + rustc_lexer::LiteralKind::RawByteStr(unvalidated_raw_str) => { + let validated_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str); + let n_hashes = validated_raw_str.num_hashes(); let n = u32::from(n_hashes); + let content_start = start + BytePos(3 + n); let content_end = suffix_start - BytePos(1 + n); self.validate_raw_byte_str_escape(content_start, content_end); @@ -485,6 +477,26 @@ impl<'a> StringReader<'a> { } } + fn validate_and_report_errors( + &self, + start: BytePos, + unvalidated_raw_str: UnvalidatedRawStr, + ) -> ValidatedRawStr { + match unvalidated_raw_str.validate() { + Err(LexRawStrError::InvalidStarter) => self.report_non_started_raw_string(start), + Err(LexRawStrError::NoTerminator { expected, found, possible_terminator_offset }) => { + self.report_unterminated_raw_string( + start, + expected, + possible_terminator_offset, + found, + ) + } + Err(LexRawStrError::TooManyDelimiters) => self.report_too_many_hashes(start), + Ok(valid) => valid, + } + } + fn report_non_started_raw_string(&self, start: BytePos) -> ! { let bad_char = self.str_from(start).chars().last().unwrap(); self.struct_fatal_span_char( @@ -498,38 +510,52 @@ impl<'a> StringReader<'a> { FatalError.raise() } - fn report_unterminated_raw_string(&self, start: BytePos, n_hashes: usize) -> ! { + fn report_unterminated_raw_string( + &self, + start: BytePos, + n_hashes: usize, + possible_offset: Option, + found_terminators: usize, + ) -> ! { let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code( self.mk_sp(start, start), "unterminated raw string", error_code!(E0748), ); + err.span_label(self.mk_sp(start, start), "unterminated raw string"); if n_hashes > 0 { err.note(&format!( "this raw string should be terminated with `\"{}`", - "#".repeat(n_hashes as usize) + "#".repeat(n_hashes) )); } + if let Some(possible_offset) = possible_offset { + let span = self.mk_sp( + start + BytePos(possible_offset as u32), + start + BytePos(possible_offset as u32) + BytePos(found_terminators as u32), + ); + err.span_suggestion( + span, + "you might have intended to terminate the string here", + "#".repeat(n_hashes), + Applicability::MaybeIncorrect, + ); + } + err.emit(); FatalError.raise() } - fn restrict_n_hashes(&self, start: BytePos, n_hashes: usize) -> u16 { - match n_hashes.try_into() { - Ok(n_hashes) => n_hashes, - Err(_) => { - self.fatal_span_( - start, - self.pos, - "too many `#` symbols: raw strings may be \ - delimited by up to 65535 `#` symbols", - ) - .raise(); - } - } + fn report_too_many_hashes(&self, start: BytePos) -> ! { + self.fatal_span_( + start, + self.pos, + "too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols", + ) + .raise(); } fn validate_char_escape(&self, content_start: BytePos, content_end: BytePos) { diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index c4546dedfcdd4..7b6840307cb42 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -6,7 +6,7 @@ use rustc_ast::ast::{ }; use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, TokenKind}; +use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -255,6 +255,10 @@ impl<'a> Parser<'a> { } } + if self.check_too_many_raw_str_terminators(&mut err) { + return Err(err); + } + let sm = self.sess.source_map(); if self.prev_token.span == DUMMY_SP { // Account for macro context where the previous span might not be @@ -282,6 +286,31 @@ impl<'a> Parser<'a> { Err(err) } + fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { + let prev_token_raw_str = match self.prev_token { + Token { kind: TokenKind::Literal(Lit { kind: LitKind::StrRaw(n), .. }), .. } => Some(n), + Token { + kind: TokenKind::Literal(Lit { kind: LitKind::ByteStrRaw(n), .. }), .. + } => Some(n), + _ => None, + }; + + if let Some(n_hashes) = prev_token_raw_str { + if self.token.kind == TokenKind::Pound { + err.set_primary_message("too many `#` when terminating raw string"); + err.span_suggestion( + self.token.span, + "Remove the extra `#`", + String::new(), + Applicability::MachineApplicable, + ); + err.note(&format!("The raw string started with {} `#`s", n_hashes)); + return true; + } + } + false + } + pub fn maybe_annotate_with_ascription( &mut self, err: &mut DiagnosticBuilder<'_>, diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr index d5f22e2a1a814..81344841c2700 100644 --- a/src/test/ui/parser/raw/raw-byte-string-eof.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr @@ -2,7 +2,9 @@ error[E0748]: unterminated raw string --> $DIR/raw-byte-string-eof.rs:2:5 | LL | br##"a"#; - | ^ unterminated raw string + | ^ - help: you might have intended to terminate the string here: `##` + | | + | unterminated raw string | = note: this raw string should be terminated with `"##` diff --git a/src/test/ui/parser/raw/raw-str-in-macro-call.rs b/src/test/ui/parser/raw/raw-str-in-macro-call.rs new file mode 100644 index 0000000000000..462c2279f5c1c --- /dev/null +++ b/src/test/ui/parser/raw/raw-str-in-macro-call.rs @@ -0,0 +1,14 @@ +// check-pass + +macro_rules! m1 { + ($tt:tt #) => () +} + +macro_rules! m2 { + ($tt:tt) => () +} + +fn main() { + m1!(r#"abc"##); + m2!(r#"abc"#); +} diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs index 5a1d1be11b633..35f118f5ce6ee 100644 --- a/src/test/ui/parser/raw/raw-str-unbalanced.rs +++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs @@ -1,4 +1,4 @@ static s: &'static str = r#" - "## //~ ERROR expected one of `.`, `;`, `?`, or an operator, found `#` + "## //~ too many `#` when terminating raw string ; diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr index ddb75722bef9f..891f1d6337cd2 100644 --- a/src/test/ui/parser/raw/raw-str-unbalanced.stderr +++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr @@ -1,8 +1,10 @@ -error: expected one of `.`, `;`, `?`, or an operator, found `#` +error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:3:9 | LL | "## - | ^ expected one of `.`, `;`, `?`, or an operator + | ^ help: Remove the extra `#` + | + = note: The raw string started with 1 `#`s error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw_string.stderr b/src/test/ui/parser/raw/raw_string.stderr index 0f1d7e4651deb..e91a16bedc46e 100644 --- a/src/test/ui/parser/raw/raw_string.stderr +++ b/src/test/ui/parser/raw/raw_string.stderr @@ -2,7 +2,9 @@ error[E0748]: unterminated raw string --> $DIR/raw_string.rs:2:13 | LL | let x = r##"lol"#; - | ^ unterminated raw string + | ^ - help: you might have intended to terminate the string here: `##` + | | + | unterminated raw string | = note: this raw string should be terminated with `"##` From c15f86b4b35a260b105dc472fc6e3556af8a8db0 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Sun, 29 Mar 2020 11:12:48 -0400 Subject: [PATCH 07/33] Cleanup error messages, improve docstrings --- src/librustc_lexer/src/cursor.rs | 2 +- src/librustc_lexer/src/lib.rs | 47 ++++++++++++------- src/librustc_parse/lexer/mod.rs | 9 ++-- src/librustc_parse/lib.rs | 1 + src/librustc_parse/parser/diagnostics.rs | 11 +++-- .../ui/parser/raw/raw-byte-string-eof.stderr | 2 +- .../ui/parser/raw/raw-str-unbalanced.stderr | 4 +- src/test/ui/parser/raw/raw_string.stderr | 2 +- 8 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/librustc_lexer/src/cursor.rs b/src/librustc_lexer/src/cursor.rs index 13d0b07d98bae..ed0911379c4b3 100644 --- a/src/librustc_lexer/src/cursor.rs +++ b/src/librustc_lexer/src/cursor.rs @@ -41,7 +41,7 @@ impl<'a> Cursor<'a> { /// If requested position doesn't exist, `EOF_CHAR` is returned. /// However, getting `EOF_CHAR` doesn't always mean actual end of file, /// it should be checked with `is_eof` method. - pub(crate) fn nth_char(&self, n: usize) -> char { + fn nth_char(&self, n: usize) -> char { self.chars().nth(n).unwrap_or(EOF_CHAR) } diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 70df6d210f4a1..132607031ce65 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -141,25 +141,41 @@ pub enum LiteralKind { RawByteStr(UnvalidatedRawStr), } +/// Represents something that looks like a raw string, but may have some +/// problems. Use `.validate()` to convert it into something +/// usable. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct UnvalidatedRawStr { + /// The prefix (`r###"`) is valid valid_start: bool, + /// The number of leading `#` n_start_hashes: usize, + /// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes` n_end_hashes: usize, + /// The offset starting at `r` or `br` where the user may have intended to end the string. + /// Currently, it is the longest sequence of pattern `"#+"`. possible_terminator_offset: Option, } +/// Error produced validating a raw string. Represents cases like: +/// - `r##~"abcde"##`: `LexRawStrError::InvalidStarter` +/// - `r###"abcde"##`: `LexRawStrError::NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)` +/// - Too many `#`s (>65536): `TooManyDelimiters` #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum LexRawStrError { - /// Non # characters between `r` and `"` eg. `r#~"..` + /// Non `#` characters exist between `r` and `"` eg. `r#~"..` InvalidStarter, - /// The string was never terminated. `possible_terminator_offset` is the best guess of where they + /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they /// may have intended to terminate it. NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option }, - /// More than 65536 # signs + /// More than 65536 `#`s exist. TooManyDelimiters, } +/// Raw String that contains a valid prefix (`#+"`) and postfix (`"#+`) where +/// there are a matching number of `#` characters in both. Note that this will +/// not consume extra trailing `#` characters: `r###"abcde"####` is lexed as a +/// `ValidatedRawString { n_hashes: 3 }` followed by a `#` token. #[derive(Debug, Eq, PartialEq, Copy, Clone)] pub struct ValidatedRawStr { n_hashes: u16, @@ -172,27 +188,26 @@ impl ValidatedRawStr { } impl UnvalidatedRawStr { - pub fn started(&self) -> bool { - self.valid_start - } - pub fn validate(self) -> Result { if !self.valid_start { return Err(LexRawStrError::InvalidStarter); } + // Only up to 65535 `#`s are allowed in raw strings let n_start_safe: u16 = self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?; - match (self.n_start_hashes, self.n_end_hashes) { - (n_start, n_end) if n_start > n_end => Err(LexRawStrError::NoTerminator { - expected: n_start, + + if self.n_start_hashes > self.n_end_hashes { + Err(LexRawStrError::NoTerminator { + expected: self.n_start_hashes, found: self.n_end_hashes, possible_terminator_offset: self.possible_terminator_offset, - }), - (n_start, n_end) => { - debug_assert_eq!(n_start, n_end); - Ok(ValidatedRawStr { n_hashes: n_start_safe }) - } + }) + } else { + // Since the lexer should never produce a literal with n_end > n_start, if n_start <= n_end, + // they must be equal. + debug_assert_eq!(self.n_start_hashes, self.n_end_hashes); + Ok(ValidatedRawStr { n_hashes: n_start_safe }) } } } @@ -656,7 +671,7 @@ impl Cursor<'_> { false } - /// Eats the double-quoted string an UnvalidatedRawStr + /// Eats the double-quoted string and returns an `UnvalidatedRawStr`. fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr { debug_assert!(self.prev() == 'r'); let mut valid_start: bool = false; diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index 2f720d95c6d2f..a367131b3f309 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -533,13 +533,12 @@ impl<'a> StringReader<'a> { } if let Some(possible_offset) = possible_offset { - let span = self.mk_sp( - start + BytePos(possible_offset as u32), - start + BytePos(possible_offset as u32) + BytePos(found_terminators as u32), - ); + let lo = start + BytePos(possible_offset as u32); + let hi = lo + BytePos(found_terminators as u32); + let span = self.mk_sp(lo, hi); err.span_suggestion( span, - "you might have intended to terminate the string here", + "consider terminating the string here", "#".repeat(n_hashes), Applicability::MaybeIncorrect, ); diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 13fb85db84779..8e2a9513d6b82 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -4,6 +4,7 @@ #![feature(crate_visibility_modifier)] #![feature(bindings_after_at)] #![feature(try_blocks)] +#![feature(or_patterns)] use rustc_ast::ast; use rustc_ast::token::{self, Nonterminal}; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 7b6840307cb42..2fc20e15c5aca 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -288,9 +288,12 @@ impl<'a> Parser<'a> { fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { let prev_token_raw_str = match self.prev_token { - Token { kind: TokenKind::Literal(Lit { kind: LitKind::StrRaw(n), .. }), .. } => Some(n), Token { - kind: TokenKind::Literal(Lit { kind: LitKind::ByteStrRaw(n), .. }), .. + kind: + TokenKind::Literal(Lit { + kind: LitKind::StrRaw(n) | LitKind::ByteStrRaw(n), .. + }), + .. } => Some(n), _ => None, }; @@ -300,11 +303,11 @@ impl<'a> Parser<'a> { err.set_primary_message("too many `#` when terminating raw string"); err.span_suggestion( self.token.span, - "Remove the extra `#`", + "remove the extra `#`", String::new(), Applicability::MachineApplicable, ); - err.note(&format!("The raw string started with {} `#`s", n_hashes)); + err.note(&format!("the raw string started with {} `#`s", n_hashes)); return true; } } diff --git a/src/test/ui/parser/raw/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr index 81344841c2700..a76668e8051b5 100644 --- a/src/test/ui/parser/raw/raw-byte-string-eof.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr @@ -2,7 +2,7 @@ error[E0748]: unterminated raw string --> $DIR/raw-byte-string-eof.rs:2:5 | LL | br##"a"#; - | ^ - help: you might have intended to terminate the string here: `##` + | ^ - help: consider terminating the string here: `##` | | | unterminated raw string | diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr index 891f1d6337cd2..bf8f3a7a5a4bd 100644 --- a/src/test/ui/parser/raw/raw-str-unbalanced.stderr +++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr @@ -2,9 +2,9 @@ error: too many `#` when terminating raw string --> $DIR/raw-str-unbalanced.rs:3:9 | LL | "## - | ^ help: Remove the extra `#` + | ^ help: remove the extra `#` | - = note: The raw string started with 1 `#`s + = note: the raw string started with 1 `#`s error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw_string.stderr b/src/test/ui/parser/raw/raw_string.stderr index e91a16bedc46e..cc0eb4927003d 100644 --- a/src/test/ui/parser/raw/raw_string.stderr +++ b/src/test/ui/parser/raw/raw_string.stderr @@ -2,7 +2,7 @@ error[E0748]: unterminated raw string --> $DIR/raw_string.rs:2:13 | LL | let x = r##"lol"#; - | ^ - help: you might have intended to terminate the string here: `##` + | ^ - help: consider terminating the string here: `##` | | | unterminated raw string | From 82b2989ae0dbb1166289a360620e07865135a5e8 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Sun, 29 Mar 2020 11:34:15 -0400 Subject: [PATCH 08/33] More raw string tests --- src/test/ui/parser/raw/raw-string-2.rs | 4 ++++ src/test/ui/parser/raw/raw-string-2.stderr | 11 +++++++++++ .../ui/parser/raw/{raw_string.rs => raw-string.rs} | 0 .../raw/{raw_string.stderr => raw-string.stderr} | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/parser/raw/raw-string-2.rs create mode 100644 src/test/ui/parser/raw/raw-string-2.stderr rename src/test/ui/parser/raw/{raw_string.rs => raw-string.rs} (100%) rename src/test/ui/parser/raw/{raw_string.stderr => raw-string.stderr} (92%) diff --git a/src/test/ui/parser/raw/raw-string-2.rs b/src/test/ui/parser/raw/raw-string-2.rs new file mode 100644 index 0000000000000..067332d2819bd --- /dev/null +++ b/src/test/ui/parser/raw/raw-string-2.rs @@ -0,0 +1,4 @@ +fn main() { + let x = r###"here's a long string"# "# "##; + //~^ ERROR unterminated raw string +} diff --git a/src/test/ui/parser/raw/raw-string-2.stderr b/src/test/ui/parser/raw/raw-string-2.stderr new file mode 100644 index 0000000000000..8bbac9d7bd0bd --- /dev/null +++ b/src/test/ui/parser/raw/raw-string-2.stderr @@ -0,0 +1,11 @@ +error[E0748]: unterminated raw string + --> $DIR/raw-string-2.rs:2:13 + | +LL | let x = r###"here's a long string"# "# "##; + | ^ unterminated raw string -- help: consider terminating the string here: `###` + | + = note: this raw string should be terminated with `"###` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0748`. diff --git a/src/test/ui/parser/raw/raw_string.rs b/src/test/ui/parser/raw/raw-string.rs similarity index 100% rename from src/test/ui/parser/raw/raw_string.rs rename to src/test/ui/parser/raw/raw-string.rs diff --git a/src/test/ui/parser/raw/raw_string.stderr b/src/test/ui/parser/raw/raw-string.stderr similarity index 92% rename from src/test/ui/parser/raw/raw_string.stderr rename to src/test/ui/parser/raw/raw-string.stderr index cc0eb4927003d..b2b853a89e751 100644 --- a/src/test/ui/parser/raw/raw_string.stderr +++ b/src/test/ui/parser/raw/raw-string.stderr @@ -1,5 +1,5 @@ error[E0748]: unterminated raw string - --> $DIR/raw_string.rs:2:13 + --> $DIR/raw-string.rs:2:13 | LL | let x = r##"lol"#; | ^ - help: consider terminating the string here: `##` From bceab25d6c206a7b92716e0c9e9a89b97d131e8e Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Sun, 29 Mar 2020 12:02:28 -0400 Subject: [PATCH 09/33] Cleanup match expression --- src/librustc_parse/parser/diagnostics.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 2fc20e15c5aca..e542588d8b5cc 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -6,7 +6,7 @@ use rustc_ast::ast::{ }; use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind}; +use rustc_ast::token::{self, Lit, LitKind, TokenKind}; use rustc_ast::util::parser::AssocOp; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -287,14 +287,10 @@ impl<'a> Parser<'a> { } fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { - let prev_token_raw_str = match self.prev_token { - Token { - kind: - TokenKind::Literal(Lit { - kind: LitKind::StrRaw(n) | LitKind::ByteStrRaw(n), .. - }), - .. - } => Some(n), + let prev_token_raw_str = match self.prev_token.kind { + TokenKind::Literal(Lit { + kind: LitKind::StrRaw(n) | LitKind::ByteStrRaw(n), .. + }) => Some(n), _ => None, }; @@ -523,7 +519,7 @@ impl<'a> Parser<'a> { .unwrap_or_else(|_| pprust::expr_to_string(&e)) }; err.span_suggestion_verbose( - inner_op.span.shrink_to_hi(), + inner_op.span.shrink_to_hi(), "split the comparison into two", format!(" && {}", expr_to_str(&r1)), Applicability::MaybeIncorrect, @@ -1118,7 +1114,7 @@ impl<'a> Parser<'a> { self.look_ahead(2, |t| t.is_ident()) || self.look_ahead(1, |t| t == &token::ModSep) && (self.look_ahead(2, |t| t.is_ident()) || // `foo:bar::baz` - self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::` + self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::` } pub(super) fn recover_seq_parse_error( From 20e21902bb993487c1486f2dd33d3bd65101f00c Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Mon, 30 Mar 2020 12:39:40 -0400 Subject: [PATCH 10/33] Clean up redudant conditions and match exprs --- src/librustc_lexer/src/lib.rs | 2 +- src/librustc_parse/parser/diagnostics.rs | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 132607031ce65..fcb7475cc2e89 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -731,7 +731,7 @@ impl Cursor<'_> { n_end_hashes, possible_terminator_offset: None, }; - } else if n_end_hashes > 0 && n_end_hashes > max_hashes { + } else if n_end_hashes > max_hashes { // Keep track of possible terminators to give a hint about where there might be // a missing terminator possible_terminator_offset = diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index e542588d8b5cc..12b9b68268248 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -287,15 +287,14 @@ impl<'a> Parser<'a> { } fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool { - let prev_token_raw_str = match self.prev_token.kind { - TokenKind::Literal(Lit { - kind: LitKind::StrRaw(n) | LitKind::ByteStrRaw(n), .. - }) => Some(n), - _ => None, - }; - - if let Some(n_hashes) = prev_token_raw_str { - if self.token.kind == TokenKind::Pound { + match (&self.prev_token.kind, &self.token.kind) { + ( + TokenKind::Literal(Lit { + kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes), + .. + }), + TokenKind::Pound, + ) => { err.set_primary_message("too many `#` when terminating raw string"); err.span_suggestion( self.token.span, @@ -304,10 +303,10 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); err.note(&format!("the raw string started with {} `#`s", n_hashes)); - return true; + true } + _ => false, } - false } pub fn maybe_annotate_with_ascription( From 097e9e528f45eea89677cf9ac3634c7cee9988aa Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 28 Mar 2020 21:47:50 -0400 Subject: [PATCH 11/33] Add `can_unwind` field to `FnAbi` This is a pure refactoring with no behavior changes. --- src/librustc_codegen_llvm/attributes.rs | 42 +---------------- src/librustc_middle/ty/layout.rs | 60 +++++++++++++++++++++++-- src/librustc_target/abi/call/mod.rs | 2 + 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index e4d6d7d8af90e..ac2bbd4b2aea4 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -13,8 +13,6 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::{OptLevel, Sanitizer}; use rustc_session::Session; -use rustc_target::abi::call::Conv; -use rustc_target::spec::PanicStrategy; use crate::abi::FnAbi; use crate::attributes; @@ -315,45 +313,7 @@ pub fn from_fn_attrs( } sanitize(cx, codegen_fn_attrs.flags, llfn); - unwind( - llfn, - if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind { - // In panic=abort mode we assume nothing can unwind anywhere, so - // optimize based on this! - false - } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { - // If a specific #[unwind] attribute is present, use that. - true - } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { - // Special attribute for allocator functions, which can't unwind. - false - } else { - if fn_abi.conv == Conv::Rust { - // Any Rust method (or `extern "Rust" fn` or `extern - // "rust-call" fn`) is explicitly allowed to unwind - // (unless it has no-unwind attribute, handled above). - true - } else { - // Anything else is either: - // - // 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or - // - // 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`). - // - // Foreign items (case 1) are assumed to not unwind; it is - // UB otherwise. (At least for now; see also - // rust-lang/rust#63909 and Rust RFC 2753.) - // - // Items defined in Rust with non-Rust ABIs (case 2) are also - // not supposed to unwind. Whether this should be enforced - // (versus stating it is UB) and *how* it would be enforced - // is currently under discussion; see rust-lang/rust#58794. - // - // In either case, we mark item as explicitly nounwind. - false - } - }, - ); + unwind(llfn, fn_abi.can_unwind); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 54fde52ba3a77..17c93922b0023 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -1,4 +1,5 @@ use crate::ich::StableHashingContext; +use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::subst::Subst; use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; @@ -15,7 +16,7 @@ use rustc_target::abi::call::{ ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind, }; pub use rustc_target::abi::*; -use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec}; +use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy}; use std::cmp; use std::fmt; @@ -2368,11 +2369,55 @@ where sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>], caller_location: Option>, + codegen_fn_attr_flags: CodegenFnAttrFlags, mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgAbi<'tcx, Ty<'tcx>>, ) -> Self; fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi); } +fn fn_can_unwind( + panic_strategy: PanicStrategy, + codegen_fn_attr_flags: CodegenFnAttrFlags, + call_conv: Conv, +) -> bool { + if panic_strategy != PanicStrategy::Unwind { + // In panic=abort mode we assume nothing can unwind anywhere, so + // optimize based on this! + false + } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::UNWIND) { + // If a specific #[unwind] attribute is present, use that. + true + } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { + // Special attribute for allocator functions, which can't unwind. + false + } else { + if call_conv == Conv::Rust { + // Any Rust method (or `extern "Rust" fn` or `extern + // "rust-call" fn`) is explicitly allowed to unwind + // (unless it has no-unwind attribute, handled above). + true + } else { + // Anything else is either: + // + // 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or + // + // 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`). + // + // Foreign items (case 1) are assumed to not unwind; it is + // UB otherwise. (At least for now; see also + // rust-lang/rust#63909 and Rust RFC 2753.) + // + // Items defined in Rust with non-Rust ABIs (case 2) are also + // not supposed to unwind. Whether this should be enforced + // (versus stating it is UB) and *how* it would be enforced + // is currently under discussion; see rust-lang/rust#58794. + // + // In either case, we mark item as explicitly nounwind. + false + } + } +} + impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>> where C: LayoutOf, TyAndLayout = TyAndLayout<'tcx>> @@ -2382,7 +2427,12 @@ where + HasParamEnv<'tcx>, { fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { - call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty))) + // Assume that fn pointers may always unwind + let codegen_fn_attr_flags = CodegenFnAttrFlags::UNWIND; + + call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, |ty, _| { + ArgAbi::new(cx.layout_of(ty)) + }) } fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self { @@ -2394,7 +2444,9 @@ where None }; - call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| { + let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags; + + call::FnAbi::new_internal(cx, sig, extra_args, caller_location, attrs, |ty, arg_idx| { let mut layout = cx.layout_of(ty); // Don't pass the vtable, it's not an argument of the virtual fn. // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` @@ -2450,6 +2502,7 @@ where sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>], caller_location: Option>, + codegen_fn_attr_flags: CodegenFnAttrFlags, mk_arg_type: impl Fn(Ty<'tcx>, Option) -> ArgAbi<'tcx, Ty<'tcx>>, ) -> Self { debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args); @@ -2639,6 +2692,7 @@ where c_variadic: sig.c_variadic, fixed_count: inputs.len(), conv, + can_unwind: fn_can_unwind(cx.tcx().sess.panic_strategy(), codegen_fn_attr_flags, conv), }; fn_abi.adjust_for_abi(cx, sig.abi); fn_abi diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index ffc85c153c9cd..72768c31e3077 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -546,6 +546,8 @@ pub struct FnAbi<'a, Ty> { pub fixed_count: usize, pub conv: Conv, + + pub can_unwind: bool, } impl<'a, Ty> FnAbi<'a, Ty> { From 6067315d58ff3d49b305ae3c99810656856c8e21 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 30 Mar 2020 14:03:39 -0700 Subject: [PATCH 12/33] Ensure LLVM is in the link path for "fulldeps" tests This is a follow-up to #70123, which added `llvm-config --libdir` to the `LIBRARY_PATH` for rustc tools. We need the same for "run-make-fulldeps" and "ui-fulldeps" tests which depend on compiler libraries, implicitly needing to link to `-lLLVM` as well. --- src/bootstrap/test.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 5b946b05735d8..2499856235f10 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -21,7 +21,7 @@ use crate::flags::Subcommand; use crate::native; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; -use crate::util::{self, dylib_path, dylib_path_var}; +use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var}; use crate::Crate as CargoCrate; use crate::{envify, DocTests, GitRepo, Mode}; @@ -1178,6 +1178,15 @@ impl Step for Compiletest { cmd.arg("--system-llvm"); } + // Tests that use compiler libraries may inherit the `-lLLVM` link + // requirement, but the `-L` library path is not propagated across + // separate compilations. We can add LLVM's library path to the + // platform-specific environment variable as a workaround. + if !builder.config.dry_run && suite.ends_with("fulldeps") { + let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); + add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); + } + // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && suite == "run-make-fulldeps" { From 55a5eea763ed330bd9c3da4fbe9cf7d448afbe83 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Tue, 31 Mar 2020 10:27:07 -0400 Subject: [PATCH 13/33] Fix tests to handle debug_assert --- src/librustc_lexer/src/tests.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs index ba5897c5d4218..4af435536f011 100644 --- a/src/librustc_lexer/src/tests.rs +++ b/src/librustc_lexer/src/tests.rs @@ -7,7 +7,9 @@ mod tests { expected: UnvalidatedRawStr, validated: Result, ) { + let s = &format!("r{}", s); let mut cursor = Cursor::new(s); + cursor.bump(); let tok = cursor.raw_double_quoted_string(0); assert_eq!(tok, expected); assert_eq!(tok.validate(), validated); From d45dca390ce3b1c099276fbd34d426a9b7e86481 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 17:49:33 -0300 Subject: [PATCH 14/33] Use Place directly, it's Copy --- src/librustc_mir/borrow_check/borrow_set.rs | 2 +- .../borrow_check/constraint_generation.rs | 8 +-- .../diagnostics/conflict_errors.rs | 33 +++++------ .../diagnostics/explain_borrow.rs | 2 +- .../diagnostics/mutability_errors.rs | 2 +- src/librustc_mir/borrow_check/invalidation.rs | 52 ++++++++-------- src/librustc_mir/borrow_check/mod.rs | 59 +++++++++---------- src/librustc_mir/borrow_check/path_utils.rs | 4 +- .../borrow_check/places_conflict.rs | 8 +-- src/librustc_mir/dataflow/impls/borrows.rs | 12 ++-- 10 files changed, 88 insertions(+), 94 deletions(-) diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 0ade0829ec306..7242bbcd2eb8f 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); - self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); + self.insert_as_pending_if_two_phase(location, assigned_place, kind, idx); self.local_map.entry(borrowed_place.local).or_default().insert(idx); } diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index c7f395885a557..e0420d974fbdf 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -114,7 +114,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { // When we see `X = ...`, then kill borrows of // `(*X).foo` and so forth. - self.record_killed_borrows_for_place(place, location); + self.record_killed_borrows_for_place(*place, location); self.super_assign(place, rvalue, location); } @@ -139,7 +139,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { // A `Call` terminator's return value can be a local which has borrows, // so we need to record those as `killed` as well. - if let TerminatorKind::Call { ref destination, .. } = terminator.kind { + if let TerminatorKind::Call { destination, .. } = terminator.kind { if let Some((place, _)) = destination { self.record_killed_borrows_for_place(place, location); } @@ -177,7 +177,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { /// When recording facts for Polonius, records the borrows on the specified place /// as `killed`. For example, when assigning to a local, or on a call's return destination. - fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) { + fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) { if let Some(all_facts) = self.all_facts { let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); @@ -217,7 +217,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { let places_conflict = places_conflict::places_conflict( self.infcx.tcx, self.body, - &self.borrow_set.borrows[borrow_index].borrowed_place, + self.borrow_set.borrows[borrow_index].borrowed_place, place, places_conflict::PlaceConflictBias::NoOverlap, ); diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index a4bed18dcef9b..563dfe3544e7d 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -247,7 +247,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(in crate::borrow_check) fn report_move_out_while_borrowed( &mut self, location: Location, - (place, span): (&Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) { debug!( @@ -291,7 +291,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(in crate::borrow_check) fn report_use_while_mutably_borrowed( &mut self, location: Location, - (place, _span): (&Place<'tcx>, Span), + (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) -> DiagnosticBuilder<'cx> { let borrow_spans = self.retrieve_borrow_spans(borrow); @@ -330,7 +330,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(in crate::borrow_check) fn report_conflicting_borrow( &mut self, location: Location, - (place, span): (&Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, ) -> DiagnosticBuilder<'cx> { @@ -347,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; let (desc_place, msg_place, msg_borrow, union_type_name) = - self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place); + self.describe_place_for_conflicting_borrow(place, issued_borrow.borrowed_place); let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None); let second_borrow_desc = if explanation.is_explained() { "second " } else { "" }; @@ -584,8 +584,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// > mutable (via `a.u.s.b`) [E0502] pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow( &self, - first_borrowed_place: &Place<'tcx>, - second_borrowed_place: &Place<'tcx>, + first_borrowed_place: Place<'tcx>, + second_borrowed_place: Place<'tcx>, ) -> (String, String, String, String) { // Define a small closure that we can use to check if the type of a place // is a union. @@ -615,13 +615,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { cursor = proj_base; match elem { - ProjectionElem::Field(field, _) - if union_ty(*local, proj_base).is_some() => - { - return Some(( - PlaceRef { local: *local, projection: proj_base }, - field, - )); + ProjectionElem::Field(field, _) if union_ty(local, proj_base).is_some() => { + return Some((PlaceRef { local, projection: proj_base }, field)); } _ => {} } @@ -631,7 +626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|(target_base, target_field)| { // With the place of a union and a field access into it, we traverse the second // borrowed place and look for a access to a different field of the same union. - let Place { local, ref projection } = *second_borrowed_place; + let Place { local, ref projection } = second_borrowed_place; let mut cursor = &projection[..]; while let [proj_base @ .., elem] = cursor { @@ -682,7 +677,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, borrow: &BorrowData<'tcx>, - place_span: (&Place<'tcx>, Span), + place_span: (Place<'tcx>, Span), kind: Option, ) { debug!( @@ -967,7 +962,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, borrow: &BorrowData<'tcx>, - (place, drop_span): (&Place<'tcx>, Span), + (place, drop_span): (Place<'tcx>, Span), kind: Option, dropped_ty: Ty<'tcx>, ) { @@ -1379,7 +1374,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed( &mut self, location: Location, - (place, span): (&Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), loan: &BorrowData<'tcx>, ) { let loan_spans = self.retrieve_borrow_spans(loan); @@ -1432,9 +1427,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { pub(in crate::borrow_check) fn report_illegal_reassignment( &mut self, _location: Location, - (place, span): (&Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), assigned_span: Span, - err_place: &Place<'tcx>, + err_place: Place<'tcx>, ) { let (from_arg, local_decl, local_name) = match err_place.as_local() { Some(local) => ( diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index a3ab36b844390..7340e88f19b37 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -286,7 +286,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, location: Location, borrow: &BorrowData<'tcx>, - kind_place: Option<(WriteKind, &Place<'tcx>)>, + kind_place: Option<(WriteKind, Place<'tcx>)>, ) -> BorrowExplanation { debug!( "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})", diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs index 2fe72e1aa086a..35edd3d803db9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs @@ -22,7 +22,7 @@ pub(crate) enum AccessKind { impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { pub(crate) fn report_mutability_error( &mut self, - access_place: &Place<'tcx>, + access_place: Place<'tcx>, span: Span, the_place_err: PlaceRef<'tcx>, error_access: AccessKind, diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index 1639b7262b005..05d21a15a5677 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -56,33 +56,33 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { self.check_activations(location); - match statement.kind { - StatementKind::Assign(box (ref lhs, ref rhs)) => { + match &statement.kind { + StatementKind::Assign(box (lhs, rhs)) => { self.consume_rvalue(location, rhs); - self.mutate_place(location, lhs, Shallow(None), JustWrite); + self.mutate_place(location, *lhs, Shallow(None), JustWrite); } StatementKind::FakeRead(_, _) => { // Only relevant for initialized/liveness/safety checks. } - StatementKind::SetDiscriminant { ref place, variant_index: _ } => { - self.mutate_place(location, place, Shallow(None), JustWrite); + StatementKind::SetDiscriminant { place, variant_index: _ } => { + self.mutate_place(location, **place, Shallow(None), JustWrite); } - StatementKind::LlvmInlineAsm(ref asm) => { + StatementKind::LlvmInlineAsm(asm) => { for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { if o.is_indirect { // FIXME(eddyb) indirect inline asm outputs should // be encoded through MIR place derefs instead. self.access_place( location, - output, + *output, (Deep, Read(ReadKind::Copy)), LocalMutationIsAllowed::No, ); } else { self.mutate_place( location, - output, + *output, if o.is_rw { Deep } else { Shallow(None) }, if o.is_rw { WriteAndRead } else { JustWrite }, ); @@ -102,7 +102,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { StatementKind::StorageDead(local) => { self.access_place( location, - &Place::from(local), + Place::from(*local), (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), LocalMutationIsAllowed::Yes, ); @@ -119,27 +119,27 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => { self.consume_operand(location, discr); } - TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => { + TerminatorKind::Drop { location: drop_place, target: _, unwind: _ } => { self.access_place( location, - drop_place, + *drop_place, (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)), LocalMutationIsAllowed::Yes, ); } TerminatorKind::DropAndReplace { - location: ref drop_place, + location: drop_place, value: ref new_value, target: _, unwind: _, } => { - self.mutate_place(location, drop_place, Deep, JustWrite); + self.mutate_place(location, *drop_place, Deep, JustWrite); self.consume_operand(location, new_value); } TerminatorKind::Call { ref func, ref args, - ref destination, + destination, cleanup: _, from_hir_call: _, } => { @@ -147,8 +147,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { for arg in args { self.consume_operand(location, arg); } - if let Some((ref dest, _ /*bb*/)) = *destination { - self.mutate_place(location, dest, Deep, JustWrite); + if let Some((dest, _ /*bb*/)) = destination { + self.mutate_place(location, *dest, Deep, JustWrite); } } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { @@ -171,7 +171,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } } - self.mutate_place(location, resume_arg, Deep, JustWrite); + self.mutate_place(location, *resume_arg, Deep, JustWrite); } TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => { // Invalidate all borrows of local places @@ -201,7 +201,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { fn mutate_place( &mut self, location: Location, - place: &Place<'tcx>, + place: Place<'tcx>, kind: AccessDepth, _mode: MutateMode, ) { @@ -216,7 +216,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { /// Simulates consumption of an operand. fn consume_operand(&mut self, location: Location, operand: &Operand<'tcx>) { match *operand { - Operand::Copy(ref place) => { + Operand::Copy(place) => { self.access_place( location, place, @@ -224,7 +224,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { LocalMutationIsAllowed::No, ); } - Operand::Move(ref place) => { + Operand::Move(place) => { self.access_place( location, place, @@ -239,7 +239,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { // Simulates consumption of an rvalue fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) { match *rvalue { - Rvalue::Ref(_ /*rgn*/, bk, ref place) => { + Rvalue::Ref(_ /*rgn*/, bk, place) => { let access_kind = match bk { BorrowKind::Shallow => { (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) @@ -258,7 +258,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.access_place(location, place, access_kind, LocalMutationIsAllowed::No); } - Rvalue::AddressOf(mutability, ref place) => { + Rvalue::AddressOf(mutability, place) => { let access_kind = match mutability { Mutability::Mut => ( Deep, @@ -279,7 +279,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, operand) } - Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => { + Rvalue::Len(place) | Rvalue::Discriminant(place) => { let af = match *rvalue { Rvalue::Len(..) => Some(ArtificialField::ArrayLength), Rvalue::Discriminant(..) => None, @@ -313,7 +313,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { fn access_place( &mut self, location: Location, - place: &Place<'tcx>, + place: Place<'tcx>, kind: (AccessDepth, ReadOrWrite), _is_local_mutation_allowed: LocalMutationIsAllowed, ) { @@ -325,7 +325,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { fn check_access_for_conflict( &mut self, location: Location, - place: &Place<'tcx>, + place: Place<'tcx>, sd: AccessDepth, rw: ReadOrWrite, ) { @@ -413,7 +413,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.access_place( location, - &borrow.borrowed_place, + borrow.borrowed_place, (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)), LocalMutationIsAllowed::No, ); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0aeabdb4dca9d..bff39f87c171e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -308,8 +308,7 @@ fn do_mir_borrowck<'a, 'tcx>( // Convert any reservation warnings into lints. let reservation_warnings = mem::take(&mut mbcx.reservation_warnings); for (_, (place, span, location, bk, borrow)) in reservation_warnings { - let mut initial_diag = - mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); + let mut initial_diag = mbcx.report_conflicting_borrow(location, (place, span), bk, &borrow); let scope = mbcx.body.source_info(location).scope; let lint_root = match &mbcx.body.source_scopes[scope].local_data { @@ -523,11 +522,11 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc self.check_activations(location, span, flow_state); - match stmt.kind { - StatementKind::Assign(box (ref lhs, ref rhs)) => { + match &stmt.kind { + StatementKind::Assign(box (lhs, ref rhs)) => { self.consume_rvalue(location, (rhs, span), flow_state); - self.mutate_place(location, (lhs, span), Shallow(None), JustWrite, flow_state); + self.mutate_place(location, (*lhs, span), Shallow(None), JustWrite, flow_state); } StatementKind::FakeRead(_, box ref place) => { // Read for match doesn't access any memory and is used to @@ -547,8 +546,8 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc flow_state, ); } - StatementKind::SetDiscriminant { ref place, variant_index: _ } => { - self.mutate_place(location, (place, span), Shallow(None), JustWrite, flow_state); + StatementKind::SetDiscriminant { place, variant_index: _ } => { + self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state); } StatementKind::LlvmInlineAsm(ref asm) => { for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { @@ -557,7 +556,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc // be encoded through MIR place derefs instead. self.access_place( location, - (output, o.span), + (*output, o.span), (Deep, Read(ReadKind::Copy)), LocalMutationIsAllowed::No, flow_state, @@ -571,7 +570,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc } else { self.mutate_place( location, - (output, o.span), + (*output, o.span), if o.is_rw { Deep } else { Shallow(None) }, if o.is_rw { WriteAndRead } else { JustWrite }, flow_state, @@ -592,7 +591,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc StatementKind::StorageDead(local) => { self.access_place( location, - (&Place::from(local), span), + (Place::from(*local), span), (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), LocalMutationIsAllowed::Yes, flow_state, @@ -638,14 +637,14 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc self.access_place( loc, - (drop_place, span), + (*drop_place, span), (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)), LocalMutationIsAllowed::Yes, flow_state, ); } TerminatorKind::DropAndReplace { - location: ref drop_place, + location: drop_place, value: ref new_value, target: _, unwind: _, @@ -664,7 +663,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc for arg in args { self.consume_operand(loc, (arg, span), flow_state); } - if let Some((ref dest, _ /*bb*/)) = *destination { + if let Some((dest, _ /*bb*/)) = *destination { self.mutate_place(loc, (dest, span), Deep, JustWrite, flow_state); } } @@ -677,7 +676,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc } } - TerminatorKind::Yield { ref value, resume: _, ref resume_arg, drop: _ } => { + TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => { self.consume_operand(loc, (value, span), flow_state); self.mutate_place(loc, (resume_arg, span), Deep, JustWrite, flow_state); } @@ -884,7 +883,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn access_place( &mut self, location: Location, - place_span: (&Place<'tcx>, Span), + place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, flow_state: &Flows<'cx, 'tcx>, @@ -905,7 +904,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Check is_empty() first because it's the common case, and doing that // way we avoid the clone() call. if !self.access_place_error_reported.is_empty() - && self.access_place_error_reported.contains(&(*place_span.0, place_span.1)) + && self.access_place_error_reported.contains(&(place_span.0, place_span.1)) { debug!( "access_place: suppressing error place_span=`{:?}` kind=`{:?}`", @@ -933,14 +932,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if conflict_error || mutability_error { debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind); - self.access_place_error_reported.insert((*place_span.0, place_span.1)); + self.access_place_error_reported.insert((place_span.0, place_span.1)); } } fn check_access_for_conflict( &mut self, location: Location, - place_span: (&Place<'tcx>, Span), + place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, flow_state: &Flows<'cx, 'tcx>, @@ -1043,7 +1042,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // these sepately so that we only emit a warning if borrow // checking was otherwise successful. this.reservation_warnings - .insert(bi, (*place_span.0, place_span.1, location, bk, borrow.clone())); + .insert(bi, (place_span.0, place_span.1, location, bk, borrow.clone())); // Don't suppress actual errors. Control::Continue @@ -1100,7 +1099,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn mutate_place( &mut self, location: Location, - place_span: (&'cx Place<'tcx>, Span), + place_span: (Place<'tcx>, Span), kind: AccessDepth, mode: MutateMode, flow_state: &Flows<'cx, 'tcx>, @@ -1150,7 +1149,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { flow_state: &Flows<'cx, 'tcx>, ) { match *rvalue { - Rvalue::Ref(_ /*rgn*/, bk, ref place) => { + Rvalue::Ref(_ /*rgn*/, bk, place) => { let access_kind = match bk { BorrowKind::Shallow => { (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) @@ -1188,7 +1187,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - Rvalue::AddressOf(mutability, ref place) => { + Rvalue::AddressOf(mutability, place) => { let access_kind = match mutability { Mutability::Mut => ( Deep, @@ -1222,7 +1221,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.consume_operand(location, (operand, span), flow_state) } - Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => { + Rvalue::Len(place) | Rvalue::Discriminant(place) => { let af = match *rvalue { Rvalue::Len(..) => Some(ArtificialField::ArrayLength), Rvalue::Discriminant(..) => None, @@ -1361,7 +1360,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { flow_state: &Flows<'cx, 'tcx>, ) { match *operand { - Operand::Copy(ref place) => { + Operand::Copy(place) => { // copy of place: check if this is "copy of frozen path" // (FIXME: see check_loans.rs) self.access_place( @@ -1380,7 +1379,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { flow_state, ); } - Operand::Move(ref place) => { + Operand::Move(place) => { // move of place: check if this is move of already borrowed path self.access_place( location, @@ -1411,7 +1410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span: Span, ) { debug!("check_for_invalidation_at_exit({:?})", borrow); - let place = &borrow.borrowed_place; + let place = borrow.borrowed_place; let mut root_place = PlaceRef { local: place.local, projection: &[] }; // FIXME(nll-rfc#40): do more precise destructor tracking here. For now @@ -1491,7 +1490,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.access_place( location, - (&borrow.borrowed_place, span), + (borrow.borrowed_place, span), (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)), LocalMutationIsAllowed::No, flow_state, @@ -1506,7 +1505,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &mut self, location: Location, local: Local, - place_span: (&Place<'tcx>, Span), + place_span: (Place<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { debug!("check_if_reassignment_to_immutable_state({:?})", local); @@ -1730,7 +1729,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn check_if_assigned_path_is_moved( &mut self, location: Location, - (place, span): (&'cx Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), flow_state: &Flows<'cx, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); @@ -1903,7 +1902,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Returns `true` if an error is reported. fn check_access_permissions( &mut self, - (place, span): (&Place<'tcx>, Span), + (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, flow_state: &Flows<'cx, 'tcx>, diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index aa5065300eae9..e1cbdc43256ef 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -27,7 +27,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, _location: Location, - access_place: (AccessDepth, &Place<'tcx>), + access_place: (AccessDepth, Place<'tcx>), borrow_set: &BorrowSet<'tcx>, candidates: I, mut op: F, @@ -48,7 +48,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( if places_conflict::borrow_conflicts_with_place( tcx, body, - &borrowed.borrowed_place, + borrowed.borrowed_place, borrowed.kind, place.as_ref(), access, diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 876c9728d0055..d48df6a91095e 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -24,8 +24,8 @@ crate enum PlaceConflictBias { crate fn places_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - borrow_place: &Place<'tcx>, - access_place: &Place<'tcx>, + borrow_place: Place<'tcx>, + access_place: Place<'tcx>, bias: PlaceConflictBias, ) -> bool { borrow_conflicts_with_place( @@ -46,7 +46,7 @@ crate fn places_conflict<'tcx>( pub(super) fn borrow_conflicts_with_place<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - borrow_place: &Place<'tcx>, + borrow_place: Place<'tcx>, borrow_kind: BorrowKind, access_place: PlaceRef<'tcx>, access: AccessDepth, @@ -71,7 +71,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>( fn place_components_conflict<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - borrow_place: &Place<'tcx>, + borrow_place: Place<'tcx>, borrow_kind: BorrowKind, access_place: PlaceRef<'tcx>, access: AccessDepth, diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 6f35d9ac83636..43f985946aaac 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -187,7 +187,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { } /// Kill any borrows that conflict with `place`. - fn kill_borrows_on_place(&self, trans: &mut impl GenKill, place: &Place<'tcx>) { + fn kill_borrows_on_place(&self, trans: &mut impl GenKill, place: Place<'tcx>) { debug!("kill_borrows_on_place: place={:?}", place); let other_borrows_of_local = self @@ -216,7 +216,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { places_conflict( self.tcx, self.body, - &self.borrow_set.borrows[i].borrowed_place, + self.borrow_set.borrows[i].borrowed_place, place, PlaceConflictBias::NoOverlap, ) @@ -262,8 +262,8 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { location: Location, ) { match stmt.kind { - mir::StatementKind::Assign(box (ref lhs, ref rhs)) => { - if let mir::Rvalue::Ref(_, _, ref place) = *rhs { + mir::StatementKind::Assign(box (lhs, ref rhs)) => { + if let mir::Rvalue::Ref(_, _, place) = *rhs { if place.ignore_borrow( self.tcx, self.body, @@ -286,13 +286,13 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { mir::StatementKind::StorageDead(local) => { // Make sure there are no remaining borrows for locals that // are gone out of scope. - self.kill_borrows_on_place(trans, &Place::from(local)); + self.kill_borrows_on_place(trans, Place::from(local)); } mir::StatementKind::LlvmInlineAsm(ref asm) => { for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { if !kind.is_indirect && !kind.is_rw { - self.kill_borrows_on_place(trans, output); + self.kill_borrows_on_place(trans, *output); } } } From f026441e322277fc2cdd9360598c62966293ff1c Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 17:55:22 -0300 Subject: [PATCH 15/33] Use Place directly on propagate_closure_used_mut_place, it's Copy --- src/librustc_mir/borrow_check/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index bff39f87c171e..89663661a8f69 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1282,7 +1282,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) { - let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| { + let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| { if !place.projection.is_empty() { if let Some(field) = this.is_upvar_field_projection(place.as_ref()) { this.used_mut_upvars.push(field); @@ -1296,7 +1296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // captures of a closure are copied/moved directly // when generating MIR. match *operand { - Operand::Move(ref place) | Operand::Copy(ref place) => { + Operand::Move(place) | Operand::Copy(place) => { match place.as_local() { Some(local) if !self.body.local_decls[local].is_user_variable() => { if self.body.local_decls[local].ty.is_mutable_ptr() { @@ -1335,8 +1335,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let stmt = &bbd.statements[loc.statement_index]; debug!("temporary assigned in: stmt={:?}", stmt); - if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, ref source))) = - stmt.kind + if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, source))) = stmt.kind { propagate_closure_used_mut_place(self, source); } else { From a67b28a96e72ff81e61235b16f2d218f73a1abe8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 18:51:48 -0300 Subject: [PATCH 16/33] Use Place directly on borrow_of_local_data, it's Copy --- src/librustc_mir/borrow_check/invalidation.rs | 4 ++-- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/borrow_check/path_utils.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index 05d21a15a5677..318751113b283 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -166,7 +166,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { let borrow_set = self.borrow_set.clone(); let resume = self.location_table.start_index(resume.start_location()); for i in borrow_set.borrows.indices() { - if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) { + if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) { self.all_facts.invalidates.push((resume, i)); } } @@ -178,7 +178,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { let borrow_set = self.borrow_set.clone(); let start = self.location_table.start_index(location); for i in borrow_set.borrows.indices() { - if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) { + if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) { self.all_facts.invalidates.push((start, i)); } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 89663661a8f69..52847af214f6c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1463,7 +1463,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) { debug!("check_for_local_borrow({:?})", borrow); - if borrow_of_local_data(&borrow.borrowed_place) { + if borrow_of_local_data(borrow.borrowed_place) { let err = self.cannot_borrow_across_generator_yield( self.retrieve_borrow_spans(borrow).var_or_use(), yield_span, diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index e1cbdc43256ef..f5238e7b7bedc 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -130,7 +130,7 @@ pub(super) fn is_active<'tcx>( /// Determines if a given borrow is borrowing local data /// This is called for all Yield expressions on movable generators -pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { +pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool { // Reborrow of already borrowed data is ignored // Any errors will be caught on the initial borrow !place.is_indirect() From 32a761809b5fee909a146b0bca34057e73c0c2b3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 19:18:54 -0300 Subject: [PATCH 17/33] Use Place directly on remove_never_initialized_mut_locals, it's Copy --- src/librustc_mir/borrow_check/used_muts.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index eb1527b874ebe..2da72f3bcc517 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -51,7 +51,7 @@ struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { } impl GatherUsedMutsVisitor<'_, '_, '_> { - fn remove_never_initialized_mut_locals(&mut self, into: &Place<'_>) { + fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) { // Remove any locals that we found were initialized from the // `never_initialized_mut_locals` set. At the end, the only remaining locals will // be those that were never initialized - we will consider those as being used as @@ -66,10 +66,10 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc debug!("visit_terminator_kind: kind={:?}", kind); match &kind { TerminatorKind::Call { destination: Some((into, _)), .. } => { - self.remove_never_initialized_mut_locals(&into); + self.remove_never_initialized_mut_locals(*into); } TerminatorKind::DropAndReplace { location, .. } => { - self.remove_never_initialized_mut_locals(&location); + self.remove_never_initialized_mut_locals(*location); } _ => {} } @@ -82,7 +82,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc never_initialized_mut_locals={:?}", statement, into.local, self.never_initialized_mut_locals ); - self.remove_never_initialized_mut_locals(into); + self.remove_never_initialized_mut_locals(*into); } } From 760bca4f5ba4fb717ff666da37f36c28f0219879 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 19:22:12 -0300 Subject: [PATCH 18/33] Use Place directly on check_mut_borrowing_layout_constrained_field, it's Copy --- src/librustc_mir/transform/check_unsafety.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index e0ff82b1e64f1..2367e83008ca5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -184,7 +184,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { // because either of these would allow modifying the layout constrained field and // insert values that violate the layout constraints. if context.is_mutating_use() || context.is_borrow() { - self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use()); + self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use()); } for (i, elem) in place.projection.iter().enumerate() { @@ -382,7 +382,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } fn check_mut_borrowing_layout_constrained_field( &mut self, - place: &Place<'tcx>, + place: Place<'tcx>, is_mut_use: bool, ) { let mut cursor = place.projection.as_ref(); From 25528c1e2826f895b6b6485f93de0477d79af8ea Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 30 Mar 2020 20:25:43 -0300 Subject: [PATCH 19/33] Use Place directly, it's Copy more use cases --- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/elaborate_drops.rs | 10 ++--- src/librustc_mir/transform/generator.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 39 +++++++++---------- 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 98a95801f1b40..0a998bbfe7068 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -230,7 +230,7 @@ fn build_drop_shim<'tcx>( elaborate_drops::elaborate_drop( &mut elaborator, source_info, - &dropee, + dropee, (), return_block, elaborate_drops::Unwind::To(resume_block), diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index fc382312aeb50..d3971c9a45cae 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -346,7 +346,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let resume_block = self.patch.resume_block(); match terminator.kind { - TerminatorKind::Drop { ref location, target, unwind } => { + TerminatorKind::Drop { location, target, unwind } => { self.init_data.seek_before(loc); match self.move_data().rev_lookup.find(location.as_ref()) { LookupResult::Exact(path) => elaborate_drop( @@ -371,7 +371,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } } } - TerminatorKind::DropAndReplace { ref location, ref value, target, unwind } => { + TerminatorKind::DropAndReplace { location, ref value, target, unwind } => { assert!(!data.is_cleanup); self.elaborate_replace(loc, location, value, target, unwind); @@ -396,7 +396,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn elaborate_replace( &mut self, loc: Location, - location: &Place<'tcx>, + location: Place<'tcx>, value: &Operand<'tcx>, target: BasicBlock, unwind: Option, @@ -407,7 +407,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported"); let assign = Statement { - kind: StatementKind::Assign(box (*location, Rvalue::Use(value.clone()))), + kind: StatementKind::Assign(box (location, Rvalue::Use(value.clone()))), source_info: terminator.source_info, }; @@ -459,7 +459,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent); self.patch.patch_terminator( bb, - TerminatorKind::Drop { location: *location, target, unwind: Some(unwind) }, + TerminatorKind::Drop { location, target, unwind: Some(unwind) }, ); } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 230a835b910d2..390d927a85471 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -853,7 +853,7 @@ fn elaborate_generator_drops<'tcx>( elaborate_drop( &mut elaborator, *source_info, - &Place::from(SELF_ARG), + Place::from(SELF_ARG), (), *target, unwind, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 7063ed1edc822..1d682b32b192d 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -100,7 +100,7 @@ where source_info: SourceInfo, - place: &'l Place<'tcx>, + place: Place<'tcx>, path: D::Path, succ: BasicBlock, unwind: Unwind, @@ -109,7 +109,7 @@ where pub fn elaborate_drop<'b, 'tcx, D>( elaborator: &mut D, source_info: SourceInfo, - place: &Place<'tcx>, + place: Place<'tcx>, path: D::Path, succ: BasicBlock, unwind: Unwind, @@ -126,7 +126,7 @@ where D: DropElaborator<'b, 'tcx>, 'tcx: 'b, { - fn place_ty(&self, place: &Place<'tcx>) -> Ty<'tcx> { + fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> { place.ty(self.elaborator.body(), self.tcx()).ty } @@ -168,7 +168,7 @@ where self.elaborator.patch().patch_terminator( bb, TerminatorKind::Drop { - location: *self.place, + location: self.place, target: self.succ, unwind: self.unwind.into_option(), }, @@ -195,7 +195,7 @@ where /// (the move path is `None` if the field is a rest field). fn move_paths_for_fields( &self, - base_place: &Place<'tcx>, + base_place: Place<'tcx>, variant_path: D::Path, variant: &'tcx ty::VariantDef, substs: SubstsRef<'tcx>, @@ -219,7 +219,7 @@ where fn drop_subpath( &mut self, - place: &Place<'tcx>, + place: Place<'tcx>, path: Option, succ: BasicBlock, unwind: Unwind, @@ -267,12 +267,10 @@ where ) -> Vec { Some(succ) .into_iter() - .chain(fields.iter().rev().zip(unwind_ladder).map( - |(&(ref place, path), &unwind_succ)| { - succ = self.drop_subpath(place, path, succ, unwind_succ); - succ - }, - )) + .chain(fields.iter().rev().zip(unwind_ladder).map(|(&(place, path), &unwind_succ)| { + succ = self.drop_subpath(place, path, succ, unwind_succ); + succ + })) .collect() } @@ -315,7 +313,7 @@ where debug!("drop_ladder({:?}, {:?})", self, fields); let mut fields = fields; - fields.retain(|&(ref place, _)| { + fields.retain(|&(place, _)| { self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env()) }); @@ -364,7 +362,7 @@ where let unwind_succ = self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup)); - self.drop_subpath(&interior, interior_path, succ, unwind_succ) + self.drop_subpath(interior, interior_path, succ, unwind_succ) } fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock { @@ -439,8 +437,7 @@ where self.place.clone(), ProjectionElem::Downcast(Some(variant.ident.name), variant_index), ); - let fields = - self.move_paths_for_fields(&base_place, variant_path, &variant, substs); + let fields = self.move_paths_for_fields(base_place, variant_path, &variant, substs); values.push(discr.val); if let Unwind::To(unwind) = unwind { // We can't use the half-ladder from the original @@ -527,7 +524,7 @@ where // way lies only trouble. let discr_ty = adt.repr.discr_type().to_ty(self.tcx()); let discr = Place::from(self.new_temp(discr_ty)); - let discr_rv = Rvalue::Discriminant(*self.place); + let discr_rv = Rvalue::Discriminant(self.place); let switch_block = BasicBlockData { statements: vec![self.assign(&discr, discr_rv)], terminator: Some(Terminator { @@ -564,7 +561,7 @@ where Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, - *self.place, + self.place, ), )], terminator: Some(Terminator { @@ -712,7 +709,7 @@ where let base_block = BasicBlockData { statements: vec![ self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)), - self.assign(len, Rvalue::Len(*self.place)), + self.assign(len, Rvalue::Len(self.place)), ], is_cleanup: self.unwind.is_cleanup(), terminator: Some(Terminator { @@ -761,7 +758,7 @@ where // cur = tmp as *mut T; // end = Offset(cur, len); vec![ - self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, *self.place)), + self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, self.place)), self.assign(&cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)), self.assign( &length_or_end, @@ -935,7 +932,7 @@ where fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock { let block = - TerminatorKind::Drop { location: *self.place, target, unwind: unwind.into_option() }; + TerminatorKind::Drop { location: self.place, target, unwind: unwind.into_option() }; self.new_block(unwind, block) } From 890b39381f587169c0684831ff04f9d8602ea95a Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 12:19:29 -0300 Subject: [PATCH 20/33] Use Place directly, it's Copy even more use cases --- .../diagnostics/conflict_errors.rs | 24 ++++++------ .../borrow_check/diagnostics/move_errors.rs | 28 +++++++------- .../dataflow/impls/borrowed_locals.rs | 18 ++++----- .../dataflow/move_paths/builder.rs | 38 +++++++++---------- src/librustc_mir/interpret/operand.rs | 4 +- src/librustc_mir/interpret/place.rs | 2 +- src/librustc_mir/interpret/step.rs | 28 +++++++------- src/librustc_mir/interpret/terminator.rs | 10 ++--- .../transform/add_moves_for_packed_drops.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 8 ++-- src/librustc_mir/transform/copy_prop.rs | 7 ++-- src/librustc_mir/transform/inline.rs | 4 +- .../transform/qualify_min_const_fn.rs | 18 +++++---- src/librustc_mir/transform/simplify_try.rs | 6 +-- src/librustc_mir/util/alignment.rs | 4 +- src/librustc_mir/util/elaborate_drops.rs | 36 +++++++++--------- 17 files changed, 120 insertions(+), 119 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 563dfe3544e7d..9df5760563129 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -396,8 +396,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); self.suggest_split_at_mut_if_applicable( &mut err, - &place, - &issued_borrow.borrowed_place, + place, + issued_borrow.borrowed_place, ); err } @@ -410,7 +410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (BorrowKind::Mut { .. }, BorrowKind::Shallow) | (BorrowKind::Unique, BorrowKind::Shallow) => { if let Some(immutable_section_description) = - self.classify_immutable_section(&issued_borrow.assigned_place) + self.classify_immutable_section(issued_borrow.assigned_place) { let mut err = self.cannot_mutate_in_immutable_section( span, @@ -546,8 +546,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn suggest_split_at_mut_if_applicable( &self, err: &mut DiagnosticBuilder<'_>, - place: &Place<'tcx>, - borrowed_place: &Place<'tcx>, + place: Place<'tcx>, + borrowed_place: Place<'tcx>, ) { if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) = (&place.projection[..], &borrowed_place.projection[..]) @@ -1382,7 +1382,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let descr_place = self.describe_any_place(place.as_ref()); if loan.kind == BorrowKind::Shallow { - if let Some(section) = self.classify_immutable_section(&loan.assigned_place) { + if let Some(section) = self.classify_immutable_section(loan.assigned_place) { let mut err = self.cannot_mutate_in_immutable_section( span, loan_span, @@ -1534,17 +1534,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } /// Describe the reason for the fake borrow that was assigned to `place`. - fn classify_immutable_section(&self, place: &Place<'tcx>) -> Option<&'static str> { + fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str> { use rustc_middle::mir::visit::Visitor; - struct FakeReadCauseFinder<'a, 'tcx> { - place: &'a Place<'tcx>, + struct FakeReadCauseFinder<'tcx> { + place: Place<'tcx>, cause: Option, } - impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> { + impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { match statement { - Statement { kind: StatementKind::FakeRead(cause, box ref place), .. } - if *place == *self.place => + Statement { kind: StatementKind::FakeRead(cause, box place), .. } + if *place == self.place => { self.cause = Some(*cause); } diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index 3c198dc74ce85..d32533b6ce9a1 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // whether or not the right-hand side is a place expression if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( VarBindingForm { - opt_match_place: Some((ref opt_match_place, match_span)), + opt_match_place: Some((opt_match_place, match_span)), binding_mode: _, opt_ty_info: _, pat_span: _, @@ -117,7 +117,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { grouped_errors, kind, original_path, - move_from, + *move_from, local, opt_match_place, match_span, @@ -143,16 +143,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { grouped_errors: &mut Vec>, kind: IllegalMoveOriginKind<'tcx>, original_path: Place<'tcx>, - move_from: &Place<'tcx>, + move_from: Place<'tcx>, bind_to: Local, - match_place: &Option>, + match_place: Option>, match_span: Span, statement_span: Span, ) { debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span); let from_simple_let = match_place.is_none(); - let match_place = match_place.as_ref().unwrap_or(move_from); + let match_place = match_place.unwrap_or(move_from); match self.move_data.rev_lookup.find(match_place.as_ref()) { // Error with the match place @@ -178,7 +178,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; grouped_errors.push(GroupedMoveError::MovesFromPlace { span, - move_from: *match_place, + move_from, original_path, kind, binds_to, @@ -223,14 +223,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let (span, use_spans, original_path, kind): ( Span, Option, - &Place<'tcx>, + Place<'tcx>, &IllegalMoveOriginKind<'_>, ) = match error { - GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } - | GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => { + GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. } + | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => { (span, None, original_path, kind) } - GroupedMoveError::OtherIllegalMove { use_spans, ref original_path, ref kind } => { + GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => { (use_spans.args_or_use(), Some(use_spans), original_path, kind) } }; @@ -247,7 +247,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { IllegalMoveOriginKind::BorrowedContent { target_place } => self .report_cannot_move_from_borrowed_content( original_path, - target_place, + *target_place, span, use_spans, ), @@ -268,7 +268,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn report_cannot_move_from_static( &mut self, - place: &Place<'tcx>, + place: Place<'tcx>, span: Span, ) -> DiagnosticBuilder<'a> { let description = if place.projection.len() == 1 { @@ -288,8 +288,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn report_cannot_move_from_borrowed_content( &mut self, - move_place: &Place<'tcx>, - deref_target_place: &Place<'tcx>, + move_place: Place<'tcx>, + deref_target_place: Place<'tcx>, span: Span, use_spans: Option, ) -> DiagnosticBuilder<'a> { diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index a62e45082cb8a..273878ea275c3 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -160,13 +160,13 @@ where match rvalue { mir::Rvalue::AddressOf(mt, borrowed_place) => { - if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, borrowed_place) { + if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) { self.trans.gen(borrowed_place.local); } } mir::Rvalue::Ref(_, kind, borrowed_place) => { - if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, borrowed_place) { + if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) { self.trans.gen(borrowed_place.local); } } @@ -230,7 +230,7 @@ impl MutBorrow<'mir, 'tcx> { /// below. See [rust-lang/unsafe-code-guidelines#134]. /// /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134 - fn shared_borrow_allows_mutation(&self, place: &Place<'tcx>) -> bool { + fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool { !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) } } @@ -238,17 +238,17 @@ impl MutBorrow<'mir, 'tcx> { pub trait BorrowAnalysisKind<'tcx> { const ANALYSIS_NAME: &'static str; - fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool; - fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool; + fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool; + fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool; } impl BorrowAnalysisKind<'tcx> for AnyBorrow { const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals"; - fn in_ref(&self, _: mir::BorrowKind, _: &Place<'_>) -> bool { + fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool { true } - fn in_address_of(&self, _: Mutability, _: &Place<'_>) -> bool { + fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool { true } } @@ -256,7 +256,7 @@ impl BorrowAnalysisKind<'tcx> for AnyBorrow { impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> { const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals"; - fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool { + fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool { match kind { mir::BorrowKind::Mut { .. } => true, mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => { @@ -265,7 +265,7 @@ impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> { } } - fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool { + fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool { match mt { Mutability::Mut => true, Mutability::Not => self.shared_borrow_allows_mutation(place), diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 1f4455318a4cf..fabe575c28904 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -94,7 +94,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { /// problematic for borrowck. /// /// Maybe we should have separate "borrowck" and "moveck" modes. - fn move_path_for(&mut self, place: &Place<'tcx>) -> Result> { + fn move_path_for(&mut self, place: Place<'tcx>) -> Result> { debug!("lookup({:?})", place); let mut base = self.builder.data.rev_lookup.locals[place.local]; @@ -195,7 +195,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }) } - fn create_move_path(&mut self, place: &Place<'tcx>) { + fn create_move_path(&mut self, place: Place<'tcx>) { // This is an non-moving access (such as an overwrite or // drop), so this not being a valid move path is OK. let _ = self.move_path_for(place); @@ -279,22 +279,22 @@ struct Gatherer<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_statement(&mut self, stmt: &Statement<'tcx>) { - match stmt.kind { - StatementKind::Assign(box (ref place, ref rval)) => { - self.create_move_path(place); + match &stmt.kind { + StatementKind::Assign(box (place, rval)) => { + self.create_move_path(*place); if let RvalueInitializationState::Shallow = rval.initialization_state() { // Box starts out uninitialized - need to create a separate // move-path for the interior so it will be separate from // the exterior. - self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone())); + self.create_move_path(self.builder.tcx.mk_place_deref(place.clone())); self.gather_init(place.as_ref(), InitKind::Shallow); } else { self.gather_init(place.as_ref(), InitKind::Deep); } self.gather_rvalue(rval); } - StatementKind::FakeRead(_, ref place) => { - self.create_move_path(place); + StatementKind::FakeRead(_, place) => { + self.create_move_path(**place); } StatementKind::LlvmInlineAsm(ref asm) => { for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { @@ -308,7 +308,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } StatementKind::StorageLive(_) => {} StatementKind::StorageDead(local) => { - self.gather_move(&Place::from(local)); + self.gather_move(Place::from(*local)); } StatementKind::SetDiscriminant { .. } => { span_bug!( @@ -369,7 +369,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { | TerminatorKind::Unreachable => {} TerminatorKind::Return => { - self.gather_move(&Place::return_place()); + self.gather_move(Place::return_place()); } TerminatorKind::Assert { ref cond, .. } => { @@ -380,16 +380,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.gather_operand(discr); } - TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => { + TerminatorKind::Yield { ref value, resume_arg: place, .. } => { self.gather_operand(value); self.create_move_path(place); self.gather_init(place.as_ref(), InitKind::Deep); } - TerminatorKind::Drop { ref location, target: _, unwind: _ } => { + TerminatorKind::Drop { location, target: _, unwind: _ } => { self.gather_move(location); } - TerminatorKind::DropAndReplace { ref location, ref value, .. } => { + TerminatorKind::DropAndReplace { location, ref value, .. } => { self.create_move_path(location); self.gather_operand(value); self.gather_init(location.as_ref(), InitKind::Deep); @@ -405,7 +405,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { for arg in args { self.gather_operand(arg); } - if let Some((ref destination, _bb)) = *destination { + if let Some((destination, _bb)) = *destination { self.create_move_path(destination); self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly); } @@ -416,14 +416,14 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_operand(&mut self, operand: &Operand<'tcx>) { match *operand { Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move - Operand::Move(ref place) => { + Operand::Move(place) => { // a move self.gather_move(place); } } } - fn gather_move(&mut self, place: &Place<'tcx>) { + fn gather_move(&mut self, place: Place<'tcx>) { debug!("gather_move({:?}, {:?})", self.loc, place); if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] = @@ -434,7 +434,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // are disjoint, which is expected by drop elaboration. let base_place = Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) }; - let base_path = match self.move_path_for(&base_place) { + let base_path = match self.move_path_for(base_place) { Ok(path) => path, Err(MoveError::UnionMove { path }) => { self.record_move(place, path); @@ -467,13 +467,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { match self.move_path_for(place) { Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path), Err(error @ MoveError::IllegalMove { .. }) => { - self.builder.errors.push((*place, error)); + self.builder.errors.push((place, error)); } }; } } - fn record_move(&mut self, place: &Place<'tcx>, path: MovePathIndex) { + fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) { let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc }); debug!( "gather_move({:?}, {:?}): adding move {:?} of {:?}", diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 24639fece46be..7191198b6c0ee 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -464,7 +464,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // avoid allocations. pub fn eval_place_to_op( &self, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { let base_op = match place.local { @@ -498,7 +498,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { use rustc_middle::mir::Operand::*; let op = match *mir_op { // FIXME: do some more logic on `move` to invalidate the old location - Copy(ref place) | Move(ref place) => self.eval_place_to_op(place, layout)?, + Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?, Constant(ref constant) => { let val = diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index f7c1a3cadb881..5c4915d54b037 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -635,7 +635,7 @@ where /// place; for reading, a more efficient alternative is `eval_place_for_read`. pub fn eval_place( &mut self, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> { let mut place_ty = match place.local { mir::RETURN_PLACE => { diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 5fb0a081648e8..961b0f4d189f8 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -87,23 +87,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.tcx.span = stmt.source_info.span; self.memory.tcx.span = stmt.source_info.span; - match stmt.kind { - Assign(box (ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?, + match &stmt.kind { + Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?, - SetDiscriminant { ref place, variant_index } => { - let dest = self.eval_place(place)?; - self.write_discriminant_index(variant_index, dest)?; + SetDiscriminant { place, variant_index } => { + let dest = self.eval_place(**place)?; + self.write_discriminant_index(*variant_index, dest)?; } // Mark locals as alive StorageLive(local) => { - let old_val = self.storage_live(local)?; + let old_val = self.storage_live(*local)?; self.deallocate_local(old_val)?; } // Mark locals as dead StorageDead(local) => { - let old_val = self.storage_dead(local); + let old_val = self.storage_dead(*local); self.deallocate_local(old_val)?; } @@ -112,9 +112,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { FakeRead(..) => {} // Stacked Borrows. - Retag(kind, ref place) => { - let dest = self.eval_place(place)?; - M::retag(self, kind, dest)?; + Retag(kind, place) => { + let dest = self.eval_place(**place)?; + M::retag(self, *kind, dest)?; } // Statements we do not track. @@ -138,7 +138,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn eval_rvalue_into_place( &mut self, rvalue: &mir::Rvalue<'tcx>, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, ) -> InterpResult<'tcx> { let dest = self.eval_place(place)?; @@ -224,7 +224,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - Len(ref place) => { + Len(place) => { // FIXME(CTFE): don't allow computing the length of arrays in const eval let src = self.eval_place(place)?; let mplace = self.force_allocation(src)?; @@ -232,7 +232,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(Scalar::from_machine_usize(len, self), dest)?; } - AddressOf(_, ref place) | Ref(_, _, ref place) => { + AddressOf(_, place) | Ref(_, _, place) => { let src = self.eval_place(place)?; let place = self.force_allocation(src)?; if place.layout.size.bytes() > 0 { @@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.cast(src, kind, dest)?; } - Discriminant(ref place) => { + Discriminant(place) => { let op = self.eval_place_to_op(place, None)?; let discr_val = self.read_discriminant(op)?.0; let size = dest.layout.size; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 8e7abcd09c233..0c2aa28d8118d 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -51,7 +51,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.go_to_block(target_block); } - Call { ref func, ref args, ref destination, ref cleanup, .. } => { + Call { ref func, ref args, destination, ref cleanup, .. } => { let func = self.eval_operand(func, None)?; let (fn_val, abi) = match func.layout.ty.kind { ty::FnPtr(sig) => { @@ -68,7 +68,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let args = self.eval_operands(args)?; let ret = match destination { - Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)), + Some((dest, ret)) => Some((self.eval_place(dest)?, ret)), None => None, }; self.eval_fn_call( @@ -81,7 +81,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )?; } - Drop { ref location, target, unwind } => { + Drop { location, target, unwind } => { // FIXME(CTFE): forbid drop in const eval let place = self.eval_place(location)?; let ty = place.layout.ty; @@ -328,7 +328,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // `pass_argument` would be the loop body. It takes care to // not advance `caller_iter` for ZSTs. for local in body.args_iter() { - let dest = self.eval_place(&mir::Place::from(local))?; + let dest = self.eval_place(mir::Place::from(local))?; if Some(local) == body.spread_arg { // Must be a tuple for i in 0..dest.layout.fields.count() { @@ -346,7 +346,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Don't forget to check the return type! if let Some((caller_ret, _)) = ret { - let callee_ret = self.eval_place(&mir::Place::return_place())?; + let callee_ret = self.eval_place(mir::Place::return_place())?; if !Self::check_argument_compat( rust_abi, caller_ret.layout, diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 98a148d60ba37..7c46855dfd63c 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -68,7 +68,7 @@ fn add_moves_for_packed_drops_patch<'tcx>( let terminator = data.terminator(); match terminator.kind { - TerminatorKind::Drop { ref location, .. } + TerminatorKind::Drop { location, .. } if util::is_disaligned(tcx, body, param_env, location) => { add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup); diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 2367e83008ca5..3ce9b875e16cc 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -191,7 +191,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let proj_base = &place.projection[..i]; if context.is_borrow() { - if util::is_disaligned(self.tcx, self.body, self.param_env, place) { + if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { let source_info = self.source_info; let lint_root = self.body.source_scopes[source_info.scope] .local_data diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 8e004e45b7a3a..3ee97bf8d56cf 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -471,7 +471,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn eval_place(&mut self, place: &Place<'tcx>) -> Option> { + fn eval_place(&mut self, place: Place<'tcx>) -> Option> { trace!("eval_place(place={:?})", place); self.use_ecx(|this| this.ecx.eval_place_to_op(place, None)) } @@ -479,7 +479,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { Operand::Constant(ref c) => self.eval_constant(c, source_info), - Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place), + Operand::Move(place) | Operand::Copy(place) => self.eval_place(place), } } @@ -575,7 +575,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { rvalue: &Rvalue<'tcx>, place_layout: TyAndLayout<'tcx>, source_info: SourceInfo, - place: &Place<'tcx>, + place: Place<'tcx>, ) -> Option<()> { // #66397: Don't try to eval into large places as that can cause an OOM if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) { @@ -828,7 +828,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { trace!("visit_statement: {:?}", statement); let source_info = statement.source_info; self.source_info = Some(source_info); - if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind { + if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind { let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty; if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { if let Some(local) = place.as_local() { diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 76cbe5a1d458a..a25b554b345eb 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -97,9 +97,8 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { if let Some(local) = place.as_local() { if local == dest_local { let maybe_action = match operand { - Operand::Copy(ref src_place) - | Operand::Move(ref src_place) => { - Action::local_copy(&body, &def_use_analysis, src_place) + Operand::Copy(src_place) | Operand::Move(src_place) => { + Action::local_copy(&body, &def_use_analysis, *src_place) } Operand::Constant(ref src_constant) => { Action::constant(src_constant) @@ -195,7 +194,7 @@ impl<'tcx> Action<'tcx> { fn local_copy( body: &Body<'tcx>, def_use_analysis: &DefUseAnalysis, - src_place: &Place<'tcx>, + src_place: Place<'tcx>, ) -> Option> { // The source must be a local. let src_local = if let Some(local) = src_place.as_local() { diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 2c27d4c0d2786..157dada831a2e 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -450,7 +450,7 @@ impl Inliner<'tcx> { // Place could result in two different locations if `f` // writes to `i`. To prevent this we need to create a temporary // borrow of the place and pass the destination as `*temp` instead. - fn dest_needs_borrow(place: &Place<'_>) -> bool { + fn dest_needs_borrow(place: Place<'_>) -> bool { for elem in place.projection.iter() { match elem { ProjectionElem::Deref | ProjectionElem::Index(_) => return true, @@ -461,7 +461,7 @@ impl Inliner<'tcx> { false } - let dest = if dest_needs_borrow(&destination.0) { + let dest = if dest_needs_borrow(destination.0) { debug!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 31ffed4cb7b27..c5b366ef57251 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -150,7 +150,7 @@ fn check_rvalue( Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) - | Rvalue::AddressOf(_, place) => check_place(tcx, place, span, def_id, body), + | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body), Rvalue::Cast(CastKind::Misc, operand, cast_ty) => { use rustc_middle::ty::cast::CastTy; let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast"); @@ -215,7 +215,7 @@ fn check_statement( let span = statement.source_info.span; match &statement.kind { StatementKind::Assign(box (place, rval)) => { - check_place(tcx, place, span, def_id, body)?; + check_place(tcx, *place, span, def_id, body)?; check_rvalue(tcx, body, def_id, rval, span) } @@ -225,10 +225,12 @@ fn check_statement( Err((span, "loops and conditional expressions are not stable in const fn".into())) } - StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body), + StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body), // just an assignment - StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body), + StatementKind::SetDiscriminant { place, .. } => { + check_place(tcx, **place, span, def_id, body) + } StatementKind::LlvmInlineAsm { .. } => { Err((span, "cannot use inline assembly in const fn".into())) @@ -251,7 +253,7 @@ fn check_operand( body: &Body<'tcx>, ) -> McfResult { match operand { - Operand::Move(place) | Operand::Copy(place) => check_place(tcx, place, span, def_id, body), + Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body), Operand::Constant(c) => match c.check_static_ptr(tcx) { Some(_) => Err((span, "cannot access `static` items in const fn".into())), None => Ok(()), @@ -261,7 +263,7 @@ fn check_operand( fn check_place( tcx: TyCtxt<'tcx>, - place: &Place<'tcx>, + place: Place<'tcx>, span: Span, def_id: DefId, body: &Body<'tcx>, @@ -330,9 +332,9 @@ fn check_terminator( | TerminatorKind::Return | TerminatorKind::Resume => Ok(()), - TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body), + TerminatorKind::Drop { location, .. } => check_place(tcx, *location, span, def_id, body), TerminatorKind::DropAndReplace { location, value, .. } => { - check_place(tcx, location, span, def_id, body)?; + check_place(tcx, *location, span, def_id, body)?; check_operand(tcx, value, span, def_id, body) } diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs index fecaee44765fc..7cdd929c7a033 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/src/librustc_mir/transform/simplify_try.rs @@ -89,7 +89,7 @@ fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from { Rvalue::Use(Operand::Copy(pf)) | Rvalue::Use(Operand::Move(pf)) => { let local_into = place_into.as_local()?; - let (local_from, vf) = match_variant_field_place(&pf)?; + let (local_from, vf) = match_variant_field_place(*pf)?; Some((local_into, local_from, vf)) } _ => None, @@ -107,7 +107,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local StatementKind::Assign(box (place_from, rvalue_into)) => match rvalue_into { Rvalue::Use(Operand::Move(place_into)) => { let local_into = place_into.as_local()?; - let (local_from, vf) = match_variant_field_place(&place_from)?; + let (local_from, vf) = match_variant_field_place(*place_from)?; Some((local_into, local_from, vf)) } _ => None, @@ -137,7 +137,7 @@ struct VarField<'tcx> { } /// Match on `((_LOCAL as Variant).FIELD: TY)`. -fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> { +fn match_variant_field_place<'tcx>(place: Place<'tcx>) -> Option<(Local, VarField<'tcx>)> { match place.as_ref() { PlaceRef { local, diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 19c2cfa3a6a4f..202e5e27f1d94 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -8,7 +8,7 @@ pub fn is_disaligned<'tcx, L>( tcx: TyCtxt<'tcx>, local_decls: &L, param_env: ty::ParamEnv<'tcx>, - place: &Place<'tcx>, + place: Place<'tcx>, ) -> bool where L: HasLocalDecls<'tcx>, @@ -34,7 +34,7 @@ where } } -fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'tcx>) -> bool +fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool where L: HasLocalDecls<'tcx>, { diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 1d682b32b192d..f6d67abcef041 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -526,7 +526,7 @@ where let discr = Place::from(self.new_temp(discr_ty)); let discr_rv = Rvalue::Discriminant(self.place); let switch_block = BasicBlockData { - statements: vec![self.assign(&discr, discr_rv)], + statements: vec![self.assign(discr, discr_rv)], terminator: Some(Terminator { source_info: self.source_info, kind: TerminatorKind::SwitchInt { @@ -557,7 +557,7 @@ where let result = BasicBlockData { statements: vec![self.assign( - &Place::from(ref_place), + Place::from(ref_place), Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, @@ -604,7 +604,7 @@ where &mut self, succ: BasicBlock, cur: Local, - length_or_end: &Place<'tcx>, + length_or_end: Place<'tcx>, ety: Ty<'tcx>, unwind: Unwind, ptr_based: bool, @@ -614,7 +614,7 @@ where let tcx = self.tcx(); let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut }); - let ptr = &Place::from(self.new_temp(ptr_ty)); + let ptr = Place::from(self.new_temp(ptr_ty)); let can_go = Place::from(self.new_temp(tcx.types.bool)); let one = self.constant_usize(1); @@ -628,7 +628,7 @@ where }; let drop_block = BasicBlockData { - statements: vec![self.assign(ptr, ptr_next), self.assign(&Place::from(cur), cur_next)], + statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, @@ -640,8 +640,8 @@ where let loop_block = BasicBlockData { statements: vec![self.assign( - &can_go, - Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(*length_or_end)), + can_go, + Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(length_or_end)), )], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { @@ -700,9 +700,9 @@ where } } - let move_ = |place: &Place<'tcx>| Operand::Move(*place); - let elem_size = &Place::from(self.new_temp(tcx.types.usize)); - let len = &Place::from(self.new_temp(tcx.types.usize)); + let move_ = |place: Place<'tcx>| Operand::Move(place); + let elem_size = Place::from(self.new_temp(tcx.types.usize)); + let len = Place::from(self.new_temp(tcx.types.usize)); static USIZE_SWITCH_ZERO: &[u128] = &[0]; @@ -745,10 +745,10 @@ where let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length }; let unwind = self.unwind.map(|unwind| { - self.drop_loop(unwind, cur, &length_or_end, ety, Unwind::InCleanup, ptr_based) + self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based) }); - let loop_block = self.drop_loop(self.succ, cur, &length_or_end, ety, unwind, ptr_based); + let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based); let cur = Place::from(cur); let drop_block_stmts = if ptr_based { @@ -758,17 +758,17 @@ where // cur = tmp as *mut T; // end = Offset(cur, len); vec![ - self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, self.place)), - self.assign(&cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)), + self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)), + self.assign(cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)), self.assign( - &length_or_end, + length_or_end, Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length)), ), ] } else { // cur = 0 (length already pushed) let zero = self.constant_usize(0); - vec![self.assign(&cur, Rvalue::Use(zero))] + vec![self.assign(cur, Rvalue::Use(zero))] }; let drop_block = self.elaborator.patch().new_block(BasicBlockData { statements: drop_block_stmts, @@ -989,7 +989,7 @@ where }) } - fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { - Statement { source_info: self.source_info, kind: StatementKind::Assign(box (*lhs, rhs)) } + fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { + Statement { source_info: self.source_info, kind: StatementKind::Assign(box (lhs, rhs)) } } } From 6a95bf884fc1daf13355f0872add172e2459d52d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 13:54:20 -0300 Subject: [PATCH 21/33] Use Place directly on Operand::place and friends, it's Copy --- src/librustc_middle/mir/mod.rs | 4 ++-- src/librustc_mir/dataflow/framework/cursor.rs | 4 ++-- src/librustc_mir/dataflow/framework/engine.rs | 14 +++++++------- src/librustc_mir/dataflow/framework/mod.rs | 18 +++++++++--------- .../dataflow/impls/borrowed_locals.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 2 +- src/librustc_mir/dataflow/impls/mod.rs | 10 +++++----- .../dataflow/impls/storage_liveness.rs | 6 +++--- .../transform/check_consts/resolver.rs | 6 +++--- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 9ba9d816d0f3f..216fe43e81997 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -2030,9 +2030,9 @@ impl<'tcx> Operand<'tcx> { /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a /// constant. - pub fn place(&self) -> Option<&Place<'tcx>> { + pub fn place(&self) -> Option> { match self { - Operand::Copy(place) | Operand::Move(place) => Some(place), + Operand::Copy(place) | Operand::Move(place) => Some(*place), Operand::Constant(_) => None, } } diff --git a/src/librustc_mir/dataflow/framework/cursor.rs b/src/librustc_mir/dataflow/framework/cursor.rs index ed7c75f2f9d97..39676d03740b2 100644 --- a/src/librustc_mir/dataflow/framework/cursor.rs +++ b/src/librustc_mir/dataflow/framework/cursor.rs @@ -135,14 +135,14 @@ where target.block, func, args, - return_place, + *return_place, ); } TerminatorKind::Yield { resume, resume_arg, .. } => { self.results.borrow().analysis.apply_yield_resume_effect( &mut self.state, *resume, - resume_arg, + *resume_arg, ); } _ => {} diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs index fc2a1bc62a6cf..9bb727354df9a 100644 --- a/src/librustc_mir/dataflow/framework/engine.rs +++ b/src/librustc_mir/dataflow/framework/engine.rs @@ -228,7 +228,7 @@ where self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list); } - self.analysis.apply_yield_resume_effect(in_out, target, &resume_arg); + self.analysis.apply_yield_resume_effect(in_out, target, resume_arg); self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); } @@ -272,7 +272,7 @@ where } } - if let Some((ref dest_place, dest_bb)) = *destination { + if let Some((dest_place, dest_bb)) = *destination { // N.B.: This must be done *last*, otherwise the unwind path will see the call // return effect. self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place); @@ -314,7 +314,7 @@ where in_out: &mut BitSet, bb: BasicBlock, enum_def: &'tcx ty::AdtDef, - enum_place: &mir::Place<'tcx>, + enum_place: mir::Place<'tcx>, dirty_list: &mut WorkQueue, values: &[u128], targets: &[BasicBlock], @@ -361,14 +361,14 @@ fn switch_on_enum_discriminant( tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, block: &'mir mir::BasicBlockData<'tcx>, - switch_on: &mir::Place<'tcx>, -) -> Option<(&'mir mir::Place<'tcx>, &'tcx ty::AdtDef)> { + switch_on: mir::Place<'tcx>, +) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> { match block.statements.last().map(|stmt| &stmt.kind) { Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated)))) - if lhs == switch_on => + if *lhs == switch_on => { match &discriminated.ty(body, tcx).ty.kind { - ty::Adt(def, _) => Some((discriminated, def)), + ty::Adt(def, _) => Some((*discriminated, def)), // `Rvalue::Discriminant` is also used to get the active yield point for a // generator, but we do not need edge-specific effects in that case. This may diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/src/librustc_mir/dataflow/framework/mod.rs index 91c4b5ad634cb..fd2a3d5ea28f2 100644 --- a/src/librustc_mir/dataflow/framework/mod.rs +++ b/src/librustc_mir/dataflow/framework/mod.rs @@ -225,7 +225,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { block: BasicBlock, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ); /// Updates the current dataflow state with the effect of resuming from a `Yield` terminator. @@ -238,7 +238,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { &self, _state: &mut BitSet, _resume_block: BasicBlock, - _resume_place: &mir::Place<'tcx>, + _resume_place: mir::Place<'tcx>, ) { } @@ -251,7 +251,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { &self, _state: &mut BitSet, _block: BasicBlock, - _enum_place: &mir::Place<'tcx>, + _enum_place: mir::Place<'tcx>, _adt: &ty::AdtDef, _variant: VariantIdx, ) { @@ -332,7 +332,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { block: BasicBlock, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ); /// See `Analysis::apply_yield_resume_effect`. @@ -340,7 +340,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { &self, _trans: &mut BitSet, _resume_block: BasicBlock, - _resume_place: &mir::Place<'tcx>, + _resume_place: mir::Place<'tcx>, ) { } @@ -349,7 +349,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { &self, _state: &mut impl GenKill, _block: BasicBlock, - _enum_place: &mir::Place<'tcx>, + _enum_place: mir::Place<'tcx>, _adt: &ty::AdtDef, _variant: VariantIdx, ) { @@ -402,7 +402,7 @@ where block: BasicBlock, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ) { self.call_return_effect(state, block, func, args, return_place); } @@ -411,7 +411,7 @@ where &self, state: &mut BitSet, resume_block: BasicBlock, - resume_place: &mir::Place<'tcx>, + resume_place: mir::Place<'tcx>, ) { self.yield_resume_effect(state, resume_block, resume_place); } @@ -420,7 +420,7 @@ where &self, state: &mut BitSet, block: BasicBlock, - enum_place: &mir::Place<'tcx>, + enum_place: mir::Place<'tcx>, adt: &ty::AdtDef, variant: VariantIdx, ) { diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 273878ea275c3..6972a81cf1b0e 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -123,7 +123,7 @@ where _block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - _dest_place: &mir::Place<'tcx>, + _dest_place: mir::Place<'tcx>, ) { } } diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 43f985946aaac..0de8f45720e6f 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -329,7 +329,7 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { _block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - _dest_place: &mir::Place<'tcx>, + _dest_place: mir::Place<'tcx>, ) { } } diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 3ffa771cb05a1..1c85226b1221f 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -323,7 +323,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { _block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - dest_place: &mir::Place<'tcx>, + dest_place: mir::Place<'tcx>, ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). @@ -342,7 +342,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { &self, trans: &mut impl GenKill, _block: mir::BasicBlock, - enum_place: &mir::Place<'tcx>, + enum_place: mir::Place<'tcx>, _adt: &ty::AdtDef, variant: VariantIdx, ) { @@ -425,7 +425,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { _block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - dest_place: &mir::Place<'tcx>, + dest_place: mir::Place<'tcx>, ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). @@ -494,7 +494,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { _block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - dest_place: &mir::Place<'tcx>, + dest_place: mir::Place<'tcx>, ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). @@ -585,7 +585,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { block: mir::BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - _dest_place: &mir::Place<'tcx>, + _dest_place: mir::Place<'tcx>, ) { let move_data = self.move_data(); let init_loc_map = &move_data.init_loc_map; diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 48dd4e9794c03..3dfcfe16fb514 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -56,7 +56,7 @@ impl dataflow::GenKillAnalysis<'tcx> for MaybeStorageLive { _block: BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - _return_place: &mir::Place<'tcx>, + _return_place: mir::Place<'tcx>, ) { // Nothing to do when a call returns successfully } @@ -231,7 +231,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, _block: BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ) { trans.gen(return_place.local); } @@ -240,7 +240,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, &self, trans: &mut BitSet, _resume_block: BasicBlock, - resume_place: &mir::Place<'tcx>, + resume_place: mir::Place<'tcx>, ) { trans.gen(resume_place.local); } diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index d39904a56c8b6..b95a3939389ba 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -68,7 +68,7 @@ where _block: BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ) { // We cannot reason about another function's internals, so use conservative type-based // qualification for the result of a function call. @@ -76,7 +76,7 @@ where let qualif = Q::in_any_value_of_ty(self.item, return_ty); if !return_place.is_indirect() { - self.assign_qualif_direct(return_place, qualif); + self.assign_qualif_direct(&return_place, qualif); } } } @@ -214,7 +214,7 @@ where block: BasicBlock, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], - return_place: &mir::Place<'tcx>, + return_place: mir::Place<'tcx>, ) { self.transfer_function(state).apply_call_return_effect(block, func, args, return_place) } From f37d2b8a633016a5269bf14b12f61fa8ab85d1da Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:08:48 -0300 Subject: [PATCH 22/33] Use Place directly in librustc_mir_build, it's Copy --- src/librustc_mir_build/build/block.rs | 4 +-- src/librustc_mir_build/build/cfg.rs | 8 +++--- src/librustc_mir_build/build/expr/as_place.rs | 6 ++--- .../build/expr/as_rvalue.rs | 23 +++++++--------- src/librustc_mir_build/build/expr/as_temp.rs | 2 +- src/librustc_mir_build/build/expr/into.rs | 17 +++++------- src/librustc_mir_build/build/expr/stmt.rs | 4 +-- src/librustc_mir_build/build/into.rs | 8 +++--- src/librustc_mir_build/build/matches/mod.rs | 26 +++++++++---------- src/librustc_mir_build/build/matches/test.rs | 10 +++---- src/librustc_mir_build/build/misc.rs | 2 +- src/librustc_mir_build/build/mod.rs | 4 +-- src/librustc_mir_build/build/scope.rs | 4 +-- 13 files changed, 55 insertions(+), 63 deletions(-) diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs index 826b3bdcfe5e3..8c41554bc85f9 100644 --- a/src/librustc_mir_build/build/block.rs +++ b/src/librustc_mir_build/build/block.rs @@ -9,7 +9,7 @@ use rustc_span::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn ast_block( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, block: BasicBlock, ast_block: &'tcx hir::Block<'tcx>, source_info: SourceInfo, @@ -43,7 +43,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn ast_block_stmts( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, mut block: BasicBlock, span: Span, stmts: Vec>, diff --git a/src/librustc_mir_build/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs index f1cb514feaaa3..f5828c4ac1fa1 100644 --- a/src/librustc_mir_build/build/cfg.rs +++ b/src/librustc_mir_build/build/cfg.rs @@ -34,12 +34,12 @@ impl<'tcx> CFG<'tcx> { &mut self, block: BasicBlock, source_info: SourceInfo, - place: &Place<'tcx>, + place: Place<'tcx>, rvalue: Rvalue<'tcx>, ) { self.push( block, - Statement { source_info, kind: StatementKind::Assign(box (*place, rvalue)) }, + Statement { source_info, kind: StatementKind::Assign(box (place, rvalue)) }, ); } @@ -47,7 +47,7 @@ impl<'tcx> CFG<'tcx> { &mut self, block: BasicBlock, source_info: SourceInfo, - temp: &Place<'tcx>, + temp: Place<'tcx>, constant: Constant<'tcx>, ) { self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant))); @@ -57,7 +57,7 @@ impl<'tcx> CFG<'tcx> { &mut self, block: BasicBlock, source_info: SourceInfo, - place: &Place<'tcx>, + place: Place<'tcx>, ) { self.push_assign( block, diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/src/librustc_mir_build/build/expr/as_place.rs index 90931a14894e6..9f74385b3368b 100644 --- a/src/librustc_mir_build/build/expr/as_place.rs +++ b/src/librustc_mir_build/build/expr/as_place.rs @@ -341,12 +341,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lt = self.temp(bool_ty, expr_span); // len = len(slice) - self.cfg.push_assign(block, source_info, &len, Rvalue::Len(slice)); + self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice)); // lt = idx < len self.cfg.push_assign( block, source_info, - <, + lt, Rvalue::BinaryOp(BinOp::Lt, Operand::Copy(Place::from(index)), Operand::Copy(len)), ); let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) }; @@ -388,7 +388,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &fake_borrow_temp.into(), + fake_borrow_temp.into(), Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Shallow, diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs index 96d6ca1ecabb1..20ef763e90cb4 100644 --- a/src/librustc_mir_build/build/expr/as_rvalue.rs +++ b/src/librustc_mir_build/build/expr/as_rvalue.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.push_assign( block, source_info, - &is_min, + is_min, Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval), ); @@ -109,15 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // malloc some memory of suitable type (thus far, uninitialized): let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty); - this.cfg.push_assign(block, source_info, &Place::from(result), box_); + this.cfg.push_assign(block, source_info, Place::from(result), box_); // initialize the box contents: unpack!( - block = this.into( - &this.hir.tcx().mk_place_deref(Place::from(result)), - block, - value - ) + block = + this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value) ); block.and(Rvalue::Use(Operand::Move(Place::from(result)))) } @@ -284,7 +281,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &result_value, + result_value, Rvalue::CheckedBinaryOp(op, lhs, rhs), ); let val_fld = Field::new(0); @@ -317,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &is_zero, + is_zero, Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero), ); @@ -338,13 +335,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &is_neg_1, + is_neg_1, Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), neg_1), ); self.cfg.push_assign( block, source_info, - &is_min, + is_min, Rvalue::BinaryOp(BinOp::Eq, lhs.to_copy(), min), ); @@ -353,7 +350,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &of, + of, Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min), ); @@ -428,7 +425,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.push_assign( block, source_info, - &Place::from(temp), + Place::from(temp), Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place), ); diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs index ef692079e0c44..73d95575e39d5 100644 --- a/src/librustc_mir_build/build/expr/as_temp.rs +++ b/src/librustc_mir_build/build/expr/as_temp.rs @@ -66,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } this.local_decls.push(local_decl) }; - let temp_place = &Place::from(temp); + let temp_place = Place::from(temp); match expr.kind { // Don't bother with StorageLive and Dead for these temporaries, diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index c61526024d076..6b93755e9da7c 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -16,7 +16,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// is assumed to be uninitialized. crate fn into_expr( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, mut block: BasicBlock, expr: Expr<'tcx>, ) -> BlockAnd<()> { @@ -160,7 +160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // introduce a unit temporary as the destination for the loop body. let tmp = this.get_unit_temp(); // Execute the body, branching back to the test. - let body_block_end = unpack!(this.into(&tmp, body_block, body)); + let body_block_end = unpack!(this.into(tmp, body_block, body)); this.cfg.goto(body_block_end, source_info, loop_block); }, ); @@ -202,8 +202,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { is_block_tail: None, }); let ptr_temp = Place::from(ptr_temp); - let block = unpack!(this.into(&ptr_temp, block, ptr)); - this.into(&this.hir.tcx().mk_place_deref(ptr_temp), block, val) + let block = unpack!(this.into(ptr_temp, block, ptr)); + this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val) } else { let args: Vec<_> = args .into_iter() @@ -228,7 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { destination: if expr.ty.is_never() { None } else { - Some((*destination, success)) + Some((destination, success)) }, from_hir_call, }, @@ -373,12 +373,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.terminate( block, source_info, - TerminatorKind::Yield { - value, - resume, - resume_arg: *destination, - drop: cleanup, - }, + TerminatorKind::Yield { value, resume, resume_arg: destination, drop: cleanup }, ); resume.unit() } diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/src/librustc_mir_build/build/expr/stmt.rs index 8bfd2ce36bb51..92e1e10518506 100644 --- a/src/librustc_mir_build/build/expr/stmt.rs +++ b/src/librustc_mir_build/build/expr/stmt.rs @@ -50,7 +50,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } else { let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); - this.cfg.push_assign(block, source_info, &lhs, rhs); + this.cfg.push_assign(block, source_info, lhs, rhs); } this.block_context.pop(); @@ -82,7 +82,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block = this.build_binary_op(block, op, expr_span, lhs_ty, Operand::Copy(lhs), rhs) ); - this.cfg.push_assign(block, source_info, &lhs, result); + this.cfg.push_assign(block, source_info, lhs, result); this.block_context.pop(); block.unit() diff --git a/src/librustc_mir_build/build/into.rs b/src/librustc_mir_build/build/into.rs index 1c0981597d326..0baa0c833a514 100644 --- a/src/librustc_mir_build/build/into.rs +++ b/src/librustc_mir_build/build/into.rs @@ -12,7 +12,7 @@ pub(in crate::build) trait EvalInto<'tcx> { fn eval_into( self, builder: &mut Builder<'_, 'tcx>, - destination: &Place<'tcx>, + destination: Place<'tcx>, block: BasicBlock, ) -> BlockAnd<()>; } @@ -20,7 +20,7 @@ pub(in crate::build) trait EvalInto<'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn into( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, block: BasicBlock, expr: E, ) -> BlockAnd<()> @@ -35,7 +35,7 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> { fn eval_into( self, builder: &mut Builder<'_, 'tcx>, - destination: &Place<'tcx>, + destination: Place<'tcx>, block: BasicBlock, ) -> BlockAnd<()> { let expr = builder.hir.mirror(self); @@ -47,7 +47,7 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> { fn eval_into( self, builder: &mut Builder<'_, 'tcx>, - destination: &Place<'tcx>, + destination: Place<'tcx>, block: BasicBlock, ) -> BlockAnd<()> { builder.into_expr(destination, block, self) diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index d205ce254d3b2..a98b18c0cf1d8 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -10,16 +10,16 @@ use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode}; use crate::hair::{self, *}; +use rustc_ast::ast::Name; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::HirId; +use rustc_index::bit_set::BitSet; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::ty::layout::VariantIdx; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::HirId; -use rustc_index::bit_set::BitSet; use rustc_span::Span; use smallvec::{smallvec, SmallVec}; -use rustc_ast::ast::Name; // helper functions, broken out by category: mod simplify; @@ -83,7 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// * From each otherwise block to the next prebinding block. crate fn match_expr( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, span: Span, mut block: BasicBlock, scrutinee: ExprRef<'tcx>, @@ -218,7 +218,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// `outer_source_info` is the SourceInfo for the whole match. fn lower_match_arms( &mut self, - destination: &Place<'tcx>, + destination: Place<'tcx>, scrutinee_place: Place<'tcx>, scrutinee_span: Span, arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>, @@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => { let place = self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); - unpack!(block = self.into(&place, block, initializer)); + unpack!(block = self.into(place, block, initializer)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. let source_info = self.source_info(irrefutable_pat.span); @@ -399,7 +399,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } => { let place = self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); - unpack!(block = self.into(&place, block, initializer)); + unpack!(block = self.into(place, block, initializer)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. let pattern_source_info = self.source_info(irrefutable_pat.span); @@ -1691,7 +1691,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scrutinee_source_info = self.source_info(scrutinee_span); for &(place, temp) in fake_borrows { let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, place); - self.cfg.push_assign(block, scrutinee_source_info, &Place::from(temp), borrow); + self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow); } // the block to branch to if the guard fails; if there is no @@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match binding.binding_mode { BindingMode::ByValue => { let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source); - self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue); + self.cfg.push_assign(block, source_info, ref_for_guard, rvalue); } BindingMode::ByRef(borrow_kind) => { let value_for_arm = self.storage_live_binding( @@ -1870,9 +1870,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source); - self.cfg.push_assign(block, source_info, &value_for_arm, rvalue); + self.cfg.push_assign(block, source_info, value_for_arm, rvalue); let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm); - self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue); + self.cfg.push_assign(block, source_info, ref_for_guard, rvalue); } } } @@ -1910,7 +1910,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Rvalue::Ref(re_erased, borrow_kind, binding.source) } }; - self.cfg.push_assign(block, source_info, &local, rvalue); + self.cfg.push_assign(block, source_info, local, rvalue); } } diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs index 01b3cfb7ba05b..450bb0a861d74 100644 --- a/src/librustc_mir_build/build/matches/test.rs +++ b/src/librustc_mir_build/build/matches/test.rs @@ -202,7 +202,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let discr_ty = adt_def.repr.discr_type().to_ty(tcx); let discr = self.temp(discr_ty, test.span); - self.cfg.push_assign(block, source_info, &discr, Rvalue::Discriminant(place)); + self.cfg.push_assign(block, source_info, discr, Rvalue::Discriminant(place)); assert_eq!(values.len() + 1, targets.len()); self.cfg.terminate( block, @@ -303,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let actual = self.temp(usize_ty, test.span); // actual = len(place) - self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(place)); + self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place)); // expected = let expected = self.push_usize(block, source_info, len); @@ -342,7 +342,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let result = self.temp(bool_ty, source_info.span); // result = op(left, right) - self.cfg.push_assign(block, source_info, &result, Rvalue::BinaryOp(op, left, right)); + self.cfg.push_assign(block, source_info, result, Rvalue::BinaryOp(op, left, right)); // branch based on result self.cfg.terminate( @@ -394,7 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &temp, + temp, Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty), ); val = Operand::Move(temp); @@ -404,7 +404,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign( block, source_info, - &slice, + slice, Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty), ); expect = Operand::Move(slice); diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs index 06371d71b9d58..8f98dd9b70e80 100644 --- a/src/librustc_mir_build/build/misc.rs +++ b/src/librustc_mir_build/build/misc.rs @@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign_constant( block, source_info, - &temp, + temp, Constant { span: source_info.span, user_ty: None, diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index c4eb9803b425f..cec7e5bc19966 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -663,7 +663,7 @@ fn construct_const<'a, 'tcx>( let mut block = START_BLOCK; let ast_expr = &tcx.hir().body(body_id).value; let expr = builder.hir.mirror(ast_expr); - unpack!(block = builder.into_expr(&Place::return_place(), block, expr)); + unpack!(block = builder.into_expr(Place::return_place(), block, expr)); let source_info = builder.source_info(span); builder.cfg.terminate(block, source_info, TerminatorKind::Return); @@ -969,7 +969,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let body = self.hir.mirror(ast_body); - self.into(&Place::return_place(), block, body) + self.into(Place::return_place(), block, body) } fn set_correct_source_scope_for_arg( diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs index be34c84f124ac..3689e5cb9d8a2 100644 --- a/src/librustc_mir_build/build/scope.rs +++ b/src/librustc_mir_build/build/scope.rs @@ -520,10 +520,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(value) = value { debug!("stmt_expr Break val block_context.push(SubExpr)"); self.block_context.push(BlockFrame::SubExpr); - unpack!(block = self.into(&destination, block, value)); + unpack!(block = self.into(destination, block, value)); self.block_context.pop(); } else { - self.cfg.push_assign_unit(block, source_info, &destination) + self.cfg.push_assign_unit(block, source_info, destination) } } else { assert!(value.is_none(), "`return` and `break` should have a destination"); From 5987b0f8bed3d6c1bf6c167f850d45f2439ed569 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:16:54 -0300 Subject: [PATCH 23/33] Use Place directly in place_as_reborrow, it's Copy --- src/librustc_mir/transform/check_consts/validation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index c8320a1561ae8..649cc0a79d636 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -260,7 +260,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { // Special-case reborrows to be more like a copy of a reference. match *rvalue { - Rvalue::Ref(_, kind, ref place) => { + Rvalue::Ref(_, kind, place) => { if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) { let ctx = match kind { BorrowKind::Shared => { @@ -281,7 +281,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { return; } } - Rvalue::AddressOf(mutbl, ref place) => { + Rvalue::AddressOf(mutbl, place) => { if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) { let ctx = match mutbl { Mutability::Not => { @@ -645,7 +645,7 @@ fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId) fn place_as_reborrow( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - place: &'a Place<'tcx>, + place: Place<'tcx>, ) -> Option<&'a [PlaceElem<'tcx>]> { place.projection.split_last().and_then(|(outermost, inner)| { if outermost != &ProjectionElem::Deref { From 947c1dcf924d8c9e5676e8d850a9754dcd1cbd71 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:20:42 -0300 Subject: [PATCH 24/33] Use Place directly on place_contents_drop_state_cannot_differ, it's Copy --- src/librustc_mir/dataflow/drop_flag_effects.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs index f9511921a8786..91b342ae5c36a 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/src/librustc_mir/dataflow/drop_flag_effects.rs @@ -49,7 +49,7 @@ where fn place_contents_drop_state_cannot_differ<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, ) -> bool { let ty = place.ty(body, tcx).ty; match ty.kind { @@ -110,7 +110,7 @@ pub(crate) fn on_all_children_bits<'tcx, F>( move_data: &MoveData<'tcx>, path: MovePathIndex, ) -> bool { - place_contents_drop_state_cannot_differ(tcx, body, &move_data.move_paths[path].place) + place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place) } fn on_all_children_bits<'tcx, F>( From 017620fdfcbe7cbb1813f8d07334b405f52fe8fa Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:26:15 -0300 Subject: [PATCH 25/33] Use Place directly in peek_at, it's Copy --- src/librustc_mir/transform/rustc_peek.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 06a697e18da56..cccf9ff30168c 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -127,7 +127,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>( let loc = Location { block: bb, statement_index }; cursor.seek_before(loc); let state = cursor.get(); - results.analysis.peek_at(tcx, place, state, call); + results.analysis.peek_at(tcx, *place, state, call); } _ => { @@ -231,7 +231,7 @@ pub trait RustcPeekAt<'tcx>: Analysis<'tcx> { fn peek_at( &self, tcx: TyCtxt<'tcx>, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, flow_state: &BitSet, call: PeekCall, ); @@ -244,7 +244,7 @@ where fn peek_at( &self, tcx: TyCtxt<'tcx>, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, flow_state: &BitSet, call: PeekCall, ) { @@ -268,7 +268,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> { fn peek_at( &self, tcx: TyCtxt<'tcx>, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, flow_state: &BitSet, call: PeekCall, ) { From afcd7fc51de94d51465766fa3a0f584cb0710a84 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:27:48 -0300 Subject: [PATCH 26/33] Use Place directly on codegen_drop_terminator, it's Copy --- src/librustc_codegen_ssa/mir/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index e71a63b7f3080..658c3127f69f4 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, helper: TerminatorCodegenHelper<'tcx>, mut bx: Bx, - location: &mir::Place<'tcx>, + location: mir::Place<'tcx>, target: mir::BasicBlock, unwind: Option, ) { @@ -873,7 +873,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.unreachable(); } - mir::TerminatorKind::Drop { ref location, target, unwind } => { + mir::TerminatorKind::Drop { location, target, unwind } => { self.codegen_drop_terminator(helper, bx, location, target, unwind); } From 5f8a6edbbbfd0289a74d1689fbeb9387350eb4f3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:31:34 -0300 Subject: [PATCH 27/33] Use Place directly on make_return_dest, it's Copy --- src/librustc_codegen_ssa/mir/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 658c3127f69f4..d75818dfbacb9 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -619,7 +619,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut llargs = Vec::with_capacity(arg_count); // Prepare the return value destination - let ret_dest = if let Some((ref dest, _)) = *destination { + let ret_dest = if let Some((dest, _)) = *destination { let is_intrinsic = intrinsic.is_some(); self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic) } else { @@ -1123,7 +1123,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn make_return_dest( &mut self, bx: &mut Bx, - dest: &mir::Place<'tcx>, + dest: mir::Place<'tcx>, fn_ret: &ArgAbi<'tcx, Ty<'tcx>>, llargs: &mut Vec, is_intrinsic: bool, From 1f5338cfd61b3eb59c2491fffdd802ce779c6487 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:35:01 -0300 Subject: [PATCH 28/33] Use Place directly in codegen_transmute, it's Copy --- src/librustc_codegen_ssa/mir/block.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d75818dfbacb9..931fab6ae01da 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -580,7 +580,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if intrinsic == Some("transmute") { if let Some(destination_ref) = destination.as_ref() { - let &(ref dest, target) = destination_ref; + let &(dest, target) = destination_ref; self.codegen_transmute(&mut bx, &args[0], dest); helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); @@ -1184,7 +1184,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) { + fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: mir::Place<'tcx>) { if let Some(index) = dst.as_local() { match self.locals[index] { LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), From a865e779b0732806111d71d2dc0aa461dc9d53f9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:37:10 -0300 Subject: [PATCH 29/33] Use Place directly in evaluate_array_len, it's Copy --- src/librustc_codegen_ssa/mir/rvalue.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 66ce50c482a6f..288afecc66fc3 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -400,7 +400,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ptr) } - mir::Rvalue::Len(ref place) => { + mir::Rvalue::Len(place) => { let size = self.evaluate_array_len(&mut bx, place); let operand = OperandRef { val: OperandValue::Immediate(size), @@ -537,7 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn evaluate_array_len(&mut self, bx: &mut Bx, place: &mir::Place<'tcx>) -> Bx::Value { + fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. if let Some(index) = place.as_local() { From 017608f5d247d8d8e5d7468d02a5b6c4f686524e Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 14:39:18 -0300 Subject: [PATCH 30/33] Use Place directly in codegen_place_to_pointer, it's Copy --- src/librustc_codegen_ssa/mir/rvalue.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 288afecc66fc3..ce681c729b2b5 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -383,7 +383,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (bx, OperandRef { val, layout: cast }) } - mir::Rvalue::Ref(_, bk, ref place) => { + mir::Rvalue::Ref(_, bk, place) => { let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { tcx.mk_ref( tcx.lifetimes.re_erased, @@ -393,7 +393,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ref) } - mir::Rvalue::AddressOf(mutability, ref place) => { + mir::Rvalue::AddressOf(mutability, place) => { let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability }) }; @@ -557,7 +557,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn codegen_place_to_pointer( &mut self, mut bx: Bx, - place: &mir::Place<'tcx>, + place: mir::Place<'tcx>, mk_ptr_ty: impl FnOnce(TyCtxt<'tcx>, Ty<'tcx>) -> Ty<'tcx>, ) -> (Bx, OperandRef<'tcx, Bx::Value>) { let cg_place = self.codegen_place(&mut bx, place.as_ref()); From b46754ea9904348fd0291cb9898556a16cf3c55f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 31 Mar 2020 18:49:21 -0300 Subject: [PATCH 31/33] Use Place directly in apply_call_return_effect on framework/tests, it's Copy --- src/librustc_mir/dataflow/framework/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/src/librustc_mir/dataflow/framework/tests.rs index c38cb456667fb..8c65b7452d1fd 100644 --- a/src/librustc_mir/dataflow/framework/tests.rs +++ b/src/librustc_mir/dataflow/framework/tests.rs @@ -223,7 +223,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> { block: BasicBlock, _func: &mir::Operand<'tcx>, _args: &[mir::Operand<'tcx>], - _return_place: &mir::Place<'tcx>, + _return_place: mir::Place<'tcx>, ) { let location = self.body.terminator_loc(block); let idx = self.effect_at_target(SeekTarget::AfterAssumeCallReturns(location)).unwrap(); From 036626f249eff9c7fcf2d1392182ec59e5460b57 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Tue, 31 Mar 2020 08:27:09 -0400 Subject: [PATCH 32/33] Address review feedback --- src/librustc_codegen_llvm/abi.rs | 7 +++++++ src/librustc_codegen_llvm/attributes.rs | 18 ++---------------- src/librustc_codegen_llvm/callee.rs | 2 +- src/librustc_codegen_llvm/mono_item.rs | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 38dd879de7d59..064ca53bd1bd1 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -396,6 +396,11 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn); } + // FIXME(eddyb, wesleywiser): apply this to callsites as well? + if !self.can_unwind { + llvm::Attribute::NoUnwind.apply_llfn(llvm::AttributePlace::Function, llfn); + } + let mut i = 0; let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty); @@ -431,6 +436,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { } fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) { + // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite. + let mut i = 0; let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty); diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index ac2bbd4b2aea4..784a3a87e9885 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -10,11 +10,10 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{OptLevel, Sanitizer}; use rustc_session::Session; -use crate::abi::FnAbi; use crate::attributes; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, Attribute}; @@ -75,12 +74,6 @@ pub fn emit_uwtable(val: &'ll Value, emit: bool) { Attribute::UWTable.toggle_llfn(Function, val, emit); } -/// Tell LLVM whether the function can or cannot unwind. -#[inline] -fn unwind(val: &'ll Value, can_unwind: bool) { - Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind); -} - /// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue. #[inline] fn naked(val: &'ll Value, is_naked: bool) { @@ -244,12 +237,7 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) { /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. -pub fn from_fn_attrs( - cx: &CodegenCx<'ll, 'tcx>, - llfn: &'ll Value, - instance: ty::Instance<'tcx>, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, -) { +pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>) { let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id()); match codegen_fn_attrs.optimize { @@ -313,8 +301,6 @@ pub fn from_fn_attrs( } sanitize(cx, codegen_fn_attrs.flags, llfn); - unwind(llfn, fn_abi.can_unwind); - // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated // functions (because Clang annotates functions this way too). diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 0759823c07a85..a36314448b170 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -78,7 +78,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value let llfn = cx.declare_fn(&sym, &fn_abi); debug!("get_fn: not casting pointer!"); - attributes::from_fn_attrs(cx, llfn, instance, &fn_abi); + attributes::from_fn_attrs(cx, llfn, instance); let instance_def_id = instance.def_id(); diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index fe1537fbd021d..a7a9d0c8a0759 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -77,7 +77,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { debug!("predefine_fn: instance = {:?}", instance); - attributes::from_fn_attrs(self, lldecl, instance, &fn_abi); + attributes::from_fn_attrs(self, lldecl, instance); self.instances.borrow_mut().insert(instance, lldecl); } From e39f542c552995173fc49910f5de5b7abfa0bd1a Mon Sep 17 00:00:00 2001 From: lzutao Date: Wed, 1 Apr 2020 19:10:19 +0700 Subject: [PATCH 33/33] Add git repo address to unstable book --- src/doc/unstable-book/book.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doc/unstable-book/book.toml b/src/doc/unstable-book/book.toml index 5b2e19bd7aa78..0cd56d0940451 100644 --- a/src/doc/unstable-book/book.toml +++ b/src/doc/unstable-book/book.toml @@ -1,3 +1,6 @@ [book] title = "The Rust Unstable Book" author = "The Rust Community" + +[output.html] +git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book"