Skip to content

Commit

Permalink
Rollup merge of rust-lang#63495 - eddyb:mir-constant-ty, r=oli-obk
Browse files Browse the repository at this point in the history
 Remove redundant `ty` fields from `mir::Constant` and `hair::pattern::PatternRange`.

Fixes rust-lang#56137.

As a side-effect, associated const literals have the correct type now, which should make things easier for rust-lang#61041.

r? @oli-obk / @matthewjasper cc @davidtwco @varkor
  • Loading branch information
Centril committed Aug 15, 2019
2 parents 677edc3 + d30f481 commit 7ff5b38
Show file tree
Hide file tree
Showing 28 changed files with 58 additions and 121 deletions.
5 changes: 1 addition & 4 deletions src/librustc/mir/mod.rs
Expand Up @@ -2197,7 +2197,6 @@ impl<'tcx> Operand<'tcx> {
let ty = tcx.type_of(def_id).subst(tcx, substs);
Operand::Constant(box Constant {
span,
ty,
user_ty: None,
literal: ty::Const::zero_sized(tcx, ty),
})
Expand Down Expand Up @@ -2476,7 +2475,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
pub struct Constant<'tcx> {
pub span: Span,
pub ty: Ty<'tcx>,

/// Optional user-given type: for something like
/// `collect::<Vec<_>>`, this would be present and would
Expand Down Expand Up @@ -3385,12 +3383,11 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
Constant {
span: self.span.clone(),
ty: self.ty.fold_with(folder),
user_ty: self.user_ty.fold_with(folder),
literal: self.literal.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.ty.visit_with(visitor) || self.literal.visit_with(visitor)
self.literal.visit_with(visitor)
}
}
2 changes: 1 addition & 1 deletion src/librustc/mir/tcx.rs
Expand Up @@ -252,7 +252,7 @@ impl<'tcx> Operand<'tcx> {
match self {
&Operand::Copy(ref l) |
&Operand::Move(ref l) => l.ty(local_decls, tcx).ty,
&Operand::Constant(ref c) => c.ty,
&Operand::Constant(ref c) => c.literal.ty,
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/mir/visit.rs
Expand Up @@ -782,13 +782,11 @@ macro_rules! make_mir_visitor {
location: Location) {
let Constant {
span,
ty,
user_ty,
literal,
} = constant;

self.visit_span(span);
self.visit_ty(ty, TyContext::Location(location));
drop(user_ty); // no visit method for this
self.visit_const(literal, location);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/analyze.rs
Expand Up @@ -221,7 +221,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
mir::TerminatorKind::Call {
func: mir::Operand::Constant(ref c),
ref args, ..
} => match c.ty.sty {
} => match c.literal.ty.sty {
ty::FnDef(did, _) => Some((did, args)),
_ => None,
},
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/block.rs
Expand Up @@ -651,7 +651,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (llval, ty) = self.simd_shuffle_indices(
&bx,
constant.span,
constant.ty,
constant.literal.ty,
c,
);
return OperandRef {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/operand.rs
Expand Up @@ -466,7 +466,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}

mir::Operand::Constant(ref constant) => {
let ty = self.monomorphize(&constant.ty);
self.eval_mir_constant(constant)
.map(|c| OperandRef::from_const(bx, c))
.unwrap_or_else(|err| {
Expand All @@ -481,6 +480,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// the above error (or silence it under some conditions) will not cause UB
bx.abort();
// We've errored, so we don't have to produce working code.
let ty = self.monomorphize(&constant.literal.ty);
let layout = bx.cx().layout_of(ty);
bx.load_operand(PlaceRef::new_sized(
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
Expand Down
44 changes: 4 additions & 40 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Expand Up @@ -272,12 +272,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {

fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
self.sanitize_constant(constant, location);
self.sanitize_type(constant, constant.ty);
self.sanitize_type(constant, constant.literal.ty);

if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
constant.ty,
constant.literal.ty,
ty::Variance::Invariant,
&UserTypeProjection { base: annotation_index, projs: vec![], },
location.to_locations(),
Expand All @@ -289,7 +288,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
constant,
"bad constant user type {:?} vs {:?}: {:?}",
annotation,
constant.ty,
constant.literal.ty,
terr,
);
}
Expand All @@ -299,7 +298,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
location.to_locations(),
ConstraintCategory::Boring,
self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
constant.literal.ty, def_id, UserSubsts { substs, user_self_ty: None },
)),
) {
span_mirbug!(
Expand Down Expand Up @@ -403,41 +402,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
}
}

/// Checks that the constant's `ty` field matches up with what would be
/// expected from its literal. Unevaluated constants and well-formed
/// constraints are checked by `visit_constant`.
fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
debug!(
"sanitize_constant(constant={:?}, location={:?})",
constant, location
);

let literal = constant.literal;

if let ConstValue::Unevaluated(..) = literal.val {
return;
}

debug!("sanitize_constant: expected_ty={:?}", literal.ty);

if let Err(terr) = self.cx.eq_types(
literal.ty,
constant.ty,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(
self,
constant,
"constant {:?} should have type {:?} but has {:?} ({:?})",
constant,
literal.ty,
constant.ty,
terr,
);
}
}

/// Checks that the types internal to the `place` match up with
/// what would be expected.
fn sanitize_place(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/as_constant.rs
Expand Up @@ -38,9 +38,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
inferred_ty: ty,
})
});
assert_eq!(literal.ty, ty);
Constant {
span,
ty,
user_ty,
literal,
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -591,7 +591,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let n = (!0u128) >> (128 - bits);
let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);

