From ed2a11da89252774fe15bd0eafdf94545ad4644f Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 12 Oct 2015 23:37:52 +0300 Subject: [PATCH] require a method callee's type to outlive the call This rather crucial requirement was not checked. In most cases, that didn't cause any trouble because the argument types are required to outlive the call and are subtypes of a subformula of the callee type. However, binary ops are taken by ref only indirectly, without it being marked in the argument types, which led to the argument types not being constrained anywhere causing spurious errors (as these are basically unconstrainable, I don't think this change can break code). Of course, the old way was also incorrent with contravariance, but that is still unsound for other reasons. This also improves rustc::front to get RUST_LOG to *somewhat* work. Fixes #28999 --- src/librustc/front/map/mod.rs | 5 ++++- src/librustc_typeck/check/regionck.rs | 4 ++++ src/test/run-pass/issue-28999.rs | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-28999.rs diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs index 396e2bb5703b1..9591ed2f71dff 100644 --- a/src/librustc/front/map/mod.rs +++ b/src/librustc/front/map/mod.rs @@ -527,6 +527,10 @@ impl<'ast> Map<'ast> { NodeTraitItem(ti) => PathName(ti.name), NodeVariant(v) => PathName(v.node.name), NodeLifetime(lt) => PathName(lt.name), + NodeTyParam(tp) => PathName(tp.name), + NodeLocal(&Pat { node: PatIdent(_,l,_), .. }) => { + PathName(l.node.name) + }, _ => panic!("no path elem for {:?}", node) } } @@ -987,4 +991,3 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { } } } - diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index c2610da3944cc..31e6c942dc697 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -592,6 +592,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { }; substs_wf_in_scope(rcx, origin, &callee.substs, expr.span, expr_region); + type_must_outlive(rcx, infer::ExprTypeIsNotInScope(callee.ty, expr.span), + callee.ty, expr_region); } // Check any autoderefs or autorefs that appear. @@ -664,6 +666,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { } } + debug!("regionck::visit_expr(e={:?}, repeating_scope={}) - visiting subexprs", + expr, rcx.repeating_scope); match expr.node { hir::ExprPath(..) => { rcx.fcx.opt_node_ty_substs(expr.id, |item_substs| { diff --git a/src/test/run-pass/issue-28999.rs b/src/test/run-pass/issue-28999.rs new file mode 100644 index 0000000000000..87112ef171981 --- /dev/null +++ b/src/test/run-pass/issue-28999.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct Xyz<'a, V> { + pub v: (V, &'a u32), +} + +pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool + where V: PartialEq { + this.v == other.v +} + +fn main() {}