From 0bce91ff0b3252b736040087f9b768027422f3f0 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 14 Dec 2019 12:13:10 -0500 Subject: [PATCH 01/13] add Scalar::try_from_(u)int methods --- src/librustc/mir/interpret/value.rs | 34 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index a038ca23ae9..4f196cda5ae 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -237,13 +237,18 @@ pub fn from_char(c: char) -> Self { } #[inline] - pub fn from_uint(i: impl Into, size: Size) -> Self { + pub fn try_from_uint(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { let i = i.into(); - assert_eq!( - truncate(i, size), i, - "Unsigned value {:#x} does not fit in {} bits", i, size.bits() - ); - Scalar::Raw { data: i, size: size.bytes() as u8 } + if truncate(i, size) == i { + Ok(Scalar::Raw { data: i, size: size.bytes() as u8 }) + } else { + throw_unsup_format!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + } + } + + #[inline] + pub fn from_uint(i: impl Into, size: Size) -> Self { + Self::try_from_uint(i, size).unwrap() } #[inline] @@ -267,15 +272,20 @@ pub fn from_u64(i: u64) -> Self { } #[inline] - pub fn from_int(i: impl Into, size: Size) -> Self { + pub fn try_from_int(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { let i = i.into(); // `into` performed sign extension, we have to truncate let truncated = truncate(i as u128, size); - assert_eq!( - sign_extend(truncated, size) as i128, i, - "Signed value {:#x} does not fit in {} bits", i, size.bits() - ); - Scalar::Raw { data: truncated, size: size.bytes() as u8 } + if sign_extend(truncated, size) as i128 == i { + Ok(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) + } else { + throw_unsup_format!("Signed value {:#x} does not fit in {} bits", i, size.bits()) + } + } + + #[inline] + pub fn from_int(i: impl Into, size: Size) -> Self { + Self::try_from_int(i, size).unwrap() } #[inline] From 90686ded25ee4f7f6676141a0413c066a2a4d393 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 14 Dec 2019 12:13:26 -0500 Subject: [PATCH 02/13] add ImmTy::try_from_(u)int methods --- src/librustc_mir/interpret/operand.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 48e7193ec39..072152a3887 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -218,14 +218,23 @@ pub fn from_scalar(val: Scalar, layout: TyLayout<'tcx>) -> Self { ImmTy { imm: val.into(), layout } } + #[inline] + pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { + Ok(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) + } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::from_scalar(Scalar::from_uint(i, layout.size), layout) + Self::try_from_uint(i, layout).unwrap() + } + + #[inline] + pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { + Ok(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) } #[inline] pub fn from_int(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::from_scalar(Scalar::from_int(i, layout.size), layout) + Self::try_from_int(i, layout).unwrap() } #[inline] From 69038363986ed1fcc46dc5c5d53c6b95ab97f9e8 Mon Sep 17 00:00:00 2001 From: Masaki Hara Date: Sat, 21 Dec 2019 15:16:00 +0900 Subject: [PATCH 03/13] Remove iter_private.rs The contents of this file have been moved in #56932 (520e8b0) and the file should have been removed as well. --- src/libcore/iter_private.rs | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/libcore/iter_private.rs diff --git a/src/libcore/iter_private.rs b/src/libcore/iter_private.rs deleted file mode 100644 index 890db47b197..00000000000 --- a/src/libcore/iter_private.rs +++ /dev/null @@ -1,17 +0,0 @@ -/// An iterator whose items are random accessible efficiently -/// -/// # Safety -/// -/// The iterator's .len() and size_hint() must be exact. -/// `.len()` must be cheap to call. -/// -/// .get_unchecked() must return distinct mutable references for distinct -/// indices (if applicable), and must return a valid reference if index is in -/// 0..self.len(). -#[doc(hidden)] -pub unsafe trait TrustedRandomAccess : ExactSizeIterator { - unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item; - /// Returns `true` if getting an iterator element may have - /// side effects. Remember to take inner iterators into account. - fn may_have_side_effect() -> bool; -} From 309f437e1d20ce93597eec0514a9cb80150d8861 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sat, 21 Dec 2019 10:27:58 -0500 Subject: [PATCH 04/13] Change results to options --- src/librustc/mir/interpret/value.rs | 12 ++++++------ src/librustc_mir/interpret/operand.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 4f196cda5ae..8f5fab4b002 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -237,12 +237,12 @@ pub fn from_char(c: char) -> Self { } #[inline] - pub fn try_from_uint(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { + pub fn try_from_uint(i: impl Into, size: Size) -> Option { let i = i.into(); if truncate(i, size) == i { - Ok(Scalar::Raw { data: i, size: size.bytes() as u8 }) + Some(Scalar::Raw { data: i, size: size.bytes() as u8 }) } else { - throw_unsup_format!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + None } } @@ -272,14 +272,14 @@ pub fn from_u64(i: u64) -> Self { } #[inline] - pub fn try_from_int(i: impl Into, size: Size) -> InterpResult<'tcx, Self> { + pub fn try_from_int(i: impl Into, size: Size) -> Option { let i = i.into(); // `into` performed sign extension, we have to truncate let truncated = truncate(i as u128, size); if sign_extend(truncated, size) as i128 == i { - Ok(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) + Some(Scalar::Raw { data: truncated, size: size.bytes() as u8 }) } else { - throw_unsup_format!("Signed value {:#x} does not fit in {} bits", i, size.bits()) + None } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 072152a3887..8dd50958350 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -219,8 +219,8 @@ pub fn from_scalar(val: Scalar, layout: TyLayout<'tcx>) -> Self { } #[inline] - pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { - Ok(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) + pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Option { + Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { @@ -228,8 +228,8 @@ pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { } #[inline] - pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> InterpResult<'tcx, Self> { - Ok(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) + pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> Option { + Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) } #[inline] From 5a0d747eefb74f6dbb6c990a97a02815b3273974 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Dec 2019 15:29:46 +0100 Subject: [PATCH 05/13] Remove clean::Mutability enum --- src/librustdoc/clean/inline.rs | 4 ++-- src/librustdoc/clean/mod.rs | 23 ++++++----------------- src/librustdoc/clean/types.rs | 8 +------- src/librustdoc/html/render.rs | 4 ++-- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7ee1054dc48..0f43555fd74 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -7,7 +7,7 @@ use syntax_pos::hygiene::MacroKind; use syntax_pos::Span; -use rustc::hir; +use rustc::hir::{self, Mutability}; use rustc::hir::def::{Res, DefKind, CtorKind}; use rustc::hir::def_id::DefId; use rustc_metadata::creader::LoadedMacro; @@ -472,7 +472,7 @@ fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant { fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { type_: cx.tcx.type_of(did).clean(cx), - mutability: if mutable {clean::Mutable} else {clean::Immutable}, + mutability: if mutable { Mutability::Mutable } else { Mutability::Immutable }, expr: "\n\n\n".to_string(), // trigger the "[definition]" links } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cebfd99452a..78e9b665c98 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -46,7 +46,6 @@ pub use self::types::*; pub use self::types::Type::*; -pub use self::types::Mutability::*; pub use self::types::ItemEnum::*; pub use self::types::SelfTy::*; pub use self::types::FunctionRetTy::*; @@ -1321,15 +1320,14 @@ fn clean(&self, cx: &DocContext<'_>) -> Type { match self.kind { TyKind::Never => Never, - TyKind::Ptr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), + TyKind::Ptr(ref m) => RawPointer(m.mutbl, box m.ty.clean(cx)), TyKind::Rptr(ref l, ref m) => { let lifetime = if l.is_elided() { None } else { Some(l.clean(cx)) }; - BorrowedRef {lifetime, mutability: m.mutbl.clean(cx), - type_: box m.ty.clean(cx)} + BorrowedRef {lifetime, mutability: m.mutbl, type_: box m.ty.clean(cx)} } TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Array(ref ty, ref length) => { @@ -1547,10 +1545,10 @@ fn clean(&self, cx: &DocContext<'_>) -> Type { let n = print_const(cx, n); Array(box ty.clean(cx), n) } - ty::RawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), + ty::RawPtr(mt) => RawPointer(mt.mutbl, box mt.ty.clean(cx)), ty::Ref(r, ty, mutbl) => BorrowedRef { lifetime: r.clean(cx), - mutability: mutbl.clean(cx), + mutability: mutbl, type_: box ty.clean(cx), }, ty::FnDef(..) | @@ -2073,7 +2071,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item { deprecation: cx.deprecation(self.id).clean(cx), inner: StaticItem(Static { type_: self.type_.clean(cx), - mutability: self.mutability.clean(cx), + mutability: self.mutability, expr: print_const_expr(cx, self.expr), }), } @@ -2098,15 +2096,6 @@ fn clean(&self, cx: &DocContext<'_>) -> Item { } } -impl Clean for hir::Mutability { - fn clean(&self, _: &DocContext<'_>) -> Mutability { - match self { - &hir::Mutability::Mut => Mutable, - &hir::Mutability::Not => Immutable, - } - } -} - impl Clean for ty::ImplPolarity { fn clean(&self, _: &DocContext<'_>) -> ImplPolarity { match self { @@ -2296,7 +2285,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item { hir::ForeignItemKind::Static(ref ty, mutbl) => { ForeignStaticItem(Static { type_: ty.clean(cx), - mutability: mutbl.clean(cx), + mutability: *mutbl, expr: String::new(), }) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bd3f2a3690a..706aef72031 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -10,7 +10,7 @@ use rustc::middle::lang_items; use rustc::middle::stability; -use rustc::hir; +use rustc::hir::{self, Mutability}; use rustc::hir::def::Res; use rustc::hir::def_id::{CrateNum, DefId}; use rustc::ty::layout::VariantIdx; @@ -1450,12 +1450,6 @@ pub struct Constant { pub expr: String, } -#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)] -pub enum Mutability { - Mutable, - Immutable, -} - #[derive(Clone, PartialEq, Debug)] pub enum ImplPolarity { Positive, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e764b7ee527..e822ada0fb9 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -54,12 +54,12 @@ use rustc::hir::def_id::DefId; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; -use rustc::hir; +use rustc::hir::{self, Mutability}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::flock; use rustc_feature::UnstableFeatures; -use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, Mutability}; +use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy}; use crate::config::RenderOptions; use crate::docfs::{DocFS, ErrorStorage, PathError}; use crate::doctree; From 4f0dc7b06c72d4b1f5caf2c40c8f7407cdb9c5ab Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 20 Dec 2019 18:05:45 +0100 Subject: [PATCH 06/13] misc cleanup in match MIR building --- src/librustc_mir/build/matches/mod.rs | 42 ++++++++++++-------------- src/librustc_mir/build/matches/test.rs | 2 +- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index bf0b2439c00..c0a7439b5ce 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -26,6 +26,7 @@ mod test; mod util; +use itertools::Itertools; use std::convert::TryFrom; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -822,9 +823,7 @@ fn match_candidates<'pat>( ); let (matched_candidates, unmatched_candidates) = candidates.split_at_mut(fully_matched); - let block: BasicBlock; - - if !matched_candidates.is_empty() { + let block: BasicBlock = if !matched_candidates.is_empty() { let otherwise_block = self.select_matched_candidates( matched_candidates, start_block, @@ -832,17 +831,17 @@ fn match_candidates<'pat>( ); if let Some(last_otherwise_block) = otherwise_block { - block = last_otherwise_block + last_otherwise_block } else { // Any remaining candidates are unreachable. if unmatched_candidates.is_empty() { return; } - block = self.cfg.start_new_block(); - }; + self.cfg.start_new_block() + } } else { - block = *start_block.get_or_insert_with(|| self.cfg.start_new_block()); - } + *start_block.get_or_insert_with(|| self.cfg.start_new_block()) + }; // If there are no candidates that still need testing, we're // done. Since all matches are exhaustive, execution should @@ -885,7 +884,7 @@ fn match_candidates<'pat>( /// ... /// /// We generate real edges from: - /// * `block` to the prebinding_block of the first pattern, + /// * `start_block` to the `prebinding_block` of the first pattern, /// * the otherwise block of the first pattern to the second pattern, /// * the otherwise block of the third pattern to the a block with an /// Unreachable terminator. @@ -948,6 +947,7 @@ fn select_matched_candidates( let first_candidate = &reachable_candidates[0]; let first_prebinding_block = first_candidate.pre_binding_block; + // `goto -> first_prebinding_block` from the `start_block` if there is one. if let Some(start_block) = *start_block { let source_info = self.source_info(first_candidate.span); self.cfg.terminate( @@ -959,21 +959,17 @@ fn select_matched_candidates( *start_block = Some(first_prebinding_block); } - for window in reachable_candidates.windows(2) { - if let [first_candidate, second_candidate] = window { - let source_info = self.source_info(first_candidate.span); - if let Some(otherwise_block) = first_candidate.otherwise_block { - self.false_edges( - otherwise_block, - second_candidate.pre_binding_block, - first_candidate.next_candidate_pre_binding_block, - source_info, - ); - } else { - bug!("candidate other than the last has no guard"); - } + for (first_candidate, second_candidate) in reachable_candidates.iter().tuple_windows() { + let source_info = self.source_info(first_candidate.span); + if let Some(otherwise_block) = first_candidate.otherwise_block { + self.false_edges( + otherwise_block, + second_candidate.pre_binding_block, + first_candidate.next_candidate_pre_binding_block, + source_info, + ); } else { - bug!("<[_]>::windows returned incorrectly sized window"); + bug!("candidate other than the last has no guard"); } } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index e320811ca05..bdc1bdd5b98 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -30,7 +30,7 @@ pub fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { Test { span: match_pair.pattern.span, kind: TestKind::Switch { - adt_def: adt_def.clone(), + adt_def, variants: BitSet::new_empty(adt_def.variants.len()), }, } From f5a8d1ab034c48b69eef8ee3618f7eb97d72810f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 20 Dec 2019 18:27:05 +0100 Subject: [PATCH 07/13] simplify MIR building with cfg.goto(...) --- src/librustc_mir/build/block.rs | 3 +-- src/librustc_mir/build/cfg.rs | 5 ++++ src/librustc_mir/build/expr/into.rs | 28 +++++---------------- src/librustc_mir/build/matches/mod.rs | 35 ++++++-------------------- src/librustc_mir/build/matches/util.rs | 10 +------- src/librustc_mir/build/mod.rs | 9 +++---- src/librustc_mir/build/scope.rs | 18 +++++-------- 7 files changed, 29 insertions(+), 79 deletions(-) diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 7353ca9285d..aceed09757e 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -33,8 +33,7 @@ pub fn ast_block(&mut self, this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode) }); - this.cfg.terminate(unpack!(block_exit), source_info, - TerminatorKind::Goto { target: exit_block }); + this.cfg.goto(unpack!(block_exit), source_info, exit_block); exit_block.unit() } else { this.ast_block_stmts(destination, block, span, stmts, expr, diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 6bd8d2f7c07..0e685486c3f 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -85,4 +85,9 @@ pub fn terminate(&mut self, kind, }); } + + /// In the `origin` block, push a `goto -> target` terminator. + pub fn goto(&mut self, origin: BasicBlock, source_info: SourceInfo, target: BasicBlock) { + self.terminate(origin, source_info, TerminatorKind::Goto { target }) + } } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 608415408e3..a9fa7cfa04a 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -140,17 +140,9 @@ pub fn into_expr( }, ); - this.cfg.terminate( - true_block, - source_info, - TerminatorKind::Goto { target: join_block }, - ); - this.cfg.terminate( - false_block, - source_info, - TerminatorKind::Goto { target: join_block }, - ); - + // Link up both branches: + this.cfg.goto(true_block, source_info, join_block); + this.cfg.goto(false_block, source_info, join_block); join_block.unit() } ExprKind::Loop { body } => { @@ -167,12 +159,8 @@ pub fn into_expr( let loop_block = this.cfg.start_new_block(); let exit_block = this.cfg.start_new_block(); - // start the loop - this.cfg.terminate( - block, - source_info, - TerminatorKind::Goto { target: loop_block }, - ); + // Start the loop. + this.cfg.goto(block, source_info, loop_block); this.in_breakable_scope( Some(loop_block), @@ -196,11 +184,7 @@ pub fn into_expr( let tmp = this.get_unit_temp(); // Execute the body, branching back to the test. let body_block_end = unpack!(this.into(&tmp, body_block, body)); - this.cfg.terminate( - body_block_end, - source_info, - TerminatorKind::Goto { target: loop_block }, - ); + this.cfg.goto(body_block_end, source_info, loop_block); }, ); exit_block.unit() diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index c0a7439b5ce..6869930509c 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -259,11 +259,7 @@ pub fn match_expr( scrutinee_span, match_scope, ); - this.cfg.terminate( - binding_end, - source_info, - TerminatorKind::Goto { target: arm_block }, - ); + this.cfg.goto(binding_end, source_info, arm_block); } } @@ -279,11 +275,7 @@ pub fn match_expr( let end_block = self.cfg.start_new_block(); for arm_block in arm_end_blocks { - self.cfg.terminate( - unpack!(arm_block), - outer_source_info, - TerminatorKind::Goto { target: end_block }, - ); + self.cfg.goto(unpack!(arm_block), outer_source_info, end_block); } self.source_scope = outer_source_info.scope; @@ -848,18 +840,9 @@ fn match_candidates<'pat>( // never reach this point. if unmatched_candidates.is_empty() { let source_info = self.source_info(span); - if let Some(otherwise) = otherwise_block { - self.cfg.terminate( - block, - source_info, - TerminatorKind::Goto { target: otherwise }, - ); - } else { - self.cfg.terminate( - block, - source_info, - TerminatorKind::Unreachable, - ) + match otherwise_block { + Some(otherwise) => self.cfg.goto(block, source_info, otherwise), + None => self.cfg.terminate(block, source_info, TerminatorKind::Unreachable), } return; } @@ -950,11 +933,7 @@ fn select_matched_candidates( // `goto -> first_prebinding_block` from the `start_block` if there is one. if let Some(start_block) = *start_block { let source_info = self.source_info(first_candidate.span); - self.cfg.terminate( - start_block, - source_info, - TerminatorKind::Goto { target: first_prebinding_block }, - ); + self.cfg.goto(start_block, source_info, first_prebinding_block); } else { *start_block = Some(first_prebinding_block); } @@ -988,8 +967,8 @@ fn select_matched_candidates( } } - let last_candidate = reachable_candidates.last().unwrap(); + let last_candidate = reachable_candidates.last().unwrap(); if let Some(otherwise) = last_candidate.otherwise_block { let source_info = self.source_info(last_candidate.span); let block = self.cfg.start_new_block(); diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index ec8b3c5e24b..87481d1d69b 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -109,15 +109,7 @@ pub fn false_edges( }, ); } - _ => { - self.cfg.terminate( - from_block, - source_info, - TerminatorKind::Goto { - target: real_target - } - ); - } + _ => self.cfg.goto(from_block, source_info, real_target), } } } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 3479ad6749a..1ecae105694 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -606,14 +606,11 @@ fn construct_fn<'a, 'tcx, A>( let fn_end = span.shrink_to_hi(); let source_info = builder.source_info(fn_end); let return_block = builder.return_block(); - builder.cfg.terminate(block, source_info, - TerminatorKind::Goto { target: return_block }); - builder.cfg.terminate(return_block, source_info, - TerminatorKind::Return); + builder.cfg.goto(block, source_info, return_block); + builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); // Attribute any unreachable codepaths to the function's closing brace if let Some(unreachable_block) = builder.cached_unreachable_block { - builder.cfg.terminate(unreachable_block, source_info, - TerminatorKind::Unreachable); + builder.cfg.terminate(unreachable_block, source_info, TerminatorKind::Unreachable); } return_block.unit() })); diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 00a30af806a..9c5966263df 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -564,14 +564,12 @@ pub fn exit_scope(&mut self, let source_info = scope.source_info(span); block = match scope.cached_exits.entry((target, region_scope)) { Entry::Occupied(e) => { - self.cfg.terminate(block, source_info, - TerminatorKind::Goto { target: *e.get() }); + self.cfg.goto(block, source_info, *e.get()); return; } Entry::Vacant(v) => { let b = self.cfg.start_new_block(); - self.cfg.terminate(block, source_info, - TerminatorKind::Goto { target: b }); + self.cfg.goto(block, source_info, b); v.insert(b); b } @@ -596,8 +594,7 @@ pub fn exit_scope(&mut self, scope = next_scope; } - let source_info = self.scopes.source_info(scope_count, span); - self.cfg.terminate(block, source_info, TerminatorKind::Goto { target }); + self.cfg.goto(block, self.scopes.source_info(scope_count, span), target); } /// Creates a path that performs all required cleanup for dropping a generator. @@ -616,14 +613,12 @@ pub fn generator_drop_cleanup(&mut self) -> Option { while let Some(scope) = scopes.next() { block = if let Some(b) = scope.cached_generator_drop { - self.cfg.terminate(block, src_info, - TerminatorKind::Goto { target: b }); + self.cfg.goto(block, src_info, b); return Some(result); } else { let b = self.cfg.start_new_block(); scope.cached_generator_drop = Some(b); - self.cfg.terminate(block, src_info, - TerminatorKind::Goto { target: b }); + self.cfg.goto(block, src_info, b); b }; @@ -1243,8 +1238,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, // block for our StorageDead statements. let block = cfg.start_new_cleanup_block(); let source_info = SourceInfo { span: DUMMY_SP, scope: source_scope }; - cfg.terminate(block, source_info, - TerminatorKind::Goto { target: target }); + cfg.goto(block, source_info, target); target = block; target_built_by_us = true; } From c010d843aacc32ed2bc03d36121aa7f6e08ef045 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 30 Nov 2019 08:42:56 +1300 Subject: [PATCH 08/13] Add simpler entry points to const eval for common usages. --- src/librustc/mir/interpret/mod.rs | 4 +- src/librustc/mir/interpret/queries.rs | 89 ++++++++++++++++++++++ src/librustc/query/mod.rs | 11 ++- src/librustc/traits/fulfill.rs | 29 ++----- src/librustc/traits/select.rs | 22 ++---- src/librustc/ty/mod.rs | 10 +-- src/librustc/ty/sty.rs | 12 +-- src/librustc_codegen_llvm/consts.rs | 10 +-- src/librustc_codegen_llvm/intrinsic.rs | 9 +-- src/librustc_codegen_ssa/mir/block.rs | 7 +- src/librustc_codegen_ssa/mir/constant.rs | 19 ++--- src/librustc_codegen_ssa/mir/place.rs | 7 +- src/librustc_lint/builtin.rs | 12 +-- src/librustc_mir/const_eval.rs | 4 +- src/librustc_mir/hair/cx/expr.rs | 18 ++--- src/librustc_mir/hair/pattern/mod.rs | 81 +++++++++----------- src/librustc_mir/interpret/intrinsics.rs | 10 +-- src/librustc_mir/interpret/place.rs | 7 +- src/librustc_mir/lib.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 38 ++------- src/librustc_typeck/check/expr.rs | 17 +---- src/librustc_typeck/check/mod.rs | 10 +-- src/librustdoc/clean/mod.rs | 20 +---- 23 files changed, 195 insertions(+), 253 deletions(-) create mode 100644 src/librustc/mir/interpret/queries.rs diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index fff876752db..80bac92d003 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -101,6 +101,7 @@ macro_rules! throw_machine_stop { mod value; mod allocation; mod pointer; +mod queries; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, @@ -116,9 +117,10 @@ macro_rules! throw_machine_stop { use crate::mir; use crate::hir::def_id::DefId; -use crate::ty::{self, TyCtxt, Instance, subst::GenericArgKind}; +use crate::ty::{self, TyCtxt, Instance}; use crate::ty::codec::TyDecoder; use crate::ty::layout::{self, Size}; +use crate::ty::subst::GenericArgKind; use std::io; use std::fmt; use std::num::NonZeroU32; diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs new file mode 100644 index 00000000000..5fd49a056d2 --- /dev/null +++ b/src/librustc/mir/interpret/queries.rs @@ -0,0 +1,89 @@ +use super::{ConstEvalResult, ErrorHandled, GlobalId}; + +use crate::mir; +use crate::hir::def_id::DefId; +use crate::ty::{self, TyCtxt}; +use crate::ty::subst::{InternalSubsts, SubstsRef}; +use syntax_pos::Span; + + +impl<'tcx> TyCtxt<'tcx> { + + /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts + /// that can't take any generic arguments like statics, const items or enum discriminants. If a + /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. + pub fn const_eval_poly(self, def_id: DefId) -> ConstEvalResult<'tcx> { + // In some situations def_id will have substitutions within scope, but they aren't allowed + // to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions + // into `const_eval` which will return `ErrorHandled::ToGeneric` if any og them are + // encountered. + let substs = InternalSubsts::identity_for_item(self, def_id); + let instance = ty::Instance::new(def_id, substs); + let cid = GlobalId { + instance, + promoted: None, + }; + let param_env = self.param_env(def_id); + self.const_eval_validated(param_env.and(cid)) + } + + /// Resolves and evaluates a constant. + /// + /// The constant can be located on a trait like `::C`, in which case the given + /// substitutions and environment are used to resolve the constant. Alternatively if the + /// constant has generic parameters in scope the substitutions are used to evaluate the value of + /// the constant. For example in `fn foo() { let _ = [0; bar::()]; }` the repeat count + /// constant `bar::()` requires a substitution for `T`, if the substitution for `T` is still + /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is + /// returned. + pub fn const_eval_resolve( + self, + param_env: ty::ParamEnv<'tcx>, + def_id: DefId, + substs: SubstsRef<'tcx>, + span: Option + ) -> ConstEvalResult<'tcx> { + let instance = ty::Instance::resolve( + self, + param_env, + def_id, + substs, + ); + if let Some(instance) = instance { + self.const_eval_instance(param_env, instance, span) + } else { + Err(ErrorHandled::TooGeneric) + } + } + + pub fn const_eval_instance( + self, + param_env: ty::ParamEnv<'tcx>, + instance: ty::Instance<'tcx>, + span: Option + ) -> ConstEvalResult<'tcx> { + let cid = GlobalId { + instance, + promoted: None, + }; + if let Some(span) = span { + self.at(span).const_eval_validated(param_env.and(cid)) + } else { + self.const_eval_validated(param_env.and(cid)) + } + } + + /// Evaluate a promoted constant. + pub fn const_eval_promoted( + self, + instance: ty::Instance<'tcx>, + promoted: mir::Promoted + ) -> ConstEvalResult<'tcx> { + let cid = GlobalId { + instance, + promoted: Some(promoted), + }; + let param_env = ty::ParamEnv::reveal_all(); + self.const_eval_validated(param_env.and(cid)) + } +} diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index cc02165f605..a9dd856e758 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -448,7 +448,8 @@ /// /// **Do not use this** outside const eval. Const eval uses this to break query cycles /// during validation. Please add a comment to every use site explaining why using - /// `const_eval` isn't sufficient. + /// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable + /// form to be used outside of const eval. query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalRawResult<'tcx> { no_force @@ -460,7 +461,13 @@ /// Results of evaluating const items or constants embedded in /// other items (such as enum variant explicit discriminants). - query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) + /// + /// In contrast to `const_eval_raw` this performs some validation on the constant, and + /// returns a proper constant that is usable by the rest of the compiler. + /// + /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, + /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_promoted`. + query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> ConstEvalResult<'tcx> { no_force desc { |tcx| diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 27731990d2b..3fd2415c83c 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -1,5 +1,4 @@ use crate::infer::{InferCtxt, ShallowResolver}; -use crate::mir::interpret::{GlobalId, ErrorHandled}; use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; use crate::ty::error::ExpectedFound; use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation}; @@ -501,27 +500,13 @@ fn infer_ty(ty: Ty<'tcx>) -> ty::InferTy { ProcessResult::Unchanged } else { if !substs.has_local_value() { - let instance = ty::Instance::resolve( - self.selcx.tcx(), - obligation.param_env, - def_id, - substs, - ); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - match self.selcx.tcx().at(obligation.cause.span) - .const_eval(obligation.param_env.and(cid)) { - Ok(_) => ProcessResult::Changed(vec![]), - Err(err) => ProcessResult::Error( - CodeSelectionError(ConstEvalFailure(err))) - } - } else { - ProcessResult::Error(CodeSelectionError( - ConstEvalFailure(ErrorHandled::TooGeneric) - )) + match self.selcx.tcx().const_eval_resolve(obligation.param_env, + def_id, + substs, + Some(obligation.cause.span)) { + Ok(_) => ProcessResult::Changed(vec![]), + Err(err) => ProcessResult::Error( + CodeSelectionError(ConstEvalFailure(err))) } } else { pending_obligation.stalled_on = diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 94a77c553e5..8d04c832f26 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -33,7 +33,6 @@ use crate::hir::def_id::DefId; use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener}; use crate::middle::lang_items; -use crate::mir::interpret::GlobalId; use crate::ty::fast_reject; use crate::ty::relate::TypeRelation; use crate::ty::subst::{Subst, SubstsRef}; @@ -820,22 +819,13 @@ fn evaluate_predicate_recursively<'o>( } ty::Predicate::ConstEvaluatable(def_id, substs) => { - let tcx = self.tcx(); if !(obligation.param_env, substs).has_local_value() { - let param_env = obligation.param_env; - let instance = - ty::Instance::resolve(tcx, param_env, def_id, substs); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - match self.tcx().const_eval(param_env.and(cid)) { - Ok(_) => Ok(EvaluatedToOk), - Err(_) => Ok(EvaluatedToErr), - } - } else { - Ok(EvaluatedToErr) + match self.tcx().const_eval_resolve(obligation.param_env, + def_id, + substs, + None) { + Ok(_) => Ok(EvaluatedToOk), + Err(_) => Ok(EvaluatedToErr), } } else { // Inference variables still left in param_env or substs. diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 15bbfa7860f..c60d4a46935 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,7 +19,7 @@ use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::mir::ReadOnlyBodyAndCache; -use crate::mir::interpret::{GlobalId, ErrorHandled}; +use crate::mir::interpret::ErrorHandled; use crate::mir::GeneratorLayout; use crate::session::CrateDisambiguator; use crate::traits::{self, Reveal}; @@ -2344,13 +2344,7 @@ pub fn variant_of_res(&self, res: Res) -> &VariantDef { pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option> { let param_env = tcx.param_env(expr_did); let repr_type = self.repr.discr_type(); - let substs = InternalSubsts::identity_for_item(tcx, expr_did); - let instance = ty::Instance::new(expr_did, substs); - let cid = GlobalId { - instance, - promoted: None - }; - match tcx.const_eval(param_env.and(cid)) { + match tcx.const_eval_poly(expr_did) { Ok(val) => { // FIXME: Find the right type and use it instead of `val.ty` here if let Some(b) = val.try_eval_bits(tcx, param_env, val.ty) { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 6cb0d1e9946..1e08c36ca50 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -15,7 +15,7 @@ use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; use crate::ty::layout::VariantIdx; use crate::util::captures::Captures; -use crate::mir::interpret::{Scalar, GlobalId}; +use crate::mir::interpret::Scalar; use polonius_engine::Atom; use rustc_index::vec::Idx; @@ -2340,13 +2340,9 @@ pub fn eval( let (param_env, substs) = param_env_and_substs.into_parts(); - // try to resolve e.g. associated constants to their definition on an impl - let instance = ty::Instance::resolve(tcx, param_env, did, substs)?; - let gid = GlobalId { - instance, - promoted: None, - }; - tcx.const_eval(param_env.and(gid)).ok() + // try to resolve e.g. associated constants to their definition on an impl, and then + // evaluate the const. + tcx.const_eval_resolve(param_env, did, substs, None).ok() }; match self.val { diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 11a105c1828..c048321e383 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -8,7 +8,7 @@ use libc::c_uint; use rustc::hir::def_id::DefId; use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint, - Pointer, ErrorHandled, GlobalId}; + Pointer, ErrorHandled}; use rustc::mir::mono::MonoItem; use rustc::hir::Node; use rustc_target::abi::HasDataLayout; @@ -81,13 +81,7 @@ pub fn codegen_static_initializer( cx: &CodegenCx<'ll, 'tcx>, def_id: DefId, ) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> { - let instance = ty::Instance::mono(cx.tcx, def_id); - let cid = GlobalId { - instance, - promoted: None, - }; - let param_env = ty::ParamEnv::reveal_all(); - let static_ = cx.tcx.const_eval(param_env.and(cid))?; + let static_ = cx.tcx.const_eval_poly(def_id)?; let alloc = match static_.val { ty::ConstKind::Value(ConstValue::ByRef { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 900f2d2defc..da776757fdf 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -14,7 +14,6 @@ use rustc_codegen_ssa::base::{to_immediate, wants_msvc_seh, compare_simd_types}; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, FnAbiExt, LayoutOf, HasTyCtxt, Primitive}; -use rustc::mir::interpret::GlobalId; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc::hir; use rustc_target::abi::HasDataLayout; @@ -202,11 +201,9 @@ fn codegen_intrinsic_call( "needs_drop" | "type_id" | "type_name" => { - let gid = GlobalId { - instance, - promoted: None, - }; - let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap(); + let ty_name = self.tcx + .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) + .unwrap(); OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self) } "init" => { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index dabd097b000..a532c23a6e0 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -638,12 +638,7 @@ fn codegen_call_terminator( projection: &[], } = place.as_ref() { - let param_env = ty::ParamEnv::reveal_all(); - let cid = mir::interpret::GlobalId { - instance: self.instance, - promoted: Some(promoted), - }; - let c = bx.tcx().const_eval(param_env.and(cid)); + let c = bx.tcx().const_eval_promoted(self.instance, promoted); let (llval, ty) = self.simd_shuffle_indices( &bx, terminator.source_info.span, diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index fb8f504d04b..fc17e2c0c71 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -43,17 +43,14 @@ pub fn eval_mir_constant( match constant.literal.val { ty::ConstKind::Unevaluated(def_id, substs) => { let substs = self.monomorphize(&substs); - let instance = ty::Instance::resolve( - self.cx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs, - ).unwrap(); - let cid = mir::interpret::GlobalId { - instance, - promoted: None, - }; - self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)).map_err(|err| { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); - err - }) + self.cx.tcx() + .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, None) + .map_err(|err| { + self.cx.tcx().sess.span_err( + constant.span, + "erroneous constant encountered"); + err + }) }, _ => Ok(self.monomorphize(&constant.literal)), } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 5e13cabced0..1132f9b2f03 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -473,14 +473,9 @@ pub fn codegen_place( }), projection: [], } => { - let param_env = ty::ParamEnv::reveal_all(); let instance = Instance::new(*def_id, self.monomorphize(substs)); - let cid = mir::interpret::GlobalId { - instance: instance, - promoted: Some(*promoted), - }; let layout = cx.layout_of(self.monomorphize(&ty)); - match bx.tcx().const_eval(param_env.and(cid)) { + match bx.tcx().const_eval_promoted(instance, *promoted) { Ok(val) => match val.val { ty::ConstKind::Value(mir::interpret::ConstValue::ByRef { alloc, offset diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 10b00d35d9b..b46e8a8438f 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1134,19 +1134,9 @@ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) { fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) { let def_id = cx.tcx.hir().body_owner_def_id(body_id); - let param_env = if cx.tcx.is_static(def_id) { - // Use the same param_env as `codegen_static_initializer`, to reuse the cache. - ty::ParamEnv::reveal_all() - } else { - cx.tcx.param_env(def_id) - }; - let cid = ::rustc::mir::interpret::GlobalId { - instance: ty::Instance::mono(cx.tcx, def_id), - promoted: None - }; // trigger the query once for all constants since that will already report the errors // FIXME: Use ensure here - let _ = cx.tcx.const_eval(param_env.and(cid)); + let _ = cx.tcx.const_eval_poly(def_id); } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst { diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index b219fec31dc..a2f066bee08 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -652,7 +652,7 @@ fn validate_and_turn_into_const<'tcx>( }) } -pub fn const_eval_provider<'tcx>( +pub fn const_eval_validated_provider<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { @@ -660,7 +660,7 @@ pub fn const_eval_provider<'tcx>( if key.param_env.reveal == Reveal::All { let mut key = key.clone(); key.param_env.reveal = Reveal::UserFacing; - match tcx.const_eval(key) { + match tcx.const_eval_validated(key) { // try again with reveal all as requested Err(ErrorHandled::TooGeneric) => { // Promoteds should never be "too generic" when getting evaluated. diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 8c852854be1..f116f7d14da 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -5,7 +5,7 @@ use crate::hair::util::UserAnnotatedTyHelpers; use rustc_index::vec::Idx; use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; -use rustc::mir::interpret::{GlobalId, ErrorHandled, Scalar}; +use rustc::mir::interpret::{ErrorHandled, Scalar}; use rustc::ty::{self, AdtKind, Ty}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast}; use rustc::ty::subst::{InternalSubsts, SubstsRef}; @@ -514,21 +514,15 @@ fn make_mirror_unadjusted<'a, 'tcx>( hir::ExprKind::Repeat(ref v, ref count) => { let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::resolve( - cx.tcx, - cx.param_env, - def_id, - substs, - ).unwrap(); - let global_id = GlobalId { - instance, - promoted: None - }; let span = cx.tcx.def_span(def_id); - let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) { + let count = match cx.tcx.const_eval_resolve(cx.param_env, + def_id, + substs, + Some(span)) { Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), Err(ErrorHandled::Reported) => 0, Err(ErrorHandled::TooGeneric) => { + let span = cx.tcx.def_span(def_id); cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); 0 }, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 0086c3b0e10..e12f0322564 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -11,7 +11,7 @@ use rustc::mir::{Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; -use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend}; +use rustc::mir::interpret::{ConstValue, ErrorHandled, get_slice_bytes, sign_extend}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{SubstsRef, GenericArg}; @@ -854,57 +854,37 @@ fn lower_path(&mut self, let kind = match res { Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => { let substs = self.tables.node_substs(id); - match ty::Instance::resolve( - self.tcx, - self.param_env, - def_id, - substs, - ) { - Some(instance) => { - let cid = GlobalId { - instance, - promoted: None, - }; - match self.tcx.at(span).const_eval(self.param_env.and(cid)) { - Ok(value) => { - let pattern = self.const_to_pat(value, id, span); - if !is_associated_const { - return pattern; - } + match self.tcx.const_eval_resolve(self.param_env, def_id, substs, Some(span)) { + Ok(value) => { + let pattern = self.const_to_pat(value, id, span); + if !is_associated_const { + return pattern; + } - let user_provided_types = self.tables().user_provided_types(); - return if let Some(u_ty) = user_provided_types.get(id) { - let user_ty = PatTyProj::from_user_type(*u_ty); - Pat { - span, - kind: Box::new( - PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - /// Note that use `Contravariant` here. See the - /// `variance` field documentation for details. - variance: ty::Variance::Contravariant, - user_ty, - user_ty_span: span, - }, - } - ), - ty: value.ty, + let user_provided_types = self.tables().user_provided_types(); + return if let Some(u_ty) = user_provided_types.get(id) { + let user_ty = PatTyProj::from_user_type(*u_ty); + Pat { + span, + kind: Box::new( + PatKind::AscribeUserType { + subpattern: pattern, + ascription: Ascription { + /// Note that use `Contravariant` here. See the + /// `variance` field documentation for details. + variance: ty::Variance::Contravariant, + user_ty, + user_ty_span: span, + }, } - } else { - pattern - } - }, - Err(_) => { - self.tcx.sess.span_err( - span, - "could not evaluate constant pattern", - ); - PatKind::Wild + ), + ty: value.ty, } + } else { + pattern } }, - None => { + Err(ErrorHandled::TooGeneric) => { self.errors.push(if is_associated_const { PatternError::AssocConstInPattern(span) } else { @@ -912,6 +892,13 @@ fn lower_path(&mut self, }); PatKind::Wild }, + Err(_) => { + self.tcx.sess.span_err( + span, + "could not evaluate constant pattern", + ); + PatKind::Wild + } } } _ => self.lower_variant_or_leaf(res, id, span, ty, vec![]), diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 67f0aed243d..46782ef0a80 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -11,7 +11,7 @@ use rustc::ty::TyCtxt; use rustc::mir::{ self, BinOp, - interpret::{InterpResult, Scalar, GlobalId, ConstValue} + interpret::{InterpResult, Scalar, ConstValue} }; use super::{ @@ -123,11 +123,9 @@ pub fn emulate_intrinsic( sym::size_of | sym::type_id | sym::type_name => { - let gid = GlobalId { - instance, - promoted: None, - }; - let val = self.tcx.const_eval(self.param_env.and(gid))?; + let val = self.tcx.const_eval_instance(self.param_env, + instance, + Some(self.tcx.span))?; let val = self.eval_const_to_op(val, None)?; self.copy_op(val, dest)?; } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 42fbfeca3f0..70ea3745b4d 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -619,11 +619,6 @@ pub(super) fn eval_static_to_mplace( let ty = place_static.ty; assert!(!ty.needs_subst()); let layout = self.layout_of(ty)?; - let instance = ty::Instance::mono(*self.tcx, place_static.def_id); - let cid = GlobalId { - instance, - promoted: None - }; // Just create a lazy reference, so we can support recursive statics. // tcx takes care of assigning every static one and only one unique AllocId. // When the data here is ever actually used, memory will notice, @@ -639,7 +634,7 @@ pub(super) fn eval_static_to_mplace( // Notice that statics have *two* AllocIds: the lazy one, and the resolved // one. Here we make sure that the interpreted program never sees the // resolved ID. Also see the doc comment of `Memory::get_static_alloc`. - let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(cid.instance.def_id()); + let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(place_static.def_id); let ptr = self.tag_static_base_pointer(Pointer::from(alloc_id)); MPlaceTy::from_aligned_ptr(ptr, layout) } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index f6b3c5b8e5e..cf54530317c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -56,7 +56,7 @@ pub fn provide(providers: &mut Providers<'_>) { shim::provide(providers); transform::provide(providers); monomorphize::partitioning::provide(providers); - providers.const_eval = const_eval::const_eval_provider; + providers.const_eval_validated = const_eval::const_eval_validated_provider; providers.const_eval_raw = const_eval::const_eval_raw_provider; providers.check_match = hair::pattern::check_match; providers.const_caller_location = const_eval::const_caller_location; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 93a76712b28..ab95c795c43 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -189,7 +189,7 @@ use rustc::mir::{self, Location, PlaceBase, Static, StaticKind}; use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::{MonoItem, InstantiationMode}; -use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; +use rustc::mir::interpret::{Scalar, GlobalAlloc, ErrorHandled}; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; @@ -379,13 +379,7 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; - let cid = GlobalId { - instance, - promoted: None, - }; - let param_env = ty::ParamEnv::reveal_all(); - - if let Ok(val) = tcx.const_eval(param_env.and(cid)) { + if let Ok(val) = tcx.const_eval_poly(def_id) { collect_const(tcx, val, InternalSubsts::empty(), &mut neighbors); } } @@ -681,12 +675,8 @@ fn visit_place_base(&mut self, def_id, .. }) => { - let param_env = ty::ParamEnv::reveal_all(); - let cid = GlobalId { - instance: Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)), - promoted: Some(*promoted), - }; - match self.tcx.const_eval(param_env.and(cid)) { + let instance = Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)); + match self.tcx.const_eval_promoted(instance, *promoted) { Ok(val) => collect_const(self.tcx, val, substs, self.output), Err(ErrorHandled::Reported) => {}, Err(ErrorHandled::TooGeneric) => { @@ -1041,14 +1031,7 @@ fn visit_item(&mut self, item: &'v hir::Item) { // but even just declaring them must collect the items they refer to let def_id = self.tcx.hir().local_def_id(item.hir_id); - let instance = Instance::mono(self.tcx, def_id); - let cid = GlobalId { - instance, - promoted: None, - }; - let param_env = ty::ParamEnv::reveal_all(); - - if let Ok(val) = self.tcx.const_eval(param_env.and(cid)) { + if let Ok(val) = self.tcx.const_eval_poly(def_id) { collect_const(self.tcx, val, InternalSubsts::empty(), &mut self.output); } } @@ -1288,16 +1271,7 @@ fn collect_const<'tcx>( } } ty::ConstKind::Unevaluated(def_id, substs) => { - let instance = ty::Instance::resolve(tcx, - param_env, - def_id, - substs).unwrap(); - - let cid = GlobalId { - instance, - promoted: None, - }; - match tcx.const_eval(param_env.and(cid)) { + match tcx.const_eval_resolve(param_env, def_id, substs, None) { Ok(val) => collect_const(tcx, val, param_substs, output), Err(ErrorHandled::Reported) => {}, Err(ErrorHandled::TooGeneric) => span_bug!( diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 19441be87b9..b287b39cb99 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -31,7 +31,6 @@ use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::middle::lang_items; -use rustc::mir::interpret::GlobalId; use rustc::ty; use rustc::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, @@ -39,7 +38,6 @@ use rustc::ty::{AdtKind, Visibility}; use rustc::ty::Ty; use rustc::ty::TypeFoldable; -use rustc::ty::subst::InternalSubsts; use rustc::traits::{self, ObligationCauseCode}; use rustc_error_codes::*; @@ -1023,20 +1021,7 @@ fn check_expr_repeat( let count = if self.const_param_def_id(count).is_some() { Ok(self.to_const(count, tcx.type_of(count_def_id))) } else { - let param_env = ty::ParamEnv::empty(); - let substs = InternalSubsts::identity_for_item(tcx, count_def_id); - let instance = ty::Instance::resolve( - tcx, - param_env, - count_def_id, - substs, - ).unwrap(); - let global_id = GlobalId { - instance, - promoted: None - }; - - tcx.const_eval(param_env.and(global_id)) + tcx.const_eval_poly(count_def_id) }; let uty = match expected { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 09771bb7625..84f5847ddd3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -106,7 +106,7 @@ use rustc::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc::middle::region; -use rustc::mir::interpret::{ConstValue, GlobalId}; +use rustc::mir::interpret::ConstValue; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{ self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, @@ -1836,13 +1836,7 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span) // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is // the consumer's responsibility to ensure all bytes that have been read // have defined values. - let instance = ty::Instance::mono(tcx, id); - let cid = GlobalId { - instance, - promoted: None - }; - let param_env = ty::ParamEnv::reveal_all(); - if let Ok(static_) = tcx.const_eval(param_env.and(cid)) { + if let Ok(static_) = tcx.const_eval_poly(id) { let alloc = if let ty::ConstKind::Value(ConstValue::ByRef { alloc, .. }) = static_.val { alloc } else { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e5f684cbca8..7eb1370c342 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -15,7 +15,6 @@ use rustc::middle::resolve_lifetime as rl; use rustc::middle::lang_items; use rustc::middle::stability; -use rustc::mir::interpret::GlobalId; use rustc::hir; use rustc::hir::def::{CtorKind, DefKind, Res}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; @@ -1334,13 +1333,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type { TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), TyKind::Array(ref ty, ref length) => { let def_id = cx.tcx.hir().local_def_id(length.hir_id); - let param_env = cx.tcx.param_env(def_id); - let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); - let cid = GlobalId { - instance: ty::Instance::new(def_id, substs), - promoted: None - }; - let length = match cx.tcx.const_eval(param_env.and(cid)) { + let length = match cx.tcx.const_eval_poly(def_id) { Ok(length) => print_const(cx, length), Err(_) => cx.sess() .source_map() @@ -1534,16 +1527,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Type { ty::Slice(ty) => Slice(box ty.clean(cx)), ty::Array(ty, n) => { let mut n = cx.tcx.lift(&n).expect("array lift failed"); - if let ty::ConstKind::Unevaluated(def_id, substs) = n.val { - let param_env = cx.tcx.param_env(def_id); - let cid = GlobalId { - instance: ty::Instance::new(def_id, substs), - promoted: None - }; - if let Ok(new_n) = cx.tcx.const_eval(param_env.and(cid)) { - n = new_n; - } - }; + n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); let n = print_const(cx, n); Array(box ty.clean(cx), n) } From c770f5114c2227109d658f41b737ffd4181c7de1 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sat, 21 Dec 2019 22:11:02 -0700 Subject: [PATCH 09/13] Fix typo in path parser name --- src/librustc_parse/parser/path.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_parse/parser/path.rs b/src/librustc_parse/parser/path.rs index 802d38e2997..a768fdc779e 100644 --- a/src/librustc_parse/parser/path.rs +++ b/src/librustc_parse/parser/path.rs @@ -173,7 +173,7 @@ pub(super) fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, Pat let args = if self.eat_lt() { // `<'a, T, A = U>` let (args, constraints) = - self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?; + self.parse_generic_args_with_leading_angle_bracket_recovery(style, lo)?; self.expect_gt()?; let span = lo.to(self.prev_span); AngleBracketedArgs { args, constraints, span }.into() @@ -212,7 +212,7 @@ pub(super) fn parse_path_segment_ident(&mut self) -> PResult<'a, Ident> { /// bar::<<<::Output>(); /// ^^ help: remove extra angle brackets /// ``` - fn parse_generic_args_with_leaning_angle_bracket_recovery( + fn parse_generic_args_with_leading_angle_bracket_recovery( &mut self, style: PathStyle, lo: Span, From 0d7a49d3563246f193e11ae63e713c0a65319f8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Dec 2019 15:47:27 +0100 Subject: [PATCH 10/13] Implement PrintWithSpace trait on hir::Mutability --- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/html/format.rs | 22 +++++++++++----------- src/librustdoc/html/render.rs | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 0f43555fd74..b7e01708fbf 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -472,7 +472,7 @@ fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant { fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { type_: cx.tcx.type_of(did).clean(cx), - mutability: if mutable { Mutability::Mutable } else { Mutability::Immutable }, + mutability: if mutable { Mutability::Mut } else { Mutability::Not }, expr: "\n\n\n".to_string(), // trigger the "[definition]" links } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index fd620d467de..501147ed459 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -670,8 +670,8 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> clean::Never => primitive_link(f, PrimitiveType::Never, "!"), clean::RawPointer(m, ref t) => { let m = match m { - clean::Immutable => "const", - clean::Mutable => "mut", + hir::Mutability::Mut => "mut", + hir::Mutability::Not => "const", }; match **t { clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => { @@ -1082,6 +1082,15 @@ fn print_with_space(&self) -> &str { } } +impl PrintWithSpace for hir::Mutability { + fn print_with_space(&self) -> &str { + match self { + hir::Mutability::Not => "", + hir::Mutability::Mut => "mut ", + } + } +} + impl clean::Import { crate fn print(&self) -> impl fmt::Display + '_ { display_fn(move |f| { @@ -1151,15 +1160,6 @@ impl clean::TypeBinding { } } -impl clean::Mutability { - crate fn print_with_space(&self) -> &str { - match self { - clean::Immutable => "", - clean::Mutable => "mut ", - } - } -} - crate fn print_abi_with_space(abi: Abi) -> impl fmt::Display { display_fn(move |f| { let quot = if f.alternate() { "\"" } else { """ }; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e822ada0fb9..100aed1af19 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3298,7 +3298,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { let (by_mut_ref, by_box, by_value) = match self_ty { SelfTy::SelfBorrowed(_, mutability) | SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => { - (mutability == Mutability::Mutable, false, false) + (mutability == Mutability::Mut, false, false) }, SelfTy::SelfExplicit(clean::ResolvedPath { did, .. }) => { (false, Some(did) == cache().owned_box_did, false) From 687891309659fd2942f4c8bc8f9fd2feaf85d864 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 22 Dec 2019 07:54:18 -0500 Subject: [PATCH 11/13] Document why Any is not an unsafe trait --- src/libcore/any.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index a2aa6b3fea5..5126fe01a3f 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -74,6 +74,16 @@ /// See the [module-level documentation][mod] for more details. /// /// [mod]: index.html +// This trait is not unsafe, though we rely on the specifics of it's sole impl's +// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be +// a problem, but because the only impl of `Any` is a blanket implementation, no +// other code can implement `Any`. +// +// We could plausibly make this trait unsafe -- it would not cause breakage, +// since we control all the implementations -- but we choose not to as that's +// both not really necessary and may confuse users about the distinction of +// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call, +// but we would likely want to indicate as such in documentation). #[stable(feature = "rust1", since = "1.0.0")] pub trait Any: 'static { /// Gets the `TypeId` of `self`. From 683c4c788f36d67fbc873629b431105c7758dd68 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Sun, 22 Dec 2019 08:22:14 -0500 Subject: [PATCH 12/13] Add error message if `Scalar::from_(u)int` fails --- src/librustc/mir/interpret/value.rs | 10 ++++++++-- src/librustc_mir/interpret/operand.rs | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 8f5fab4b002..f48d22291c6 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -248,7 +248,10 @@ pub fn try_from_uint(i: impl Into, size: Size) -> Option { #[inline] pub fn from_uint(i: impl Into, size: Size) -> Self { - Self::try_from_uint(i, size).unwrap() + let i = i.into(); + Self::try_from_uint(i, size).unwrap_or_else(|| { + bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) + }) } #[inline] @@ -285,7 +288,10 @@ pub fn try_from_int(i: impl Into, size: Size) -> Option { #[inline] pub fn from_int(i: impl Into, size: Size) -> Self { - Self::try_from_int(i, size).unwrap() + let i = i.into(); + Self::try_from_int(i, size).unwrap_or_else(|| { + bug!("Signed value {:#x} does not fit in {} bits", i, size.bits()) + }) } #[inline] diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 8dd50958350..294b361ee27 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -224,7 +224,7 @@ pub fn try_from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Option } #[inline] pub fn from_uint(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::try_from_uint(i, layout).unwrap() + Self::from_scalar(Scalar::from_uint(i, layout.size), layout) } #[inline] @@ -234,7 +234,7 @@ pub fn try_from_int(i: impl Into, layout: TyLayout<'tcx>) -> Option #[inline] pub fn from_int(i: impl Into, layout: TyLayout<'tcx>) -> Self { - Self::try_from_int(i, layout).unwrap() + Self::from_scalar(Scalar::from_int(i, layout.size), layout) } #[inline] From a6df38ec9f3c1c1126ba750e50a0a40741913ebb Mon Sep 17 00:00:00 2001 From: Rust Toolstate Update <7378925+rust-toolstate-update@users.noreply.github.com> Date: Sun, 22 Dec 2019 09:21:08 -0500 Subject: [PATCH 13/13] Utilize rust-lang/rust commit hashes in toolstate When moving the script out of CI configuration and into a proper script we lost track of the current directory changing (and as such the parameters of the script needing to be different now). --- src/ci/publish_toolstate.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ci/publish_toolstate.sh b/src/ci/publish_toolstate.sh index d8ff7407822..4c047069571 100755 --- a/src/ci/publish_toolstate.sh +++ b/src/ci/publish_toolstate.sh @@ -14,12 +14,15 @@ printf 'https://%s:x-oauth-basic@github.com\n' "$TOOLSTATE_REPO_ACCESS_TOKEN" \ > "$HOME/.git-credentials" git clone --depth=1 $TOOLSTATE_REPO +GIT_COMMIT="$(git rev-parse HEAD)" +GIT_COMMIT_MSG="$(git log --format=%s -n1 HEAD)" + cd rust-toolstate FAILURE=1 for RETRY_COUNT in 1 2 3 4 5; do # The purpose is to publish the new "current" toolstate in the toolstate repo. - "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \ - "$(git log --format=%s -n1 HEAD)" \ + "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$GIT_COMMIT" \ + "$GIT_COMMIT_MSG" \ "$MESSAGE_FILE" \ "$TOOLSTATE_REPO_ACCESS_TOKEN" # `git commit` failing means nothing to commit.