self.literal_operand(span, ty, literal)
self.literal_operand(span, literal)
}

// Helper to get the minimum value of the appropriate type
Expand All @@ -602,6 +602,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let n = 1 << (bits - 1);
let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);

self.literal_operand(span, ty, literal)
self.literal_operand(span, literal)
}
}
2 changes: 0 additions & 2 deletions src/librustc_mir/build/expr/into.rs
Expand Up @@ -114,7 +114,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
destination,
Constant {
span: expr_span,
ty: this.hir.bool_ty(),
user_ty: None,
literal: this.hir.true_literal(),
},
Expand All @@ -126,7 +125,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
destination,
Constant {
span: expr_span,
ty: this.hir.bool_ty(),
user_ty: None,
literal: this.hir.false_literal(),
},
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/matches/simplify.rs
Expand Up @@ -108,8 +108,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Err(match_pair)
}

PatternKind::Range(PatternRange { lo, hi, ty, end }) => {
let (range, bias) = match ty.sty {
PatternKind::Range(PatternRange { lo, hi, end }) => {
let (range, bias) = match lo.ty.sty {
ty::Char => {
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
}
Expand Down
26 changes: 14 additions & 12 deletions src/librustc_mir/build/matches/test.rs
Expand Up @@ -63,7 +63,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}

PatternKind::Range(range) => {
assert!(range.ty == match_pair.pattern.ty);
assert_eq!(range.lo.ty, match_pair.pattern.ty);
assert_eq!(range.hi.ty, match_pair.pattern.ty);
Test {
span: match_pair.pattern.span,
kind: TestKind::Range(range),
Expand Down Expand Up @@ -270,22 +271,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
} else {
if let [success, fail] = *make_target_blocks(self) {
assert_eq!(value.ty, ty);
let expect = self.literal_operand(test.span, value);
let val = Operand::Copy(place.clone());
let expect = self.literal_operand(test.span, ty, value);
self.compare(block, success, fail, source_info, BinOp::Eq, expect, val);
} else {
bug!("`TestKind::Eq` should have two target blocks");
}
}
}

TestKind::Range(PatternRange { ref lo, ref hi, ty, ref end }) => {
TestKind::Range(PatternRange { ref lo, ref hi, ref end }) => {
let lower_bound_success = self.cfg.start_new_block();
let target_blocks = make_target_blocks(self);

// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
let lo = self.literal_operand(test.span, ty, lo);
let hi = self.literal_operand(test.span, ty, hi);
let lo = self.literal_operand(test.span, lo);
let hi = self.literal_operand(test.span, hi);
let val = Operand::Copy(place.clone());

if let [success, fail] = *target_blocks {
Expand Down Expand Up @@ -387,7 +389,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
) {
use rustc::middle::lang_items::EqTraitLangItem;

let mut expect = self.literal_operand(source_info.span, value.ty, value);
let mut expect = self.literal_operand(source_info.span, value);
let mut val = Operand::Copy(place.clone());

// If we're using `b"..."` as a pattern, we need to insert an
Expand Down Expand Up @@ -440,7 +442,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};

let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem);
let (mty, method) = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
let method = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);

let bool_ty = self.hir.bool_ty();
let eq_result = self.temp(bool_ty, source_info.span);
Expand All @@ -449,7 +451,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.cfg.terminate(block, source_info, TerminatorKind::Call {
func: Operand::Constant(box Constant {
span: source_info.span,
ty: mty,

// FIXME(#54571): This constant comes from user input (a
// constant in a pattern). Are there forms where users can add
Expand Down Expand Up @@ -656,8 +657,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

let tcx = self.hir.tcx();

let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test.ty)?;
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test.ty)?;
let test_ty = test.lo.ty;
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test_ty)?;
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test_ty)?;

match (test.end, pat.end, lo, hi) {
// pat < test
Expand Down Expand Up @@ -774,8 +776,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

let tcx = self.hir.tcx();

let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.ty)?;
let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.ty)?;
let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.lo.ty)?;
let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.lo.ty)?;

