From 56147219a552b8383e66f9e3e8f0c92ea332aaf4 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 27 Mar 2020 19:18:52 -0400 Subject: [PATCH 1/7] Stabilize float::to_int_unchecked This renames and stabilizes unsafe floating point to integer casts, which are intended to be the substitute for the currently unsound `as` behavior, once that changes to safe-but-slower saturating casts. --- src/libcore/convert/num.rs | 15 +++++++++++---- src/libcore/intrinsics.rs | 8 ++++++++ src/libcore/num/f32.rs | 12 +++++------- src/libcore/num/f64.rs | 12 +++++------- src/librustc_codegen_llvm/intrinsic.rs | 6 +++--- src/librustc_typeck/check/intrinsic.rs | 2 +- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs index 752199c94b8ae..66ae760fc1f79 100644 --- a/src/libcore/convert/num.rs +++ b/src/libcore/convert/num.rs @@ -13,9 +13,9 @@ mod private { /// Typically doesn’t need to be used directly. #[unstable(feature = "convert_float_to_int", issue = "67057")] pub trait FloatToInt: private::Sealed + Sized { - #[unstable(feature = "float_approx_unchecked_to", issue = "67058")] + #[unstable(feature = "convert_float_to_int", issue = "67057")] #[doc(hidden)] - unsafe fn approx_unchecked(self) -> Int; + unsafe fn to_int_unchecked(self) -> Int; } macro_rules! impl_float_to_int { @@ -27,8 +27,15 @@ macro_rules! impl_float_to_int { impl FloatToInt<$Int> for $Float { #[doc(hidden)] #[inline] - unsafe fn approx_unchecked(self) -> $Int { - crate::intrinsics::float_to_int_approx_unchecked(self) + unsafe fn to_int_unchecked(self) -> $Int { + #[cfg(bootstrap)] + { + crate::intrinsics::float_to_int_approx_unchecked(self) + } + #[cfg(not(bootstrap))] + { + crate::intrinsics::float_to_int_unchecked(self) + } } } )+ diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 0c956104221eb..7e9140faa6411 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1582,8 +1582,16 @@ extern "rust-intrinsic" { /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range /// () /// This is under stabilization at + #[cfg(bootstrap)] pub fn float_to_int_approx_unchecked(value: Float) -> Int; + /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range + /// () + /// + /// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`. + #[cfg(not(bootstrap))] + pub fn float_to_int_unchecked(value: Float) -> Int; + /// Returns the number of bits set in an integer type `T` /// /// The stabilized versions of this intrinsic are available on the integer diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 3fdc2bae33876..09f1eab2d4b9d 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -464,14 +464,12 @@ impl f32 { /// assuming that the value is finite and fits in that type. /// /// ``` - /// #![feature(float_approx_unchecked_to)] - /// /// let value = 4.6_f32; - /// let rounded = unsafe { value.approx_unchecked_to::() }; + /// let rounded = unsafe { value.to_int_unchecked::() }; /// assert_eq!(rounded, 4); /// /// let value = -128.9_f32; - /// let rounded = unsafe { value.approx_unchecked_to::() }; + /// let rounded = unsafe { value.to_int_unchecked::() }; /// assert_eq!(rounded, std::i8::MIN); /// ``` /// @@ -482,13 +480,13 @@ impl f32 { /// * Not be `NaN` /// * Not be infinite /// * Be representable in the return type `Int`, after truncating off its fractional part - #[unstable(feature = "float_approx_unchecked_to", issue = "67058")] + #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")] #[inline] - pub unsafe fn approx_unchecked_to(self) -> Int + pub unsafe fn to_int_unchecked(self) -> Int where Self: FloatToInt, { - FloatToInt::::approx_unchecked(self) + FloatToInt::::to_int_unchecked(self) } /// Raw transmutation to `u32`. diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 129df937c0bb8..65ef7ba9ac768 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -478,14 +478,12 @@ impl f64 { /// assuming that the value is finite and fits in that type. /// /// ``` - /// #![feature(float_approx_unchecked_to)] - /// /// let value = 4.6_f32; - /// let rounded = unsafe { value.approx_unchecked_to::() }; + /// let rounded = unsafe { value.to_int_unchecked::() }; /// assert_eq!(rounded, 4); /// /// let value = -128.9_f32; - /// let rounded = unsafe { value.approx_unchecked_to::() }; + /// let rounded = unsafe { value.to_int_unchecked::() }; /// assert_eq!(rounded, std::i8::MIN); /// ``` /// @@ -496,13 +494,13 @@ impl f64 { /// * Not be `NaN` /// * Not be infinite /// * Be representable in the return type `Int`, after truncating off its fractional part - #[unstable(feature = "float_approx_unchecked_to", issue = "67058")] + #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")] #[inline] - pub unsafe fn approx_unchecked_to(self) -> Int + pub unsafe fn to_int_unchecked(self) -> Int where Self: FloatToInt, { - FloatToInt::::approx_unchecked(self) + FloatToInt::::to_int_unchecked(self) } /// Raw transmutation to `u64`. diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index bc25b9496d9b5..a3aa73e6217e8 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -544,13 +544,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } } - "float_to_int_approx_unchecked" => { + "float_to_int_unchecked" => { if float_type_width(arg_tys[0]).is_none() { span_invalid_monomorphization_error( tcx.sess, span, &format!( - "invalid monomorphization of `float_to_int_approx_unchecked` \ + "invalid monomorphization of `float_to_int_unchecked` \ intrinsic: expected basic float type, \ found `{}`", arg_tys[0] @@ -571,7 +571,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { tcx.sess, span, &format!( - "invalid monomorphization of `float_to_int_approx_unchecked` \ + "invalid monomorphization of `float_to_int_unchecked` \ intrinsic: expected basic integer type, \ found `{}`", ret_ty diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 6f9d8a8e58fa5..d506d3445f62e 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -275,7 +275,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { (1, vec![param(0), param(0)], param(0)) } - "float_to_int_approx_unchecked" => (2, vec![param(0)], param(1)), + "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), From f87afec2cec4f75e2caf9f72a7d8ee5e93b1eaab Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Thu, 2 Apr 2020 03:55:35 +0000 Subject: [PATCH 2/7] Use Self over specific type in return position --- src/libstd/fs.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index e20fcfafa229b..119bdfcb0f442 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -734,7 +734,7 @@ impl OpenOptions { /// let file = options.read(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> OpenOptions { + pub fn new() -> Self { OpenOptions(fs_imp::OpenOptions::new()) } @@ -751,7 +751,7 @@ impl OpenOptions { /// let file = OpenOptions::new().read(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn read(&mut self, read: bool) -> &mut OpenOptions { + pub fn read(&mut self, read: bool) -> &mut Self { self.0.read(read); self } @@ -772,7 +772,7 @@ impl OpenOptions { /// let file = OpenOptions::new().write(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn write(&mut self, write: bool) -> &mut OpenOptions { + pub fn write(&mut self, write: bool) -> &mut Self { self.0.write(write); self } @@ -819,7 +819,7 @@ impl OpenOptions { /// let file = OpenOptions::new().append(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn append(&mut self, append: bool) -> &mut OpenOptions { + pub fn append(&mut self, append: bool) -> &mut Self { self.0.append(append); self } @@ -839,7 +839,7 @@ impl OpenOptions { /// let file = OpenOptions::new().write(true).truncate(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions { + pub fn truncate(&mut self, truncate: bool) -> &mut Self { self.0.truncate(truncate); self } @@ -860,7 +860,7 @@ impl OpenOptions { /// let file = OpenOptions::new().write(true).create(true).open("foo.txt"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn create(&mut self, create: bool) -> &mut OpenOptions { + pub fn create(&mut self, create: bool) -> &mut Self { self.0.create(create); self } @@ -893,7 +893,7 @@ impl OpenOptions { /// .open("foo.txt"); /// ``` #[stable(feature = "expand_open_options2", since = "1.9.0")] - pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions { + pub fn create_new(&mut self, create_new: bool) -> &mut Self { self.0.create_new(create_new); self } From 75e2e8c71b4988324ebed0696d0177030d26be1d Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 30 Mar 2020 09:56:52 -0400 Subject: [PATCH 3/7] Remove unused discriminant reads from MIR bodies Allow the `SimplifyLocals` pass to remove reads of discriminants if the read is never used. --- src/librustc_mir/transform/simplify.rs | 26 +++++++------ ...ocals-removes-unused-discriminant-reads.rs | 12 ++++++ .../rustc.map.SimplifyLocals.diff | 37 +++++++++++++++++++ src/test/mir-opt/simplify_try.rs | 16 ++++---- 4 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs create mode 100644 src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index faee077f51e1a..c2029a223b941 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -368,18 +368,22 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { if location.statement_index != block.statements.len() { let stmt = &block.statements[location.statement_index]; - if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = - &stmt.kind - { - match c.literal.val { - // Keep assignments from unevaluated constants around, since the evaluation - // may report errors, even if the use of the constant is dead code. - ty::ConstKind::Unevaluated(..) => {} - _ => { - if !p.is_indirect() { - trace!("skipping store of const value {:?} to {:?}", c, p); - return; + if let StatementKind::Assign(box (dest, rvalue)) = &stmt.kind { + if !dest.is_indirect() && dest.local == *local { + if let Rvalue::Use(Operand::Constant(c)) = rvalue { + match c.literal.val { + // Keep assignments from unevaluated constants around, since the + // evaluation may report errors, even if the use of the constant + // is dead code. + ty::ConstKind::Unevaluated(..) => {} + _ => { + trace!("skipping store of const value {:?} to {:?}", c, dest); + return; + } } + } else if let Rvalue::Discriminant(d) = rvalue { + trace!("skipping store of discriminant value {:?} to {:?}", d, dest); + return; } } } diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs new file mode 100644 index 0000000000000..067fa879b4038 --- /dev/null +++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads.rs @@ -0,0 +1,12 @@ +fn map(x: Option>) -> Option> { + match x { + None => None, + Some(x) => Some(x), + } +} + +fn main() { + map(None); +} + +// EMIT_MIR rustc.map.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff new file mode 100644 index 0000000000000..bba8bc82fe7d9 --- /dev/null +++ b/src/test/mir-opt/simplify-locals-removes-unused-discriminant-reads/rustc.map.SimplifyLocals.diff @@ -0,0 +1,37 @@ +- // MIR for `map` before SimplifyLocals ++ // MIR for `map` after SimplifyLocals + + fn map(_1: std::option::Option>) -> std::option::Option> { + debug x => _1; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:8: 1:9 + let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:1:31: 1:46 + let mut _2: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 + let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15 +- let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:25: 4:26 +- let mut _5: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 +- let mut _6: isize; // in scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 + scope 1 { + debug x => _3; // in scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:14: 4:15 + } + + bb0: { + _2 = discriminant(_1); // bb0[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 + switchInt(move _2) -> [0isize: bb2, otherwise: bb1]; // bb0[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:9: 3:13 + } + + bb1: { + _0 = move _1; // bb1[0]: scope 1 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:4:20: 4:27 + goto -> bb3; // bb1[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 + } + + bb2: { + discriminant(_0) = 0; // bb2[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:3:17: 3:21 + goto -> bb3; // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:2:5: 5:6 + } + + bb3: { +- _5 = discriminant(_1); // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:1: 6:2 +- return; // bb3[1]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2 ++ return; // bb3[0]: scope 0 at $DIR/simplify-locals-removes-unused-discriminant-reads.rs:6:2: 6:2 + } + } + diff --git a/src/test/mir-opt/simplify_try.rs b/src/test/mir-opt/simplify_try.rs index abac66d95c548..78a7f722538ed 100644 --- a/src/test/mir-opt/simplify_try.rs +++ b/src/test/mir-opt/simplify_try.rs @@ -183,25 +183,24 @@ fn main() { // fn try_identity(_1: std::result::Result) -> std::result::Result { // debug x => _1; // let mut _0: std::result::Result; -// let mut _2: isize; -// let _3: i32; -// let _4: u32; +// let _2: i32; +// let _3: u32; // scope 1 { -// debug y => _4; +// debug y => _3; // } // scope 2 { -// debug err => _3; +// debug err => _2; // scope 3 { // scope 7 { -// debug t => _3; +// debug t => _2; // } // scope 8 { -// debug v => _3; +// debug v => _2; // } // } // } // scope 4 { -// debug val => _4; +// debug val => _3; // scope 5 { // } // } @@ -209,7 +208,6 @@ fn main() { // debug self => _1; // } // bb0: { -// _2 = discriminant(_1); // _0 = move _1; // return; // } From 0b612399366e28b5314b5fd289f46c636d596a7b Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Thu, 2 Apr 2020 14:20:35 +0200 Subject: [PATCH 4/7] Improve docs in `AllocRef` --- src/libcore/alloc/mod.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libcore/alloc/mod.rs b/src/libcore/alloc/mod.rs index e8c4b68c64890..77ac93c7b7905 100644 --- a/src/libcore/alloc/mod.rs +++ b/src/libcore/alloc/mod.rs @@ -33,9 +33,7 @@ impl fmt::Display for AllocErr { #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[unstable(feature = "allocator_api", issue = "32838")] pub enum AllocInit { - /// The contents of the new memory are undefined. - /// - /// Reading uninitialized memory is Undefined Behavior; it must be initialized before use. + /// The contents of the new memory are uninitialized. Uninitialized, /// The new memory is guaranteed to be zeroed. Zeroed, @@ -196,7 +194,11 @@ pub unsafe trait AllocRef { /// /// # Safety /// - /// `memory` must be a memory block returned by this allocator. + /// * `ptr` must be [*currently allocated*] via this allocator, and + /// * `layout` must [*fit*] the `ptr`. + /// + /// [*currently allocated*]: #currently-allocated-memory + /// [*fit*]: #memory-fitting unsafe fn dealloc(&mut self, ptr: NonNull, layout: Layout); /// Attempts to extend the memory block. @@ -237,7 +239,7 @@ pub unsafe trait AllocRef { // * `new_size must be strictly greater than `memory.size` or both are zero /// * `new_size` must be greater than or equal to `layout.size()` /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not overflow - /// (i.e., the rounded value must be less than `usize::MAX`). + /// (i.e., the rounded value must be less than or equal to `usize::MAX`). /// /// [*currently allocated*]: #currently-allocated-memory /// [*fit*]: #memory-fitting From 65fcc3f1cdc623607a7529487a6b869b3a6c1943 Mon Sep 17 00:00:00 2001 From: Roberto Vidal Date: Thu, 2 Apr 2020 16:34:43 +0200 Subject: [PATCH 5/7] Expand on platform details of `include_xxx` macros --- src/libcore/macros/mod.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs index f67762cd04346..9c885ef99a980 100644 --- a/src/libcore/macros/mod.rs +++ b/src/libcore/macros/mod.rs @@ -1070,8 +1070,10 @@ pub(crate) mod builtin { /// Includes a utf8-encoded file as a string. /// - /// The file is located relative to the current file. (similarly to how - /// modules are found) + /// The file is located relative to the current file (similarly to how + /// modules are found). The provided path is interpreted in a platform-specific + /// way at compile time. So, for instance, an invocation with a Windows path + /// containing backslashes `\` would not compile correctly on Unix. /// /// This macro will yield an expression of type `&'static str` which is the /// contents of the file. @@ -1108,8 +1110,10 @@ pub(crate) mod builtin { /// Includes a file as a reference to a byte array. /// - /// The file is located relative to the current file. (similarly to how - /// modules are found) + /// The file is located relative to the current file (similarly to how + /// modules are found). The provided path is interpreted in a platform-specific + /// way at compile time. So, for instance, an invocation with a Windows path + /// containing backslashes `\` would not compile correctly on Unix. /// /// This macro will yield an expression of type `&'static [u8; N]` which is /// the contents of the file. @@ -1202,7 +1206,9 @@ pub(crate) mod builtin { /// Parses a file as an expression or an item according to the context. /// /// The file is located relative to the current file (similarly to how - /// modules are found). + /// modules are found). The provided path is interpreted in a platform-specific + /// way at compile time. So, for instance, an invocation with a Windows path + /// containing backslashes `\` would not compile correctly on Unix. /// /// Using this macro is often a bad idea, because if the file is /// parsed as an expression, it is going to be placed in the From 354ddbfb3f14f68aecb63d87fc31f87400b6f820 Mon Sep 17 00:00:00 2001 From: Pocakking <42542447+Pocakking@users.noreply.github.com> Date: Thu, 2 Apr 2020 20:01:29 +0200 Subject: [PATCH 6/7] Fix typo in u8::to_ascii_uppercase and u8::to_ascii_lowercase fith => fifth --- src/libcore/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 853092dd85ee9..c85064759ea03 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4376,7 +4376,7 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> u8 { - // Unset the fith bit if this is a lowercase letter + // Unset the fifth bit if this is a lowercase letter *self & !((self.is_ascii_lowercase() as u8) << 5) } @@ -4399,7 +4399,7 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> u8 { - // Set the fith bit if this is an uppercase letter + // Set the fifth bit if this is an uppercase letter *self | ((self.is_ascii_uppercase() as u8) << 5) } From a12ebd3027e9c2b63f3d94c122c9d95d2d3ac739 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 2 Apr 2020 20:31:51 +0100 Subject: [PATCH 7/7] unerase regions in `infer_placeholder_type` --- src/librustc_typeck/collect/type_of.rs | 6 +++++- src/test/ui/suggestions/const-no-type.rs | 5 +++++ src/test/ui/suggestions/const-no-type.stderr | 12 +++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 1d34a58fabb31..e6099b98dc82b 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -655,7 +655,11 @@ fn infer_placeholder_type( } } - ty + // Typeck doesn't expect erased regions to be returned from `type_of`. + tcx.fold_regions(&ty, &mut false, |r, _| match r { + ty::ReErased => tcx.lifetimes.re_static, + _ => r, + }) } fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) { diff --git a/src/test/ui/suggestions/const-no-type.rs b/src/test/ui/suggestions/const-no-type.rs index 6b79697e9839e..b931a04c2860c 100644 --- a/src/test/ui/suggestions/const-no-type.rs +++ b/src/test/ui/suggestions/const-no-type.rs @@ -35,6 +35,11 @@ const C = 42; //~| HELP provide a type for the item //~| SUGGESTION C: i32 +const D = &&42; +//~^ ERROR missing type for `const` item +//~| HELP provide a type for the item +//~| SUGGESTION D: &&i32 + static S = Vec::::new(); //~^ ERROR missing type for `static` item //~| HELP provide a type for the item diff --git a/src/test/ui/suggestions/const-no-type.stderr b/src/test/ui/suggestions/const-no-type.stderr index a7b5aa5e5b124..874c1bac10bd5 100644 --- a/src/test/ui/suggestions/const-no-type.stderr +++ b/src/test/ui/suggestions/const-no-type.stderr @@ -4,14 +4,20 @@ error: missing type for `const` item LL | const C = 42; | ^ help: provide a type for the item: `C: i32` +error: missing type for `const` item + --> $DIR/const-no-type.rs:38:7 + | +LL | const D = &&42; + | ^ help: provide a type for the item: `D: &&i32` + error: missing type for `static` item - --> $DIR/const-no-type.rs:38:8 + --> $DIR/const-no-type.rs:43:8 | LL | static S = Vec::::new(); | ^ help: provide a type for the item: `S: std::vec::Vec` error: missing type for `static mut` item - --> $DIR/const-no-type.rs:43:12 + --> $DIR/const-no-type.rs:48:12 | LL | static mut SM = "abc"; | ^^ help: provide a type for the item: `SM: &str` @@ -34,5 +40,5 @@ error: missing type for `static mut` item LL | static mut SM2 = "abc"; | ^^^ help: provide a type for the item: `SM2: ` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors