diff --git a/rust-toolchain.toml b/rust-toolchain.toml index da0cfe2..dba9988 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-08" +channel = "nightly-2024-09-08" components = [ "rustc-dev", "rust-src", "llvm-tools-preview", "rust-analyzer" ] diff --git a/src/analyze.rs b/src/analyze.rs index 523b56d..15a35e2 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -75,7 +75,7 @@ pub fn resolve_discr(tcx: TyCtxt<'_>, discr: mir_ty::VariantDiscr) -> u32 { mir_ty::VariantDiscr::Relative(i) => i, mir_ty::VariantDiscr::Explicit(did) => { let val = tcx.const_eval_poly(did).unwrap(); - val.try_to_scalar_int().unwrap().try_to_u32().unwrap() + val.try_to_scalar_int().unwrap().to_u32() } } } @@ -561,7 +561,7 @@ impl<'tcx> Analyzer<'tcx> { body.args_iter().map(|arg| body.local_decls[arg].ty), body.return_ty(), sig.c_variadic, - sig.unsafety, + sig.safety, sig.abi, ) } @@ -582,8 +582,7 @@ impl<'tcx> Analyzer<'tcx> { attr_path: &[Symbol], ) -> Option { let map = self.tcx.hir(); - let body_id = map.maybe_body_owned_by(local_def_id)?; - let body = map.body(body_id); + let body = map.maybe_body_owned_by(local_def_id)?; let rustc_hir::ExprKind::Block(block, _) = body.value.kind else { return None; diff --git a/src/analyze/annot_fn.rs b/src/analyze/annot_fn.rs index 6e2bb44..aca05e1 100644 --- a/src/analyze/annot_fn.rs +++ b/src/analyze/annot_fn.rs @@ -136,8 +136,7 @@ pub struct AnnotFnTranslator<'tcx> { impl<'tcx> AnnotFnTranslator<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> Self { let map = tcx.hir(); - let body_id = map.body_owned_by(local_def_id); - let body = map.body(body_id); + let body = map.body_owned_by(local_def_id); let generic_args = tcx.mk_args(&[]); let typeck = tcx.typeck(local_def_id); let def_ids = DefIdCache::new(tcx); diff --git a/src/analyze/basic_block.rs b/src/analyze/basic_block.rs index 29b086d..bdfeac2 100644 --- a/src/analyze/basic_block.rs +++ b/src/analyze/basic_block.rs @@ -213,7 +213,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { mir_ty::TyKind::Int(_) | mir_ty::TyKind::Uint(_), ConstValue::Scalar(Scalar::Int(val)), ) => { - let val = val.try_to_int(val.size()).unwrap(); + let val = val.to_int(val.size()); PlaceType::with_ty_and_term( rty::Type::int(), chc::Term::int(val.try_into().unwrap()), @@ -270,7 +270,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { let param_env = self.tcx.param_env(self.local_def_id); let val = self .tcx - .const_eval_resolve(param_env, *unevaluated, None) + .const_eval_resolve(param_env, *unevaluated, rustc_span::DUMMY_SP) .unwrap(); self.const_value_ty(&val, ty) } @@ -595,7 +595,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { .param_env(self.local_def_id) .with_reveal_all_normalized(self.tcx); let instance = - mir_ty::Instance::resolve(self.tcx, param_env, def_id, args).unwrap(); + mir_ty::Instance::try_resolve(self.tcx, param_env, def_id, args).unwrap(); if let Some(instance) = instance { (instance.def_id(), instance.args) } else { @@ -606,11 +606,15 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { tracing::info!(?def_id, ?resolved_def_id, ?resolved_args, "resolved"); } - self.ctx + let Some(ty) = self + .ctx .def_ty_with_args(resolved_def_id, resolved_args) - .expect("unknown def") - .ty - .vacuous() + .or_else(|| self.ctx.def_ty_with_args(def_id, args)) + else { + tracing::debug!(?resolved_def_id, "unknown def, skipping constraints"); + return; + }; + ty.ty.vacuous() } else { self.operand_type(func.clone()).ty }; @@ -815,7 +819,11 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { .for_template(&mut self.ctx) .with_scope(&self.env) .build_refined(decl.ty); - self.type_call(func.clone(), args.clone().into_iter().map(|a| a.node), &rty); + self.type_call( + func.clone(), + args.clone().iter().map(|a| a.node.clone()), + &rty, + ); self.bind_local(destination, rty); } } @@ -905,7 +913,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { unimplemented!(); } // TODO: is it appropriate to use builtin_deref here... maybe we should handle dereferencing logic in `refine` - let inner_ty = self.local_decls[p.local].ty.builtin_deref(true).unwrap().ty; + let inner_ty = self.local_decls[p.local].ty.builtin_deref(true).unwrap(); self.add_prophecy_var(stmt_idx, inner_ty); } } diff --git a/src/analyze/basic_block/drop_point.rs b/src/analyze/basic_block/drop_point.rs index bcb0c1d..a9685c3 100644 --- a/src/analyze/basic_block/drop_point.rs +++ b/src/analyze/basic_block/drop_point.rs @@ -96,7 +96,7 @@ impl<'mir, 'tcx> DropPointsBuilder<'mir, 'tcx> { results.seek_to_block_end(bb); let live_locals_after_terminator = results.get().clone(); - use rustc_data_structures::graph::WithSuccessors as _; + use rustc_data_structures::graph::Successors as _; let mut ins = BitSet::new_empty(self.body.local_decls.len()); for succ_bb in self.body.basic_blocks.successors(bb) { self.bb_ins_cache.entry(succ_bb).or_insert_with(|| { diff --git a/src/analyze/local_def.rs b/src/analyze/local_def.rs index 09d0216..9c0d0fa 100644 --- a/src/analyze/local_def.rs +++ b/src/analyze/local_def.rs @@ -130,8 +130,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { use rustc_hir::{Block, Expr, ExprKind}; let hir_map = self.tcx.hir(); - let body_id = hir_map.maybe_body_owned_by(local_def_id).unwrap(); - let hir_body = hir_map.body(body_id); + let hir_body = hir_map.maybe_body_owned_by(local_def_id).unwrap(); let predicate_body = match hir_body.value { Expr { @@ -432,7 +431,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { let args = typeck_result.node_args(hir_id); let param_env = self.tcx.param_env(self.local_def_id); - let instance = mir_ty::Instance::resolve(self.tcx, param_env, def_id, args).unwrap(); + let instance = mir_ty::Instance::try_resolve(self.tcx, param_env, def_id, args).unwrap(); if let Some(instance) = instance { instance.def_id() } else { @@ -478,7 +477,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { if !local_ty.is_box() { return None; } - let inner_ty = local_ty.boxed_ty(); + let inner_ty = local_ty.boxed_ty()?; use mir::ProjectionElem::Field; use rustc_target::abi::FieldIdx; @@ -502,8 +501,8 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { } if !matches!( - ty2.kind(), mir_ty::TyKind::RawPtr(t) - if t.ty == inner_ty && t.mutbl.is_not() + ty2.kind(), mir_ty::TyKind::RawPtr(t, mutbl) + if *t == inner_ty && mutbl.is_not() ) { return None; } @@ -586,12 +585,70 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { visitor.locals } + // XXX: In nightly-2024-09-08, `MaybeInitializedPlaces::switch_int_edge_effects` + // requires `SwitchInt` values to be in the same order as `AdtDef::discriminants`. + // Since optimizations can sometimes break this order, we normalize it beforehand. + // + // > thread 'rustc' panicked at /rustc/12b26c13fba25c9e1bc2fdf05f3c2dbb851c83de/compiler/rustc_mir_dataflow/src/impls/initialized.rs:431:18: + // > Order of `AdtDef::discriminants` differed from `SwitchInt::values` + fn normalize_switch_int_discriminant_order(&mut self) { + let blocks = self.body.basic_blocks.as_mut().as_mut_slice(); + for block in blocks.iter_mut() { + let Some(terminator) = &mut block.terminator else { + continue; + }; + let mir::TerminatorKind::SwitchInt { discr, targets } = &mut terminator.kind else { + continue; + }; + let Some(discr_place) = discr.place() else { + continue; + }; + + let enum_adt = block.statements.iter().rev().find_map(|stmt| { + let mir::StatementKind::Assign(assign) = &stmt.kind else { + return None; + }; + let (lhs, mir::Rvalue::Discriminant(disc_place)) = assign.as_ref() else { + return None; + }; + if *lhs != discr_place { + return None; + } + let ty = disc_place.ty(&self.body.local_decls, self.tcx).ty; + if let mir_ty::TyKind::Adt(def, _) = ty.kind() { + Some(*def) + } else { + None + } + }); + let Some(adt_def) = enum_adt else { + continue; + }; + + let otherwise = targets.otherwise(); + let mut pairs: Vec<(u128, mir::BasicBlock)> = targets.iter().collect(); + let discriminant_order: Vec = adt_def + .discriminants(self.tcx) + .map(|(_, discr)| discr.val) + .collect(); + pairs.sort_by_key(|(val, _)| { + discriminant_order + .iter() + .position(|d| d == val) + .unwrap_or(usize::MAX) + }); + *targets = mir::SwitchTargets::new(pairs.into_iter(), otherwise); + } + } + fn reassign_local_mutabilities(&mut self) { use rustc_mir_dataflow::{ move_paths::{HasMoveData as _, MoveData}, Analysis as _, MaybeReachable, MoveDataParamEnv, }; + self.normalize_switch_int_discriminant_order(); + for local_decl in &mut self.body.local_decls { local_decl.mutability = mir::Mutability::Not; } @@ -638,7 +695,7 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> { let mut results = rustc_mir_dataflow::impls::MaybeInitializedPlaces::new( self.tcx, &tmp_body, - &move_data_param_env, + &move_data_param_env.move_data, ) .into_engine(self.tcx, &self.body) .iterate_to_fixpoint() diff --git a/src/annot.rs b/src/annot.rs index 270aed1..03965a2 100644 --- a/src/annot.rs +++ b/src/annot.rs @@ -377,7 +377,7 @@ where generic_args: Vec::new(), }); while let Some(Token { - kind: TokenKind::ModSep, + kind: TokenKind::PathSep, .. }) = self.look_ahead_token(0) { diff --git a/src/main.rs b/src/main.rs index 1a26967..a4746d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,8 @@ impl Callbacks for CompilerCalls { &compiler.sess.psess, rustc_span::FileName::Custom("thrust std injected".to_string()), injected.to_owned(), - ); + ) + .unwrap(); while let Some(item) = parser .parse_item(rustc_parse::parser::ForceCollect::No) .unwrap() diff --git a/src/refine/template.rs b/src/refine/template.rs index fceb757..b4ec137 100644 --- a/src/refine/template.rs +++ b/src/refine/template.rs @@ -128,7 +128,7 @@ impl<'tcx> TypeBuilder<'tcx> { use mir_ty::fold::TypeFoldable; impl<'tcx> mir_ty::fold::TypeFolder> for ReplaceClosureModel<'tcx> { - fn interner(&self) -> mir_ty::TyCtxt<'tcx> { + fn cx(&self) -> mir_ty::TyCtxt<'tcx> { self.tcx } @@ -222,9 +222,9 @@ impl<'tcx> TypeBuilder<'tcx> { } mir_ty::TyKind::Never => rty::Type::never(), mir_ty::TyKind::Param(ty) => self.translate_param_type(ty), - mir_ty::TyKind::FnPtr(sig) => { + mir_ty::TyKind::FnPtr(sig_tys, hdr) => { // TODO: justification for skip_binder - let sig = sig.skip_binder(); + let sig = sig_tys.with(*hdr).skip_binder(); let params = sig .inputs() .iter() @@ -384,9 +384,9 @@ where } mir_ty::TyKind::Never => rty::Type::never(), mir_ty::TyKind::Param(ty) => self.inner.translate_param_type(ty).vacuous(), - mir_ty::TyKind::FnPtr(sig) => { + mir_ty::TyKind::FnPtr(sig_tys, hdr) => { // TODO: justification for skip_binder - let sig = sig.skip_binder(); + let sig = sig_tys.with(*hdr).skip_binder(); let ty = self.inner.for_function_template(self.registry, sig).build(); rty::Type::function(ty) } @@ -562,7 +562,7 @@ where let param_rty = if let Some(param_refinement) = &self.param_refinement { rty::RefinedType::new(rty::Type::unit(), param_refinement.clone()) } else { - let unit_ty = mir_ty::Ty::new_unit(self.inner.tcx); + let unit_ty = self.inner.tcx.types.unit; self.inner .for_template(self.registry) .with_scope(&builder) diff --git a/tests/ui/fail/iterators/range.rs b/tests/ui/fail/iterators/range.rs index 0199ef0..1af93a7 100644 --- a/tests/ui/fail/iterators/range.rs +++ b/tests/ui/fail/iterators/range.rs @@ -1,5 +1,6 @@ //@error-in-other-file: Unsat //@compile-flags: -C debug-assertions=off +//@rustc-env: THRUST_SOLVER_ARGS= struct Range { start: i64, diff --git a/tests/ui/pass/iterators/range.rs b/tests/ui/pass/iterators/range.rs index 97f3de6..7febdc6 100644 --- a/tests/ui/pass/iterators/range.rs +++ b/tests/ui/pass/iterators/range.rs @@ -1,5 +1,6 @@ //@check-pass //@compile-flags: -C debug-assertions=off +//@rustc-env: THRUST_SOLVER_ARGS= struct Range { start: i64,