use crate::dataflow::impls::MaybeInitializedPlaces;
use crate::dataflow::move_paths::MoveData;
use crate::dataflow::ResultsCursor;
+use crate::transform::{
+ check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression,
+};
use crate::borrow_check::{
borrow_set::BorrowSet,
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
- let ty = self.sanitize_type(constant, constant.literal.ty);
+ let ty = self.sanitize_type(constant, constant.literal.ty());
self.cx.infcx.tcx.for_each_free_region(&ty, |live_region| {
let live_region_vid =
if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
- constant.literal.ty,
+ constant.literal.ty(),
ty::Variance::Invariant,
&UserTypeProjection { base: annotation_index, projs: vec![] },
location.to_locations(),
constant,
"bad constant user type {:?} vs {:?}: {:?}",
annotation,
- constant.literal.ty,
+ constant.literal.ty(),
terr,
);
}
} else {
let tcx = self.tcx();
- if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val {
+ let maybe_uneval = match constant.literal {
+ ConstantKind::Ty(ct) => match ct.val {
+ ty::ConstKind::Unevaluated(def, substs, promoted) => {
+ Some((def, substs, promoted))
+ }
+ _ => None,
+ },
+ _ => None,
+ };
+ if let Some((def, substs, promoted)) = maybe_uneval {
if let Some(promoted) = promoted {
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
promoted: &Body<'tcx>,
location.to_locations(),
ConstraintCategory::Boring,
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
- constant.literal.ty,
+ constant.literal.ty(),
def.did,
UserSubsts { substs, user_self_ty: None },
)),
let unnormalized_ty = tcx.type_of(static_def_id);
let locations = location.to_locations();
let normalized_ty = self.cx.normalize(unnormalized_ty, locations);
- let literal_ty = constant.literal.ty.builtin_deref(true).unwrap().ty;
+ let literal_ty = constant.literal.ty().builtin_deref(true).unwrap().ty;
if let Err(terr) = self.cx.eq_types(
normalized_ty,
}
}
- if let ty::FnDef(def_id, substs) = *constant.literal.ty.kind() {
+ if let ty::FnDef(def_id, substs) = *constant.literal.ty().kind() {
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
self.cx.normalize_and_prove_instantiated_predicates(
instantiated_predicates,
) -> Fallible<()> {
relate_tys::relate_types(
self.infcx,
+ self.param_env,
a,
v,
b,
);
}
}
+ StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
+ ..
+ }) => span_bug!(
+ stmt.source_info.span,
+ "Unexpected StatementKind::CopyNonOverlapping, should only appear after lowering_intrinsics",
+ ),
StatementKind::FakeRead(..)
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
}
TerminatorKind::Yield { ref value, .. } => {
let value_ty = value.ty(body, tcx);
- match body.yield_ty {
+ match body.yield_ty() {
None => span_mirbug!(self, term, "yield in non-generator"),
Some(ty) => {
if let Err(terr) = self.sub_types(
}
}
None => {
- if !sig.output().conservative_is_privately_uninhabited(self.tcx()) {
+ if !self
+ .tcx()
+ .conservative_is_privately_uninhabited(self.param_env.and(sig.output()))
+ {
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
}
}
Operand::Copy(..) | Operand::Constant(..) => {
// These are always okay: direct use of a const, or a value that can evidently be copied.
}
- Operand::Move(_) => {
+ Operand::Move(place) => {
// Make sure that repeated elements implement `Copy`.
let span = body.source_info(location).span;
let ty = operand.ty(body, tcx);
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
+ let ccx = ConstCx::new_with_param_env(tcx, body, self.param_env);
+ let is_const_fn =
+ is_const_fn_in_array_repeat_expression(&ccx, &place, &body);
+
+ debug!("check_rvalue: is_const_fn={:?}", is_const_fn);
+
let def_id = body.source.def_id().expect_local();
self.infcx.report_selection_error(
&traits::Obligation::new(
ObligationCause::new(
span,
self.tcx().hir().local_def_id_to_hir_id(def_id),
- traits::ObligationCauseCode::RepeatVec,
+ traits::ObligationCauseCode::RepeatVec(is_const_fn),
),
self.param_env,
ty::Binder::bind(ty::TraitRef::new(
CastKind::Pointer(PointerCast::ArrayToPointer) => {
let ty_from = op.ty(body, tcx);
- let opt_ty_elem = match ty_from.kind() {
- ty::RawPtr(ty::TypeAndMut {
- mutbl: hir::Mutability::Not,
- ty: array_ty,
- }) => match array_ty.kind() {
- ty::Array(ty_elem, _) => Some(ty_elem),
- _ => None,
- },
+ let opt_ty_elem_mut = match ty_from.kind() {
+ ty::RawPtr(ty::TypeAndMut { mutbl: array_mut, ty: array_ty }) => {
+ match array_ty.kind() {
+ ty::Array(ty_elem, _) => Some((ty_elem, *array_mut)),
+ _ => None,
+ }
+ }
_ => None,
};
- let ty_elem = match opt_ty_elem {
- Some(ty_elem) => ty_elem,
+ let (ty_elem, ty_mut) = match opt_ty_elem_mut {
+ Some(ty_elem_mut) => ty_elem_mut,
None => {
span_mirbug!(
self,
}
};
- let ty_to = match ty.kind() {
- ty::RawPtr(ty::TypeAndMut {
- mutbl: hir::Mutability::Not,
- ty: ty_to,
- }) => ty_to,
+ let (ty_to, ty_to_mut) = match ty.kind() {
+ ty::RawPtr(ty::TypeAndMut { mutbl: ty_to_mut, ty: ty_to }) => {
+ (ty_to, *ty_to_mut)
+ }
_ => {
span_mirbug!(
self,
}
};
+ if ty_to_mut == Mutability::Mut && ty_mut == Mutability::Not {
+ span_mirbug!(
+ self,
+ rvalue,
+ "ArrayToPointer cast from const {:?} to mut {:?}",
+ ty,
+ ty_to
+ );
+ return;
+ }
+
if let Err(terr) = self.sub_types(
ty_elem,
ty_to,
Rvalue::BinaryOp(
BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
- left,
- right,
+ box (left, right),
) => {
let ty_left = left.ty(body, tcx);
match ty_left.kind() {