Skip to content

Commit 2d98e9e

Browse files
committed
create type ascription for any cast
Also, avoid shadowing of the `ty` variable by giving the `cast_ty` and `var_ty` variables different names. We want to get the user-provided type from `cast_ty.hir_id`.
1 parent 80ad300 commit 2d98e9e

File tree

2 files changed

+52
-25
lines changed

2 files changed

+52
-25
lines changed

src/librustc_mir/hair/cx/expr.rs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -637,12 +637,25 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
637637
name: Field::new(cx.tcx.field_index(expr.id, cx.tables)),
638638
}
639639
}
640-
hir::ExprKind::Cast(ref source, ref ty) => {
640+
hir::ExprKind::Cast(ref source, ref cast_ty) => {
641+
// Check for a user-given type annotation on this `cast`
642+
let user_ty = cx.tables.user_provided_tys().get(cast_ty.hir_id)
643+
.map(|&t| UserTypeAnnotation::Ty(t));
644+
645+
debug!(
646+
"cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}",
647+
expr,
648+
cast_ty.hir_id,
649+
user_ty,
650+
);
651+
641652
// Check to see if this cast is a "coercion cast", where the cast is actually done
642653
// using a coercion (or is a no-op).
643-
if let Some(&TyCastKind::CoercionCast) = cx.tables()
644-
.cast_kinds()
645-
.get(source.hir_id) {
654+
let cast = if let Some(&TyCastKind::CoercionCast) =
655+
cx.tables()
656+
.cast_kinds()
657+
.get(source.hir_id)
658+
{
646659
// Convert the lexpr to a vexpr.
647660
ExprKind::Use { source: source.to_ref() }
648661
} else {
@@ -679,32 +692,33 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
679692
} else {
680693
None
681694
};
682-
let source = if let Some((did, offset, ty)) = var {
695+
696+
let source = if let Some((did, offset, var_ty)) = var {
683697
let mk_const = |literal| Expr {
684698
temp_lifetime,
685-
ty,
699+
ty: var_ty,
686700
span: expr.span,
687701
kind: ExprKind::Literal { literal, user_ty: None },
688702
}.to_ref();
689703
let offset = mk_const(ty::Const::from_bits(
690704
cx.tcx,
691705
offset as u128,
692-
cx.param_env.and(ty),
706+
cx.param_env.and(var_ty),
693707
));
694708
match did {
695709
Some(did) => {
696710
// in case we are offsetting from a computed discriminant
697711
// and not the beginning of discriminants (which is always `0`)
698712
let substs = Substs::identity_for_item(cx.tcx(), did);
699-
let lhs = mk_const(ty::Const::unevaluated(cx.tcx(), did, substs, ty));
713+
let lhs = mk_const(ty::Const::unevaluated(cx.tcx(), did, substs, var_ty));
700714
let bin = ExprKind::Binary {
701715
op: BinOp::Add,
702716
lhs,
703717
rhs: offset,
704718
};
705719
Expr {
706720
temp_lifetime,
707-
ty,
721+
ty: var_ty,
708722
span: expr.span,
709723
kind: bin,
710724
}.to_ref()
@@ -715,25 +729,25 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
715729
source.to_ref()
716730
};
717731

718-
let cast = ExprKind::Cast { source };
732+
ExprKind::Cast { source }
733+
};
719734

720-
if let Some(user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
721-
// NOTE: Creating a new Expr and wrapping a Cast inside of it may be
722-
// inefficient, revisit this when performance becomes an issue.
723-
let cast_expr = Expr {
724-
temp_lifetime,
725-
ty: expr_ty,
726-
span: expr.span,
727-
kind: cast,
728-
};
735+
if let Some(user_ty) = user_ty {
736+
// NOTE: Creating a new Expr and wrapping a Cast inside of it may be
737+
// inefficient, revisit this when performance becomes an issue.
738+
let cast_expr = Expr {
739+
temp_lifetime,
740+
ty: expr_ty,
741+
span: expr.span,
742+
kind: cast,
743+
};
729744

730-
ExprKind::ValueTypeAscription {
731-
source: cast_expr.to_ref(),
732-
user_ty: UserTypeAnnotation::Ty(*user_ty),
733-
}
734-
} else {
735-
cast
745+
ExprKind::ValueTypeAscription {
746+
source: cast_expr.to_ref(),
747+
user_ty: user_ty,
736748
}
749+
} else {
750+
cast
737751
}
738752
}
739753
hir::ExprKind::Type(ref source, ref ty) => {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0597]: `x` does not live long enough
2+
--> $DIR/cast_static_lifetime.rs:16:19
3+
|
4+
LL | let y: &u32 = (&x) as &'static u32;
5+
| ^^^^ borrowed value does not live long enough
6+
LL | }
7+
| - `x` dropped here while still borrowed
8+
|
9+
= note: borrowed value must be valid for the static lifetime...
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)