diff options
| author | bors <bors@rust-lang.org> | 2022-12-16 13:20:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-16 13:20:14 +0000 |
| commit | e82a604a88fec3adc0645c5cc5328ea7eba5faa4 (patch) | |
| tree | aafe13e8c6822c8d03d987868bc131ded4421746 /compiler/rustc_mir_transform/src | |
| parent | 789313267d2f814ec0bf1861d6e22e678668e998 (diff) | |
| parent | 39bb865759dcf2cd6c5f3cf84fc1c11b2c71e7b0 (diff) | |
| download | rust-e82a604a88fec3adc0645c5cc5328ea7eba5faa4.tar.gz rust-e82a604a88fec3adc0645c5cc5328ea7eba5faa4.zip | |
Auto merge of #2731 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/check_unsafety.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/const_prop.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/dest_prop.rs | 171 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/generator.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/inline.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/normalize_array_len.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/remove_zsts.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/shim.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/simplify.rs | 1 |
10 files changed, 160 insertions, 104 deletions
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index e783d189137..9c22b5df73c 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::HirId; use rustc_hir::intravisit; @@ -134,6 +135,28 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { self.super_rvalue(rvalue, location); } + fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { + if let Operand::Constant(constant) = op { + let maybe_uneval = match constant.literal { + ConstantKind::Val(..) | ConstantKind::Ty(_) => None, + ConstantKind::Unevaluated(uv, _) => Some(uv), + }; + + if let Some(uv) = maybe_uneval { + if uv.promoted.is_none() { + let def_id = uv.def.def_id_for_type_of(); + if self.tcx.def_kind(def_id) == DefKind::InlineConst { + let local_def_id = def_id.expect_local(); + let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = + self.tcx.unsafety_check_result(local_def_id); + self.register_violations(violations, used_unsafe_blocks.iter().copied()); + } + } + } + } + self.super_operand(op, location); + } + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { // On types with `scalar_valid_range`, prevent // * `&mut x.field` @@ -410,6 +433,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> { intravisit::walk_block(self, block); } + fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { + if matches!(self.tcx.def_kind(c.def_id), DefKind::InlineConst) { + self.visit_body(self.tcx.hir().body(c.body)) + } + } + fn visit_fn( &mut self, fk: intravisit::FnKind<'tcx>, @@ -471,7 +500,7 @@ fn unsafety_check_result<'tcx>( // `mir_built` force this. let body = &tcx.mir_built(def).borrow(); - if body.should_skip() { + if body.is_custom_mir() { return tcx.arena.alloc(UnsafetyCheckResult { violations: Vec::new(), used_unsafe_blocks: FxHashSet::default(), @@ -484,7 +513,7 @@ fn unsafety_check_result<'tcx>( let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); checker.visit_body(&body); - let unused_unsafes = (!tcx.is_closure(def.did.to_def_id())) + let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id())) .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks)); tcx.arena.alloc(UnsafetyCheckResult { @@ -516,8 +545,8 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { debug!("check_unsafety({:?})", def_id); - // closures are handled by their parent fn. - if tcx.is_closure(def_id.to_def_id()) { + // closures and inline consts are handled by their parent fn. + if tcx.is_typeck_child(def_id.to_def_id()) { return; } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index b0514e03356..044b7ce65bd 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -6,6 +6,7 @@ use std::cell::Cell; use either::Right; use rustc_ast::Mutability; +use rustc_const_eval::const_eval::CheckAlignment; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; @@ -22,7 +23,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayo use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_span::{def_id::DefId, Span}; -use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; +use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; @@ -186,16 +187,27 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> type MemoryKind = !; #[inline(always)] - fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { // We do not check for alignment to avoid having to carry an `Align` // in `ConstValue::ByRef`. - false + CheckAlignment::No } #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + span_bug!( + ecx.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ) + } fn load_mir( _ecx: &InterpCx<'mir, 'tcx, Self>, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index e9027387413..c75fe2327de 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -2,6 +2,7 @@ //! //! Currently, this pass only propagates scalar values. +use rustc_const_eval::const_eval::CheckAlignment; use rustc_const_eval::interpret::{ConstValue, ImmTy, Immediate, InterpCx, Scalar}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::mir::visit::{MutVisitor, Visitor}; @@ -10,6 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace}; use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects}; use rustc_span::DUMMY_SP; +use rustc_target::abi::Align; use crate::MirPass; @@ -448,13 +450,21 @@ impl<'mir, 'tcx> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachi type MemoryKind = !; const PANIC_ON_ALLOC_FAIL: bool = true; - fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { + fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> CheckAlignment { unimplemented!() } fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { unimplemented!() } + fn alignment_check_failed( + _ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> interpret::InterpResult<'tcx, ()> { + unimplemented!() + } fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 97485c4f57b..3e45319431c 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -132,15 +132,12 @@ use std::collections::hash_map::{Entry, OccupiedEntry}; use crate::MirPass; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; +use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::{dump_mir, PassWhere}; use rustc_middle::mir::{ traversal, BasicBlock, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; -use rustc_middle::mir::{ - visit::{MutVisitor, PlaceContext, Visitor}, - ProjectionElem, -}; use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::impls::MaybeLiveLocals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -359,40 +356,45 @@ struct FilterInformation<'a, 'body, 'alloc, 'tcx> { // through these methods, and not directly. impl<'alloc> Candidates<'alloc> { /// Just `Vec::retain`, but the condition is inverted and we add debugging output - fn vec_remove_debug( + fn vec_filter_candidates( src: Local, v: &mut Vec<Local>, - mut f: impl FnMut(Local) -> bool, + mut f: impl FnMut(Local) -> CandidateFilter, at: Location, ) { v.retain(|dest| { let remove = f(*dest); - if remove { + if remove == CandidateFilter::Remove { trace!("eliminating {:?} => {:?} due to conflict at {:?}", src, dest, at); } - !remove + remove == CandidateFilter::Keep }); } - /// `vec_remove_debug` but for an `Entry` - fn entry_remove( + /// `vec_filter_candidates` but for an `Entry` + fn entry_filter_candidates( mut entry: OccupiedEntry<'_, Local, Vec<Local>>, p: Local, - f: impl FnMut(Local) -> bool, + f: impl FnMut(Local) -> CandidateFilter, at: Location, ) { let candidates = entry.get_mut(); - Self::vec_remove_debug(p, candidates, f, at); + Self::vec_filter_candidates(p, candidates, f, at); if candidates.len() == 0 { entry.remove(); } } - /// Removes all candidates `(p, q)` or `(q, p)` where `p` is the indicated local and `f(q)` is true. - fn remove_candidates_if(&mut self, p: Local, mut f: impl FnMut(Local) -> bool, at: Location) { + /// For all candidates `(p, q)` or `(q, p)` removes the candidate if `f(q)` says to do so + fn filter_candidates_by( + &mut self, + p: Local, + mut f: impl FnMut(Local) -> CandidateFilter, + at: Location, + ) { // Cover the cases where `p` appears as a `src` if let Entry::Occupied(entry) = self.c.entry(p) { - Self::entry_remove(entry, p, &mut f, at); + Self::entry_filter_candidates(entry, p, &mut f, at); } // And the cases where `p` appears as a `dest` let Some(srcs) = self.reverse.get_mut(&p) else { @@ -401,18 +403,31 @@ impl<'alloc> Candidates<'alloc> { // We use `retain` here to remove the elements from the reverse set if we've removed the // matching candidate in the forward set. srcs.retain(|src| { - if !f(*src) { + if f(*src) == CandidateFilter::Keep { return true; } let Entry::Occupied(entry) = self.c.entry(*src) else { return false; }; - Self::entry_remove(entry, *src, |dest| dest == p, at); + Self::entry_filter_candidates( + entry, + *src, + |dest| { + if dest == p { CandidateFilter::Remove } else { CandidateFilter::Keep } + }, + at, + ); false }); } } +#[derive(Copy, Clone, PartialEq, Eq)] +enum CandidateFilter { + Keep, + Remove, +} + impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> { /// Filters the set of candidates to remove those that conflict. /// @@ -460,7 +475,7 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> { for (i, statement) in data.statements.iter().enumerate().rev() { self.at = Location { block, statement_index: i }; self.live.seek_after_primary_effect(self.at); - self.get_statement_write_info(&statement.kind); + self.write_info.for_statement(&statement.kind, self.body); self.apply_conflicts(); } } @@ -469,80 +484,59 @@ impl<'a, 'body, 'alloc, 'tcx> FilterInformation<'a, 'body, 'alloc, 'tcx> { fn apply_conflicts(&mut self) { let writes = &self.write_info.writes; for p in writes { - self.candidates.remove_candidates_if( + let other_skip = self.write_info.skip_pair.and_then(|(a, b)| { + if a == *p { + Some(b) + } else if b == *p { + Some(a) + } else { + None + } + }); + self.candidates.filter_candidates_by( *p, - // It is possible that a local may be live for less than the - // duration of a statement This happens in the case of function - // calls or inline asm. Because of this, we also mark locals as - // conflicting when both of them are written to in the same - // statement. - |q| self.live.contains(q) || writes.contains(&q), + |q| { + if Some(q) == other_skip { + return CandidateFilter::Keep; + } + // It is possible that a local may be live for less than the + // duration of a statement This happens in the case of function + // calls or inline asm. Because of this, we also mark locals as + // conflicting when both of them are written to in the same + // statement. + if self.live.contains(q) || writes.contains(&q) { + CandidateFilter::Remove + } else { + CandidateFilter::Keep + } + }, self.at, ); } } - - /// Gets the write info for the `statement`. - fn get_statement_write_info(&mut self, statement: &StatementKind<'tcx>) { - self.write_info.writes.clear(); - match statement { - StatementKind::Assign(box (lhs, rhs)) => match rhs { - Rvalue::Use(op) => { - if !lhs.is_indirect() { - self.get_assign_use_write_info(*lhs, op); - return; - } - } - _ => (), - }, - _ => (), - } - - self.write_info.for_statement(statement); - } - - fn get_assign_use_write_info(&mut self, lhs: Place<'tcx>, rhs: &Operand<'tcx>) { - // We register the writes for the operand unconditionally - self.write_info.add_operand(rhs); - // However, we cannot do the same thing for the `lhs` as that would always block the - // optimization. Instead, we consider removing candidates manually. - let Some(rhs) = rhs.place() else { - self.write_info.add_place(lhs); - return; - }; - // Find out which candidate pair we should skip, if any - let Some((src, dest)) = places_to_candidate_pair(lhs, rhs, self.body) else { - self.write_info.add_place(lhs); - return; - }; - self.candidates.remove_candidates_if( - lhs.local, - |other| { - // Check if this is the candidate pair that should not be removed - if (lhs.local == src && other == dest) || (lhs.local == dest && other == src) { - return false; - } - // Otherwise, do the "standard" thing - self.live.contains(other) - }, - self.at, - ) - } } /// Describes where a statement/terminator writes to #[derive(Default, Debug)] struct WriteInfo { writes: Vec<Local>, + /// If this pair of locals is a candidate pair, completely skip processing it during this + /// statement. All other candidates are unaffected. + skip_pair: Option<(Local, Local)>, } impl WriteInfo { - fn for_statement<'tcx>(&mut self, statement: &StatementKind<'tcx>) { + fn for_statement<'tcx>(&mut self, statement: &StatementKind<'tcx>, body: &Body<'tcx>) { + self.reset(); match statement { StatementKind::Assign(box (lhs, rhs)) => { self.add_place(*lhs); match rhs { - Rvalue::Use(op) | Rvalue::Repeat(op, _) => { + Rvalue::Use(op) => { + self.add_operand(op); + self.consider_skipping_for_assign_use(*lhs, op, body); + } + Rvalue::Repeat(op, _) => { self.add_operand(op); } Rvalue::Cast(_, op, _) @@ -586,8 +580,22 @@ impl WriteInfo { } } + fn consider_skipping_for_assign_use<'tcx>( + &mut self, + lhs: Place<'tcx>, + rhs: &Operand<'tcx>, + body: &Body<'tcx>, + ) { + let Some(rhs) = rhs.place() else { + return + }; + if let Some(pair) = places_to_candidate_pair(lhs, rhs, body) { + self.skip_pair = Some(pair); + } + } + fn for_terminator<'tcx>(&mut self, terminator: &TerminatorKind<'tcx>) { - self.writes.clear(); + self.reset(); match terminator { TerminatorKind::SwitchInt { discr: op, .. } | TerminatorKind::Assert { cond: op, .. } => { @@ -657,15 +665,16 @@ impl WriteInfo { Operand::Copy(_) | Operand::Constant(_) => (), } } + + fn reset(&mut self) { + self.writes.clear(); + self.skip_pair = None; + } } ///////////////////////////////////////////////////// // Candidate accumulation -fn is_constant<'tcx>(place: Place<'tcx>) -> bool { - place.projection.iter().all(|p| !matches!(p, ProjectionElem::Deref | ProjectionElem::Index(_))) -} - /// If the pair of places is being considered for merging, returns the candidate which would be /// merged in order to accomplish this. /// @@ -741,10 +750,6 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, '_, 'tcx> { Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), )) = &statement.kind { - if !is_constant(*lhs) || !is_constant(*rhs) { - return; - } - let Some((src, dest)) = places_to_candidate_pair(*lhs, *rhs, self.body) else { return; }; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index c08593afe9d..c097af61611 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -490,7 +490,7 @@ fn locals_live_across_suspend_points<'tcx>( // Calculate when MIR locals have live storage. This gives us an upper bound of their // lifetimes. - let mut storage_live = MaybeStorageLive::new(always_live_locals.clone()) + let mut storage_live = MaybeStorageLive::new(std::borrow::Cow::Borrowed(always_live_locals)) .into_engine(tcx, body_ref) .iterate_to_fixpoint() .into_results_cursor(body_ref); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 220cf7df9c6..9d560f5c837 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -849,7 +849,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { }; let kind = match parent_ty.ty.kind() { - &ty::Opaque(def_id, substs) => { + &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind() } kind => kind, diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index a159e617178..1708b287e56 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -16,7 +16,8 @@ pub struct NormalizeArrayLen; impl<'tcx> MirPass<'tcx> for NormalizeArrayLen { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 4 + // See #105929 + sess.mir_opt_level() >= 4 && sess.opts.unstable_opts.unsound_mir_opts } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index 569e783fee8..6cabef92d8c 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -52,7 +52,11 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts { fn maybe_zst(ty: Ty<'_>) -> bool { match ty.kind() { // maybe ZST (could be more precise) - ty::Adt(..) | ty::Array(..) | ty::Closure(..) | ty::Tuple(..) | ty::Opaque(..) => true, + ty::Adt(..) + | ty::Array(..) + | ty::Closure(..) + | ty::Tuple(..) + | ty::Alias(ty::Opaque, ..) => true, // definitely ZST ty::FnDef(..) | ty::Never => true, // unreachable or can't be ZST diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index f92a0e826dc..f8b55c86287 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -336,8 +336,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, []); - let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); + let sig = tcx.bound_fn_sig(def_id).subst(tcx, &[self_ty.into()]); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -417,10 +416,8 @@ impl<'tcx> CloneShimBuilder<'tcx> { ) { let tcx = self.tcx; - let substs = tcx.mk_substs_trait(ty, []); - // `func == Clone::clone(&ty) -> ty` - let func_ty = tcx.mk_fn_def(self.def_id, substs); + let func_ty = tcx.mk_fn_def(self.def_id, [ty]); let func = Operand::Constant(Box::new(Constant { span: self.span, user_ty: None, @@ -575,9 +572,8 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = tcx.mk_substs_trait(ty, [ty::subst::GenericArg::from(arg_tup)]); - (Some(sig_substs), Some(untuple_args)) + (Some([ty.into(), arg_tup.into()]), Some(untuple_args)) } else { (None, None) }; @@ -588,7 +584,7 @@ fn build_call_shim<'tcx>( assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body()); let mut sig = - if let Some(sig_substs) = sig_substs { sig.subst(tcx, sig_substs) } else { sig.0 }; + if let Some(sig_substs) = sig_substs { sig.subst(tcx, &sig_substs) } else { sig.0 }; if let CallKind::Indirect(fnty) = call_kind { // `sig` determines our local decls, and thus the callee type in the `Call` terminator. This diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 475e2ec9a1d..8212a7b523b 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -35,7 +35,6 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use smallvec::SmallVec; -use std::convert::TryInto; pub struct SimplifyCfg { label: String, |
