diff --git a/README.md b/README.md
index 42fc0a63c0ffb..c2ded10f05a36 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,9 @@
-# The Rust Programming Language
+
+
+
This is the main source code repository for [Rust]. It contains the compiler,
-standard library, and documentation.
+standard library, and documentation.
[Rust]: https://www.rust-lang.org
@@ -17,9 +19,9 @@ Read ["Installation"] from [The Book].
_Note: If you wish to contribute to the compiler, you should read [this
chapter][rustcguidebuild] of the rustc-dev-guide instead of this section._
-The Rust build system has a Python script called `x.py` to bootstrap building
-the compiler. More information about it may be found by running `./x.py --help`
-or reading the [rustc dev guide][rustcguidebuild].
+The Rust build system uses a Python script called `x.py` to build the compiler,
+which manages the bootstrapping process. More information about it can be found
+by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
[rustcguidebuild]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html
@@ -54,9 +56,8 @@ or reading the [rustc dev guide][rustcguidebuild].
$ cp config.toml.example config.toml
```
- It is recommended that if you plan to use the Rust build system to create
- an installation (using `./x.py install`) that you set the `prefix` value
- in the `[install]` section to a directory that you have write permissions.
+ If you plan to use `x.py install` to create an installation, it is recommended
+ that you set the `prefix` value in the `[install]` section to a directory.
Create install directory if you are not installing in default directory
@@ -143,8 +144,8 @@ shell with:
```
Currently, building Rust only works with some known versions of Visual Studio. If
-you have a more recent version installed the build system doesn't understand
-then you may need to force rustbuild to use an older version. This can be done
+you have a more recent version installed and the build system doesn't understand,
+you may need to force rustbuild to use an older version. This can be done
by manually calling the appropriate vcvars file before running the bootstrap.
```batch
diff --git a/src/doc/unstable-book/src/language-features/track-caller.md b/src/doc/unstable-book/src/language-features/track-caller.md
deleted file mode 100644
index afc11a2b9492c..0000000000000
--- a/src/doc/unstable-book/src/language-features/track-caller.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# `track_caller`
-
-The tracking issue for this feature is: [#47809](https://github.com/rust-lang/rust/issues/47809).
-
-------------------------
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index f1b560b9b9685..3320ebdf821d0 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -384,7 +384,10 @@ impl Box {
///
/// unsafe {
/// let ptr = alloc(Layout::new::()) as *mut i32;
- /// *ptr = 5;
+ /// // In general .write is required to avoid attempting to destruct
+ /// // the (uninitialized) previous contents of `ptr`, though for this
+ /// // simple example `*ptr = 5` would have worked as well.
+ /// ptr.write(5);
/// let x = Box::from_raw(ptr);
/// }
/// ```
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 64d9692244dde..13ef94dee2326 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -2518,3 +2518,11 @@ impl DoubleEndedIterator for Drain<'_> {
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for Drain<'_> {}
+
+#[stable(feature = "from_char_for_string", since = "1.46.0")]
+impl From for String {
+ #[inline]
+ fn from(c: char) -> Self {
+ c.to_string()
+ }
+}
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 9ea020d2d19f4..d38655af78cb7 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -714,3 +714,10 @@ fn test_try_reserve_exact() {
}
}
}
+
+#[test]
+fn test_from_char() {
+ assert_eq!(String::from('a'), 'a'.to_string());
+ let s: String = 'x'.into();
+ assert_eq!(s, 'x'.to_string());
+}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 5d09018759191..57ffed19c0085 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -952,6 +952,7 @@ extern "rust-intrinsic" {
/// Any use other than with `if` statements will probably not have an effect.
///
/// This intrinsic does not have a stable counterpart.
+ #[rustc_const_unstable(feature = "const_likely", issue = "none")]
pub fn likely(b: bool) -> bool;
/// Hints to the compiler that branch condition is likely to be false.
@@ -960,6 +961,7 @@ extern "rust-intrinsic" {
/// Any use other than with `if` statements will probably not have an effect.
///
/// This intrinsic does not have a stable counterpart.
+ #[rustc_const_unstable(feature = "const_likely", issue = "none")]
pub fn unlikely(b: bool) -> bool;
/// Executes a breakpoint trap, for inspection by a debugger.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index aeb52bffbf24c..63ddd97eed3df 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -92,6 +92,7 @@
#![feature(const_slice_from_raw_parts)]
#![feature(const_slice_ptr_len)]
#![feature(const_type_name)]
+#![feature(const_likely)]
#![feature(custom_inner_attributes)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
@@ -118,7 +119,7 @@
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stmt_expr_attributes)]
-#![feature(track_caller)]
+#![cfg_attr(bootstrap, feature(track_caller))]
#![feature(transparent_unions)]
#![feature(unboxed_closures)]
#![feature(unsized_locals)]
diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs
index 3cfdde60135b7..13c0e8daf740f 100644
--- a/src/libcore/macros/mod.rs
+++ b/src/libcore/macros/mod.rs
@@ -1,6 +1,6 @@
#[doc(include = "panic.md")]
#[macro_export]
-#[allow_internal_unstable(core_panic, track_caller)]
+#[allow_internal_unstable(core_panic, const_caller_location)]
#[stable(feature = "core", since = "1.6.0")]
macro_rules! panic {
() => (
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
index c7009b76e8148..543aa969330ae 100644
--- a/src/libcore/panic.rs
+++ b/src/libcore/panic.rs
@@ -190,7 +190,6 @@ impl<'a> Location<'a> {
/// # Examples
///
/// ```
- /// #![feature(track_caller)]
/// use core::panic::Location;
///
/// /// Returns the [`Location`] at which it is called.
@@ -206,7 +205,7 @@ impl<'a> Location<'a> {
///
/// let fixed_location = get_just_one_location();
/// assert_eq!(fixed_location.file(), file!());
- /// assert_eq!(fixed_location.line(), 15);
+ /// assert_eq!(fixed_location.line(), 14);
/// assert_eq!(fixed_location.column(), 5);
///
/// // running the same untracked function in a different location gives us the same result
@@ -217,7 +216,7 @@ impl<'a> Location<'a> {
///
/// let this_location = get_caller_location();
/// assert_eq!(this_location.file(), file!());
- /// assert_eq!(this_location.line(), 29);
+ /// assert_eq!(this_location.line(), 28);
/// assert_eq!(this_location.column(), 21);
///
/// // running the tracked function in a different location produces a different value
@@ -226,13 +225,8 @@ impl<'a> Location<'a> {
/// assert_ne!(this_location.line(), another_location.line());
/// assert_ne!(this_location.column(), another_location.column());
/// ```
- // FIXME: When stabilizing this method, please also update the documentation
- // of `intrinsics::caller_location`.
- #[unstable(
- feature = "track_caller",
- reason = "uses #[track_caller] which is not yet stable",
- issue = "47809"
- )]
+ #[stable(feature = "track_caller", since = "1.46.0")]
+ #[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
#[track_caller]
pub const fn caller() -> &'static Location<'static> {
crate::intrinsics::caller_location()
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index 86faa1f086ce2..501cd3748282b 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -9,7 +9,7 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_ast::attr;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
-use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
+use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::util::parser::{self, AssocOp, Fixity};
use rustc_ast::util::{classify, comments};
use rustc_span::edition::Edition;
@@ -293,7 +293,7 @@ pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(),
token::NtLifetime(e) => e.to_string(),
token::NtLiteral(ref e) => expr_to_string(e),
- token::NtTT(ref tree) => tt_to_string(tree.clone()),
+ token::NtTT(ref tree) => tt_to_string(tree),
token::NtVis(ref e) => vis_to_string(e),
}
}
@@ -314,11 +314,11 @@ pub fn expr_to_string(e: &ast::Expr) -> String {
to_string(|s| s.print_expr(e))
}
-pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
+pub fn tt_to_string(tt: &TokenTree) -> String {
to_string(|s| s.print_tt(tt, false))
}
-pub fn tts_to_string(tokens: TokenStream) -> String {
+pub fn tts_to_string(tokens: &TokenStream) -> String {
to_string(|s| s.print_tts(tokens, false))
}
@@ -585,7 +585,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
false,
None,
delim.to_token(),
- tokens.clone(),
+ tokens,
true,
span,
),
@@ -594,7 +594,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
if let MacArgs::Eq(_, tokens) = &item.args {
self.space();
self.word_space("=");
- self.print_tts(tokens.clone(), true);
+ self.print_tts(tokens, true);
}
}
}
@@ -635,9 +635,9 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
/// appropriate macro, transcribe back into the grammar we just parsed from,
/// and then pretty-print the resulting AST nodes (so, e.g., we print
/// expression arguments as expressions). It can be done! I think.
- fn print_tt(&mut self, tt: tokenstream::TokenTree, convert_dollar_crate: bool) {
+ fn print_tt(&mut self, tt: &TokenTree, convert_dollar_crate: bool) {
match tt {
- TokenTree::Token(ref token) => {
+ TokenTree::Token(token) => {
self.word(token_to_string_ext(&token, convert_dollar_crate));
if let token::DocComment(..) = token.kind {
self.hardbreak()
@@ -648,7 +648,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
None,
false,
None,
- delim,
+ *delim,
tts,
convert_dollar_crate,
dspan.entire(),
@@ -657,14 +657,14 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
}
}
- fn print_tts(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) {
- let mut iter = tts.into_trees().peekable();
+ fn print_tts(&mut self, tts: &TokenStream, convert_dollar_crate: bool) {
+ let mut iter = tts.trees().peekable();
while let Some(tt) = iter.next() {
- let show_space =
- if let Some(next) = iter.peek() { tt_prepend_space(next, &tt) } else { false };
- self.print_tt(tt, convert_dollar_crate);
- if show_space {
- self.space();
+ self.print_tt(&tt, convert_dollar_crate);
+ if let Some(next) = iter.peek() {
+ if tt_prepend_space(next, &tt) {
+ self.space();
+ }
}
}
}
@@ -675,7 +675,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere
has_bang: bool,
ident: Option,
delim: DelimToken,
- tts: TokenStream,
+ tts: &TokenStream,
convert_dollar_crate: bool,
span: Span,
) {
@@ -1253,7 +1253,7 @@ impl<'a> State<'a> {
has_bang,
Some(item.ident),
macro_def.body.delim(),
- macro_def.body.inner_tokens(),
+ ¯o_def.body.inner_tokens(),
true,
item.span,
);
@@ -1577,7 +1577,7 @@ impl<'a> State<'a> {
true,
None,
m.args.delim(),
- m.args.inner_tokens(),
+ &m.args.inner_tokens(),
true,
m.span(),
);
diff --git a/src/librustc_builtin_macros/log_syntax.rs b/src/librustc_builtin_macros/log_syntax.rs
index ae3a889428ae4..ede34a7612589 100644
--- a/src/librustc_builtin_macros/log_syntax.rs
+++ b/src/librustc_builtin_macros/log_syntax.rs
@@ -7,7 +7,7 @@ pub fn expand_log_syntax<'cx>(
sp: rustc_span::Span,
tts: TokenStream,
) -> Box {
- println!("{}", pprust::tts_to_string(tts));
+ println!("{}", pprust::tts_to_string(&tts));
// any so that `log_syntax` can be invoked as an expression and item.
base::DummyResult::any_valid(sp)
diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs
index 1b164eae5a345..e46cf67e64d66 100644
--- a/src/librustc_builtin_macros/source_util.rs
+++ b/src/librustc_builtin_macros/source_util.rs
@@ -71,7 +71,7 @@ pub fn expand_stringify(
tts: TokenStream,
) -> Box {
let sp = cx.with_def_site_ctxt(sp);
- let s = pprust::tts_to_string(tts);
+ let s = pprust::tts_to_string(&tts);
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
}
diff --git a/src/librustc_error_codes/error_codes/E0736.md b/src/librustc_error_codes/error_codes/E0736.md
index 8a60dc320599b..0f3d41ba66dc4 100644
--- a/src/librustc_error_codes/error_codes/E0736.md
+++ b/src/librustc_error_codes/error_codes/E0736.md
@@ -3,8 +3,6 @@
Erroneous code example:
```compile_fail,E0736
-#![feature(track_caller)]
-
#[naked]
#[track_caller]
fn foo() {}
diff --git a/src/librustc_error_codes/error_codes/E0737.md b/src/librustc_error_codes/error_codes/E0737.md
index c6553e97b7e91..ab5e60692b4da 100644
--- a/src/librustc_error_codes/error_codes/E0737.md
+++ b/src/librustc_error_codes/error_codes/E0737.md
@@ -5,8 +5,6 @@ restrictions.
Erroneous code example:
```compile_fail,E0737
-#![feature(track_caller)]
-
#[track_caller]
extern "C" fn foo() {}
```
diff --git a/src/librustc_error_codes/error_codes/E0739.md b/src/librustc_error_codes/error_codes/E0739.md
index 707751066edbc..8d9039bef93f6 100644
--- a/src/librustc_error_codes/error_codes/E0739.md
+++ b/src/librustc_error_codes/error_codes/E0739.md
@@ -3,7 +3,6 @@
Erroneous code example:
```compile_fail,E0739
-#![feature(track_caller)]
#[track_caller]
struct Bar {
a: u8,
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 0c1418d3cad27..362913ceadf18 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -5,7 +5,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(crate_visibility_modifier)]
#![feature(nll)]
-#![feature(track_caller)]
+#![cfg_attr(bootstrap, feature(track_caller))]
pub use emitter::ColorConfig;
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index 8cdb5b09c9e8b..28a3970918ee6 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -224,7 +224,7 @@ fn generic_extension<'cx>(
let sess = cx.parse_sess;
if cx.trace_macros() {
- let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone()));
+ let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(&arg));
trace_macros_note(&mut cx.expansions, sp, msg);
}
@@ -300,7 +300,7 @@ fn generic_extension<'cx>(
}
if cx.trace_macros() {
- let msg = format!("to `{}`", pprust::tts_to_string(tts.clone()));
+ let msg = format!("to `{}`", pprust::tts_to_string(&tts));
trace_macros_note(&mut cx.expansions, sp, msg);
}
diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs
index c88b5a37f718a..e5e530227e43a 100644
--- a/src/librustc_expand/proc_macro_server.rs
+++ b/src/librustc_expand/proc_macro_server.rs
@@ -413,7 +413,7 @@ impl server::TokenStream for Rustc<'_> {
)
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
- pprust::tts_to_string(stream.clone())
+ pprust::tts_to_string(stream)
}
fn from_token_tree(
&mut self,
diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs
index b164b21913d6e..d93c17b05b498 100644
--- a/src/librustc_feature/accepted.rs
+++ b/src/librustc_feature/accepted.rs
@@ -265,6 +265,9 @@ declare_features! (
(accepted, const_if_match, "1.45.0", Some(49146), None),
/// Allows the use of `loop` and `while` in constants.
(accepted, const_loop, "1.45.0", Some(52000), None),
+ /// Allows `#[track_caller]` to be used which provides
+ /// accurate caller location reporting during panic (RFC 2091).
+ (accepted, track_caller, "1.46.0", Some(47809), None),
// -------------------------------------------------------------------------
// feature-group-end: accepted features
diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs
index 8660d6a8d6410..b9a55377949f2 100644
--- a/src/librustc_feature/active.rs
+++ b/src/librustc_feature/active.rs
@@ -494,10 +494,6 @@ declare_features! (
/// Allows the use of raw-dylibs (RFC 2627).
(active, raw_dylib, "1.40.0", Some(58713), None),
- /// Allows `#[track_caller]` to be used which provides
- /// accurate caller location reporting during panic (RFC 2091).
- (active, track_caller, "1.40.0", Some(47809), None),
-
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.
diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs
index 524a357971029..c9a34f033758b 100644
--- a/src/librustc_feature/builtin_attrs.rs
+++ b/src/librustc_feature/builtin_attrs.rs
@@ -260,6 +260,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(cold, Whitelisted, template!(Word)),
ungated!(no_builtins, Whitelisted, template!(Word)),
ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
+ ungated!(track_caller, Whitelisted, template!(Word)),
gated!(
no_sanitize, Whitelisted,
template!(List: "address, memory, thread"),
@@ -333,7 +334,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
gated!(ffi_pure, Whitelisted, template!(Word), experimental!(ffi_pure)),
gated!(ffi_const, Whitelisted, template!(Word), experimental!(ffi_const)),
- gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),
gated!(
register_attr, CrateLevel, template!(List: "attr1, attr2, ..."),
experimental!(register_attr),
diff --git a/src/librustc_infer/infer/at.rs b/src/librustc_infer/infer/at.rs
index d44b8f554143c..a7749d33b7c13 100644
--- a/src/librustc_infer/infer/at.rs
+++ b/src/librustc_infer/infer/at.rs
@@ -82,7 +82,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
- self.trace_exp(a_is_expected, a, b).sub(&a, &b)
+ self.trace_exp(a_is_expected, a, b).sub(a, b)
}
/// Makes `actual <: expected`. For example, if type-checking a
@@ -109,7 +109,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
- self.trace_exp(a_is_expected, a, b).eq(&a, &b)
+ self.trace_exp(a_is_expected, a, b).eq(a, b)
}
/// Makes `expected <: actual`.
@@ -117,7 +117,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
- self.trace(expected, actual).eq(&expected, &actual)
+ self.trace(expected, actual).eq(expected, actual)
}
pub fn relate(self, expected: T, variance: ty::Variance, actual: T) -> InferResult<'tcx, ()>
@@ -147,7 +147,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
- self.trace(expected, actual).lub(&expected, &actual)
+ self.trace(expected, actual).lub(expected, actual)
}
/// Computes the greatest-lower-bound, or mutual subtype, of two
@@ -157,7 +157,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
where
T: ToTrace<'tcx>,
{
- self.trace(expected, actual).glb(&expected, &actual)
+ self.trace(expected, actual).glb(expected, actual)
}
/// Sets the "trace" values that will be used for
@@ -186,7 +186,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
impl<'a, 'tcx> Trace<'a, 'tcx> {
/// Makes `a <: b` where `a` may or may not be expected (if
/// `a_is_expected` is true, then `a` is expected).
- pub fn sub(self, a: &T, b: &T) -> InferResult<'tcx, ()>
+ pub fn sub(self, a: T, b: T) -> InferResult<'tcx, ()>
where
T: Relate<'tcx>,
{
@@ -203,7 +203,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
/// Makes `a == b`; the expectation is set by the call to
/// `trace()`.
- pub fn eq(self, a: &T, b: &T) -> InferResult<'tcx, ()>
+ pub fn eq(self, a: T, b: T) -> InferResult<'tcx, ()>
where
T: Relate<'tcx>,
{
@@ -218,7 +218,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
})
}
- pub fn lub(self, a: &T, b: &T) -> InferResult<'tcx, T>
+ pub fn lub(self, a: T, b: T) -> InferResult<'tcx, T>
where
T: Relate<'tcx>,
{
@@ -233,7 +233,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
})
}
- pub fn glb(self, a: &T, b: &T) -> InferResult<'tcx, T>
+ pub fn glb(self, a: T, b: T) -> InferResult<'tcx, T>
where
T: Relate<'tcx>,
{
diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/src/librustc_infer/infer/canonical/query_response.rs
index 8af526e3ad31b..5cba581b9dffb 100644
--- a/src/librustc_infer/infer/canonical/query_response.rs
+++ b/src/librustc_infer/infer/canonical/query_response.rs
@@ -271,7 +271,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
},
ty::Variance::Invariant,
)
- .relate(&v1, &v2)?;
+ .relate(v1, v2)?;
}
(GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
@@ -285,7 +285,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
},
ty::Variance::Invariant,
)
- .relate(&v1, &v2)?;
+ .relate(v1, v2)?;
}
_ => {
@@ -302,7 +302,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
// Screen out `'a: 'a` cases -- we skip the binder here but
// only compare the inner values to one another, so they are still at
// consistent binding levels.
- let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
+ let ty::OutlivesPredicate(k1, r2) = r_c.skip_binder();
if k1 != r2.into() { Some(r_c) } else { None }
}),
);
@@ -526,7 +526,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
) -> impl Iterator- > + 'a + Captures<'tcx> {
unsubstituted_region_constraints.iter().map(move |constraint| {
let constraint = substitute_value(self.tcx, result_subst, constraint);
- let &ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
+ let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
Obligation::new(
cause.clone(),
diff --git a/src/librustc_infer/infer/combine.rs b/src/librustc_infer/infer/combine.rs
index 4ef4ed47cb11a..c8d4e9f0e14b9 100644
--- a/src/librustc_infer/infer/combine.rs
+++ b/src/librustc_infer/infer/combine.rs
@@ -318,10 +318,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
// to associate causes/spans with each of the relations in
// the stack to get this right.
match dir {
- EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty),
- SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty),
+ EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
+ SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
SupertypeOf => {
- self.sub(a_is_expected).relate_with_variance(ty::Contravariant, &a_ty, &b_ty)
+ self.sub(a_is_expected).relate_with_variance(ty::Contravariant, a_ty, b_ty)
}
}?;
@@ -379,7 +379,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
param_env: self.param_env,
};
- let ty = match generalize.relate(&ty, &ty) {
+ let ty = match generalize.relate(ty, ty) {
Ok(ty) => ty,
Err(e) => {
debug!("generalize: failure {:?}", e);
@@ -490,8 +490,8 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -519,8 +519,8 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
let old_ambient_variance = self.ambient_variance;
self.ambient_variance = self.ambient_variance.xform(variance);
@@ -552,7 +552,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
match probe {
TypeVariableValue::Known { value: u } => {
debug!("generalize: known value {:?}", u);
- self.relate(&u, &u)
+ self.relate(u, u)
}
TypeVariableValue::Unknown { universe } => {
match self.ambient_variance {
@@ -655,7 +655,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
let variable_table = &mut inner.const_unification_table();
let var_value = variable_table.probe_value(vid);
match var_value.val {
- ConstVariableValue::Known { value: u } => self.relate(&u, &u),
+ ConstVariableValue::Known { value: u } => self.relate(u, u),
ConstVariableValue::Unknown { universe } => {
if self.for_universe.can_name(universe) {
Ok(c)
diff --git a/src/librustc_infer/infer/equate.rs b/src/librustc_infer/infer/equate.rs
index e3cafb82719dd..7de752d1de0db 100644
--- a/src/librustc_infer/infer/equate.rs
+++ b/src/librustc_infer/infer/equate.rs
@@ -59,8 +59,8 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
fn relate_with_variance>(
&mut self,
_: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
self.relate(a, b)
}
@@ -124,8 +124,8 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -136,7 +136,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
} else {
// Fast path for the common case.
self.relate(a.skip_binder(), b.skip_binder())?;
- Ok(a.clone())
+ Ok(a)
}
}
}
diff --git a/src/librustc_infer/infer/glb.rs b/src/librustc_infer/infer/glb.rs
index ec219a95b9441..8a0ab52f38306 100644
--- a/src/librustc_infer/infer/glb.rs
+++ b/src/librustc_infer/infer/glb.rs
@@ -43,8 +43,8 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
match variance {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
@@ -85,8 +85,8 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -112,8 +112,8 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx,
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected);
- sub.relate(&v, &a)?;
- sub.relate(&v, &b)?;
+ sub.relate(v, a)?;
+ sub.relate(v, b)?;
Ok(())
}
}
diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs
index b6251e34008a3..ea19dff7db125 100644
--- a/src/librustc_infer/infer/higher_ranked/mod.rs
+++ b/src/librustc_infer/infer/higher_ranked/mod.rs
@@ -11,8 +11,8 @@ use rustc_middle::ty::{self, Binder, TypeFoldable};
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
pub fn higher_ranked_sub(
&mut self,
- a: &Binder,
- b: &Binder,
+ a: Binder,
+ b: Binder,
a_is_expected: bool,
) -> RelateResult<'tcx, Binder>
where
@@ -33,20 +33,20 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
self.infcx.commit_if_ok(|_| {
// First, we instantiate each bound region in the supertype with a
// fresh placeholder region.
- let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(b);
+ let (b_prime, _) = self.infcx.replace_bound_vars_with_placeholders(&b);
// Next, we instantiate each bound region in the subtype
// with a fresh region variable. These region variables --
// but no other pre-existing region variables -- can name
// the placeholders.
let (a_prime, _) =
- self.infcx.replace_bound_vars_with_fresh_vars(span, HigherRankedType, a);
+ self.infcx.replace_bound_vars_with_fresh_vars(span, HigherRankedType, &a);
debug!("a_prime={:?}", a_prime);
debug!("b_prime={:?}", b_prime);
// Compare types now that bound regions have been replaced.
- let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?;
+ let result = self.sub(a_is_expected).relate(a_prime, b_prime)?;
debug!("higher_ranked_sub: OK result={:?}", result);
diff --git a/src/librustc_infer/infer/lub.rs b/src/librustc_infer/infer/lub.rs
index a0453db2cb499..3e2ea3d0f8fbf 100644
--- a/src/librustc_infer/infer/lub.rs
+++ b/src/librustc_infer/infer/lub.rs
@@ -43,8 +43,8 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
match variance {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
@@ -85,8 +85,8 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -97,7 +97,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
// very challenging, switch to invariance. This is obviously
// overly conservative but works ok in practice.
self.relate_with_variance(ty::Variance::Invariant, a, b)?;
- Ok(a.clone())
+ Ok(a)
}
}
@@ -118,8 +118,8 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx,
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected);
- sub.relate(&a, &v)?;
- sub.relate(&b, &v)?;
+ sub.relate(a, v)?;
+ sub.relate(b, v)?;
Ok(())
}
}
diff --git a/src/librustc_infer/infer/nll_relate/mod.rs b/src/librustc_infer/infer/nll_relate/mod.rs
index 2350c28dfaaff..cb1f1c08d88f8 100644
--- a/src/librustc_infer/infer/nll_relate/mod.rs
+++ b/src/librustc_infer/infer/nll_relate/mod.rs
@@ -161,7 +161,7 @@ where
fn create_scope(
&mut self,
- value: &ty::Binder>,
+ value: ty::Binder>,
universally_quantified: UniversallyQuantified,
) -> BoundRegionScope<'tcx> {
let mut scope = BoundRegionScope::default();
@@ -369,7 +369,7 @@ where
universe,
};
- generalizer.relate(&value, &value)
+ generalizer.relate(value, value)
}
}
@@ -495,8 +495,8 @@ where
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
debug!("relate_with_variance(variance={:?}, a={:?}, b={:?})", variance, a, b);
@@ -613,8 +613,8 @@ where
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -640,11 +640,10 @@ where
debug!("binders({:?}: {:?}, ambient_variance={:?})", a, b, self.ambient_variance);
- if !a.skip_binder().has_escaping_bound_vars() && !b.skip_binder().has_escaping_bound_vars()
- {
+ if let (Some(a), Some(b)) = (a.no_bound_vars(), b.no_bound_vars()) {
// Fast path for the common case.
- self.relate(a.skip_binder(), b.skip_binder())?;
- return Ok(a.clone());
+ self.relate(a, b)?;
+ return Ok(ty::Binder::bind(a));
}
if self.ambient_covariance() {
@@ -839,8 +838,8 @@ where
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
debug!(
"TypeGeneralizer::relate_with_variance(variance={:?}, a={:?}, b={:?})",
@@ -890,7 +889,7 @@ where
match variables.probe(vid) {
TypeVariableValue::Known { value: u } => {
drop(variables);
- self.relate(&u, &u)
+ self.relate(u, u)
}
TypeVariableValue::Unknown { universe: _universe } => {
if self.ambient_variance == ty::Bivariant {
@@ -984,7 +983,7 @@ where
let variable_table = &mut inner.const_unification_table();
let var_value = variable_table.probe_value(vid);
match var_value.val.known() {
- Some(u) => self.relate(&u, &u),
+ Some(u) => self.relate(u, u),
None => {
let new_var_id = variable_table.new_key(ConstVarValue {
origin: var_value.origin,
@@ -1001,8 +1000,8 @@ where
fn binders(
&mut self,
- a: &ty::Binder,
- _: &ty::Binder,
+ a: ty::Binder,
+ _: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
diff --git a/src/librustc_infer/infer/sub.rs b/src/librustc_infer/infer/sub.rs
index 90962d210b5b4..d190f7e434298 100644
--- a/src/librustc_infer/infer/sub.rs
+++ b/src/librustc_infer/infer/sub.rs
@@ -62,8 +62,8 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
match variance {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
@@ -162,8 +162,8 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 36d2954ac6ef7..d55cbbe19c279 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -911,7 +911,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
}
let sig = cx.tables().node_type(expr.hir_id).fn_sig(cx.tcx);
let from = sig.inputs().skip_binder()[0];
- let to = *sig.output().skip_binder();
+ let to = sig.output().skip_binder();
return Some((from, to));
}
None
diff --git a/src/librustc_middle/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs
index ef6247881c0be..8f15c99f951fe 100644
--- a/src/librustc_middle/ich/impls_ty.rs
+++ b/src/librustc_middle/ich/impls_ty.rs
@@ -123,7 +123,7 @@ where
T: HashStable>,
{
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
- self.skip_binder().hash_stable(hcx, hasher);
+ self.as_ref().skip_binder().hash_stable(hcx, hasher);
}
}
diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs
index 676346fbebdd1..96b8ca27183ed 100644
--- a/src/librustc_middle/lib.rs
+++ b/src/librustc_middle/lib.rs
@@ -42,7 +42,7 @@
#![feature(or_patterns)]
#![feature(range_is_empty)]
#![feature(min_specialization)]
-#![feature(track_caller)]
+#![cfg_attr(bootstrap, feature(track_caller))]
#![feature(trusted_len)]
#![feature(stmt_expr_attributes)]
#![feature(test)]
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 0ed0d9050078c..ae59f8c542d8c 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -19,7 +19,6 @@ use rustc_target::abi::VariantIdx;
use polonius_engine::Atom;
pub use rustc_ast::ast::Mutability;
-use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::dominators::{dominators, Dominators};
use rustc_data_structures::graph::{self, GraphSuccessors};
@@ -45,6 +44,8 @@ pub mod mono;
mod predecessors;
mod query;
pub mod tcx;
+pub mod terminator;
+pub use terminator::*;
pub mod traversal;
mod type_foldable;
pub mod visit;
@@ -1046,191 +1047,6 @@ pub struct BasicBlockData<'tcx> {
pub is_cleanup: bool,
}
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Terminator<'tcx> {
- pub source_info: SourceInfo,
- pub kind: TerminatorKind<'tcx>,
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
-pub enum TerminatorKind<'tcx> {
- /// Block should have one successor in the graph; we jump there.
- Goto { target: BasicBlock },
-
- /// Operand evaluates to an integer; jump depending on its value
- /// to one of the targets, and otherwise fallback to `otherwise`.
- SwitchInt {
- /// The discriminant value being tested.
- discr: Operand<'tcx>,
-
- /// The type of value being tested.
- /// This is always the same as the type of `discr`.
- /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
- switch_ty: Ty<'tcx>,
-
- /// Possible values. The locations to branch to in each case
- /// are found in the corresponding indices from the `targets` vector.
- values: Cow<'tcx, [u128]>,
-
- /// Possible branch sites. The last element of this vector is used
- /// for the otherwise branch, so targets.len() == values.len() + 1
- /// should hold.
- //
- // This invariant is quite non-obvious and also could be improved.
- // One way to make this invariant is to have something like this instead:
- //
- // branches: Vec<(ConstInt, BasicBlock)>,
- // otherwise: Option // exhaustive if None
- //
- // However we’ve decided to keep this as-is until we figure a case
- // where some other approach seems to be strictly better than other.
- targets: Vec,
- },
-
- /// Indicates that the landing pad is finished and unwinding should
- /// continue. Emitted by `build::scope::diverge_cleanup`.
- Resume,
-
- /// Indicates that the landing pad is finished and that the process
- /// should abort. Used to prevent unwinding for foreign items.
- Abort,
-
- /// Indicates a normal return. The return place should have
- /// been filled in before this executes. This can occur multiple times
- /// in different basic blocks.
- Return,
-
- /// Indicates a terminator that can never be reached.
- Unreachable,
-
- /// Drop the `Place`.
- Drop { place: Place<'tcx>, target: BasicBlock, unwind: Option },
-
- /// Drop the `Place` and assign the new value over it. This ensures
- /// that the assignment to `P` occurs *even if* the destructor for
- /// place unwinds. Its semantics are best explained by the
- /// elaboration:
- ///
- /// ```
- /// BB0 {
- /// DropAndReplace(P <- V, goto BB1, unwind BB2)
- /// }
- /// ```
- ///
- /// becomes
- ///
- /// ```
- /// BB0 {
- /// Drop(P, goto BB1, unwind BB2)
- /// }
- /// BB1 {
- /// // P is now uninitialized
- /// P <- V
- /// }
- /// BB2 {
- /// // P is now uninitialized -- its dtor panicked
- /// P <- V
- /// }
- /// ```
- DropAndReplace {
- place: Place<'tcx>,
- value: Operand<'tcx>,
- target: BasicBlock,
- unwind: Option,
- },
-
- /// Block ends with a call of a converging function.
- Call {
- /// The function that’s being called.
- func: Operand<'tcx>,
- /// Arguments the function is called with.
- /// These are owned by the callee, which is free to modify them.
- /// This allows the memory occupied by "by-value" arguments to be
- /// reused across function calls without duplicating the contents.
- args: Vec>,
- /// Destination for the return value. If some, the call is converging.
- destination: Option<(Place<'tcx>, BasicBlock)>,
- /// Cleanups to be done if the call unwinds.
- cleanup: Option,
- /// `true` if this is from a call in HIR rather than from an overloaded
- /// operator. True for overloaded function call.
- from_hir_call: bool,
- /// This `Span` is the span of the function, without the dot and receiver
- /// (e.g. `foo(a, b)` in `x.foo(a, b)`
- fn_span: Span,
- },
-
- /// Jump to the target if the condition has the expected value,
- /// otherwise panic with a message and a cleanup target.
- Assert {
- cond: Operand<'tcx>,
- expected: bool,
- msg: AssertMessage<'tcx>,
- target: BasicBlock,
- cleanup: Option,
- },
-
- /// A suspend point.
- Yield {
- /// The value to return.
- value: Operand<'tcx>,
- /// Where to resume to.
- resume: BasicBlock,
- /// The place to store the resume argument in.
- resume_arg: Place<'tcx>,
- /// Cleanup to be done if the generator is dropped at this suspend point.
- drop: Option,
- },
-
- /// Indicates the end of the dropping of a generator.
- GeneratorDrop,
-
- /// A block where control flow only ever takes one real path, but borrowck
- /// needs to be more conservative.
- FalseEdge {
- /// The target normal control flow will take.
- real_target: BasicBlock,
- /// A block control flow could conceptually jump to, but won't in
- /// practice.
- imaginary_target: BasicBlock,
- },
- /// A terminator for blocks that only take one path in reality, but where we
- /// reserve the right to unwind in borrowck, even if it won't happen in practice.
- /// This can arise in infinite loops with no function calls for example.
- FalseUnwind {
- /// The target normal control flow will take.
- real_target: BasicBlock,
- /// The imaginary cleanup block link. This particular path will never be taken
- /// in practice, but in order to avoid fragility we want to always
- /// consider it in borrowck. We don't want to accept programs which
- /// pass borrowck only when `panic=abort` or some assertions are disabled
- /// due to release vs. debug mode builds. This needs to be an `Option` because
- /// of the `remove_noop_landing_pads` and `no_landing_pads` passes.
- unwind: Option,
- },
-
- /// Block ends with an inline assembly block. This is a terminator since
- /// inline assembly is allowed to diverge.
- InlineAsm {
- /// The template for the inline assembly, with placeholders.
- template: &'tcx [InlineAsmTemplatePiece],
-
- /// The operands for the inline assembly, as `Operand`s or `Place`s.
- operands: Vec>,
-
- /// Miscellaneous options for the inline assembly.
- options: InlineAsmOptions,
-
- /// Source spans for each line of the inline assembly code. These are
- /// used to map assembler errors back to the line in the source code.
- line_spans: &'tcx [Span],
-
- /// Destination block after the inline assembly returns, unless it is
- /// diverging (InlineAsmOptions::NORETURN).
- destination: Option,
- },
-}
-
/// Information about an assertion failure.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
pub enum AssertKind {
@@ -1279,149 +1095,6 @@ pub type Successors<'a> =
pub type SuccessorsMut<'a> =
iter::Chain, slice::IterMut<'a, BasicBlock>>;
-impl<'tcx> Terminator<'tcx> {
- pub fn successors(&self) -> Successors<'_> {
- self.kind.successors()
- }
-
- pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
- self.kind.successors_mut()
- }
-
- pub fn unwind(&self) -> Option<&Option> {
- self.kind.unwind()
- }
-
- pub fn unwind_mut(&mut self) -> Option<&mut Option> {
- self.kind.unwind_mut()
- }
-}
-
-impl<'tcx> TerminatorKind<'tcx> {
- pub fn if_(
- tcx: TyCtxt<'tcx>,
- cond: Operand<'tcx>,
- t: BasicBlock,
- f: BasicBlock,
- ) -> TerminatorKind<'tcx> {
- static BOOL_SWITCH_FALSE: &[u128] = &[0];
- TerminatorKind::SwitchInt {
- discr: cond,
- switch_ty: tcx.types.bool,
- values: From::from(BOOL_SWITCH_FALSE),
- targets: vec![f, t],
- }
- }
-
- pub fn successors(&self) -> Successors<'_> {
- use self::TerminatorKind::*;
- match *self {
- Resume
- | Abort
- | GeneratorDrop
- | Return
- | Unreachable
- | Call { destination: None, cleanup: None, .. }
- | InlineAsm { destination: None, .. } => None.into_iter().chain(&[]),
- Goto { target: ref t }
- | Call { destination: None, cleanup: Some(ref t), .. }
- | Call { destination: Some((_, ref t)), cleanup: None, .. }
- | Yield { resume: ref t, drop: None, .. }
- | DropAndReplace { target: ref t, unwind: None, .. }
- | Drop { target: ref t, unwind: None, .. }
- | Assert { target: ref t, cleanup: None, .. }
- | FalseUnwind { real_target: ref t, unwind: None }
- | InlineAsm { destination: Some(ref t), .. } => Some(t).into_iter().chain(&[]),
- Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. }
- | Yield { resume: ref t, drop: Some(ref u), .. }
- | DropAndReplace { target: ref t, unwind: Some(ref u), .. }
- | Drop { target: ref t, unwind: Some(ref u), .. }
- | Assert { target: ref t, cleanup: Some(ref u), .. }
- | FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
- Some(t).into_iter().chain(slice::from_ref(u))
- }
- SwitchInt { ref targets, .. } => None.into_iter().chain(&targets[..]),
- FalseEdge { ref real_target, ref imaginary_target } => {
- Some(real_target).into_iter().chain(slice::from_ref(imaginary_target))
- }
- }
- }
-
- pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
- use self::TerminatorKind::*;
- match *self {
- Resume
- | Abort
- | GeneratorDrop
- | Return
- | Unreachable
- | Call { destination: None, cleanup: None, .. }
- | InlineAsm { destination: None, .. } => None.into_iter().chain(&mut []),
- Goto { target: ref mut t }
- | Call { destination: None, cleanup: Some(ref mut t), .. }
- | Call { destination: Some((_, ref mut t)), cleanup: None, .. }
- | Yield { resume: ref mut t, drop: None, .. }
- | DropAndReplace { target: ref mut t, unwind: None, .. }
- | Drop { target: ref mut t, unwind: None, .. }
- | Assert { target: ref mut t, cleanup: None, .. }
- | FalseUnwind { real_target: ref mut t, unwind: None }
- | InlineAsm { destination: Some(ref mut t), .. } => Some(t).into_iter().chain(&mut []),
- Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. }
- | Yield { resume: ref mut t, drop: Some(ref mut u), .. }
- | DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. }
- | Drop { target: ref mut t, unwind: Some(ref mut u), .. }
- | Assert { target: ref mut t, cleanup: Some(ref mut u), .. }
- | FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
- Some(t).into_iter().chain(slice::from_mut(u))
- }
- SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets[..]),
- FalseEdge { ref mut real_target, ref mut imaginary_target } => {
- Some(real_target).into_iter().chain(slice::from_mut(imaginary_target))
- }
- }
- }
-
- pub fn unwind(&self) -> Option<&Option> {
- match *self {
- TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
- | TerminatorKind::Abort
- | TerminatorKind::Return
- | TerminatorKind::Unreachable
- | TerminatorKind::GeneratorDrop
- | TerminatorKind::Yield { .. }
- | TerminatorKind::SwitchInt { .. }
- | TerminatorKind::FalseEdge { .. }
- | TerminatorKind::InlineAsm { .. } => None,
- TerminatorKind::Call { cleanup: ref unwind, .. }
- | TerminatorKind::Assert { cleanup: ref unwind, .. }
- | TerminatorKind::DropAndReplace { ref unwind, .. }
- | TerminatorKind::Drop { ref unwind, .. }
- | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind),
- }
- }
-
- pub fn unwind_mut(&mut self) -> Option<&mut Option> {
- match *self {
- TerminatorKind::Goto { .. }
- | TerminatorKind::Resume
- | TerminatorKind::Abort
- | TerminatorKind::Return
- | TerminatorKind::Unreachable
- | TerminatorKind::GeneratorDrop
- | TerminatorKind::Yield { .. }
- | TerminatorKind::SwitchInt { .. }
- | TerminatorKind::FalseEdge { .. }
- | TerminatorKind::InlineAsm { .. } => None,
- TerminatorKind::Call { cleanup: ref mut unwind, .. }
- | TerminatorKind::Assert { cleanup: ref mut unwind, .. }
- | TerminatorKind::DropAndReplace { ref mut unwind, .. }
- | TerminatorKind::Drop { ref mut unwind, .. }
- | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind),
- }
- }
-}
-
impl<'tcx> BasicBlockData<'tcx> {
pub fn new(terminator: Option>) -> BasicBlockData<'tcx> {
BasicBlockData { statements: vec![], terminator, is_cleanup: false }
@@ -1628,169 +1301,6 @@ impl fmt::Debug for AssertKind {
}
}
-impl<'tcx> Debug for TerminatorKind<'tcx> {
- fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
- self.fmt_head(fmt)?;
- let successor_count = self.successors().count();
- let labels = self.fmt_successor_labels();
- assert_eq!(successor_count, labels.len());
-
- match successor_count {
- 0 => Ok(()),
-
- 1 => write!(fmt, " -> {:?}", self.successors().next().unwrap()),
-
- _ => {
- write!(fmt, " -> [")?;
- for (i, target) in self.successors().enumerate() {
- if i > 0 {
- write!(fmt, ", ")?;
- }
- write!(fmt, "{}: {:?}", labels[i], target)?;
- }
- write!(fmt, "]")
- }
- }
- }
-}
-
-impl<'tcx> TerminatorKind<'tcx> {
- /// Writes the "head" part of the terminator; that is, its name and the data it uses to pick the
- /// successor basic block, if any. The only information not included is the list of possible
- /// successors, which may be rendered differently between the text and the graphviz format.
- pub fn fmt_head(&self, fmt: &mut W) -> fmt::Result {
- use self::TerminatorKind::*;
- match self {
- Goto { .. } => write!(fmt, "goto"),
- SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
- Return => write!(fmt, "return"),
- GeneratorDrop => write!(fmt, "generator_drop"),
- Resume => write!(fmt, "resume"),
- Abort => write!(fmt, "abort"),
- Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
- Unreachable => write!(fmt, "unreachable"),
- Drop { place, .. } => write!(fmt, "drop({:?})", place),
- DropAndReplace { place, value, .. } => {
- write!(fmt, "replace({:?} <- {:?})", place, value)
- }
- Call { func, args, destination, .. } => {
- if let Some((destination, _)) = destination {
- write!(fmt, "{:?} = ", destination)?;
- }
- write!(fmt, "{:?}(", func)?;
- for (index, arg) in args.iter().enumerate() {
- if index > 0 {
- write!(fmt, ", ")?;
- }
- write!(fmt, "{:?}", arg)?;
- }
- write!(fmt, ")")
- }
- Assert { cond, expected, msg, .. } => {
- write!(fmt, "assert(")?;
- if !expected {
- write!(fmt, "!")?;
- }
- write!(fmt, "{:?}, ", cond)?;
- msg.fmt_assert_args(fmt)?;
- write!(fmt, ")")
- }
- FalseEdge { .. } => write!(fmt, "falseEdge"),
- FalseUnwind { .. } => write!(fmt, "falseUnwind"),
- InlineAsm { template, ref operands, options, .. } => {
- write!(fmt, "asm!(\"{}\"", InlineAsmTemplatePiece::to_string(template))?;
- for op in operands {
- write!(fmt, ", ")?;
- let print_late = |&late| if late { "late" } else { "" };
- match op {
- InlineAsmOperand::In { reg, value } => {
- write!(fmt, "in({}) {:?}", reg, value)?;
- }
- InlineAsmOperand::Out { reg, late, place: Some(place) } => {
- write!(fmt, "{}out({}) {:?}", print_late(late), reg, place)?;
- }
- InlineAsmOperand::Out { reg, late, place: None } => {
- write!(fmt, "{}out({}) _", print_late(late), reg)?;
- }
- InlineAsmOperand::InOut {
- reg,
- late,
- in_value,
- out_place: Some(out_place),
- } => {
- write!(
- fmt,
- "in{}out({}) {:?} => {:?}",
- print_late(late),
- reg,
- in_value,
- out_place
- )?;
- }
- InlineAsmOperand::InOut { reg, late, in_value, out_place: None } => {
- write!(fmt, "in{}out({}) {:?} => _", print_late(late), reg, in_value)?;
- }
- InlineAsmOperand::Const { value } => {
- write!(fmt, "const {:?}", value)?;
- }
- InlineAsmOperand::SymFn { value } => {
- write!(fmt, "sym_fn {:?}", value)?;
- }
- InlineAsmOperand::SymStatic { def_id } => {
- write!(fmt, "sym_static {:?}", def_id)?;
- }
- }
- }
- write!(fmt, ", options({:?}))", options)
- }
- }
- }
-
- /// Returns the list of labels for the edges to the successor basic blocks.
- pub fn fmt_successor_labels(&self) -> Vec> {
- use self::TerminatorKind::*;
- match *self {
- Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
- Goto { .. } => vec!["".into()],
- SwitchInt { ref values, switch_ty, .. } => ty::tls::with(|tcx| {
- let param_env = ty::ParamEnv::empty();
- let switch_ty = tcx.lift(&switch_ty).unwrap();
- let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
- values
- .iter()
- .map(|&u| {
- ty::Const::from_scalar(tcx, Scalar::from_uint(u, size), switch_ty)
- .to_string()
- .into()
- })
- .chain(iter::once("otherwise".into()))
- .collect()
- }),
- Call { destination: Some(_), cleanup: Some(_), .. } => {
- vec!["return".into(), "unwind".into()]
- }
- Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()],
- Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()],
- Call { destination: None, cleanup: None, .. } => vec![],
- Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
- Yield { drop: None, .. } => vec!["resume".into()],
- DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {
- vec!["return".into()]
- }
- DropAndReplace { unwind: Some(_), .. } | Drop { unwind: Some(_), .. } => {
- vec!["return".into(), "unwind".into()]
- }
- Assert { cleanup: None, .. } => vec!["".into()],
- Assert { .. } => vec!["success".into(), "unwind".into()],
- FalseEdge { .. } => vec!["real".into(), "imaginary".into()],
- FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()],
- FalseUnwind { unwind: None, .. } => vec!["real".into()],
- InlineAsm { destination: Some(_), .. } => vec!["".into()],
- InlineAsm { destination: None, .. } => vec![],
- }
- }
-}
-
///////////////////////////////////////////////////////////////////////////
// Statements
diff --git a/src/librustc_middle/mir/terminator/mod.rs b/src/librustc_middle/mir/terminator/mod.rs
new file mode 100644
index 0000000000000..1f5041141d55b
--- /dev/null
+++ b/src/librustc_middle/mir/terminator/mod.rs
@@ -0,0 +1,507 @@
+use crate::mir::interpret::Scalar;
+use crate::ty::{self, Ty, TyCtxt};
+use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+
+use super::{
+ AssertMessage, BasicBlock, InlineAsmOperand, Operand, Place, SourceInfo, Successors,
+ SuccessorsMut,
+};
+pub use rustc_ast::ast::Mutability;
+use rustc_macros::HashStable;
+use rustc_span::Span;
+use std::borrow::Cow;
+use std::fmt::{self, Debug, Formatter, Write};
+use std::iter;
+use std::slice;
+
+pub use super::query::*;
+
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)]
+pub enum TerminatorKind<'tcx> {
+ /// Block should have one successor in the graph; we jump there.
+ Goto { target: BasicBlock },
+
+ /// Operand evaluates to an integer; jump depending on its value
+ /// to one of the targets, and otherwise fallback to `otherwise`.
+ SwitchInt {
+ /// The discriminant value being tested.
+ discr: Operand<'tcx>,
+
+ /// The type of value being tested.
+ /// This is always the same as the type of `discr`.
+ /// FIXME: remove this redundant information. Currently, it is relied on by pretty-printing.
+ switch_ty: Ty<'tcx>,
+
+ /// Possible values. The locations to branch to in each case
+ /// are found in the corresponding indices from the `targets` vector.
+ values: Cow<'tcx, [u128]>,
+
+ /// Possible branch sites. The last element of this vector is used
+ /// for the otherwise branch, so targets.len() == values.len() + 1
+ /// should hold.
+ //
+ // This invariant is quite non-obvious and also could be improved.
+ // One way to make this invariant is to have something like this instead:
+ //
+ // branches: Vec<(ConstInt, BasicBlock)>,
+ // otherwise: Option // exhaustive if None
+ //
+ // However we’ve decided to keep this as-is until we figure a case
+ // where some other approach seems to be strictly better than other.
+ targets: Vec,
+ },
+
+ /// Indicates that the landing pad is finished and unwinding should
+ /// continue. Emitted by `build::scope::diverge_cleanup`.
+ Resume,
+
+ /// Indicates that the landing pad is finished and that the process
+ /// should abort. Used to prevent unwinding for foreign items.
+ Abort,
+
+ /// Indicates a normal return. The return place should have
+ /// been filled in before this executes. This can occur multiple times
+ /// in different basic blocks.
+ Return,
+
+ /// Indicates a terminator that can never be reached.
+ Unreachable,
+
+ /// Drop the `Place`.
+ Drop { place: Place<'tcx>, target: BasicBlock, unwind: Option },
+
+ /// Drop the `Place` and assign the new value over it. This ensures
+ /// that the assignment to `P` occurs *even if* the destructor for
+ /// place unwinds. Its semantics are best explained by the
+ /// elaboration:
+ ///
+ /// ```
+ /// BB0 {
+ /// DropAndReplace(P <- V, goto BB1, unwind BB2)
+ /// }
+ /// ```
+ ///
+ /// becomes
+ ///
+ /// ```
+ /// BB0 {
+ /// Drop(P, goto BB1, unwind BB2)
+ /// }
+ /// BB1 {
+ /// // P is now uninitialized
+ /// P <- V
+ /// }
+ /// BB2 {
+ /// // P is now uninitialized -- its dtor panicked
+ /// P <- V
+ /// }
+ /// ```
+ DropAndReplace {
+ place: Place<'tcx>,
+ value: Operand<'tcx>,
+ target: BasicBlock,
+ unwind: Option,
+ },
+
+ /// Block ends with a call of a converging function.
+ Call {
+ /// The function that’s being called.
+ func: Operand<'tcx>,
+ /// Arguments the function is called with.
+ /// These are owned by the callee, which is free to modify them.
+ /// This allows the memory occupied by "by-value" arguments to be
+ /// reused across function calls without duplicating the contents.
+ args: Vec>,
+ /// Destination for the return value. If some, the call is converging.
+ destination: Option<(Place<'tcx>, BasicBlock)>,
+ /// Cleanups to be done if the call unwinds.
+ cleanup: Option,
+ /// `true` if this is from a call in HIR rather than from an overloaded
+ /// operator. True for overloaded function call.
+ from_hir_call: bool,
+ /// This `Span` is the span of the function, without the dot and receiver
+ /// (e.g. `foo(a, b)` in `x.foo(a, b)`
+ fn_span: Span,
+ },
+
+ /// Jump to the target if the condition has the expected value,
+ /// otherwise panic with a message and a cleanup target.
+ Assert {
+ cond: Operand<'tcx>,
+ expected: bool,
+ msg: AssertMessage<'tcx>,
+ target: BasicBlock,
+ cleanup: Option,
+ },
+
+ /// A suspend point.
+ Yield {
+ /// The value to return.
+ value: Operand<'tcx>,
+ /// Where to resume to.
+ resume: BasicBlock,
+ /// The place to store the resume argument in.
+ resume_arg: Place<'tcx>,
+ /// Cleanup to be done if the generator is dropped at this suspend point.
+ drop: Option,
+ },
+
+ /// Indicates the end of the dropping of a generator.
+ GeneratorDrop,
+
+ /// A block where control flow only ever takes one real path, but borrowck
+ /// needs to be more conservative.
+ FalseEdge {
+ /// The target normal control flow will take.
+ real_target: BasicBlock,
+ /// A block control flow could conceptually jump to, but won't in
+ /// practice.
+ imaginary_target: BasicBlock,
+ },
+ /// A terminator for blocks that only take one path in reality, but where we
+ /// reserve the right to unwind in borrowck, even if it won't happen in practice.
+ /// This can arise in infinite loops with no function calls for example.
+ FalseUnwind {
+ /// The target normal control flow will take.
+ real_target: BasicBlock,
+ /// The imaginary cleanup block link. This particular path will never be taken
+ /// in practice, but in order to avoid fragility we want to always
+ /// consider it in borrowck. We don't want to accept programs which
+ /// pass borrowck only when `panic=abort` or some assertions are disabled
+ /// due to release vs. debug mode builds. This needs to be an `Option` because
+ /// of the `remove_noop_landing_pads` and `no_landing_pads` passes.
+ unwind: Option,
+ },
+
+ /// Block ends with an inline assembly block. This is a terminator since
+ /// inline assembly is allowed to diverge.
+ InlineAsm {
+ /// The template for the inline assembly, with placeholders.
+ template: &'tcx [InlineAsmTemplatePiece],
+
+ /// The operands for the inline assembly, as `Operand`s or `Place`s.
+ operands: Vec>,
+
+ /// Miscellaneous options for the inline assembly.
+ options: InlineAsmOptions,
+
+ /// Source spans for each line of the inline assembly code. These are
+ /// used to map assembler errors back to the line in the source code.
+ line_spans: &'tcx [Span],
+
+ /// Destination block after the inline assembly returns, unless it is
+ /// diverging (InlineAsmOptions::NORETURN).
+ destination: Option,
+ },
+}
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
+pub struct Terminator<'tcx> {
+ pub source_info: SourceInfo,
+ pub kind: TerminatorKind<'tcx>,
+}
+
+impl<'tcx> Terminator<'tcx> {
+ pub fn successors(&self) -> Successors<'_> {
+ self.kind.successors()
+ }
+
+ pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
+ self.kind.successors_mut()
+ }
+
+ pub fn unwind(&self) -> Option<&Option> {
+ self.kind.unwind()
+ }
+
+ pub fn unwind_mut(&mut self) -> Option<&mut Option> {
+ self.kind.unwind_mut()
+ }
+}
+
+impl<'tcx> TerminatorKind<'tcx> {
+ pub fn if_(
+ tcx: TyCtxt<'tcx>,
+ cond: Operand<'tcx>,
+ t: BasicBlock,
+ f: BasicBlock,
+ ) -> TerminatorKind<'tcx> {
+ static BOOL_SWITCH_FALSE: &[u128] = &[0];
+ TerminatorKind::SwitchInt {
+ discr: cond,
+ switch_ty: tcx.types.bool,
+ values: From::from(BOOL_SWITCH_FALSE),
+ targets: vec![f, t],
+ }
+ }
+
+ pub fn successors(&self) -> Successors<'_> {
+ use self::TerminatorKind::*;
+ match *self {
+ Resume
+ | Abort
+ | GeneratorDrop
+ | Return
+ | Unreachable
+ | Call { destination: None, cleanup: None, .. }
+ | InlineAsm { destination: None, .. } => None.into_iter().chain(&[]),
+ Goto { target: ref t }
+ | Call { destination: None, cleanup: Some(ref t), .. }
+ | Call { destination: Some((_, ref t)), cleanup: None, .. }
+ | Yield { resume: ref t, drop: None, .. }
+ | DropAndReplace { target: ref t, unwind: None, .. }
+ | Drop { target: ref t, unwind: None, .. }
+ | Assert { target: ref t, cleanup: None, .. }
+ | FalseUnwind { real_target: ref t, unwind: None }
+ | InlineAsm { destination: Some(ref t), .. } => Some(t).into_iter().chain(&[]),
+ Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. }
+ | Yield { resume: ref t, drop: Some(ref u), .. }
+ | DropAndReplace { target: ref t, unwind: Some(ref u), .. }
+ | Drop { target: ref t, unwind: Some(ref u), .. }
+ | Assert { target: ref t, cleanup: Some(ref u), .. }
+ | FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
+ Some(t).into_iter().chain(slice::from_ref(u))
+ }
+ SwitchInt { ref targets, .. } => None.into_iter().chain(&targets[..]),
+ FalseEdge { ref real_target, ref imaginary_target } => {
+ Some(real_target).into_iter().chain(slice::from_ref(imaginary_target))
+ }
+ }
+ }
+
+ pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
+ use self::TerminatorKind::*;
+ match *self {
+ Resume
+ | Abort
+ | GeneratorDrop
+ | Return
+ | Unreachable
+ | Call { destination: None, cleanup: None, .. }
+ | InlineAsm { destination: None, .. } => None.into_iter().chain(&mut []),
+ Goto { target: ref mut t }
+ | Call { destination: None, cleanup: Some(ref mut t), .. }
+ | Call { destination: Some((_, ref mut t)), cleanup: None, .. }
+ | Yield { resume: ref mut t, drop: None, .. }
+ | DropAndReplace { target: ref mut t, unwind: None, .. }
+ | Drop { target: ref mut t, unwind: None, .. }
+ | Assert { target: ref mut t, cleanup: None, .. }
+ | FalseUnwind { real_target: ref mut t, unwind: None }
+ | InlineAsm { destination: Some(ref mut t), .. } => Some(t).into_iter().chain(&mut []),
+ Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. }
+ | Yield { resume: ref mut t, drop: Some(ref mut u), .. }
+ | DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. }
+ | Drop { target: ref mut t, unwind: Some(ref mut u), .. }
+ | Assert { target: ref mut t, cleanup: Some(ref mut u), .. }
+ | FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
+ Some(t).into_iter().chain(slice::from_mut(u))
+ }
+ SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets[..]),
+ FalseEdge { ref mut real_target, ref mut imaginary_target } => {
+ Some(real_target).into_iter().chain(slice::from_mut(imaginary_target))
+ }
+ }
+ }
+
+ pub fn unwind(&self) -> Option<&Option> {
+ match *self {
+ TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::Abort
+ | TerminatorKind::Return
+ | TerminatorKind::Unreachable
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Yield { .. }
+ | TerminatorKind::SwitchInt { .. }
+ | TerminatorKind::FalseEdge { .. }
+ | TerminatorKind::InlineAsm { .. } => None,
+ TerminatorKind::Call { cleanup: ref unwind, .. }
+ | TerminatorKind::Assert { cleanup: ref unwind, .. }
+ | TerminatorKind::DropAndReplace { ref unwind, .. }
+ | TerminatorKind::Drop { ref unwind, .. }
+ | TerminatorKind::FalseUnwind { ref unwind, .. } => Some(unwind),
+ }
+ }
+
+ pub fn unwind_mut(&mut self) -> Option<&mut Option> {
+ match *self {
+ TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::Abort
+ | TerminatorKind::Return
+ | TerminatorKind::Unreachable
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Yield { .. }
+ | TerminatorKind::SwitchInt { .. }
+ | TerminatorKind::FalseEdge { .. }
+ | TerminatorKind::InlineAsm { .. } => None,
+ TerminatorKind::Call { cleanup: ref mut unwind, .. }
+ | TerminatorKind::Assert { cleanup: ref mut unwind, .. }
+ | TerminatorKind::DropAndReplace { ref mut unwind, .. }
+ | TerminatorKind::Drop { ref mut unwind, .. }
+ | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind),
+ }
+ }
+}
+
+impl<'tcx> Debug for TerminatorKind<'tcx> {
+ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
+ self.fmt_head(fmt)?;
+ let successor_count = self.successors().count();
+ let labels = self.fmt_successor_labels();
+ assert_eq!(successor_count, labels.len());
+
+ match successor_count {
+ 0 => Ok(()),
+
+ 1 => write!(fmt, " -> {:?}", self.successors().next().unwrap()),
+
+ _ => {
+ write!(fmt, " -> [")?;
+ for (i, target) in self.successors().enumerate() {
+ if i > 0 {
+ write!(fmt, ", ")?;
+ }
+ write!(fmt, "{}: {:?}", labels[i], target)?;
+ }
+ write!(fmt, "]")
+ }
+ }
+ }
+}
+
+impl<'tcx> TerminatorKind<'tcx> {
+ /// Writes the "head" part of the terminator; that is, its name and the data it uses to pick the
+ /// successor basic block, if any. The only information not included is the list of possible
+ /// successors, which may be rendered differently between the text and the graphviz format.
+ pub fn fmt_head(&self, fmt: &mut W) -> fmt::Result {
+ use self::TerminatorKind::*;
+ match self {
+ Goto { .. } => write!(fmt, "goto"),
+ SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
+ Return => write!(fmt, "return"),
+ GeneratorDrop => write!(fmt, "generator_drop"),
+ Resume => write!(fmt, "resume"),
+ Abort => write!(fmt, "abort"),
+ Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
+ Unreachable => write!(fmt, "unreachable"),
+ Drop { place, .. } => write!(fmt, "drop({:?})", place),
+ DropAndReplace { place, value, .. } => {
+ write!(fmt, "replace({:?} <- {:?})", place, value)
+ }
+ Call { func, args, destination, .. } => {
+ if let Some((destination, _)) = destination {
+ write!(fmt, "{:?} = ", destination)?;
+ }
+ write!(fmt, "{:?}(", func)?;
+ for (index, arg) in args.iter().enumerate() {
+ if index > 0 {
+ write!(fmt, ", ")?;
+ }
+ write!(fmt, "{:?}", arg)?;
+ }
+ write!(fmt, ")")
+ }
+ Assert { cond, expected, msg, .. } => {
+ write!(fmt, "assert(")?;
+ if !expected {
+ write!(fmt, "!")?;
+ }
+ write!(fmt, "{:?}, ", cond)?;
+ msg.fmt_assert_args(fmt)?;
+ write!(fmt, ")")
+ }
+ FalseEdge { .. } => write!(fmt, "falseEdge"),
+ FalseUnwind { .. } => write!(fmt, "falseUnwind"),
+ InlineAsm { template, ref operands, options, .. } => {
+ write!(fmt, "asm!(\"{}\"", InlineAsmTemplatePiece::to_string(template))?;
+ for op in operands {
+ write!(fmt, ", ")?;
+ let print_late = |&late| if late { "late" } else { "" };
+ match op {
+ InlineAsmOperand::In { reg, value } => {
+ write!(fmt, "in({}) {:?}", reg, value)?;
+ }
+ InlineAsmOperand::Out { reg, late, place: Some(place) } => {
+ write!(fmt, "{}out({}) {:?}", print_late(late), reg, place)?;
+ }
+ InlineAsmOperand::Out { reg, late, place: None } => {
+ write!(fmt, "{}out({}) _", print_late(late), reg)?;
+ }
+ InlineAsmOperand::InOut {
+ reg,
+ late,
+ in_value,
+ out_place: Some(out_place),
+ } => {
+ write!(
+ fmt,
+ "in{}out({}) {:?} => {:?}",
+ print_late(late),
+ reg,
+ in_value,
+ out_place
+ )?;
+ }
+ InlineAsmOperand::InOut { reg, late, in_value, out_place: None } => {
+ write!(fmt, "in{}out({}) {:?} => _", print_late(late), reg, in_value)?;
+ }
+ InlineAsmOperand::Const { value } => {
+ write!(fmt, "const {:?}", value)?;
+ }
+ InlineAsmOperand::SymFn { value } => {
+ write!(fmt, "sym_fn {:?}", value)?;
+ }
+ InlineAsmOperand::SymStatic { def_id } => {
+ write!(fmt, "sym_static {:?}", def_id)?;
+ }
+ }
+ }
+ write!(fmt, ", options({:?}))", options)
+ }
+ }
+ }
+
+ /// Returns the list of labels for the edges to the successor basic blocks.
+ pub fn fmt_successor_labels(&self) -> Vec> {
+ use self::TerminatorKind::*;
+ match *self {
+ Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
+ Goto { .. } => vec!["".into()],
+ SwitchInt { ref values, switch_ty, .. } => ty::tls::with(|tcx| {
+ let param_env = ty::ParamEnv::empty();
+ let switch_ty = tcx.lift(&switch_ty).unwrap();
+ let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
+ values
+ .iter()
+ .map(|&u| {
+ ty::Const::from_scalar(tcx, Scalar::from_uint(u, size), switch_ty)
+ .to_string()
+ .into()
+ })
+ .chain(iter::once("otherwise".into()))
+ .collect()
+ }),
+ Call { destination: Some(_), cleanup: Some(_), .. } => {
+ vec!["return".into(), "unwind".into()]
+ }
+ Call { destination: Some(_), cleanup: None, .. } => vec!["return".into()],
+ Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into()],
+ Call { destination: None, cleanup: None, .. } => vec![],
+ Yield { drop: Some(_), .. } => vec!["resume".into(), "drop".into()],
+ Yield { drop: None, .. } => vec!["resume".into()],
+ DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {
+ vec!["return".into()]
+ }
+ DropAndReplace { unwind: Some(_), .. } | Drop { unwind: Some(_), .. } => {
+ vec!["return".into(), "unwind".into()]
+ }
+ Assert { cleanup: None, .. } => vec!["".into()],
+ Assert { .. } => vec!["success".into(), "unwind".into()],
+ FalseEdge { .. } => vec!["real".into(), "imaginary".into()],
+ FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()],
+ FalseUnwind { unwind: None, .. } => vec!["real".into()],
+ InlineAsm { destination: Some(_), .. } => vec!["".into()],
+ InlineAsm { destination: None, .. } => vec![],
+ }
+ }
+}
diff --git a/src/librustc_middle/ty/_match.rs b/src/librustc_middle/ty/_match.rs
index db9229ae3d214..4693a2f66fb4c 100644
--- a/src/librustc_middle/ty/_match.rs
+++ b/src/librustc_middle/ty/_match.rs
@@ -46,8 +46,8 @@ impl TypeRelation<'tcx> for Match<'tcx> {
fn relate_with_variance>(
&mut self,
_: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
self.relate(a, b)
}
@@ -112,8 +112,8 @@ impl TypeRelation<'tcx> for Match<'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs
index 6113359ca93a7..30ff5a2d9ebdf 100644
--- a/src/librustc_middle/ty/error.rs
+++ b/src/librustc_middle/ty/error.rs
@@ -57,7 +57,6 @@ pub enum TypeError<'tcx> {
/// type).
CyclicTy(Ty<'tcx>),
ProjectionMismatched(ExpectedFound),
- ProjectionBoundsLength(ExpectedFound),
ExistentialMismatch(ExpectedFound<&'tcx ty::List>>),
ObjectUnsafeCoercion(DefId),
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
@@ -174,13 +173,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
tcx.def_path_str(values.found)
)
}),
- ProjectionBoundsLength(ref values) => write!(
- f,
- "expected {} associated type binding{}, found {}",
- values.expected,
- pluralize!(values.expected),
- values.found
- ),
ExistentialMismatch(ref values) => report_maybe_different(
f,
&format!("trait `{}`", values.expected),
@@ -216,7 +208,6 @@ impl<'tcx> TypeError<'tcx> {
| RegionsPlaceholderMismatch
| Traits(_)
| ProjectionMismatched(_)
- | ProjectionBoundsLength(_)
| ExistentialMismatch(_)
| ConstMismatch(_)
| IntrinsicCast
diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs
index c782eee938721..0e86fcf53b247 100644
--- a/src/librustc_middle/ty/flags.rs
+++ b/src/librustc_middle/ty/flags.rs
@@ -88,13 +88,13 @@ impl FlagComputation {
self.add_substs(substs);
}
- &ty::GeneratorWitness(ref ts) => {
+ &ty::GeneratorWitness(ts) => {
let mut computation = FlagComputation::new();
- computation.add_tys(&ts.skip_binder()[..]);
+ computation.add_tys(ts.skip_binder());
self.add_bound_computation(computation);
}
- &ty::Closure(_, ref substs) => {
+ &ty::Closure(_, substs) => {
self.add_substs(substs);
}
@@ -122,7 +122,7 @@ impl FlagComputation {
self.add_substs(substs);
}
- &ty::Projection(ref data) => {
+ &ty::Projection(data) => {
self.add_flags(TypeFlags::HAS_TY_PROJECTION);
self.add_projection_ty(data);
}
@@ -211,7 +211,7 @@ impl FlagComputation {
self.add_bound_computation(computation);
}
- ty::PredicateKind::Projection(projection) => {
+ &ty::PredicateKind::Projection(projection) => {
let mut computation = FlagComputation::new();
let ty::ProjectionPredicate { projection_ty, ty } = projection.skip_binder();
computation.add_projection_ty(projection_ty);
@@ -298,7 +298,7 @@ impl FlagComputation {
self.add_ty(projection.ty);
}
- fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy<'_>) {
+ fn add_projection_ty(&mut self, projection_ty: ty::ProjectionTy<'_>) {
self.add_substs(projection_ty.substs);
}
diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs
index 2d25c7c6ac983..492f8ce9ef1a9 100644
--- a/src/librustc_middle/ty/fold.rs
+++ b/src/librustc_middle/ty/fold.rs
@@ -336,7 +336,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
fn visit_binder>(&mut self, t: &Binder) -> bool {
self.outer_index.shift_in(1);
- let result = t.skip_binder().visit_with(self);
+ let result = t.as_ref().skip_binder().visit_with(self);
self.outer_index.shift_out(1);
result
}
@@ -558,7 +558,7 @@ impl<'tcx> TyCtxt<'tcx> {
let fld_c = |bound_ct, ty| {
self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty })
};
- self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
+ self.replace_escaping_bound_vars(value.as_ref().skip_binder(), fld_r, fld_t, fld_c)
}
/// Replaces all escaping bound vars. The `fld_r` closure replaces escaping
@@ -617,7 +617,7 @@ impl<'tcx> TyCtxt<'tcx> {
H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>,
T: TypeFoldable<'tcx>,
{
- self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c)
+ self.replace_escaping_bound_vars(value.as_ref().skip_binder(), fld_r, fld_t, fld_c)
}
/// Replaces any late-bound regions bound in `value` with
@@ -673,7 +673,7 @@ impl<'tcx> TyCtxt<'tcx> {
T: TypeFoldable<'tcx>,
{
let mut collector = LateBoundRegionsCollector::new(just_constraint);
- let result = value.skip_binder().visit_with(&mut collector);
+ let result = value.as_ref().skip_binder().visit_with(&mut collector);
assert!(!result); // should never have stopped early
collector.regions
}
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index e4cc96dd83bfb..39b8566e7a873 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -2303,7 +2303,7 @@ impl<'tcx> ty::Instance<'tcx> {
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
sig.map_bound(|sig| tcx.mk_fn_sig(
- iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
+ iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
sig.output(),
sig.c_variadic,
sig.unsafety,
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 061214249713d..9fa1260f64d74 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -189,7 +189,7 @@ pub trait PrettyPrinter<'tcx>:
where
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
{
- value.skip_binder().print(self)
+ value.as_ref().skip_binder().print(self)
}
/// Prints comma-separated elements.
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs
index e9a8b9095bf72..cee04ce8c6a83 100644
--- a/src/librustc_middle/ty/relate.rs
+++ b/src/librustc_middle/ty/relate.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId;
use rustc_span::DUMMY_SP;
use rustc_target::spec::abi;
use std::iter;
-use std::rc::Rc;
pub type RelateResult<'tcx, T> = Result>;
@@ -42,7 +41,7 @@ pub trait TypeRelation<'tcx>: Sized {
}
/// Generic relation routine suitable for most anything.
- fn relate>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
+ fn relate>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> {
Relate::relate(self, a, b)
}
@@ -68,8 +67,8 @@ pub trait TypeRelation<'tcx>: Sized {
fn relate_with_variance>(
&mut self,
variance: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T>;
// Overridable relations. You shouldn't typically call these
@@ -94,18 +93,18 @@ pub trait TypeRelation<'tcx>: Sized {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>;
}
-pub trait Relate<'tcx>: TypeFoldable<'tcx> {
+pub trait Relate<'tcx>: TypeFoldable<'tcx> + Copy {
fn relate>(
relation: &mut R,
- a: &Self,
- b: &Self,
+ a: Self,
+ b: Self,
) -> RelateResult<'tcx, Self>;
}
@@ -115,8 +114,8 @@ pub trait Relate<'tcx>: TypeFoldable<'tcx> {
impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::TypeAndMut<'tcx>,
- b: &ty::TypeAndMut<'tcx>,
+ a: ty::TypeAndMut<'tcx>,
+ b: ty::TypeAndMut<'tcx>,
) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> {
debug!("{}.mts({:?}, {:?})", relation.tag(), a, b);
if a.mutbl != b.mutbl {
@@ -127,7 +126,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
ast::Mutability::Not => ty::Covariant,
ast::Mutability::Mut => ty::Invariant,
};
- let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?;
+ let ty = relation.relate_with_variance(variance, a.ty, b.ty)?;
Ok(ty::TypeAndMut { ty, mutbl })
}
}
@@ -143,7 +142,7 @@ pub fn relate_substs>(
let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| {
let variance = variances.map_or(ty::Invariant, |v| v[i]);
- relation.relate_with_variance(variance, &a, &b)
+ relation.relate_with_variance(variance, a, b)
});
Ok(tcx.mk_substs(params)?)
@@ -152,8 +151,8 @@ pub fn relate_substs>(
impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::FnSig<'tcx>,
- b: &ty::FnSig<'tcx>,
+ a: ty::FnSig<'tcx>,
+ b: ty::FnSig<'tcx>,
) -> RelateResult<'tcx, ty::FnSig<'tcx>> {
let tcx = relation.tcx();
@@ -164,8 +163,8 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
&b.c_variadic,
)));
}
- let unsafety = relation.relate(&a.unsafety, &b.unsafety)?;
- let abi = relation.relate(&a.abi, &b.abi)?;
+ let unsafety = relation.relate(a.unsafety, b.unsafety)?;
+ let abi = relation.relate(a.abi, b.abi)?;
if a.inputs().len() != b.inputs().len() {
return Err(TypeError::ArgCount);
@@ -180,9 +179,9 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
.chain(iter::once(((a.output(), b.output()), true)))
.map(|((a, b), is_output)| {
if is_output {
- relation.relate(&a, &b)
+ relation.relate(a, b)
} else {
- relation.relate_with_variance(ty::Contravariant, &a, &b)
+ relation.relate_with_variance(ty::Contravariant, a, b)
}
});
Ok(ty::FnSig {
@@ -197,13 +196,13 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
impl<'tcx> Relate<'tcx> for ast::Unsafety {
fn relate>(
relation: &mut R,
- a: &ast::Unsafety,
- b: &ast::Unsafety,
+ a: ast::Unsafety,
+ b: ast::Unsafety,
) -> RelateResult<'tcx, ast::Unsafety> {
if a != b {
- Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
+ Err(TypeError::UnsafetyMismatch(expected_found(relation, &a, &b)))
} else {
- Ok(*a)
+ Ok(a)
}
}
}
@@ -211,18 +210,18 @@ impl<'tcx> Relate<'tcx> for ast::Unsafety {
impl<'tcx> Relate<'tcx> for abi::Abi {
fn relate>(
relation: &mut R,
- a: &abi::Abi,
- b: &abi::Abi,
+ a: abi::Abi,
+ b: abi::Abi,
) -> RelateResult<'tcx, abi::Abi> {
- if a == b { Ok(*a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) }
+ if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(relation, &a, &b))) }
}
}
impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::ProjectionTy<'tcx>,
- b: &ty::ProjectionTy<'tcx>,
+ a: ty::ProjectionTy<'tcx>,
+ b: ty::ProjectionTy<'tcx>,
) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> {
if a.item_def_id != b.item_def_id {
Err(TypeError::ProjectionMismatched(expected_found(
@@ -231,7 +230,7 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
&b.item_def_id,
)))
} else {
- let substs = relation.relate(&a.substs, &b.substs)?;
+ let substs = relation.relate(a.substs, b.substs)?;
Ok(ty::ProjectionTy { item_def_id: a.item_def_id, substs: &substs })
}
}
@@ -240,8 +239,8 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::ExistentialProjection<'tcx>,
- b: &ty::ExistentialProjection<'tcx>,
+ a: ty::ExistentialProjection<'tcx>,
+ b: ty::ExistentialProjection<'tcx>,
) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
if a.item_def_id != b.item_def_id {
Err(TypeError::ProjectionMismatched(expected_found(
@@ -250,37 +249,18 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
&b.item_def_id,
)))
} else {
- let ty = relation.relate_with_variance(ty::Invariant, &a.ty, &b.ty)?;
- let substs = relation.relate_with_variance(ty::Invariant, &a.substs, &b.substs)?;
+ let ty = relation.relate_with_variance(ty::Invariant, a.ty, b.ty)?;
+ let substs = relation.relate_with_variance(ty::Invariant, a.substs, b.substs)?;
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty })
}
}
}
-impl<'tcx> Relate<'tcx> for Vec> {
- fn relate>(
- relation: &mut R,
- a: &Vec>,
- b: &Vec>,
- ) -> RelateResult<'tcx, Vec>> {
- // To be compatible, `a` and `b` must be for precisely the
- // same set of traits and item names. We always require that
- // projection bounds lists are sorted by trait-def-id and item-name,
- // so we can just iterate through the lists pairwise, so long as they are the
- // same length.
- if a.len() != b.len() {
- Err(TypeError::ProjectionBoundsLength(expected_found(relation, &a.len(), &b.len())))
- } else {
- a.iter().zip(b).map(|(a, b)| relation.relate(a, b)).collect()
- }
- }
-}
-
impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::TraitRef<'tcx>,
- b: &ty::TraitRef<'tcx>,
+ a: ty::TraitRef<'tcx>,
+ b: ty::TraitRef<'tcx>,
) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
// Different traits cannot be related.
if a.def_id != b.def_id {
@@ -295,8 +275,8 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::ExistentialTraitRef<'tcx>,
- b: &ty::ExistentialTraitRef<'tcx>,
+ a: ty::ExistentialTraitRef<'tcx>,
+ b: ty::ExistentialTraitRef<'tcx>,
) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
// Different traits cannot be related.
if a.def_id != b.def_id {
@@ -308,18 +288,18 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
}
}
-#[derive(Debug, Clone, TypeFoldable)]
+#[derive(Copy, Debug, Clone, TypeFoldable)]
struct GeneratorWitness<'tcx>(&'tcx ty::List>);
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
fn relate>(
relation: &mut R,
- a: &GeneratorWitness<'tcx>,
- b: &GeneratorWitness<'tcx>,
+ a: GeneratorWitness<'tcx>,
+ b: GeneratorWitness<'tcx>,
) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
assert_eq!(a.0.len(), b.0.len());
let tcx = relation.tcx();
- let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(&a, &b)))?;
+ let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(a, b)))?;
Ok(GeneratorWitness(types))
}
}
@@ -327,8 +307,8 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
impl<'tcx> Relate<'tcx> for Ty<'tcx> {
fn relate>(
relation: &mut R,
- a: &Ty<'tcx>,
- b: &Ty<'tcx>,
+ a: Ty<'tcx>,
+ b: Ty<'tcx>,
) -> RelateResult<'tcx, Ty<'tcx>> {
relation.tys(a, b)
}
@@ -379,7 +359,7 @@ pub fn super_relate_tys>(
(&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(tcx.mk_foreign(a_id)),
- (&ty::Dynamic(ref a_obj, ref a_region), &ty::Dynamic(ref b_obj, ref b_region)) => {
+ (&ty::Dynamic(a_obj, a_region), &ty::Dynamic(b_obj, b_region)) => {
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
relation.relate_with_variance(ty::Contravariant, a_region, b_region)
})?;
@@ -392,7 +372,7 @@ pub fn super_relate_tys>(
// All Generator types with the same id represent
// the (anonymous) type of the same generator expression. So
// all of their regions should be equated.
- let substs = relation.relate(&a_substs, &b_substs)?;
+ let substs = relation.relate(a_substs, b_substs)?;
Ok(tcx.mk_generator(a_id, substs, movability))
}
@@ -402,7 +382,7 @@ pub fn super_relate_tys>(
let a_types = a_types.map_bound(GeneratorWitness);
let b_types = b_types.map_bound(GeneratorWitness);
// Then remove the GeneratorWitness for the result
- let types = relation.relate(&a_types, &b_types)?.map_bound(|witness| witness.0);
+ let types = relation.relate(a_types, b_types)?.map_bound(|witness| witness.0);
Ok(tcx.mk_generator_witness(types))
}
@@ -410,26 +390,26 @@ pub fn super_relate_tys>(
// All Closure types with the same id represent
// the (anonymous) type of the same closure expression. So
// all of their regions should be equated.
- let substs = relation.relate(&a_substs, &b_substs)?;
+ let substs = relation.relate(a_substs, b_substs)?;
Ok(tcx.mk_closure(a_id, &substs))
}
- (&ty::RawPtr(ref a_mt), &ty::RawPtr(ref b_mt)) => {
+ (&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => {
let mt = relation.relate(a_mt, b_mt)?;
Ok(tcx.mk_ptr(mt))
}
(&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
- let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?;
+ let r = relation.relate_with_variance(ty::Contravariant, a_r, b_r)?;
let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
- let mt = relation.relate(&a_mt, &b_mt)?;
+ let mt = relation.relate(a_mt, b_mt)?;
Ok(tcx.mk_ref(r, mt))
}
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => {
- let t = relation.relate(&a_t, &b_t)?;
- match relation.relate(&sz_a, &sz_b) {
+ let t = relation.relate(a_t, b_t)?;
+ match relation.relate(sz_a, sz_b) {
Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
// FIXME(#72219) Implement improved diagnostics for mismatched array
// length?
@@ -450,16 +430,14 @@ pub fn super_relate_tys>(
}
(&ty::Slice(a_t), &ty::Slice(b_t)) => {
- let t = relation.relate(&a_t, &b_t)?;
+ let t = relation.relate(a_t, b_t)?;
Ok(tcx.mk_slice(t))
}
(&ty::Tuple(as_), &ty::Tuple(bs)) => {
if as_.len() == bs.len() {
Ok(tcx.mk_tup(
- as_.iter()
- .zip(bs)
- .map(|(a, b)| relation.relate(&a.expect_ty(), &b.expect_ty())),
+ as_.iter().zip(bs).map(|(a, b)| relation.relate(a.expect_ty(), b.expect_ty())),
)?)
} else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize(expected_found(relation, &as_.len(), &bs.len())))
@@ -476,12 +454,12 @@ pub fn super_relate_tys>(
}
(&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => {
- let fty = relation.relate(&a_fty, &b_fty)?;
+ let fty = relation.relate(a_fty, b_fty)?;
Ok(tcx.mk_fn_ptr(fty))
}
// these two are already handled downstream in case of lazy normalization
- (ty::Projection(a_data), ty::Projection(b_data)) => {
+ (&ty::Projection(a_data), &ty::Projection(b_data)) => {
let projection_ty = relation.relate(a_data, b_data)?;
Ok(tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs))
}
@@ -603,8 +581,8 @@ pub fn super_relate_consts>(
ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
) if a_def_id == b_def_id && a_promoted == b_promoted => {
let substs =
- relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
- Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted))
+ relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
+ Ok(ty::ConstKind::Unevaluated(a_def_id, substs, a_promoted))
}
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
};
@@ -614,8 +592,8 @@ pub fn super_relate_consts>(
impl<'tcx> Relate<'tcx> for &'tcx ty::List> {
fn relate>(
relation: &mut R,
- a: &Self,
- b: &Self,
+ a: Self,
+ b: Self,
) -> RelateResult<'tcx, Self> {
let tcx = relation.tcx();
@@ -629,16 +607,16 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> {
b_v.sort_by(|a, b| a.stable_cmp(tcx, b));
b_v.dedup();
if a_v.len() != b_v.len() {
- return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
+ return Err(TypeError::ExistentialMismatch(expected_found(relation, &a, &b)));
}
let v = a_v.into_iter().zip(b_v.into_iter()).map(|(ep_a, ep_b)| {
use crate::ty::ExistentialPredicate::*;
match (ep_a, ep_b) {
- (Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)),
- (Projection(ref a), Projection(ref b)) => Ok(Projection(relation.relate(a, b)?)),
- (AutoTrait(ref a), AutoTrait(ref b)) if a == b => Ok(AutoTrait(*a)),
- _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
+ (Trait(a), Trait(b)) => Ok(Trait(relation.relate(a, b)?)),
+ (Projection(a), Projection(b)) => Ok(Projection(relation.relate(a, b)?)),
+ (AutoTrait(a), AutoTrait(b)) if a == b => Ok(AutoTrait(a)),
+ _ => Err(TypeError::ExistentialMismatch(expected_found(relation, &a, &b))),
}
});
Ok(tcx.mk_existential_predicates(v)?)
@@ -648,8 +626,8 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> {
impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::ClosureSubsts<'tcx>,
- b: &ty::ClosureSubsts<'tcx>,
+ a: ty::ClosureSubsts<'tcx>,
+ b: ty::ClosureSubsts<'tcx>,
) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
Ok(ty::ClosureSubsts { substs })
@@ -659,8 +637,8 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::GeneratorSubsts<'tcx>,
- b: &ty::GeneratorSubsts<'tcx>,
+ a: ty::GeneratorSubsts<'tcx>,
+ b: ty::GeneratorSubsts<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
Ok(ty::GeneratorSubsts { substs })
@@ -670,8 +648,8 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
fn relate>(
relation: &mut R,
- a: &SubstsRef<'tcx>,
- b: &SubstsRef<'tcx>,
+ a: SubstsRef<'tcx>,
+ b: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
relate_substs(relation, None, a, b)
}
@@ -680,72 +658,48 @@ impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::Region<'tcx>,
- b: &ty::Region<'tcx>,
+ a: ty::Region<'tcx>,
+ b: ty::Region<'tcx>,
) -> RelateResult<'tcx, ty::Region<'tcx>> {
- relation.regions(*a, *b)
+ relation.regions(a, b)
}
}
impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
fn relate>(
relation: &mut R,
- a: &&'tcx ty::Const<'tcx>,
- b: &&'tcx ty::Const<'tcx>,
+ a: &'tcx ty::Const<'tcx>,
+ b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
- relation.consts(*a, *b)
+ relation.consts(a, b)
}
}
impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder {
fn relate>(
relation: &mut R,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder> {
relation.binders(a, b)
}
}
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Rc {
- fn relate>(
- relation: &mut R,
- a: &Rc,
- b: &Rc,
- ) -> RelateResult<'tcx, Rc> {
- let a: &T = a;
- let b: &T = b;
- Ok(Rc::new(relation.relate(a, b)?))
- }
-}
-
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Box {
- fn relate>(
- relation: &mut R,
- a: &Box,
- b: &Box,
- ) -> RelateResult<'tcx, Box> {
- let a: &T = a;
- let b: &T = b;
- Ok(Box::new(relation.relate(a, b)?))
- }
-}
-
impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
fn relate>(
relation: &mut R,
- a: &GenericArg<'tcx>,
- b: &GenericArg<'tcx>,
+ a: GenericArg<'tcx>,
+ b: GenericArg<'tcx>,
) -> RelateResult<'tcx, GenericArg<'tcx>> {
match (a.unpack(), b.unpack()) {
(GenericArgKind::Lifetime(a_lt), GenericArgKind::Lifetime(b_lt)) => {
- Ok(relation.relate(&a_lt, &b_lt)?.into())
+ Ok(relation.relate(a_lt, b_lt)?.into())
}
(GenericArgKind::Type(a_ty), GenericArgKind::Type(b_ty)) => {
- Ok(relation.relate(&a_ty, &b_ty)?.into())
+ Ok(relation.relate(a_ty, b_ty)?.into())
}
(GenericArgKind::Const(a_ct), GenericArgKind::Const(b_ct)) => {
- Ok(relation.relate(&a_ct, &b_ct)?.into())
+ Ok(relation.relate(a_ct, b_ct)?.into())
}
(GenericArgKind::Lifetime(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
@@ -763,22 +717,22 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::TraitPredicate<'tcx>,
- b: &ty::TraitPredicate<'tcx>,
+ a: ty::TraitPredicate<'tcx>,
+ b: ty::TraitPredicate<'tcx>,
) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
- Ok(ty::TraitPredicate { trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)? })
+ Ok(ty::TraitPredicate { trait_ref: relation.relate(a.trait_ref, b.trait_ref)? })
}
}
impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
fn relate>(
relation: &mut R,
- a: &ty::ProjectionPredicate<'tcx>,
- b: &ty::ProjectionPredicate<'tcx>,
+ a: ty::ProjectionPredicate<'tcx>,
+ b: ty::ProjectionPredicate<'tcx>,
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
Ok(ty::ProjectionPredicate {
- projection_ty: relation.relate(&a.projection_ty, &b.projection_ty)?,
- ty: relation.relate(&a.ty, &b.ty)?,
+ projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
+ ty: relation.relate(a.ty, b.ty)?,
})
}
}
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index f736037b5c15a..1d3607fe32ffc 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -514,7 +514,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder {
type Lifted = ty::Binder;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option {
- tcx.lift(self.skip_binder()).map(ty::Binder::bind)
+ tcx.lift(self.as_ref().skip_binder()).map(ty::Binder::bind)
}
}
@@ -655,7 +655,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
VariadicMismatch(x) => VariadicMismatch(x),
CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
ProjectionMismatched(x) => ProjectionMismatched(x),
- ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
Sorts(ref x) => return tcx.lift(x).map(Sorts),
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
@@ -798,7 +797,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder {
}
fn super_visit_with>(&self, visitor: &mut V) -> bool {
- self.skip_binder().visit_with(visitor)
+ self.as_ref().skip_binder().visit_with(visitor)
}
fn visit_with>(&self, visitor: &mut V) -> bool {
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 8f86d2ef522d3..c7683cefd82f6 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -615,7 +615,7 @@ impl<'tcx> ExistentialPredicate<'tcx> {
impl<'tcx> Binder> {
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
use crate::ty::ToPredicate;
- match *self.skip_binder() {
+ match self.skip_binder() {
ExistentialPredicate::Trait(tr) => {
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
}
@@ -776,7 +776,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> {
// Note that we preserve binding levels
- Binder(ty::TraitPredicate { trait_ref: *self.skip_binder() })
+ Binder(ty::TraitPredicate { trait_ref: self.skip_binder() })
}
}
@@ -880,8 +880,8 @@ impl Binder {
/// - extracting the `DefId` from a PolyTraitRef;
/// - comparing the self type of a PolyTraitRef to see if it is equal to
/// a type parameter `X`, since the type `X` does not reference any regions
- pub fn skip_binder(&self) -> &T {
- &self.0
+ pub fn skip_binder(self) -> T {
+ self.0
}
pub fn as_ref(&self) -> Binder<&T> {
@@ -916,11 +916,7 @@ impl Binder {
where
T: TypeFoldable<'tcx>,
{
- if self.skip_binder().has_escaping_bound_vars() {
- None
- } else {
- Some(self.skip_binder().clone())
- }
+ if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
}
/// Given two things that have the same binder level,
@@ -997,7 +993,7 @@ impl<'tcx> ProjectionTy<'tcx> {
}
}
-#[derive(Clone, Debug, TypeFoldable)]
+#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct GenSig<'tcx> {
pub resume_ty: Ty<'tcx>,
pub yield_ty: Ty<'tcx>,
diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs
index 633d4fda8a46d..82c649b8f543b 100644
--- a/src/librustc_middle/ty/walk.rs
+++ b/src/librustc_middle/ty/walk.rs
@@ -133,7 +133,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
ty::Dynamic(obj, lt) => {
stack.push(lt.into());
stack.extend(obj.iter().rev().flat_map(|predicate| {
- let (substs, opt_ty) = match *predicate.skip_binder() {
+ let (substs, opt_ty) = match predicate.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.ty)),
ty::ExistentialPredicate::AutoTrait(_) =>
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index e85f69554d0c8..17846055f6c96 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -1923,7 +1923,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// We use a mix of the HIR and the Ty types to get information
// as the HIR doesn't have full types for closure arguments.
- let return_ty = *sig.output().skip_binder();
+ let return_ty = sig.output().skip_binder();
let mut return_span = fn_decl.output.span();
if let hir::FnRetTy::Return(ty) = &fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
@@ -1965,7 +1965,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let argument_ty = sig.inputs().skip_binder().first()?;
let return_span = fn_decl.output.span();
- let return_ty = *sig.output().skip_binder();
+ let return_ty = sig.output().skip_binder();
// We expect the first argument to be a reference.
match argument_ty.kind {
diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
index 285d9ed64691a..91b1a1fbd9705 100644
--- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
@@ -31,7 +31,7 @@ pub(super) fn relate_types<'tcx>(
NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category),
v,
)
- .relate(&a, &b)?;
+ .relate(a, b)?;
Ok(())
}
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 88ba28dab82e1..01eb2d0b8e266 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -409,6 +409,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
);
self.copy_op(self.operand_index(args[0], index)?, dest)?;
}
+ sym::likely | sym::unlikely => {
+ // These just return their argument
+ self.copy_op(args[0], dest)?;
+ }
// FIXME(#73156): Handle source code coverage in const eval
sym::count_code_region => (),
_ => return Ok(false),
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index ca1f0aecd048a..f00fc96e5915a 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -531,9 +531,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
if is_lang_panic_fn(self.tcx, def_id) {
self.check_op(ops::Panic);
} else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {
- // Exempt unstable const fns inside of macros with
+ // Exempt unstable const fns inside of macros or functions with
// `#[allow_internal_unstable]`.
- if !self.span.allows_unstable(feature) {
+ use crate::transform::qualify_min_const_fn::lib_feature_allowed;
+ if !self.span.allows_unstable(feature)
+ && !lib_feature_allowed(self.tcx, self.def_id, feature)
+ {
self.check_op(ops::FnCallUnstable(def_id, feature));
}
} else {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 5a3663384fb87..2f5257080cd5c 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -328,6 +328,26 @@ fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bo
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}
+/// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
+pub fn lib_feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
+ // All features require that the corresponding gate be enabled,
+ // even if the function has `#[allow_internal_unstable(the_gate)]`.
+ if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_gate) {
+ return false;
+ }
+
+ // If this crate is not using stability attributes, or this function is not claiming to be a
+ // stable `const fn`, that is all that is required.
+ if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
+ return true;
+ }
+
+ // However, we cannot allow stable `const fn`s to use unstable features without an explicit
+ // opt-in via `allow_internal_unstable`.
+ attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
+ .map_or(false, |mut features| features.any(|name| name == feature_gate))
+}
+
fn check_terminator(
tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>,
@@ -367,8 +387,17 @@ fn check_terminator(
fn_span: _,
} => {
let fn_ty = func.ty(body, tcx);
- if let ty::FnDef(def_id, _) = fn_ty.kind {
- if !crate::const_eval::is_min_const_fn(tcx, def_id) {
+ if let ty::FnDef(fn_def_id, _) = fn_ty.kind {
+ // Allow unstable const if we opt in by using #[allow_internal_unstable]
+ // on function or macro declaration.
+ if !crate::const_eval::is_min_const_fn(tcx, fn_def_id)
+ && !crate::const_eval::is_unstable_const_fn(tcx, fn_def_id)
+ .map(|feature| {
+ span.allows_unstable(feature)
+ || lib_feature_allowed(tcx, def_id, feature)
+ })
+ .unwrap_or(false)
+ {
return Err((
span,
format!(
@@ -380,10 +409,10 @@ fn check_terminator(
));
}
- check_operand(tcx, func, span, def_id, body)?;
+ check_operand(tcx, func, span, fn_def_id, body)?;
for arg in args {
- check_operand(tcx, arg, span, def_id, body)?;
+ check_operand(tcx, arg, span, fn_def_id, body)?;
}
Ok(())
} else {
diff --git a/src/librustc_mir/transform/validate.rs b/src/librustc_mir/transform/validate.rs
index d3f486c815e6c..e794a6949d2f0 100644
--- a/src/librustc_mir/transform/validate.rs
+++ b/src/librustc_mir/transform/validate.rs
@@ -74,8 +74,8 @@ pub fn equal_up_to_regions(
fn relate_with_variance>(
&mut self,
_: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
// Ignore variance, require types to be exactly the same.
self.relate(a, b)
@@ -108,8 +108,8 @@ pub fn equal_up_to_regions(
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -121,7 +121,7 @@ pub fn equal_up_to_regions(
// Instantiate and run relation.
let mut relator: LifetimeIgnoreRelation<'tcx> = LifetimeIgnoreRelation { tcx: tcx, param_env };
- relator.relate(&src, &dest).is_ok()
+ relator.relate(src, dest).is_ok()
}
struct TypeChecker<'a, 'tcx> {
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 6ac5d41ec6135..18b92bf29bf1b 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -4,8 +4,8 @@
//! This file includes the logic for exhaustiveness and usefulness checking for
//! pattern-matching. Specifically, given a list of patterns for a type, we can
//! tell whether:
-//! (a) the patterns cover every possible constructor for the type [exhaustiveness]
-//! (b) each pattern is necessary [usefulness]
+//! (a) the patterns cover every possible constructor for the type (exhaustiveness)
+//! (b) each pattern is necessary (usefulness)
//!
//! The algorithm implemented here is a modified version of the one described in:
//! http://moscova.inria.fr/~maranget/papers/warn/index.html
@@ -101,53 +101,54 @@
//! To match the paper, the top of the stack is at the beginning / on the left.
//!
//! There are two important operations on pattern-stacks necessary to understand the algorithm:
-//! 1. We can pop a given constructor off the top of a stack. This operation is called
-//! `specialize`, and is denoted `S(c, p)` where `c` is a constructor (like `Some` or
-//! `None`) and `p` a pattern-stack.
-//! If the pattern on top of the stack can cover `c`, this removes the constructor and
-//! pushes its arguments onto the stack. It also expands OR-patterns into distinct patterns.
-//! Otherwise the pattern-stack is discarded.
-//! This essentially filters those pattern-stacks whose top covers the constructor `c` and
-//! discards the others.
//!
-//! For example, the first pattern above initially gives a stack `[(Some(true), _)]`. If we
-//! pop the tuple constructor, we are left with `[Some(true), _]`, and if we then pop the
-//! `Some` constructor we get `[true, _]`. If we had popped `None` instead, we would get
-//! nothing back.
+//! 1. We can pop a given constructor off the top of a stack. This operation is called
+//! `specialize`, and is denoted `S(c, p)` where `c` is a constructor (like `Some` or
+//! `None`) and `p` a pattern-stack.
+//! If the pattern on top of the stack can cover `c`, this removes the constructor and
+//! pushes its arguments onto the stack. It also expands OR-patterns into distinct patterns.
+//! Otherwise the pattern-stack is discarded.
+//! This essentially filters those pattern-stacks whose top covers the constructor `c` and
+//! discards the others.
//!
-//! This returns zero or more new pattern-stacks, as follows. We look at the pattern `p_1`
-//! on top of the stack, and we have four cases:
-//! 1.1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We
-//! push onto the stack the arguments of this constructor, and return the result:
-//! r_1, .., r_a, p_2, .., p_n
-//! 1.2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and
-//! return nothing.
-//! 1.3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c` has
-//! arguments (its arity), and return the resulting stack:
-//! _, .., _, p_2, .., p_n
-//! 1.4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
-//! stack:
-//! S(c, (r_1, p_2, .., p_n))
-//! S(c, (r_2, p_2, .., p_n))
+//! For example, the first pattern above initially gives a stack `[(Some(true), _)]`. If we
+//! pop the tuple constructor, we are left with `[Some(true), _]`, and if we then pop the
+//! `Some` constructor we get `[true, _]`. If we had popped `None` instead, we would get
+//! nothing back.
//!
-//! 2. We can pop a wildcard off the top of the stack. This is called `D(p)`, where `p` is
-//! a pattern-stack.
-//! This is used when we know there are missing constructor cases, but there might be
-//! existing wildcard patterns, so to check the usefulness of the matrix, we have to check
-//! all its *other* components.
+//! This returns zero or more new pattern-stacks, as follows. We look at the pattern `p_1`
+//! on top of the stack, and we have four cases:
+//! 1.1. `p_1 = c(r_1, .., r_a)`, i.e. the top of the stack has constructor `c`. We
+//! push onto the stack the arguments of this constructor, and return the result:
+//! r_1, .., r_a, p_2, .., p_n
+//! 1.2. `p_1 = c'(r_1, .., r_a')` where `c ≠ c'`. We discard the current stack and
+//! return nothing.
+//! 1.3. `p_1 = _`. We push onto the stack as many wildcards as the constructor `c` has
+//! arguments (its arity), and return the resulting stack:
+//! _, .., _, p_2, .., p_n
+//! 1.4. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
+//! stack:
+//! S(c, (r_1, p_2, .., p_n))
+//! S(c, (r_2, p_2, .., p_n))
//!
-//! It is computed as follows. We look at the pattern `p_1` on top of the stack,
-//! and we have three cases:
-//! 1.1. `p_1 = c(r_1, .., r_a)`. We discard the current stack and return nothing.
-//! 1.2. `p_1 = _`. We return the rest of the stack:
-//! p_2, .., p_n
-//! 1.3. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
-//! stack.
-//! D((r_1, p_2, .., p_n))
-//! D((r_2, p_2, .., p_n))
+//! 2. We can pop a wildcard off the top of the stack. This is called `D(p)`, where `p` is
+//! a pattern-stack.
+//! This is used when we know there are missing constructor cases, but there might be
+//! existing wildcard patterns, so to check the usefulness of the matrix, we have to check
+//! all its *other* components.
//!
-//! Note that the OR-patterns are not always used directly in Rust, but are used to derive the
-//! exhaustive integer matching rules, so they're written here for posterity.
+//! It is computed as follows. We look at the pattern `p_1` on top of the stack,
+//! and we have three cases:
+//! 1.1. `p_1 = c(r_1, .., r_a)`. We discard the current stack and return nothing.
+//! 1.2. `p_1 = _`. We return the rest of the stack:
+//! p_2, .., p_n
+//! 1.3. `p_1 = r_1 | r_2`. We expand the OR-pattern and then recurse on each resulting
+//! stack.
+//! D((r_1, p_2, .., p_n))
+//! D((r_2, p_2, .., p_n))
+//!
+//! Note that the OR-patterns are not always used directly in Rust, but are used to derive the
+//! exhaustive integer matching rules, so they're written here for posterity.
//!
//! Both those operations extend straightforwardly to a list or pattern-stacks, i.e. a matrix, by
//! working row-by-row. Popping a constructor ends up keeping only the matrix rows that start with
@@ -168,66 +169,66 @@
//!
//! Inductive step. (`n > 0`, i.e., whether there's at least one column
//! [which may then be expanded into further columns later])
-//! We're going to match on the top of the new pattern-stack, `p_1`.
-//! - If `p_1 == c(r_1, .., r_a)`, i.e. we have a constructor pattern.
-//! Then, the usefulness of `p_1` can be reduced to whether it is useful when
-//! we ignore all the patterns in the first column of `P` that involve other constructors.
-//! This is where `S(c, P)` comes in:
-//! `U(P, p) := U(S(c, P), S(c, p))`
-//! This special case is handled in `is_useful_specialized`.
+//! We're going to match on the top of the new pattern-stack, `p_1`.
+//! - If `p_1 == c(r_1, .., r_a)`, i.e. we have a constructor pattern.
+//! Then, the usefulness of `p_1` can be reduced to whether it is useful when
+//! we ignore all the patterns in the first column of `P` that involve other constructors.
+//! This is where `S(c, P)` comes in:
+//! `U(P, p) := U(S(c, P), S(c, p))`
+//! This special case is handled in `is_useful_specialized`.
//!
-//! For example, if `P` is:
-//! [
-//! [Some(true), _],
-//! [None, 0],
-//! ]
-//! and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
-//! matches values that row 2 doesn't. For row 1 however, we need to dig into the
-//! arguments of `Some` to know whether some new value is covered. So we compute
-//! `U([[true, _]], [false, 0])`.
+//! For example, if `P` is:
+//! [
+//! [Some(true), _],
+//! [None, 0],
+//! ]
+//! and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
+//! matches values that row 2 doesn't. For row 1 however, we need to dig into the
+//! arguments of `Some` to know whether some new value is covered. So we compute
+//! `U([[true, _]], [false, 0])`.
//!
-//! - If `p_1 == _`, then we look at the list of constructors that appear in the first
-//! component of the rows of `P`:
-//! + If there are some constructors that aren't present, then we might think that the
-//! wildcard `_` is useful, since it covers those constructors that weren't covered
-//! before.
-//! That's almost correct, but only works if there were no wildcards in those first
-//! components. So we need to check that `p` is useful with respect to the rows that
-//! start with a wildcard, if there are any. This is where `D` comes in:
-//! `U(P, p) := U(D(P), D(p))`
+//! - If `p_1 == _`, then we look at the list of constructors that appear in the first
+//! component of the rows of `P`:
+//! + If there are some constructors that aren't present, then we might think that the
+//! wildcard `_` is useful, since it covers those constructors that weren't covered
+//! before.
+//! That's almost correct, but only works if there were no wildcards in those first
+//! components. So we need to check that `p` is useful with respect to the rows that
+//! start with a wildcard, if there are any. This is where `D` comes in:
+//! `U(P, p) := U(D(P), D(p))`
//!
-//! For example, if `P` is:
-//! [
-//! [_, true, _],
-//! [None, false, 1],
-//! ]
-//! and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
-//! only had row 2, we'd know that `p` is useful. However row 1 starts with a
-//! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
+//! For example, if `P` is:
+//! [
+//! [_, true, _],
+//! [None, false, 1],
+//! ]
+//! and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
+//! only had row 2, we'd know that `p` is useful. However row 1 starts with a
+//! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
//!
-//! + Otherwise, all possible constructors (for the relevant type) are present. In this
-//! case we must check whether the wildcard pattern covers any unmatched value. For
-//! that, we can think of the `_` pattern as a big OR-pattern that covers all
-//! possible constructors. For `Option`, that would mean `_ = None | Some(_)` for
-//! example. The wildcard pattern is useful in this case if it is useful when
-//! specialized to one of the possible constructors. So we compute:
-//! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
+//! + Otherwise, all possible constructors (for the relevant type) are present. In this
+//! case we must check whether the wildcard pattern covers any unmatched value. For
+//! that, we can think of the `_` pattern as a big OR-pattern that covers all
+//! possible constructors. For `Option`, that would mean `_ = None | Some(_)` for
+//! example. The wildcard pattern is useful in this case if it is useful when
+//! specialized to one of the possible constructors. So we compute:
+//! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
//!
-//! For example, if `P` is:
-//! [
-//! [Some(true), _],
-//! [None, false],
-//! ]
-//! and `p` is [_, false], both `None` and `Some` constructors appear in the first
-//! components of `P`. We will therefore try popping both constructors in turn: we
-//! compute U([[true, _]], [_, false]) for the `Some` constructor, and U([[false]],
-//! [false]) for the `None` constructor. The first case returns true, so we know that
-//! `p` is useful for `P`. Indeed, it matches `[Some(false), _]` that wasn't matched
-//! before.
+//! For example, if `P` is:
+//! [
+//! [Some(true), _],
+//! [None, false],
+//! ]
+//! and `p` is [_, false], both `None` and `Some` constructors appear in the first
+//! components of `P`. We will therefore try popping both constructors in turn: we
+//! compute `U([[true, _]], [_, false])` for the `Some` constructor, and `U([[false]],
+//! [false])` for the `None` constructor. The first case returns true, so we know that
+//! `p` is useful for `P`. Indeed, it matches `[Some(false), _]` that wasn't matched
+//! before.
//!
-//! - If `p_1 == r_1 | r_2`, then the usefulness depends on each `r_i` separately:
-//! `U(P, p) := U(P, (r_1, p_2, .., p_n))
-//! || U(P, (r_2, p_2, .., p_n))`
+//! - If `p_1 == r_1 | r_2`, then the usefulness depends on each `r_i` separately:
+//! `U(P, p) := U(P, (r_1, p_2, .., p_n))
+//! || U(P, (r_2, p_2, .., p_n))`
//!
//! Modifications to the algorithm
//! ------------------------------
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index fc9ffc3092447..16a118cb48c91 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -376,7 +376,14 @@ impl<'a> Parser<'a> {
/// let _ = vec![1, 2, 3].into_iter().collect::>>>();
/// ^^ help: remove extra angle brackets
/// ```
- pub(super) fn check_trailing_angle_brackets(&mut self, segment: &PathSegment, end: TokenKind) {
+ ///
+ /// If `true` is returned, then trailing brackets were recovered, tokens were consumed
+ /// up until one of the tokens in 'end' was encountered, and an error was emitted.
+ pub(super) fn check_trailing_angle_brackets(
+ &mut self,
+ segment: &PathSegment,
+ end: &[&TokenKind],
+ ) -> bool {
// This function is intended to be invoked after parsing a path segment where there are two
// cases:
//
@@ -409,7 +416,7 @@ impl<'a> Parser<'a> {
parsed_angle_bracket_args,
);
if !parsed_angle_bracket_args {
- return;
+ return false;
}
// Keep the span at the start so we can highlight the sequence of `>` characters to be
@@ -447,18 +454,18 @@ impl<'a> Parser<'a> {
number_of_gt, number_of_shr,
);
if number_of_gt < 1 && number_of_shr < 1 {
- return;
+ return false;
}
// Finally, double check that we have our end token as otherwise this is the
// second case.
if self.look_ahead(position, |t| {
trace!("check_trailing_angle_brackets: t={:?}", t);
- *t == end
+ end.contains(&&t.kind)
}) {
// Eat from where we started until the end token so that parsing can continue
// as if we didn't have those extra angle brackets.
- self.eat_to_tokens(&[&end]);
+ self.eat_to_tokens(end);
let span = lo.until(self.token.span);
let total_num_of_gt = number_of_gt + number_of_shr * 2;
@@ -473,7 +480,9 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable,
)
.emit();
+ return true;
}
+ false
}
/// Check to see if a pair of chained operators looks like an attempt at chained comparison,
@@ -1415,7 +1424,7 @@ impl<'a> Parser<'a> {
if self.token != token::Lt {
err.span_suggestion(
pat.span,
- "if this was a parameter name, give it a type",
+ "if this is a parameter name, give it a type",
format!("{}: TypeName", ident),
Applicability::HasPlaceholders,
);
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 2745b18a8cd51..fb38fdc26c782 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -867,7 +867,7 @@ impl<'a> Parser<'a> {
let fn_span_lo = self.token.span;
let segment = self.parse_path_segment(PathStyle::Expr)?;
- self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
+ self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(token::Paren)]);
if self.check(&token::OpenDelim(token::Paren)) {
// Method call `expr.f()`
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 10df16964da08..fa6264c98e4f0 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -9,7 +9,7 @@ use rustc_ast::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind,
use rustc_ast::ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, UseTreeKind};
use rustc_ast::ast::{BindingMode, Block, FnDecl, FnSig, Param, SelfKind};
use rustc_ast::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData};
-use rustc_ast::ast::{FnHeader, ForeignItem, PathSegment, Visibility, VisibilityKind};
+use rustc_ast::ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
use rustc_ast::ast::{MacArgs, MacCall, MacDelimiter};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
@@ -1262,6 +1262,25 @@ impl<'a> Parser<'a> {
sp,
&format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
);
+
+ // Try to recover extra trailing angle brackets
+ let mut recovered = false;
+ if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
+ if let Some(last_segment) = segments.last() {
+ recovered = self.check_trailing_angle_brackets(
+ last_segment,
+ &[&token::Comma, &token::CloseDelim(token::Brace)],
+ );
+ if recovered {
+ // Handle a case like `Vec>,` where we can continue parsing fields
+ // after the comma
+ self.eat(&token::Comma);
+ // `check_trailing_angle_brackets` already emitted a nicer error
+ err.cancel();
+ }
+ }
+ }
+
if self.token.is_ident() {
// This is likely another field; emit the diagnostic and keep going
err.span_suggestion(
@@ -1271,6 +1290,14 @@ impl<'a> Parser<'a> {
Applicability::MachineApplicable,
);
err.emit();
+ recovered = true;
+ }
+
+ if recovered {
+ // Make sure an error was emitted (either by recovering an angle bracket,
+ // or by finding an identifier as the next token), since we're
+ // going to continue parsing
+ assert!(self.sess.span_diagnostic.has_errors());
} else {
return Err(err);
}
diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs
index 5210614548da3..67e9b3af4a8cf 100644
--- a/src/librustc_parse/parser/path.rs
+++ b/src/librustc_parse/parser/path.rs
@@ -169,7 +169,7 @@ impl<'a> Parser<'a> {
// `PathStyle::Expr` is only provided at the root invocation and never in
// `parse_path_segment` to recurse and therefore can be checked to maintain
// this invariant.
- self.check_trailing_angle_brackets(&segment, token::ModSep);
+ self.check_trailing_angle_brackets(&segment, &[&token::ModSep]);
}
segments.push(segment);
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 683039df15ac6..e4f4885690fd9 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -422,7 +422,7 @@ impl Visitor<'tcx> for ExprVisitor<'tcx> {
let typ = self.tables.node_type(expr.hir_id);
let sig = typ.fn_sig(self.tcx);
let from = sig.inputs().skip_binder()[0];
- let to = *sig.output().skip_binder();
+ let to = sig.output().skip_binder();
self.check_transmute(expr.span, from, to);
}
}
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 9e6e7ea962bc3..20f09ef52f00b 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -92,14 +92,14 @@ where
for (predicate, _span) in predicates {
match predicate.kind() {
ty::PredicateKind::Trait(poly_predicate, _) => {
- let ty::TraitPredicate { trait_ref } = *poly_predicate.skip_binder();
+ let ty::TraitPredicate { trait_ref } = poly_predicate.skip_binder();
if self.visit_trait(trait_ref) {
return true;
}
}
ty::PredicateKind::Projection(poly_predicate) => {
let ty::ProjectionPredicate { projection_ty, ty } =
- *poly_predicate.skip_binder();
+ poly_predicate.skip_binder();
if ty.visit_with(self) {
return true;
}
@@ -108,7 +108,7 @@ where
}
}
ty::PredicateKind::TypeOutlives(poly_predicate) => {
- let ty::OutlivesPredicate(ty, _region) = *poly_predicate.skip_binder();
+ let ty::OutlivesPredicate(ty, _region) = poly_predicate.skip_binder();
if ty.visit_with(self) {
return true;
}
@@ -175,7 +175,7 @@ where
ty::Dynamic(predicates, ..) => {
// All traits in the list are considered the "primary" part of the type
// and are visited by shallow visitors.
- for predicate in *predicates.skip_binder() {
+ for predicate in predicates.skip_binder() {
let trait_ref = match predicate {
ty::ExistentialPredicate::Trait(trait_ref) => trait_ref,
ty::ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
@@ -1270,7 +1270,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
);
for (trait_predicate, _, _) in bounds.trait_bounds {
- if self.visit_trait(*trait_predicate.skip_binder()) {
+ if self.visit_trait(trait_predicate.skip_binder()) {
return;
}
}
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index 857734037afe7..e67ca3259ff6b 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -152,10 +152,14 @@ symbols! {
arm_target_feature,
asm,
assert,
+ assert_inhabited,
+ assert_uninit_valid,
+ assert_zero_valid,
associated_consts,
associated_type_bounds,
associated_type_defaults,
associated_types,
+ assume,
assume_init,
async_await,
async_closure,
@@ -181,11 +185,14 @@ symbols! {
box_patterns,
box_syntax,
braced_empty_structs,
+ breakpoint,
bswap,
bitreverse,
C,
caller_location,
cdylib,
+ ceilf32,
+ ceilf64,
cfg,
cfg_accessible,
cfg_attr,
@@ -239,8 +246,14 @@ symbols! {
convert,
Copy,
copy_closures,
+ copy,
+ copy_nonoverlapping,
+ copysignf32,
+ copysignf64,
core,
core_intrinsics,
+ cosf32,
+ cosf64,
count_code_region,
crate_id,
crate_in_paths,
@@ -296,6 +309,7 @@ symbols! {
dropck_eyepatch,
dropck_parametricity,
drop_types_in_const,
+ drop_in_place,
dylib,
dyn_trait,
eh_personality,
@@ -308,11 +322,16 @@ symbols! {
Eq,
Equal,
enclosing_scope,
+ exact_div,
except,
exclusive_range_pattern,
exhaustive_integer_patterns,
exhaustive_patterns,
existential_type,
+ expf32,
+ expf64,
+ exp2f32,
+ exp2f64,
expected,
export_name,
expr,
@@ -326,6 +345,10 @@ symbols! {
f16c_target_feature,
f32,
f64,
+ fadd_fast,
+ fabsf32,
+ fabsf64,
+ fdiv_fast,
feature,
ffi_const,
ffi_pure,
@@ -333,12 +356,20 @@ symbols! {
field,
field_init_shorthand,
file,
+ float_to_int_unchecked,
+ floorf64,
+ floorf32,
+ fmaf32,
+ fmaf64,
fmt,
fmt_internals,
+ fmul_fast,
fn_must_use,
forbid,
+ forget,
format_args,
format_args_nl,
+ frem_fast,
from,
From,
from_desugaring,
@@ -348,6 +379,7 @@ symbols! {
from_ok,
from_usize,
from_trait,
+ fsub_fast,
fundamental,
future,
Future,
@@ -427,6 +459,7 @@ symbols! {
lhs,
lib,
lifetime,
+ likely,
line,
link,
linkage,
@@ -442,6 +475,12 @@ symbols! {
llvm_asm,
local_inner_macros,
log_syntax,
+ logf32,
+ logf64,
+ log10f32,
+ log10f64,
+ log2f32,
+ log2f64,
loop_break_value,
macro_at_most_once_rep,
macro_escape,
@@ -469,10 +508,16 @@ symbols! {
message,
meta,
min_align_of,
+ min_align_of_val,
min_const_fn,
min_const_unsafe_fn,
min_specialization,
+ minnumf32,
+ minnumf64,
+ maxnumf32,
+ maxnumf64,
mips_target_feature,
+ miri_start_panic,
mmx_target_feature,
module,
module_path,
@@ -485,6 +530,8 @@ symbols! {
naked,
naked_functions,
name,
+ nearbyintf32,
+ nearbyintf64,
needs_allocator,
needs_drop,
needs_panic_runtime,
@@ -512,6 +559,7 @@ symbols! {
None,
non_exhaustive,
non_modrs_mods,
+ nontemporal_store,
noreturn,
no_niche,
no_sanitize,
@@ -570,8 +618,16 @@ symbols! {
poll,
Poll,
powerpc_target_feature,
+ powf32,
+ powf64,
+ powif32,
+ powif64,
precise_pointer_size_matching,
pref_align_of,
+ prefetch_read_data,
+ prefetch_read_instruction,
+ prefetch_write_data,
+ prefetch_write_instruction,
prelude,
prelude_import,
preserves_flags,
@@ -631,10 +687,14 @@ symbols! {
Result,
Return,
rhs,
+ rintf32,
+ rintf64,
riscv_target_feature,
rlib,
rotate_left,
rotate_right,
+ roundf32,
+ roundf64,
rt,
rtm_target_feature,
rust,
@@ -717,14 +777,19 @@ symbols! {
simd_ffi,
simd_insert,
since,
+ sinf32,
+ sinf64,
size,
size_of,
+ size_of_val,
slice_patterns,
slicing_syntax,
soft,
Some,
specialization,
speed,
+ sqrtf32,
+ sqrtf64,
sse4a_target_feature,
stable,
staged_api,
@@ -778,6 +843,8 @@ symbols! {
transparent_enums,
transparent_unions,
trivial_bounds,
+ truncf32,
+ truncf64,
Try,
try_blocks,
try_trait,
@@ -800,6 +867,8 @@ symbols! {
u32,
u64,
u8,
+ unaligned_volatile_load,
+ unaligned_volatile_store,
unboxed_closures,
unchecked_add,
unchecked_div,
@@ -813,7 +882,9 @@ symbols! {
underscore_lifetimes,
uniform_paths,
universal_impl_trait,
+ unlikely,
unmarked_api,
+ unreachable,
unreachable_code,
unrestricted_attribute_tokens,
unsafe_block_in_unsafe_fn,
@@ -833,12 +904,21 @@ symbols! {
val,
var,
variant_count,
+ va_arg,
+ va_copy,
+ va_end,
+ va_start,
vec,
Vec,
version,
vis,
visible_private_types,
volatile,
+ volatile_copy_memory,
+ volatile_copy_nonoverlapping_memory,
+ volatile_load,
+ volatile_set_memory,
+ volatile_store,
warn,
wasm_import_module,
wasm_target_feature,
@@ -848,6 +928,7 @@ symbols! {
wrapping_add,
wrapping_sub,
wrapping_mul,
+ write_bytes,
Yield,
}
}
diff --git a/src/librustc_symbol_mangling/v0.rs b/src/librustc_symbol_mangling/v0.rs
index 7d117b77cf5e5..ecf27fbf54220 100644
--- a/src/librustc_symbol_mangling/v0.rs
+++ b/src/librustc_symbol_mangling/v0.rs
@@ -219,7 +219,7 @@ impl SymbolMangler<'tcx> {
lifetime_depths.end += lifetimes;
self.binders.push(BinderLevel { lifetime_depths });
- self = print_value(self, value.skip_binder())?;
+ self = print_value(self, value.as_ref().skip_binder())?;
self.binders.pop();
Ok(self)
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index adccdd0b2617a..ce478de7c755c 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -691,7 +691,7 @@ where
OP: FnMut(ty::Region<'tcx>),
{
fn visit_binder>(&mut self, t: &ty::Binder) -> bool {
- t.skip_binder().visit_with(self);
+ t.as_ref().skip_binder().visit_with(self);
false // keep visiting
}
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index fd0c1a54d27ad..49e43873df759 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -1569,7 +1569,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
// no need to overload user in such cases
return;
}
- let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
+ let SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
// both must be type variables, or the other would've been instantiated
assert!(a.is_ty_var() && b.is_ty_var());
self.need_type_info_err(body_id, span, a, ErrorCode::E0282)
diff --git a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
index fd87759a7621f..ec51dddc2c810 100644
--- a/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/on_unimplemented.rs
@@ -122,7 +122,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
) -> OnUnimplementedNote {
let def_id =
self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id());
- let trait_ref = *trait_ref.skip_binder();
+ let trait_ref = trait_ref.skip_binder();
let mut flags = vec![];
flags.push((
@@ -219,7 +219,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
if let ty::Dynamic(traits, _) = self_ty.kind {
- for t in *traits.skip_binder() {
+ for t in traits.skip_binder() {
if let ty::ExistentialPredicate::Trait(trait_ref) = t {
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))
}
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 176bd90303ddd..1fafa9ec035ce 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -1179,7 +1179,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
) -> DiagnosticBuilder<'tcx> {
crate fn build_fn_sig_string<'tcx>(
tcx: TyCtxt<'tcx>,
- trait_ref: &ty::TraitRef<'tcx>,
+ trait_ref: ty::TraitRef<'tcx>,
) -> String {
let inputs = trait_ref.substs.type_at(1);
let sig = if let ty::Tuple(inputs) = inputs.kind {
@@ -1360,7 +1360,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
ty::GeneratorWitness(..) => {}
_ if generator.is_none() => {
- trait_ref = Some(*derived_obligation.parent_trait_ref.skip_binder());
+ trait_ref = Some(derived_obligation.parent_trait_ref.skip_binder());
target_ty = Some(ty);
}
_ => {}
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
index 4dab5814f7b7e..91c162872b215 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
@@ -220,7 +220,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Okay to skip binder because the substs on generator types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
- let self_ty = *obligation.self_ty().skip_binder();
+ let self_ty = obligation.self_ty().skip_binder();
match self_ty.kind {
ty::Generator(..) => {
debug!(
@@ -299,7 +299,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
// Okay to skip binder because what we are inspecting doesn't involve bound regions.
- let self_ty = *obligation.self_ty().skip_binder();
+ let self_ty = obligation.self_ty().skip_binder();
match self_ty.kind {
ty::Infer(ty::TyVar(_)) => {
debug!("assemble_fn_pointer_candidates: ambiguous self-type");
@@ -362,7 +362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
// Okay to skip binder here because the tests we do below do not involve bound regions.
- let self_ty = *obligation.self_ty().skip_binder();
+ let self_ty = obligation.self_ty().skip_binder();
debug!("assemble_candidates_from_auto_impls(self_ty={:?})", self_ty);
let def_id = obligation.predicate.def_id();
@@ -583,7 +583,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
// Okay to skip binder here because the tests we do below do not involve bound regions.
- let self_ty = *obligation.self_ty().skip_binder();
+ let self_ty = obligation.self_ty().skip_binder();
debug!("assemble_candidates_for_trait_alias(self_ty={:?})", self_ty);
let def_id = obligation.predicate.def_id();
diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/src/librustc_trait_selection/traits/select/confirmation.rs
index 834bf17227d2e..fa970589bbbf6 100644
--- a/src/librustc_trait_selection/traits/select/confirmation.rs
+++ b/src/librustc_trait_selection/traits/select/confirmation.rs
@@ -326,7 +326,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// probably flatten the binder from the obligation and the binder
// from the object. Have to try to make a broken test case that
// results.
- let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let poly_trait_ref = match self_ty.kind {
ty::Dynamic(ref data, ..) => data
.principal()
@@ -379,7 +379,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!("confirm_fn_pointer_candidate({:?})", obligation);
// Okay to skip binder; it is reintroduced below.
- let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let sig = self_ty.fn_sig(self.tcx());
let trait_ref = closure_trait_ref_and_return_type(
self.tcx(),
@@ -448,7 +448,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Okay to skip binder because the substs on generator types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
- let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let (generator_def_id, substs) = match self_ty.kind {
ty::Generator(id, substs, _) => (id, substs),
_ => bug!("closure candidate for non-closure {:?}", obligation),
@@ -497,7 +497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Okay to skip binder because the substs on closure types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
- let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
+ let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let (closure_def_id, substs) = match self_ty.kind {
ty::Closure(id, substs) => (id, substs),
_ => bug!("closure candidate for non-closure {:?}", obligation),
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index cff5efbfd0fd1..c41a27c6f431f 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -748,8 +748,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&& stack.iter().skip(1).any(|prev| {
stack.obligation.param_env == prev.obligation.param_env
&& self.match_fresh_trait_refs(
- &stack.fresh_trait_ref,
- &prev.fresh_trait_ref,
+ stack.fresh_trait_ref,
+ prev.fresh_trait_ref,
prev.obligation.param_env,
)
})
@@ -1944,8 +1944,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn match_fresh_trait_refs(
&self,
- previous: &ty::PolyTraitRef<'tcx>,
- current: &ty::PolyTraitRef<'tcx>,
+ previous: ty::PolyTraitRef<'tcx>,
+ current: ty::PolyTraitRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs
index 1825c159ff3fb..ebff2dd9b23c1 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/src/librustc_trait_selection/traits/wf.rs
@@ -695,7 +695,7 @@ pub fn object_region_bounds<'tcx>(
let open_ty = tcx.mk_ty_infer(ty::FreshTy(0));
let predicates = existential_predicates.iter().filter_map(|predicate| {
- if let ty::ExistentialPredicate::Projection(_) = *predicate.skip_binder() {
+ if let ty::ExistentialPredicate::Projection(_) = predicate.skip_binder() {
None
} else {
Some(predicate.with_self_ty(tcx, open_ty))
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index e09359b8b3fc1..ed021e5b9de1b 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -615,7 +615,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
ty: &'a Binder,
) -> (T, chalk_ir::VariableKinds>, BTreeMap) {
let mut bound_vars_collector = BoundVarsCollector::new();
- ty.skip_binder().visit_with(&mut bound_vars_collector);
+ ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector);
let mut parameters = bound_vars_collector.parameters;
let named_parameters: BTreeMap = bound_vars_collector
.named_parameters
@@ -625,7 +625,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
.collect();
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
- let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
+ let new_ty = ty.as_ref().skip_binder().fold_with(&mut bound_var_substitutor);
for var in named_parameters.values() {
parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 1b08bf2fc7710..5d1949626dd84 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1802,7 +1802,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Calling `skip_binder` is okay because the predicates are re-bound.
let regular_trait_predicates = existential_trait_refs
- .map(|trait_ref| ty::ExistentialPredicate::Trait(*trait_ref.skip_binder()));
+ .map(|trait_ref| ty::ExistentialPredicate::Trait(trait_ref.skip_binder()));
let auto_trait_predicates = auto_traits
.into_iter()
.map(|trait_ref| ty::ExistentialPredicate::AutoTrait(trait_ref.trait_ref().def_id()));
@@ -1810,7 +1810,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.chain(auto_trait_predicates)
.chain(
existential_projections
- .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())),
+ .map(|x| ty::ExistentialPredicate::Projection(x.skip_binder())),
)
.collect::>();
v.sort_by(|a, b| a.stable_cmp(tcx, b));
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 6d09ddc925ffe..fce2b18b782fb 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -188,7 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
ty::FnPtr(sig) => {
- let expected_sig = ExpectedSig { cause_span: None, sig: *sig.skip_binder() };
+ let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder() };
(Some(expected_sig), Some(ty::ClosureKind::Fn))
}
_ => (None, None),
@@ -501,7 +501,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for ((hir_ty, &supplied_ty), expected_ty) in decl
.inputs
.iter()
- .zip(*supplied_sig.inputs().skip_binder()) // binder moved to (*) below
+ .zip(supplied_sig.inputs().skip_binder()) // binder moved to (*) below
.zip(expected_sigs.liberated_sig.inputs())
// `liberated_sig` is E'.
{
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index b6cd8da236260..e6b3224050e9b 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -964,7 +964,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let sig = self
.at(cause, self.param_env)
.trace(prev_ty, new_ty)
- .lub(&a_sig, &b_sig)
+ .lub(a_sig, b_sig)
.map(|ok| self.register_infer_ok_obligations(ok))?;
// Reify both sides and return the reified fn pointer type.
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 4e97ba41dcbb3..e6217e0cc1b6e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -502,7 +502,7 @@ fn compare_self_type<'tcx>(
ty::ImplContainer(_) => impl_trait_ref.self_ty(),
ty::TraitContainer(_) => tcx.types.self_param,
};
- let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
+ let self_arg_ty = tcx.fn_sig(method.def_id).input(0).skip_binder();
let param_env = ty::ParamEnv::reveal_all();
tcx.infer_ctxt().enter(|infcx| {
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index e27c2e4503910..f6991120f3479 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -227,10 +227,10 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
let predicate_matches_closure = |p: Predicate<'tcx>| {
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
match (predicate.kind(), p.kind()) {
- (ty::PredicateKind::Trait(a, _), ty::PredicateKind::Trait(b, _)) => {
+ (&ty::PredicateKind::Trait(a, _), &ty::PredicateKind::Trait(b, _)) => {
relator.relate(a, b).is_ok()
}
- (ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
+ (&ty::PredicateKind::Projection(a), &ty::PredicateKind::Projection(b)) => {
relator.relate(a, b).is_ok()
}
_ => predicate == p,
@@ -310,8 +310,8 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
fn relate_with_variance>(
&mut self,
_: ty::Variance,
- a: &T,
- b: &T,
+ a: T,
+ b: T,
) -> RelateResult<'tcx, T> {
// Here we ignore variance because we require drop impl's types
// to be *exactly* the same as to the ones in the struct definition.
@@ -354,8 +354,8 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
fn binders(
&mut self,
- a: &ty::Binder,
- b: &ty::Binder,
+ a: ty::Binder,
+ b: ty::Binder,
) -> RelateResult<'tcx, ty::Binder>
where
T: Relate<'tcx>,
@@ -364,8 +364,8 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
// Anonymizing the LBRs is necessary to solve (Issue #59497).
// After we do so, it should be totally fine to skip the binders.
- let anon_a = self.tcx.anonymize_late_bound_regions(a);
- let anon_b = self.tcx.anonymize_late_bound_regions(b);
+ let anon_a = self.tcx.anonymize_late_bound_regions(&a);
+ let anon_b = self.tcx.anonymize_late_bound_regions(&b);
self.relate(anon_a.skip_binder(), anon_b.skip_binder())?;
Ok(a.clone())
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 1c0b22ca7370b..62e62435a08ea 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -5,10 +5,11 @@ use crate::require_same_types;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::symbol::Symbol;
+use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::spec::abi::Abi;
use std::iter;
@@ -16,14 +17,13 @@ use std::iter;
fn equate_intrinsic_type<'tcx>(
tcx: TyCtxt<'tcx>,
it: &hir::ForeignItem<'_>,
+ def_id: DefId,
n_tps: usize,
abi: Abi,
safety: hir::Unsafety,
inputs: Vec>,
output: Ty<'tcx>,
) {
- let def_id = tcx.hir().local_def_id(it.hir_id);
-
match it.kind {
hir::ForeignItemKind::Fn(..) => {}
_ => {
@@ -67,15 +67,43 @@ fn equate_intrinsic_type<'tcx>(
}
/// Returns `true` if the given intrinsic is unsafe to call or not.
-pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
+pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
match intrinsic {
- "abort" | "size_of" | "min_align_of" | "needs_drop" | "caller_location" | "size_of_val"
- | "min_align_of_val" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow"
- | "wrapping_add" | "wrapping_sub" | "wrapping_mul" | "saturating_add"
- | "saturating_sub" | "rotate_left" | "rotate_right" | "ctpop" | "ctlz" | "cttz"
- | "bswap" | "bitreverse" | "discriminant_value" | "type_id" | "likely" | "unlikely"
- | "ptr_guaranteed_eq" | "ptr_guaranteed_ne" | "minnumf32" | "minnumf64" | "maxnumf32"
- | "maxnumf64" | "type_name" | "variant_count" => hir::Unsafety::Normal,
+ sym::abort
+ | sym::size_of
+ | sym::min_align_of
+ | sym::needs_drop
+ | sym::caller_location
+ | sym::size_of_val
+ | sym::min_align_of_val
+ | sym::add_with_overflow
+ | sym::sub_with_overflow
+ | sym::mul_with_overflow
+ | sym::wrapping_add
+ | sym::wrapping_sub
+ | sym::wrapping_mul
+ | sym::saturating_add
+ | sym::saturating_sub
+ | sym::rotate_left
+ | sym::rotate_right
+ | sym::ctpop
+ | sym::ctlz
+ | sym::cttz
+ | sym::bswap
+ | sym::bitreverse
+ | sym::discriminant_value
+ | sym::type_id
+ | sym::likely
+ | sym::unlikely
+ | sym::ptr_guaranteed_eq
+ | sym::ptr_guaranteed_ne
+ | sym::minnumf32
+ | sym::minnumf64
+ | sym::maxnumf32
+ | sym::rustc_peek
+ | sym::maxnumf64
+ | sym::type_name
+ | sym::variant_count => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
}
}
@@ -84,7 +112,9 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
/// and in libcore/intrinsics.rs
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
- let name = it.ident.as_str();
+ let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
+ let intrinsic_name = tcx.item_name(def_id);
+ let name_str = intrinsic_name.as_str();
let mk_va_list_ty = |mutbl| {
tcx.lang_items().va_list().map(|did| {
@@ -98,8 +128,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
})
};
- let (n_tps, inputs, output, unsafety) = if name.starts_with("atomic_") {
- let split: Vec<&str> = name.split('_').collect();
+ let (n_tps, inputs, output, unsafety) = if name_str.starts_with("atomic_") {
+ let split: Vec<&str> = name_str.split('_').collect();
assert!(split.len() >= 2, "Atomic intrinsic in an incorrect format");
//We only care about the operation here
@@ -129,32 +159,30 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
}
};
(n_tps, inputs, output, hir::Unsafety::Unsafe)
- } else if &name[..] == "abort" {
- (0, Vec::new(), tcx.types.never, hir::Unsafety::Normal)
- } else if &name[..] == "unreachable" {
- (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
} else {
- let unsafety = intrinsic_operation_unsafety(&name[..]);
- let (n_tps, inputs, output) = match &name[..] {
- "breakpoint" => (0, Vec::new(), tcx.mk_unit()),
- "size_of" | "pref_align_of" | "min_align_of" | "variant_count" => {
+ let unsafety = intrinsic_operation_unsafety(intrinsic_name);
+ let (n_tps, inputs, output) = match intrinsic_name {
+ sym::abort => (0, Vec::new(), tcx.types.never),
+ sym::unreachable => (0, Vec::new(), tcx.types.never),
+ sym::breakpoint => (0, Vec::new(), tcx.mk_unit()),
+ sym::size_of | sym::pref_align_of | sym::min_align_of | sym::variant_count => {
(1, Vec::new(), tcx.types.usize)
}
- "size_of_val" | "min_align_of_val" => {
+ sym::size_of_val | sym::min_align_of_val => {
(1, vec![tcx.mk_imm_ptr(param(0))], tcx.types.usize)
}
- "rustc_peek" => (1, vec![param(0)], param(0)),
- "caller_location" => (0, vec![], tcx.caller_location_ty()),
- "assert_inhabited" | "assert_zero_valid" | "assert_uninit_valid" => {
+ sym::rustc_peek => (1, vec![param(0)], param(0)),
+ sym::caller_location => (0, vec![], tcx.caller_location_ty()),
+ sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
(1, Vec::new(), tcx.mk_unit())
}
- "forget" => (1, vec![param(0)], tcx.mk_unit()),
- "transmute" => (2, vec![param(0)], param(1)),
- "move_val_init" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
- "prefetch_read_data"
- | "prefetch_write_data"
- | "prefetch_read_instruction"
- | "prefetch_write_instruction" => (
+ sym::forget => (1, vec![param(0)], tcx.mk_unit()),
+ sym::transmute => (2, vec![param(0)], param(1)),
+ sym::move_val_init => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+ sym::prefetch_read_data
+ | sym::prefetch_write_data
+ | sym::prefetch_read_instruction
+ | sym::prefetch_write_instruction => (
1,
vec![
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -162,12 +190,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_unit(),
),
- "drop_in_place" => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()),
- "needs_drop" => (1, Vec::new(), tcx.types.bool),
+ sym::drop_in_place => (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_unit()),
+ sym::needs_drop => (1, Vec::new(), tcx.types.bool),
- "type_name" => (1, Vec::new(), tcx.mk_static_str()),
- "type_id" => (1, Vec::new(), tcx.types.u64),
- "offset" | "arith_offset" => (
+ sym::type_name => (1, Vec::new(), tcx.mk_static_str()),
+ sym::type_id => (1, Vec::new(), tcx.types.u64),
+ sym::offset | sym::arith_offset => (
1,
vec![
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -175,7 +203,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
),
- "copy" | "copy_nonoverlapping" => (
+ sym::copy | sym::copy_nonoverlapping => (
1,
vec![
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Not }),
@@ -184,7 +212,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_unit(),
),
- "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => (
+ sym::volatile_copy_memory | sym::volatile_copy_nonoverlapping_memory => (
1,
vec![
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
@@ -193,7 +221,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_unit(),
),
- "write_bytes" | "volatile_set_memory" => (
+ sym::write_bytes | sym::volatile_set_memory => (
1,
vec![
tcx.mk_ptr(ty::TypeAndMut { ty: param(0), mutbl: hir::Mutability::Mut }),
@@ -202,93 +230,98 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
],
tcx.mk_unit(),
),
- "sqrtf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "sqrtf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "powif32" => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
- "powif64" => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
- "sinf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "sinf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "cosf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "cosf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "powf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
- "powf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
- "expf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "expf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "exp2f32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "exp2f64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "logf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "logf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "log10f32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "log10f64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "log2f32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "log2f64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "fmaf32" => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
- "fmaf64" => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
- "fabsf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "fabsf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "minnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
- "minnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
- "maxnumf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
- "maxnumf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
- "copysignf32" => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
- "copysignf64" => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
- "floorf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "floorf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "ceilf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "ceilf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "truncf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "truncf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "rintf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "rintf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "nearbyintf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "nearbyintf64" => (0, vec![tcx.types.f64], tcx.types.f64),
- "roundf32" => (0, vec![tcx.types.f32], tcx.types.f32),
- "roundf64" => (0, vec![tcx.types.f64], tcx.types.f64),
-
- "volatile_load" | "unaligned_volatile_load" => {
+ sym::sqrtf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::sqrtf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::powif32 => (0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32),
+ sym::powif64 => (0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64),
+ sym::sinf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::sinf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::cosf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::cosf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::powf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+ sym::powf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+ sym::expf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::expf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::exp2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::exp2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::logf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::logf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::log10f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::log10f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::log2f32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::log2f64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::fmaf32 => (0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32),
+ sym::fmaf64 => (0, vec![tcx.types.f64, tcx.types.f64, tcx.types.f64], tcx.types.f64),
+ sym::fabsf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::fabsf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::minnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+ sym::minnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+ sym::maxnumf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+ sym::maxnumf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+ sym::copysignf32 => (0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
+ sym::copysignf64 => (0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
+ sym::floorf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::floorf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::ceilf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::ceilf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::truncf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::truncf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::rintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::rintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::nearbyintf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::nearbyintf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+ sym::roundf32 => (0, vec![tcx.types.f32], tcx.types.f32),
+ sym::roundf64 => (0, vec![tcx.types.f64], tcx.types.f64),
+
+ sym::volatile_load | sym::unaligned_volatile_load => {
(1, vec![tcx.mk_imm_ptr(param(0))], param(0))
}
- "volatile_store" | "unaligned_volatile_store" => {
+ sym::volatile_store | sym::unaligned_volatile_store => {
(1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit())
}
- "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "bswap"
- | "bitreverse" => (1, vec![param(0)], param(0)),
+ sym::ctpop
+ | sym::ctlz
+ | sym::ctlz_nonzero
+ | sym::cttz
+ | sym::cttz_nonzero
+ | sym::bswap
+ | sym::bitreverse => (1, vec![param(0)], param(0)),
- "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => {
+ sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
(1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool]))
}
- "ptr_guaranteed_eq" | "ptr_guaranteed_ne" => {
+ sym::ptr_guaranteed_eq | sym::ptr_guaranteed_ne => {
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.bool)
}
- "ptr_offset_from" => {
+ sym::ptr_offset_from => {
(1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)
}
- "unchecked_div" | "unchecked_rem" | "exact_div" => {
+ sym::unchecked_div | sym::unchecked_rem | sym::exact_div => {
(1, vec![param(0), param(0)], param(0))
}
- "unchecked_shl" | "unchecked_shr" | "rotate_left" | "rotate_right" => {
+ sym::unchecked_shl | sym::unchecked_shr | sym::rotate_left | sym::rotate_right => {
(1, vec![param(0), param(0)], param(0))
}
- "unchecked_add" | "unchecked_sub" | "unchecked_mul" => {
+ sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
(1, vec![param(0), param(0)], param(0))
}
- "wrapping_add" | "wrapping_sub" | "wrapping_mul" => {
+ sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul => {
(1, vec![param(0), param(0)], param(0))
}
- "saturating_add" | "saturating_sub" => (1, vec![param(0), param(0)], param(0)),
- "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
+ sym::saturating_add | sym::saturating_sub => (1, vec![param(0), param(0)], param(0)),
+ sym::fadd_fast | sym::fsub_fast | sym::fmul_fast | sym::fdiv_fast | sym::frem_fast => {
(1, vec![param(0), param(0)], param(0))
}
- "float_to_int_unchecked" => (2, vec![param(0)], param(1)),
+ sym::float_to_int_unchecked => (2, vec![param(0)], param(1)),
- "assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
- "likely" => (0, vec![tcx.types.bool], tcx.types.bool),
- "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
+ sym::assume => (0, vec![tcx.types.bool], tcx.mk_unit()),
+ sym::likely => (0, vec![tcx.types.bool], tcx.types.bool),
+ sym::unlikely => (0, vec![tcx.types.bool], tcx.types.bool),
- "discriminant_value" => {
+ sym::discriminant_value => {
let assoc_items =
tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
@@ -303,7 +336,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
)
}
- "try" => {
+ kw::Try => {
let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8);
let try_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
iter::once(mut_u8),
@@ -326,12 +359,12 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
)
}
- "va_start" | "va_end" => match mk_va_list_ty(hir::Mutability::Mut) {
+ sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()),
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
- "va_copy" => match mk_va_list_ty(hir::Mutability::Not) {
+ sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
Some((va_list_ref_ty, va_list_ty)) => {
let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty);
(0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit())
@@ -339,28 +372,28 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
- "va_arg" => match mk_va_list_ty(hir::Mutability::Mut) {
+ sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) {
Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)),
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
},
- "nontemporal_store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
+ sym::nontemporal_store => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()),
- "miri_start_panic" => {
+ sym::miri_start_panic => {
// FIXME - the relevant types aren't lang items,
// so it's not trivial to check this
return;
}
- "count_code_region" => (0, vec![tcx.types.u32], tcx.mk_unit()),
+ sym::count_code_region => (0, vec![tcx.types.u32], tcx.mk_unit()),
- ref other => {
+ other => {
struct_span_err!(
tcx.sess,
it.span,
E0093,
"unrecognized intrinsic function: `{}`",
- *other
+ other,
)
.span_label(it.span, "unrecognized intrinsic")
.emit();
@@ -369,7 +402,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
};
(n_tps, inputs, output, unsafety)
};
- equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, unsafety, inputs, output)
+ equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output)
}
/// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -379,6 +412,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
tcx.mk_ty_param(n, name)
};
+ let def_id = tcx.hir().local_def_id(it.hir_id).to_def_id();
let name = it.ident.as_str();
let (n_tps, inputs, output) = match &*name {
@@ -453,6 +487,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
equate_intrinsic_type(
tcx,
it,
+ def_id,
n_tps,
Abi::PlatformIntrinsic,
hir::Unsafety::Unsafe,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 67bdd04d3715c..b75dac52b93e5 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -608,7 +608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Adt(def, _) => bound_spans.push((def_span(def.did), msg)),
// Point at the trait object that couldn't satisfy the bound.
ty::Dynamic(preds, _) => {
- for pred in *preds.skip_binder() {
+ for pred in preds.skip_binder() {
match pred {
ty::ExistentialPredicate::Trait(tr) => {
bound_spans.push((def_span(tr.def_id), msg.clone()))
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 7c4048ab22302..b617937d6bd54 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2446,7 +2446,7 @@ fn bounds_from_generic_predicates(
/// Return placeholder code for the given function.
fn fn_sig_suggestion(
tcx: TyCtxt<'_>,
- sig: &ty::FnSig<'_>,
+ sig: ty::FnSig<'_>,
ident: Ident,
predicates: ty::GenericPredicates<'_>,
assoc: &ty::AssocItem,
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 94a5685a992fe..a1e060b97ad28 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -500,7 +500,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false;
}
// We're emitting a suggestion, so we can just ignore regions
- let fn_sig = *self.tcx.fn_sig(def_id).skip_binder();
+ let fn_sig = self.tcx.fn_sig(def_id).skip_binder();
let other_ty = if let FnDef(def_id, _) = other_ty.kind {
if !self.tcx.has_typeck_tables(def_id) {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index a45a44a6801e8..3b203dd222afb 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -216,7 +216,7 @@ fn check_object_overlap<'tcx>(
let component_def_ids = data.iter().flat_map(|predicate| {
match predicate.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => Some(tr.def_id),
- ty::ExistentialPredicate::AutoTrait(def_id) => Some(*def_id),
+ ty::ExistentialPredicate::AutoTrait(def_id) => Some(def_id),
// An associated type projection necessarily comes with
// an additional `Trait` requirement.
ty::ExistentialPredicate::Projection(..) => None,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index b486e3d3536c9..cc491c527db0b 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2063,7 +2063,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
ident: Ident,
) -> ty::PolyFnSig<'tcx> {
let unsafety = if abi == abi::Abi::RustIntrinsic {
- intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str())
+ intrinsic_operation_unsafety(tcx.item_name(def_id))
} else {
hir::Unsafety::Unsafe
};
@@ -2102,11 +2102,11 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
.emit();
}
};
- for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
+ for (input, ty) in decl.inputs.iter().zip(fty.inputs().skip_binder()) {
check(&input, ty)
}
if let hir::FnRetTy::Return(ref ty) = decl.output {
- check(&ty, *fty.output().skip_binder())
+ check(&ty, fty.output().skip_binder())
}
}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 73fe87b05d477..bfe8464347d29 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -347,7 +347,7 @@ impl Clean for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
GenericBound::TraitBound(
PolyTrait {
- trait_: (*poly_trait_ref.skip_binder(), bounds).clean(cx),
+ trait_: (poly_trait_ref.skip_binder(), bounds).clean(cx),
generic_params: late_bound_regions,
},
hir::TraitBoundModifier::None,
@@ -549,7 +549,7 @@ impl<'tcx> Clean