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/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile
index 9276e4ed82d78..6775baa8c3273 100644
--- a/src/ci/docker/test-various/Dockerfile
+++ b/src/ci/docker/test-various/Dockerfile
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
wget \
patch
-RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \
+RUN curl -sL https://nodejs.org/dist/v14.4.0/node-v14.4.0-linux-x64.tar.xz | \
tar -xJ
WORKDIR /build/
@@ -30,7 +30,7 @@ RUN sh /scripts/sccache.sh
ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
- --set build.nodejs=/node-v9.2.0-linux-x64/bin/node \
+ --set build.nodejs=/node-v14.4.0-linux-x64/bin/node \
--set rust.lld
# Some run-make tests have assertions about code size, and enabling debug
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/lib.rs b/src/libcore/lib.rs
index aeb52bffbf24c..b732dacae1c5b 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -118,7 +118,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_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index ba285b5ef38d1..89b70dce52c66 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -18,6 +18,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::sym;
use rustc_target::abi::{self, Align, Size};
use rustc_target::spec::{HasTargetSpec, Target};
use std::borrow::Cow;
@@ -652,6 +653,56 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) }
}
+ fn fptoui_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
+ // WebAssembly has saturating floating point to integer casts if the
+ // `nontrapping-fptoint` target feature is activated. We'll use those if
+ // they are available.
+ if self.sess().target.target.arch == "wasm32"
+ && self.sess().target_features.contains(&sym::nontrapping_fptoint)
+ {
+ let src_ty = self.cx.val_ty(val);
+ let float_width = self.cx.float_width(src_ty);
+ let int_width = self.cx.int_width(dest_ty);
+ let name = match (int_width, float_width) {
+ (32, 32) => Some("llvm.wasm.trunc.saturate.unsigned.i32.f32"),
+ (32, 64) => Some("llvm.wasm.trunc.saturate.unsigned.i32.f64"),
+ (64, 32) => Some("llvm.wasm.trunc.saturate.unsigned.i64.f32"),
+ (64, 64) => Some("llvm.wasm.trunc.saturate.unsigned.i64.f64"),
+ _ => None,
+ };
+ if let Some(name) = name {
+ let intrinsic = self.get_intrinsic(name);
+ return Some(self.call(intrinsic, &[val], None));
+ }
+ }
+ None
+ }
+
+ fn fptosi_sat(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> Option<&'ll Value> {
+ // WebAssembly has saturating floating point to integer casts if the
+ // `nontrapping-fptoint` target feature is activated. We'll use those if
+ // they are available.
+ if self.sess().target.target.arch == "wasm32"
+ && self.sess().target_features.contains(&sym::nontrapping_fptoint)
+ {
+ let src_ty = self.cx.val_ty(val);
+ let float_width = self.cx.float_width(src_ty);
+ let int_width = self.cx.int_width(dest_ty);
+ let name = match (int_width, float_width) {
+ (32, 32) => Some("llvm.wasm.trunc.saturate.signed.i32.f32"),
+ (32, 64) => Some("llvm.wasm.trunc.saturate.signed.i32.f64"),
+ (64, 32) => Some("llvm.wasm.trunc.saturate.signed.i64.f32"),
+ (64, 64) => Some("llvm.wasm.trunc.saturate.signed.i64.f64"),
+ _ => None,
+ };
+ if let Some(name) = name {
+ let intrinsic = self.get_intrinsic(name);
+ return Some(self.call(intrinsic, &[val], None));
+ }
+ }
+ None
+ }
+
fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) }
}
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 7ff5ac5cbdc10..896d3c1de62d5 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -482,6 +482,15 @@ impl CodegenCx<'b, 'tcx> {
t_v8f64: t_f64, 8;
}
+ ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f32", fn(t_f32) -> t_i32);
+ ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f64", fn(t_f64) -> t_i32);
+ ifn!("llvm.wasm.trunc.saturate.unsigned.i64.f32", fn(t_f32) -> t_i64);
+ ifn!("llvm.wasm.trunc.saturate.unsigned.i64.f64", fn(t_f64) -> t_i64);
+ ifn!("llvm.wasm.trunc.saturate.signed.i32.f32", fn(t_f32) -> t_i32);
+ ifn!("llvm.wasm.trunc.saturate.signed.i32.f64", fn(t_f64) -> t_i32);
+ ifn!("llvm.wasm.trunc.saturate.signed.i64.f32", fn(t_f32) -> t_i64);
+ ifn!("llvm.wasm.trunc.saturate.signed.i64.f64", fn(t_f64) -> t_i64);
+
ifn!("llvm.trap", fn() -> void);
ifn!("llvm.debugtrap", fn() -> void);
ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 80278bb9f53d8..2e2ce1544109a 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -250,8 +250,11 @@ const RISCV_WHITELIST: &[(&str, Option)] = &[
("e", Some(sym::riscv_target_feature)),
];
-const WASM_WHITELIST: &[(&str, Option)] =
- &[("simd128", Some(sym::wasm_target_feature)), ("atomics", Some(sym::wasm_target_feature))];
+const WASM_WHITELIST: &[(&str, Option)] = &[
+ ("simd128", Some(sym::wasm_target_feature)),
+ ("atomics", Some(sym::wasm_target_feature)),
+ ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
+];
/// When rustdoc is running, provide a list of all known features so that all their respective
/// primitives may be documented.
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 57f72b1065d05..4b2be7b5321ff 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -774,12 +774,17 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
float_ty: Bx::Type,
int_ty: Bx::Type,
) -> Bx::Value {
- let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
-
if let Some(false) = bx.cx().sess().opts.debugging_opts.saturating_float_casts {
- return fptosui_result;
+ return if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
+ }
+
+ let try_sat_result = if signed { bx.fptosi_sat(x, int_ty) } else { bx.fptoui_sat(x, int_ty) };
+ if let Some(try_sat_result) = try_sat_result {
+ return try_sat_result;
}
+ let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) };
+
let int_width = bx.cx().int_width(int_ty);
let float_width = bx.cx().float_width(float_ty);
// LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 7ffc9f15bffdc..d33d6857bc0ef 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -156,6 +156,8 @@ pub trait BuilderMethods<'a, 'tcx>:
fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
+ fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option;
+ fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Option;
fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index b45ab0f80ffac..afe5342877462 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -6,6 +6,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(nll)]
+#![feature(track_caller)]
#![recursion_limit = "256"]
#[macro_use]
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 0a21eb8de059c..6a34a310f735a 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -80,8 +80,7 @@ where
PpmTyped => {
abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
- let empty_tables = ty::TypeckTables::empty(None);
- let annotation = TypedAnnotation { tcx, tables: Cell::new(&empty_tables) };
+ let annotation = TypedAnnotation { tcx, maybe_typeck_tables: Cell::new(None) };
tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().krate()))
}
_ => panic!("Should use call_with_pp_support"),
@@ -304,12 +303,22 @@ impl<'a> pprust::PpAnn for HygieneAnnotation<'a> {
}
}
-struct TypedAnnotation<'a, 'tcx> {
+struct TypedAnnotation<'tcx> {
tcx: TyCtxt<'tcx>,
- tables: Cell<&'a ty::TypeckTables<'tcx>>,
+ maybe_typeck_tables: Cell