match (b, range.end) {
(Less, _) |
Expand Down
5 changes: 1 addition & 4 deletions src/librustc_mir/build/misc.rs
Expand Up @@ -26,12 +26,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// without any user type annotation.
pub fn literal_operand(&mut self,
span: Span,
ty: Ty<'tcx>,
literal: &'tcx ty::Const<'tcx>)
-> Operand<'tcx> {
let constant = box Constant {
span,
ty,
user_ty: None,
literal,
};
Expand All @@ -47,7 +45,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
let literal = ty::Const::from_bits(self.hir.tcx(), 0, ty::ParamEnv::empty().and(ty));

self.literal_operand(span, ty, literal)
self.literal_operand(span, literal)
}

pub fn push_usize(&mut self,
Expand All @@ -61,7 +59,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block, source_info, &temp,
Constant {
span: source_info.span,
ty: self.hir.usize_ty(),
user_ty: None,
literal: self.hir.usize_literal(value),
});
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/hair/cx/expr.rs
Expand Up @@ -927,7 +927,7 @@ fn convert_path_expr<'a, 'tcx>(
ExprKind::Literal {
literal: cx.tcx.mk_const(ty::Const {
val: ConstValue::Unevaluated(def_id, substs),
ty: cx.tcx.type_of(def_id),
ty: cx.tables().node_type(expr.hir_id),
}),
user_ty,
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/hair/cx/mod.rs
Expand Up @@ -170,13 +170,13 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
method_name: Symbol,
self_ty: Ty<'tcx>,
params: &[Kind<'tcx>])
-> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
-> &'tcx ty::Const<'tcx> {
let substs = self.tcx.mk_substs_trait(self_ty, params);
for item in self.tcx.associated_items(trait_def_id) {
if item.kind == ty::AssocKind::Method && item.ident.name == method_name {
let method_ty = self.tcx.type_of(item.def_id);
let method_ty = method_ty.subst(self.tcx, substs);
return (method_ty, ty::Const::zero_sized(self.tcx, method_ty));
return ty::Const::zero_sized(self.tcx, method_ty);
}
}

Expand Down

0 comments on commit 7ff5b38

Please sign in to comment.