rustc: remove temporary lifetime extension by borrow hint
This commit is contained in:
parent
d7798c3d17
commit
ac8a1f5b6d
@ -298,7 +298,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
arg.id,
|
||||
arg.pat.span,
|
||||
fn_body_scope_r, // Args live only as long as the fn body.
|
||||
fn_body_scope_r,
|
||||
arg_ty);
|
||||
|
||||
self.walk_irrefutable_pat(arg_cmt, &arg.pat);
|
||||
|
@ -88,8 +88,7 @@ use std::rc::Rc;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum Categorization<'tcx> {
|
||||
// temporary val, argument is its scope
|
||||
Rvalue(ty::Region<'tcx>, ty::Region<'tcx>),
|
||||
Rvalue(ty::Region<'tcx>), // temporary val, argument is its scope
|
||||
StaticItem,
|
||||
Upvar(Upvar), // upvar referenced by closure env
|
||||
Local(ast::NodeId), // local variable
|
||||
@ -827,18 +826,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
|
||||
/// Returns the lifetime of a temporary created by expr with id `id`.
|
||||
/// This could be `'static` if `id` is part of a constant expression.
|
||||
pub fn temporary_scope(&self, id: ast::NodeId) -> (ty::Region<'tcx>, ty::Region<'tcx>)
|
||||
pub fn temporary_scope(&self, id: ast::NodeId) -> ty::Region<'tcx>
|
||||
{
|
||||
let (scope, old_scope) =
|
||||
self.region_maps.old_and_new_temporary_scope(id);
|
||||
(self.tcx().mk_region(match scope {
|
||||
let scope = self.region_maps.temporary_scope(id);
|
||||
self.tcx().mk_region(match scope {
|
||||
Some(scope) => ty::ReScope(scope),
|
||||
None => ty::ReStatic
|
||||
}),
|
||||
self.tcx().mk_region(match old_scope {
|
||||
Some(scope) => ty::ReScope(scope),
|
||||
None => ty::ReStatic
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cat_rvalue_node(&self,
|
||||
@ -858,13 +852,12 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
// Compute maximum lifetime of this rvalue. This is 'static if
|
||||
// we can promote to a constant, otherwise equal to enclosing temp
|
||||
// lifetime.
|
||||
let (re, old_re) = if promotable {
|
||||
(self.tcx().types.re_static,
|
||||
self.tcx().types.re_static)
|
||||
let re = if promotable {
|
||||
self.tcx().types.re_static
|
||||
} else {
|
||||
self.temporary_scope(id)
|
||||
};
|
||||
let ret = self.cat_rvalue(id, span, re, old_re, expr_ty);
|
||||
let ret = self.cat_rvalue(id, span, re, expr_ty);
|
||||
debug!("cat_rvalue_node ret {:?}", ret);
|
||||
ret
|
||||
}
|
||||
@ -873,12 +866,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
cmt_id: ast::NodeId,
|
||||
span: Span,
|
||||
temp_scope: ty::Region<'tcx>,
|
||||
old_temp_scope: ty::Region<'tcx>,
|
||||
expr_ty: Ty<'tcx>) -> cmt<'tcx> {
|
||||
let ret = Rc::new(cmt_ {
|
||||
id:cmt_id,
|
||||
span:span,
|
||||
cat:Categorization::Rvalue(temp_scope, old_temp_scope),
|
||||
cat:Categorization::Rvalue(temp_scope),
|
||||
mutbl:McDeclared,
|
||||
ty:expr_ty,
|
||||
note: NoteNone
|
||||
@ -1415,9 +1407,7 @@ impl<'tcx> fmt::Debug for Categorization<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Categorization::StaticItem => write!(f, "static"),
|
||||
Categorization::Rvalue(r, or) => {
|
||||
write!(f, "rvalue({:?}, {:?})", r, or)
|
||||
}
|
||||
Categorization::Rvalue(r) => { write!(f, "rvalue({:?})", r) }
|
||||
Categorization::Local(id) => {
|
||||
let name = ty::tls::with(|tcx| tcx.local_var_name_str(id));
|
||||
write!(f, "local({})", name)
|
||||
|
@ -223,13 +223,6 @@ pub struct RegionMaps {
|
||||
/// block (see `terminating_scopes`).
|
||||
rvalue_scopes: NodeMap<CodeExtent>,
|
||||
|
||||
/// Records the value of rvalue scopes before they were shrunk by
|
||||
/// #36082, for error reporting.
|
||||
///
|
||||
/// FIXME: this should be temporary. Remove this by 1.18.0 or
|
||||
/// so.
|
||||
shrunk_rvalue_scopes: NodeMap<CodeExtent>,
|
||||
|
||||
/// Encodes the hierarchy of fn bodies. Every fn body (including
|
||||
/// closures) forms its own distinct region hierarchy, rooted in
|
||||
/// the block that is the fn body. This map points from the id of
|
||||
@ -301,7 +294,6 @@ impl<'tcx> RegionMaps {
|
||||
destruction_scopes: FxHashMap(),
|
||||
var_map: NodeMap(),
|
||||
rvalue_scopes: NodeMap(),
|
||||
shrunk_rvalue_scopes: NodeMap(),
|
||||
fn_tree: NodeMap(),
|
||||
}
|
||||
}
|
||||
@ -370,12 +362,6 @@ impl<'tcx> RegionMaps {
|
||||
self.rvalue_scopes.insert(var, lifetime);
|
||||
}
|
||||
|
||||
fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
|
||||
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
|
||||
assert!(var != lifetime.node_id());
|
||||
self.shrunk_rvalue_scopes.insert(var, lifetime);
|
||||
}
|
||||
|
||||
pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
|
||||
//! Returns the narrowest scope that encloses `id`, if any.
|
||||
self.scope_map.get(&id).cloned()
|
||||
@ -395,32 +381,6 @@ impl<'tcx> RegionMaps {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn temporary_scope2(&self, expr_id: ast::NodeId)
|
||||
-> (Option<CodeExtent>, bool) {
|
||||
let temporary_scope = self.temporary_scope(expr_id);
|
||||
let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) {
|
||||
Some(&s) => {
|
||||
info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})",
|
||||
expr_id, temporary_scope, s);
|
||||
temporary_scope != Some(s)
|
||||
}
|
||||
_ => false
|
||||
};
|
||||
info!("temporary_scope2({:?}) - was_shrunk={:?}", expr_id, was_shrunk);
|
||||
(temporary_scope, was_shrunk)
|
||||
}
|
||||
|
||||
pub fn old_and_new_temporary_scope(&self, expr_id: ast::NodeId)
|
||||
-> (Option<CodeExtent>,
|
||||
Option<CodeExtent>)
|
||||
{
|
||||
let temporary_scope = self.temporary_scope(expr_id);
|
||||
(temporary_scope,
|
||||
self.shrunk_rvalue_scopes
|
||||
.get(&expr_id).cloned()
|
||||
.or(temporary_scope))
|
||||
}
|
||||
|
||||
pub fn temporary_scope(&self, expr_id: ast::NodeId) -> Option<CodeExtent> {
|
||||
//! Returns the scope when temp created by expr_id will be cleaned up
|
||||
|
||||
@ -896,10 +856,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
// Rule A. `let (ref x, ref y) = (foo().x, 44)`. The rvalue `(22, 44)`
|
||||
// would have an extended lifetime, but not `foo()`.
|
||||
//
|
||||
// Rule B. `let x: &[...] = [foo().x]`. The rvalue `[foo().x]`
|
||||
// would have an extended lifetime, but not `foo()`.
|
||||
//
|
||||
// Rule C. `let x = &foo().x`. The rvalue ``foo()` would have extended
|
||||
// Rule B. `let x = &foo().x`. The rvalue ``foo()` would have extended
|
||||
// lifetime.
|
||||
//
|
||||
// In some cases, multiple rules may apply (though not to the same
|
||||
@ -916,13 +873,8 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
if let Some(ref expr) = local.init {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &expr, blk_scope);
|
||||
|
||||
let is_borrow =
|
||||
if let Some(ref ty) = local.ty { is_borrowed_ty(&ty) } else { false };
|
||||
|
||||
if is_binding_pat(&local.pat) {
|
||||
record_rvalue_scope(visitor, &expr, blk_scope, false);
|
||||
} else if is_borrow {
|
||||
record_rvalue_scope(visitor, &expr, blk_scope, true);
|
||||
record_rvalue_scope(visitor, &expr, blk_scope);
|
||||
}
|
||||
}
|
||||
|
||||
@ -963,14 +915,6 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
/// True if `ty` is a borrowed pointer type like `&int` or `&[...]`.
|
||||
fn is_borrowed_ty(ty: &hir::Ty) -> bool {
|
||||
match ty.node {
|
||||
hir::TyRptr(..) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// If `expr` matches the `E&` grammar, then records an extended rvalue scope as appropriate:
|
||||
///
|
||||
/// E& = & ET
|
||||
@ -989,7 +933,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
match expr.node {
|
||||
hir::ExprAddrOf(_, ref subexpr) => {
|
||||
record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id);
|
||||
record_rvalue_scope(visitor, &subexpr, blk_id, false);
|
||||
record_rvalue_scope(visitor, &subexpr, blk_id);
|
||||
}
|
||||
hir::ExprStruct(_, ref fields, _) => {
|
||||
for field in fields {
|
||||
@ -1034,8 +978,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
/// Note: ET is intended to match "rvalues or lvalues based on rvalues".
|
||||
fn record_rvalue_scope<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
expr: &hir::Expr,
|
||||
blk_scope: CodeExtent,
|
||||
is_shrunk: bool) {
|
||||
blk_scope: CodeExtent) {
|
||||
let mut expr = expr;
|
||||
loop {
|
||||
// Note: give all the expressions matching `ET` with the
|
||||
@ -1043,12 +986,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>,
|
||||
// because in trans if we must compile e.g. `*rvalue()`
|
||||
// into a temporary, we request the temporary scope of the
|
||||
// outer expression.
|
||||
if is_shrunk {
|
||||
// this changed because of #36082
|
||||
visitor.region_maps.record_shrunk_rvalue_scope(expr.id, blk_scope);
|
||||
} else {
|
||||
visitor.region_maps.record_rvalue_scope(expr.id, blk_scope);
|
||||
}
|
||||
visitor.region_maps.record_rvalue_scope(expr.id, blk_scope);
|
||||
|
||||
match expr.node {
|
||||
hir::ExprAddrOf(_, ref subexpr) |
|
||||
|
@ -108,7 +108,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
|
||||
//! rooting etc, and presuming `cmt` is not mutated.
|
||||
|
||||
match cmt.cat {
|
||||
Categorization::Rvalue(temp_scope, _) => {
|
||||
Categorization::Rvalue(temp_scope) => {
|
||||
temp_scope
|
||||
}
|
||||
Categorization::Upvar(..) => {
|
||||
|
@ -1125,17 +1125,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
if let Some(_) = statement_scope_span(self.tcx, super_scope) {
|
||||
db.note("consider using a `let` binding to increase its lifetime");
|
||||
}
|
||||
|
||||
|
||||
|
||||
match err.cmt.cat {
|
||||
mc::Categorization::Rvalue(r, or) if r != or => {
|
||||
db.note("\
|
||||
before rustc 1.16, this temporary lived longer - see issue #39283 \
|
||||
(https://github.com/rust-lang/rust/issues/39283)");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
|
||||
|
@ -26,7 +26,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> {
|
||||
let this = self;
|
||||
let Expr { ty, temp_lifetime: _, temp_lifetime_was_shrunk: _, span, kind }
|
||||
let Expr { ty, temp_lifetime: _, span, kind }
|
||||
= expr;
|
||||
match kind {
|
||||
ExprKind::Scope { extent: _, value } =>
|
||||
|
@ -50,13 +50,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let temp = this.temp(expr_ty.clone(), expr_span);
|
||||
let source_info = this.source_info(expr_span);
|
||||
|
||||
if expr.temp_lifetime_was_shrunk && this.hir.needs_drop(expr_ty) {
|
||||
this.hir.tcx().sess.span_warn(
|
||||
expr_span,
|
||||
"this temporary used to live longer - see issue #39283 \
|
||||
(https://github.com/rust-lang/rust/issues/39283)");
|
||||
}
|
||||
|
||||
if !expr_ty.is_never() && temp_lifetime.is_some() {
|
||||
this.cfg.push(block, Statement {
|
||||
source_info: source_info,
|
||||
|
@ -82,11 +82,10 @@ pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
block: &'tcx hir::Block)
|
||||
-> ExprRef<'tcx> {
|
||||
let block_ty = cx.tables().node_id_to_type(block.id);
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(block.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(block.id);
|
||||
let expr = Expr {
|
||||
ty: block_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: block.span,
|
||||
kind: ExprKind::Block { body: block },
|
||||
};
|
||||
|
@ -26,7 +26,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||
type Output = Expr<'tcx>;
|
||||
|
||||
fn make_mirror<'a, 'gcx>(self, cx: &mut Cx<'a, 'gcx, 'tcx>) -> Expr<'tcx> {
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(self.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(self.id);
|
||||
let expr_extent = CodeExtent::Misc(self.id);
|
||||
|
||||
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
|
||||
@ -44,7 +44,6 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||
// Next, wrap this up in the expr's scope.
|
||||
expr = Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: expr.ty,
|
||||
span: self.span,
|
||||
kind: ExprKind::Scope {
|
||||
@ -57,7 +56,6 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||
if let Some(extent) = cx.region_maps.opt_destruction_extent(self.id) {
|
||||
expr = Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: expr.ty,
|
||||
span: self.span,
|
||||
kind: ExprKind::Scope {
|
||||
@ -77,7 +75,7 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
mut expr: Expr<'tcx>,
|
||||
adjustment: &Adjustment<'tcx>)
|
||||
-> Expr<'tcx> {
|
||||
let Expr { temp_lifetime, temp_lifetime_was_shrunk, span, .. } = expr;
|
||||
let Expr { temp_lifetime, span, .. } = expr;
|
||||
let kind = match adjustment.kind {
|
||||
Adjust::ReifyFnPointer => {
|
||||
ExprKind::ReifyFnPointer { source: expr.to_ref() }
|
||||
@ -102,7 +100,6 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
expr = Expr {
|
||||
temp_lifetime,
|
||||
temp_lifetime_was_shrunk,
|
||||
ty: cx.tcx.mk_ref(deref.region,
|
||||
ty::TypeAndMut {
|
||||
ty: expr.ty,
|
||||
@ -133,7 +130,6 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
let region = cx.tcx.mk_region(region);
|
||||
expr = Expr {
|
||||
temp_lifetime,
|
||||
temp_lifetime_was_shrunk,
|
||||
ty: cx.tcx.mk_ref(region,
|
||||
ty::TypeAndMut {
|
||||
ty: expr.ty,
|
||||
@ -155,7 +151,6 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
Expr {
|
||||
temp_lifetime,
|
||||
temp_lifetime_was_shrunk,
|
||||
ty: adjustment.target,
|
||||
span,
|
||||
kind,
|
||||
@ -166,7 +161,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &'tcx hir::Expr)
|
||||
-> Expr<'tcx> {
|
||||
let expr_ty = cx.tables().expr_ty(expr);
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
|
||||
|
||||
let kind = match expr.node {
|
||||
// Here comes the interesting stuff:
|
||||
@ -198,7 +193,6 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
let tupled_args = Expr {
|
||||
ty: cx.tcx.mk_tup(arg_tys, false),
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() },
|
||||
};
|
||||
@ -575,7 +569,6 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: expr_ty,
|
||||
span: expr.span,
|
||||
kind: kind,
|
||||
@ -586,14 +579,13 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &hir::Expr,
|
||||
custom_callee: Option<(DefId, &'tcx Substs<'tcx>)>)
|
||||
-> Expr<'tcx> {
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
|
||||
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
|
||||
(cx.tables().type_dependent_defs[&expr.id].def_id(),
|
||||
cx.tables().node_substs(expr.id))
|
||||
});
|
||||
Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: cx.tcx.type_of(def_id).subst(cx.tcx, substs),
|
||||
span: expr.span,
|
||||
kind: ExprKind::Literal {
|
||||
@ -673,7 +665,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
def: Def)
|
||||
-> ExprKind<'tcx> {
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
|
||||
|
||||
match def {
|
||||
Def::Local(def_id) => {
|
||||
@ -712,13 +704,11 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
Expr {
|
||||
ty: closure_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Deref {
|
||||
arg: Expr {
|
||||
ty: ref_closure_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::SelfRef,
|
||||
}
|
||||
@ -735,13 +725,11 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
Expr {
|
||||
ty: closure_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Deref {
|
||||
arg: Expr {
|
||||
ty: ref_closure_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::SelfRef,
|
||||
}.to_ref(),
|
||||
@ -752,7 +740,6 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
Expr {
|
||||
ty: closure_ty,
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
span: expr.span,
|
||||
kind: ExprKind::SelfRef,
|
||||
}
|
||||
@ -783,7 +770,6 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
ExprKind::Deref {
|
||||
arg: Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: cx.tcx.mk_ref(borrow.region,
|
||||
ty::TypeAndMut {
|
||||
ty: var_ty,
|
||||
@ -865,11 +851,10 @@ fn overloaded_lvalue<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
// construct the complete expression `foo()` for the overloaded call,
|
||||
// which will yield the &T type
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(expr.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
|
||||
let fun = method_callee(cx, expr, custom_callee);
|
||||
let ref_expr = Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: ref_ty,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Call {
|
||||
@ -894,11 +879,10 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
closure_expr_id: closure_expr.id,
|
||||
};
|
||||
let upvar_capture = cx.tables().upvar_capture(upvar_id).unwrap();
|
||||
let (temp_lifetime, was_shrunk) = cx.region_maps.temporary_scope2(closure_expr.id);
|
||||
let temp_lifetime = cx.region_maps.temporary_scope(closure_expr.id);
|
||||
let var_ty = cx.tables().node_id_to_type(id_var);
|
||||
let captured_var = Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: var_ty,
|
||||
span: closure_expr.span,
|
||||
kind: convert_var(cx, closure_expr, freevar.def),
|
||||
@ -913,7 +897,6 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
};
|
||||
Expr {
|
||||
temp_lifetime: temp_lifetime,
|
||||
temp_lifetime_was_shrunk: was_shrunk,
|
||||
ty: freevar_ty,
|
||||
span: closure_expr.span,
|
||||
kind: ExprKind::Borrow {
|
||||
|
@ -99,9 +99,6 @@ pub struct Expr<'tcx> {
|
||||
/// temporary; should be None only if in a constant context
|
||||
pub temp_lifetime: Option<CodeExtent>,
|
||||
|
||||
/// whether this temp lifetime was shrunk by #36082.
|
||||
pub temp_lifetime_was_shrunk: bool,
|
||||
|
||||
/// span of the expression in the source
|
||||
pub span: Span,
|
||||
|
||||
|
@ -911,7 +911,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
cmt: mc::cmt<'tcx>,
|
||||
span: Span) {
|
||||
match cmt.cat {
|
||||
Categorization::Rvalue(region, _) => {
|
||||
Categorization::Rvalue(region) => {
|
||||
match *region {
|
||||
ty::ReScope(rvalue_scope) => {
|
||||
let typ = self.resolve_type(cmt.ty);
|
||||
@ -1029,7 +1029,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
let arg_ty = self.node_ty(arg.id);
|
||||
let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
|
||||
let arg_cmt = mc.cat_rvalue(
|
||||
arg.id, arg.pat.span, re_scope, re_scope, arg_ty);
|
||||
arg.id, arg.pat.span, re_scope, arg_ty);
|
||||
debug!("arg_ty={:?} arg_cmt={:?} arg={:?}",
|
||||
arg_ty,
|
||||
arg_cmt,
|
||||
|
@ -16,12 +16,10 @@ fn main() {
|
||||
let x = RefCell::new((&mut r,s));
|
||||
|
||||
let val: &_ = x.borrow().0;
|
||||
//~^ WARNING this temporary used to live longer - see issue #39283
|
||||
//~^^ ERROR borrowed value does not live long enough
|
||||
//~^ ERROR borrowed value does not live long enough
|
||||
//~| temporary value dropped here while still borrowed
|
||||
//~| temporary value created here
|
||||
//~| consider using a `let` binding to increase its lifetime
|
||||
//~| before rustc 1.16, this temporary lived longer - see issue #39283
|
||||
println!("{}", val);
|
||||
}
|
||||
//~^ temporary value needs to live until here
|
||||
|
Loading…
x
Reference in New Issue
Block a user