mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-13 08:13:21 +00:00
Constrain operands to outlive the operation. Fixes #21422.
This commit is contained in:
parent
801bc48939
commit
f2529ac10d
@ -675,6 +675,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
sup,
|
||||
"");
|
||||
}
|
||||
infer::Operand(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"lifetime of operand does not outlive \
|
||||
the operation");
|
||||
note_and_explain_region(
|
||||
self.tcx,
|
||||
"the operand is only valid for ",
|
||||
sup,
|
||||
"");
|
||||
}
|
||||
infer::AddrOf(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
@ -1593,6 +1604,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
span,
|
||||
"...so that return value is valid for the call");
|
||||
}
|
||||
infer::Operand(span) => {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"...so that operand is valid for operation");
|
||||
}
|
||||
infer::AddrOf(span) => {
|
||||
self.tcx.sess.span_note(
|
||||
span,
|
||||
|
@ -210,6 +210,9 @@ pub enum SubregionOrigin<'tcx> {
|
||||
// Region in return type of invoked fn must enclose call
|
||||
CallReturn(Span),
|
||||
|
||||
// Operands must be in scope
|
||||
Operand(Span),
|
||||
|
||||
// Region resulting from a `&` expr must enclose the `&` expr
|
||||
AddrOf(Span),
|
||||
|
||||
@ -1195,6 +1198,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||
CallRcvr(a) => a,
|
||||
CallArg(a) => a,
|
||||
CallReturn(a) => a,
|
||||
Operand(a) => a,
|
||||
AddrOf(a) => a,
|
||||
AutoBorrow(a) => a,
|
||||
SafeDestructor(a) => a,
|
||||
@ -1258,6 +1262,7 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
|
||||
CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
|
||||
CallArg(a) => format!("CallArg({})", a.repr(tcx)),
|
||||
CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
|
||||
Operand(a) => format!("Operand({})", a.repr(tcx)),
|
||||
AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
|
||||
AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
|
||||
SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)),
|
||||
|
@ -610,6 +610,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||
// If you do `x OP y`, then the types of `x` and `y` must
|
||||
// outlive the operation you are performing.
|
||||
let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs);
|
||||
let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs);
|
||||
for &ty in [lhs_ty, rhs_ty].iter() {
|
||||
type_must_outlive(rcx,
|
||||
infer::Operand(expr.span),
|
||||
ty,
|
||||
ty::ReScope(CodeExtent::from_node_id(expr.id)));
|
||||
}
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
||||
ast::ExprUnary(op, ref lhs) if has_method_map => {
|
||||
let implicitly_ref_args = !ast_util::is_by_value_unop(op);
|
||||
|
||||
|
25
src/test/run-pass/regions-issue-21422.rs
Normal file
25
src/test/run-pass/regions-issue-21422.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Regression test for issue #21422, which was related to failing to
|
||||
// add inference constraints that the operands of a binary operator
|
||||
// should outlive the binary operation itself.
|
||||
|
||||
pub struct P<'a> {
|
||||
_ptr: *const &'a u8,
|
||||
}
|
||||
|
||||
impl <'a> PartialEq for P<'a> {
|
||||
fn eq(&self, other: &P<'a>) -> bool {
|
||||
(self as *const _) == (other as *const _)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user