mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
add closure requirement tests, improve debugging output
The overall format is now easier to read. Also, There is now graphviz output, as well as a `#[rustc_regions]` annotation that dumps internal state.
This commit is contained in:
parent
ab1c1bc6bc
commit
05441abd2b
@ -14,6 +14,7 @@ use rustc::infer::InferCtxt;
|
||||
use rustc::ty::{self, RegionKind, RegionVid};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::io;
|
||||
use transform::MirSource;
|
||||
use transform::type_check;
|
||||
use util::liveness::{self, LivenessMode, LivenessResult, LocalSet};
|
||||
@ -22,6 +23,7 @@ use dataflow::MaybeInitializedLvals;
|
||||
use dataflow::move_paths::MoveData;
|
||||
|
||||
use util as mir_util;
|
||||
use util::pretty::{self, ALIGN};
|
||||
use self::mir_util::PassWhere;
|
||||
|
||||
mod constraint_generation;
|
||||
@ -117,8 +119,19 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
||||
let closure_region_requirements = regioncx.solve(infcx, &mir, def_id);
|
||||
|
||||
// Dump MIR results into a file, if that is enabled. This let us
|
||||
// write unit-tests.
|
||||
dump_mir_results(infcx, liveness, MirSource::item(def_id), &mir, ®ioncx);
|
||||
// write unit-tests, as well as helping with debugging.
|
||||
dump_mir_results(
|
||||
infcx,
|
||||
liveness,
|
||||
MirSource::item(def_id),
|
||||
&mir,
|
||||
®ioncx,
|
||||
&closure_region_requirements,
|
||||
);
|
||||
|
||||
// We also have a `#[rustc_nll]` annotation that causes us to dump
|
||||
// information
|
||||
dump_annotation(infcx, &mir, def_id, ®ioncx, &closure_region_requirements);
|
||||
|
||||
(regioncx, closure_region_requirements)
|
||||
}
|
||||
@ -134,6 +147,7 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
regioncx: &RegionInferenceContext,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements>,
|
||||
) {
|
||||
if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
|
||||
return;
|
||||
@ -168,9 +182,17 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
mir_util::dump_mir(infcx.tcx, None, "nll", &0, source, mir, |pass_where, out| {
|
||||
match pass_where {
|
||||
// Before the CFG, dump out the values for each region variable.
|
||||
PassWhere::BeforeCFG => for region in regioncx.regions() {
|
||||
writeln!(out, "| {:?}: {}", region, regioncx.region_value_str(region))?;
|
||||
},
|
||||
PassWhere::BeforeCFG => {
|
||||
regioncx.dump_mir(out)?;
|
||||
|
||||
if let Some(closure_region_requirements) = closure_region_requirements {
|
||||
writeln!(out, "|")?;
|
||||
writeln!(out, "| Free Region Constraints")?;
|
||||
for_each_region_constraint(closure_region_requirements, &mut |msg| {
|
||||
writeln!(out, "| {}", msg)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
// Before each basic block, dump out the values
|
||||
// that are live on entry to the basic block.
|
||||
@ -184,13 +206,90 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
®ular_liveness_per_location[&location],
|
||||
&drop_liveness_per_location[&location],
|
||||
);
|
||||
writeln!(out, " | Live variables at {:?}: {}", location, s)?;
|
||||
writeln!(
|
||||
out,
|
||||
"{:ALIGN$} | Live variables on entry to {:?}: {}",
|
||||
"",
|
||||
location,
|
||||
s,
|
||||
ALIGN = ALIGN
|
||||
)?;
|
||||
}
|
||||
|
||||
PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// Also dump the inference graph constraints as a graphviz file.
|
||||
let _: io::Result<()> = do catch {
|
||||
let mut file =
|
||||
pretty::create_dump_file(infcx.tcx, "regioncx.dot", None, "nll", &0, source)?;
|
||||
regioncx.dump_graphviz(&mut file)
|
||||
};
|
||||
}
|
||||
|
||||
fn dump_annotation<'a, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
regioncx: &RegionInferenceContext,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements>,
|
||||
) {
|
||||
let tcx = infcx.tcx;
|
||||
let base_def_id = tcx.closure_base_def_id(mir_def_id);
|
||||
if !tcx.has_attr(base_def_id, "rustc_regions") {
|
||||
return;
|
||||
}
|
||||
|
||||
// When the enclosing function is tagged with `#[rustc_regions]`,
|
||||
// we dump out various bits of state as warnings. This is useful
|
||||
// for verifying that the compiler is behaving as expected. These
|
||||
// warnings focus on the closure region requirements -- for
|
||||
// viewing the intraprocedural state, the -Zdump-mir output is
|
||||
// better.
|
||||
|
||||
if let Some(closure_region_requirements) = closure_region_requirements {
|
||||
let mut err = tcx.sess
|
||||
.diagnostic()
|
||||
.span_note_diag(mir.span, "External requirements");
|
||||
|
||||
regioncx.annotate(&mut err);
|
||||
|
||||
err.note(&format!(
|
||||
"number of external vids: {}",
|
||||
closure_region_requirements.num_external_vids
|
||||
));
|
||||
|
||||
// Dump the region constraints we are imposing *between* those
|
||||
// newly created variables.
|
||||
for_each_region_constraint(closure_region_requirements, &mut |msg| {
|
||||
err.note(msg);
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
|
||||
err.emit();
|
||||
} else {
|
||||
let mut err = tcx.sess
|
||||
.diagnostic()
|
||||
.span_note_diag(mir.span, "No external requirements");
|
||||
regioncx.annotate(&mut err);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn for_each_region_constraint(
|
||||
closure_region_requirements: &ClosureRegionRequirements,
|
||||
with_msg: &mut FnMut(&str) -> io::Result<()>,
|
||||
) -> io::Result<()> {
|
||||
for req in &closure_region_requirements.outlives_requirements {
|
||||
with_msg(&format!(
|
||||
"where {:?}: {:?}",
|
||||
req.free_region,
|
||||
req.outlived_free_region,
|
||||
))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Right now, we piggy back on the `ReVar` to store our NLL inference
|
||||
|
48
src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
Normal file
48
src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
//! As part of the NLL unit tests, you can annotate a function with
|
||||
//! `#[rustc_regions]`, and we will emit information about the region
|
||||
//! inference context and -- in particular -- the external constraints
|
||||
//! that this region imposes on others. The methods in this file
|
||||
//! handle the part about dumping the inference context internal
|
||||
//! state.
|
||||
|
||||
use rustc::ty;
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
impl<'gcx, 'tcx> RegionInferenceContext<'tcx> {
|
||||
/// Write out our state into the `.mir` files.
|
||||
pub(crate) fn annotate(&self, err: &mut DiagnosticBuilder<'_>) {
|
||||
match self.universal_regions.defining_ty.sty {
|
||||
ty::TyClosure(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
"defining type: {:?} with closure substs {:#?}",
|
||||
def_id,
|
||||
&substs.substs[..]
|
||||
));
|
||||
}
|
||||
ty::TyFnDef(def_id, substs) => {
|
||||
err.note(&format!(
|
||||
"defining type: {:?} with substs {:#?}",
|
||||
def_id,
|
||||
&substs[..]
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
err.note(&format!(
|
||||
"defining type: {:?}",
|
||||
self.universal_regions.defining_ty
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
100
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
Normal file
100
src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
//! As part of generating the regions, if you enable `-Zdump-mir=nll`,
|
||||
//! we will generate an annotated copy of the MIR that includes the
|
||||
//! state of region inference. This code handles emitting the region
|
||||
//! context internal state.
|
||||
|
||||
use std::io::{self, Write};
|
||||
use super::{Constraint, RegionInferenceContext};
|
||||
|
||||
// Room for "'_#NNNNr" before things get misaligned.
|
||||
// Easy enough to fix if this ever doesn't seem like
|
||||
// enough.
|
||||
const REGION_WIDTH: usize = 8;
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
/// Write out our state into the `.mir` files.
|
||||
pub(crate) fn dump_mir(&self, out: &mut Write) -> io::Result<()> {
|
||||
writeln!(out, "| Free Region Mapping")?;
|
||||
|
||||
for region in self.regions() {
|
||||
if self.definitions[region].is_universal {
|
||||
let classification = self.universal_regions.region_classification(region).unwrap();
|
||||
let outlived_by = self.universal_regions.regions_outlived_by(region);
|
||||
writeln!(
|
||||
out,
|
||||
"| {r:rw$} | {c:cw$} | {ob}",
|
||||
r = format!("{:?}", region),
|
||||
rw = REGION_WIDTH,
|
||||
c = format!("{:?}", classification),
|
||||
cw = 8, // "External" at most
|
||||
ob = format!("{:?}", outlived_by)
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(out, "|")?;
|
||||
writeln!(out, "| Inferred Region Values")?;
|
||||
for region in self.regions() {
|
||||
writeln!(
|
||||
out,
|
||||
"| {r:rw$} | {v}",
|
||||
r = format!("{:?}", region),
|
||||
rw = REGION_WIDTH,
|
||||
v = self.region_value_str(region),
|
||||
)?;
|
||||
}
|
||||
|
||||
writeln!(out, "|")?;
|
||||
writeln!(out, "| Inference Constraints")?;
|
||||
self.for_each_constraint(&mut |msg| writeln!(out, "| {}", msg))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Debugging aid: Invokes the `with_msg` callback repeatedly with
|
||||
/// our internal region constraints. These are dumped into the
|
||||
/// -Zdump-mir file so that we can figure out why the region
|
||||
/// inference resulted in the values that it did when debugging.
|
||||
fn for_each_constraint(
|
||||
&self,
|
||||
with_msg: &mut FnMut(&str) -> io::Result<()>,
|
||||
) -> io::Result<()> {
|
||||
for region in self.definitions.indices() {
|
||||
let value = self.region_value_str_from_matrix(&self.liveness_constraints, region);
|
||||
if value != "{}" {
|
||||
with_msg(&format!("{:?} live at {}", region, value))?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut constraints: Vec<_> = self.constraints.iter().collect();
|
||||
constraints.sort();
|
||||
for constraint in &constraints {
|
||||
let Constraint {
|
||||
sup,
|
||||
sub,
|
||||
point,
|
||||
span,
|
||||
} = constraint;
|
||||
with_msg(&format!(
|
||||
"{:?}: {:?} @ {:?} due to {:?}",
|
||||
sup,
|
||||
sub,
|
||||
point,
|
||||
span
|
||||
))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
71
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
Normal file
71
src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! This module provides linkage between RegionInferenceContext and
|
||||
//! libgraphviz traits, specialized to attaching borrowck analysis
|
||||
//! data to rendered labels.
|
||||
|
||||
use dot::{self, IntoCow};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::borrow::Cow;
|
||||
use std::io::{self, Write};
|
||||
use super::*;
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
/// Write out the region constraint graph.
|
||||
pub(crate) fn dump_graphviz(&self, mut w: &mut Write) -> io::Result<()> {
|
||||
dot::render(self, &mut w)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'this, 'tcx> dot::Labeller<'this> for RegionInferenceContext<'tcx> {
|
||||
type Node = RegionVid;
|
||||
type Edge = Constraint;
|
||||
|
||||
fn graph_id(&'this self) -> dot::Id<'this> {
|
||||
dot::Id::new(format!("RegionInferenceContext")).unwrap()
|
||||
}
|
||||
fn node_id(&'this self, n: &RegionVid) -> dot::Id<'this> {
|
||||
dot::Id::new(format!("r{}", n.index())).unwrap()
|
||||
}
|
||||
fn node_shape(&'this self, _node: &RegionVid) -> Option<dot::LabelText<'this>> {
|
||||
Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
|
||||
}
|
||||
fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
|
||||
dot::LabelText::LabelStr(format!("{:?}", n).into_cow())
|
||||
}
|
||||
fn edge_label(&'this self, e: &Constraint) -> dot::LabelText<'this> {
|
||||
dot::LabelText::LabelStr(format!("{:?}", e.point).into_cow())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'this, 'tcx> dot::GraphWalk<'this> for RegionInferenceContext<'tcx> {
|
||||
type Node = RegionVid;
|
||||
type Edge = Constraint;
|
||||
|
||||
fn nodes(&'this self) -> dot::Nodes<'this, RegionVid> {
|
||||
let vids: Vec<RegionVid> = self.definitions.indices().collect();
|
||||
vids.into_cow()
|
||||
}
|
||||
fn edges(&'this self) -> dot::Edges<'this, Constraint> {
|
||||
(&self.constraints[..]).into_cow()
|
||||
}
|
||||
|
||||
// Render `a: b` as `a <- b`, indicating the flow
|
||||
// of data during inference.
|
||||
|
||||
fn source(&'this self, edge: &Constraint) -> RegionVid {
|
||||
edge.sub
|
||||
}
|
||||
|
||||
fn target(&'this self, edge: &Constraint) -> RegionVid {
|
||||
edge.sup
|
||||
}
|
||||
}
|
@ -25,6 +25,10 @@ use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use syntax_pos::Span;
|
||||
|
||||
mod annotation;
|
||||
mod dump_mir;
|
||||
mod graphviz;
|
||||
|
||||
pub struct RegionInferenceContext<'tcx> {
|
||||
/// Contains the definition for every region variable. Region
|
||||
/// variables are identified by their index (`RegionVid`). The
|
||||
|
@ -717,6 +717,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
||||
is just used for rustc unit tests \
|
||||
and will never be stable",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
("rustc_regions", Normal, Gated(Stability::Unstable,
|
||||
"rustc_attrs",
|
||||
"the `#[rustc_regions]` attribute \
|
||||
is just used for rustc unit tests \
|
||||
and will never be stable",
|
||||
cfg_fn!(rustc_attrs))),
|
||||
("rustc_error", Whitelisted, Gated(Stability::Unstable,
|
||||
"rustc_attrs",
|
||||
"the `#[rustc_error]` attribute \
|
||||
|
@ -28,18 +28,18 @@ fn main() {
|
||||
// START rustc.main.nll.0.mir
|
||||
// | Live variables on entry to bb0: []
|
||||
// bb0: {
|
||||
// | Live variables at bb0[0]: []
|
||||
// | Live variables on entry to bb0[0]: []
|
||||
// StorageLive(_1);
|
||||
// | Live variables at bb0[1]: []
|
||||
// | Live variables on entry to bb0[1]: []
|
||||
// _1 = const <std::boxed::Box<T>>::new(const 22usize) -> [return: bb2, unwind: bb1];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// | Live variables on entry to bb2: [_1 (drop)]
|
||||
// bb2: {
|
||||
// | Live variables at bb2[0]: [_1 (drop)]
|
||||
// | Live variables on entry to bb2[0]: [_1 (drop)]
|
||||
// StorageLive(_2);
|
||||
// | Live variables at bb2[1]: [_1 (drop)]
|
||||
// | Live variables on entry to bb2[1]: [_1 (drop)]
|
||||
// _2 = const can_panic() -> [return: bb3, unwind: bb4];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -27,15 +27,15 @@ fn main() {
|
||||
// START rustc.main.nll.0.mir
|
||||
// | Live variables on entry to bb2: []
|
||||
// bb2: {
|
||||
// | Live variables at bb2[0]: []
|
||||
// | Live variables on entry to bb2[0]: []
|
||||
// _1 = const 55usize;
|
||||
// | Live variables at bb2[1]: [_1]
|
||||
// | Live variables on entry to bb2[1]: [_1]
|
||||
// StorageLive(_3);
|
||||
// | Live variables at bb2[2]: [_1]
|
||||
// | Live variables on entry to bb2[2]: [_1]
|
||||
// StorageLive(_4);
|
||||
// | Live variables at bb2[3]: [_1]
|
||||
// | Live variables on entry to bb2[3]: [_1]
|
||||
// _4 = _1;
|
||||
// | Live variables at bb2[4]: [_4]
|
||||
// | Live variables on entry to bb2[4]: [_4]
|
||||
// _3 = const use_x(move _4) -> [return: bb3, unwind: bb1];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -31,18 +31,18 @@ fn main() {
|
||||
// START rustc.main.nll.0.mir
|
||||
// | Live variables on entry to bb3: [_1]
|
||||
// bb3: {
|
||||
// | Live variables at bb3[0]: [_1]
|
||||
// | Live variables on entry to bb3[0]: [_1]
|
||||
// StorageLive(_4);
|
||||
// | Live variables at bb3[1]: [_1]
|
||||
// | Live variables on entry to bb3[1]: [_1]
|
||||
// _4 = _1;
|
||||
// | Live variables at bb3[2]: [_4]
|
||||
// | Live variables on entry to bb3[2]: [_4]
|
||||
// _3 = const make_live(move _4) -> [return: bb5, unwind: bb1];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// | Live variables on entry to bb4: []
|
||||
// bb4: {
|
||||
// | Live variables at bb4[0]: []
|
||||
// | Live variables on entry to bb4[0]: []
|
||||
// _5 = const make_dead() -> [return: bb6, unwind: bb1];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -26,9 +26,18 @@ fn main() {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.use_x.nll.0.mir
|
||||
// | '_#0r: {bb0[0], bb0[1], '_#0r}
|
||||
// | '_#1r: {bb0[0], bb0[1], '_#1r}
|
||||
// | '_#2r: {bb0[0], bb0[1], '_#2r}
|
||||
// | '_#3r: {bb0[0], bb0[1], '_#3r}
|
||||
// | Free Region Mapping
|
||||
// | '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#3r]
|
||||
// | '_#1r | External | ['_#1r]
|
||||
// | '_#2r | External | ['_#2r, '_#1r]
|
||||
// | '_#3r | Local | ['_#3r]
|
||||
// |
|
||||
// | Inferred Region Values
|
||||
// | '_#0r | {bb0[0], bb0[1], '_#0r}
|
||||
// | '_#1r | {bb0[0], bb0[1], '_#1r}
|
||||
// | '_#2r | {bb0[0], bb0[1], '_#2r}
|
||||
// | '_#3r | {bb0[0], bb0[1], '_#3r}
|
||||
// |
|
||||
// ...
|
||||
// fn use_x(_1: &'_#1r mut i32, _2: &'_#2r u32, _3: &'_#1r u32, _4: &'_#3r u32) -> bool {
|
||||
// END rustc.use_x.nll.0.mir
|
||||
|
@ -28,11 +28,10 @@ fn main() {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#6r: {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
|
||||
// | '_#6r | {bb0[6], bb0[7], bb0[8], bb0[9], bb0[10], bb0[11], bb0[12], bb0[13], bb0[14]}
|
||||
// ...
|
||||
// | '_#8r | {bb0[11], bb0[12], bb0[13], bb0[14]}
|
||||
// ...
|
||||
// | '_#8r: {bb0[11], bb0[12], bb0[13], bb0[14]}
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// let _2: &'_#6r mut i32;
|
||||
// ...
|
||||
// let _4: &'_#8r mut i32;
|
||||
|
@ -31,26 +31,26 @@ fn main() {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#1r: {bb2[0], bb2[1], bb3[0], bb3[1]}
|
||||
// | '_#2r: {bb2[1], bb3[0], bb3[1]}
|
||||
// | '_#1r | {bb2[0], bb2[1], bb3[0], bb3[1]}
|
||||
// | '_#2r | {bb2[1], bb3[0], bb3[1]}
|
||||
// ...
|
||||
// let _2: &'_#2r usize;
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// bb2: {
|
||||
// | Live variables at bb2[0]: [_1, _3]
|
||||
// | Live variables on entry to bb2[0]: [_1, _3]
|
||||
// _2 = &'_#1r _1[_3];
|
||||
// | Live variables at bb2[1]: [_2]
|
||||
// | Live variables on entry to bb2[1]: [_2]
|
||||
// switchInt(const true) -> [0u8: bb4, otherwise: bb3];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// bb3: {
|
||||
// | Live variables at bb3[0]: [_2]
|
||||
// | Live variables on entry to bb3[0]: [_2]
|
||||
// StorageLive(_7);
|
||||
// | Live variables at bb3[1]: [_2]
|
||||
// | Live variables on entry to bb3[1]: [_2]
|
||||
// _7 = (*_2);
|
||||
// | Live variables at bb3[2]: [_7]
|
||||
// | Live variables on entry to bb3[2]: [_7]
|
||||
// _6 = const use_x(move _7) -> [return: bb5, unwind: bb1];
|
||||
// }
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -44,5 +44,5 @@ unsafe impl<#[may_dangle] T> Drop for Wrap<T> {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#5r: {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1]}
|
||||
// | '_#5r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1]}
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -46,5 +46,5 @@ impl<T> Drop for Wrap<T> {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#5r: {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1], bb3[2], bb4[0], bb5[0], bb5[1], bb5[2], bb6[0], bb7[0], bb7[1], bb8[0]}
|
||||
// | '_#5r | {bb2[3], bb2[4], bb2[5], bb3[0], bb3[1], bb3[2], bb4[0], bb5[0], bb5[1], bb5[2], bb6[0], bb7[0], bb7[1], bb8[0]}
|
||||
// END rustc.main.nll.0.mir
|
||||
|
@ -36,10 +36,10 @@ fn main() {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#1r: {bb2[0], bb2[1], bb3[0], bb3[1]}
|
||||
// | '_#1r | {bb2[0], bb2[1], bb3[0], bb3[1]}
|
||||
// ...
|
||||
// | '_#3r: {bb8[1], bb8[2], bb8[3], bb8[4]}
|
||||
// | '_#4r: {bb2[1], bb3[0], bb3[1], bb8[2], bb8[3], bb8[4]}
|
||||
// | '_#3r | {bb8[1], bb8[2], bb8[3], bb8[4]}
|
||||
// | '_#4r | {bb2[1], bb3[0], bb3[1], bb8[2], bb8[3], bb8[4]}
|
||||
// ...
|
||||
// let mut _2: &'_#4r usize;
|
||||
// ...
|
||||
|
@ -32,9 +32,9 @@ fn main() {
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.nll.0.mir
|
||||
// | '_#1r: {bb2[0], bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// | '_#2r: {bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// | '_#3r: {bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// | '_#1r | {bb2[0], bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// | '_#2r | {bb2[1], bb2[2], bb2[3], bb2[4], bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// | '_#3r | {bb2[5], bb2[6], bb3[0], bb3[1]}
|
||||
// END rustc.main.nll.0.mir
|
||||
// START rustc.main.nll.0.mir
|
||||
// let _2: &'_#2r usize;
|
||||
|
50
src/test/ui/nll/capture-ref-in-struct.rs
Normal file
50
src/test/ui/nll/capture-ref-in-struct.rs
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir
|
||||
|
||||
// Test that a structure which tries to store a pointer to `y` into
|
||||
// `p` (indirectly) fails to compile.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct SomeStruct<'a, 'b: 'a> {
|
||||
p: &'a mut &'b i32,
|
||||
y: &'b i32,
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let x = 44;
|
||||
let mut p = &x;
|
||||
|
||||
{
|
||||
let y = 22;
|
||||
|
||||
let closure = SomeStruct {
|
||||
p: &mut p,
|
||||
y: &y,
|
||||
};
|
||||
|
||||
closure.invoke();
|
||||
}
|
||||
//~^ ERROR borrowed value does not live long enough [E0597]
|
||||
|
||||
deref(p);
|
||||
}
|
||||
|
||||
impl<'a, 'b> SomeStruct<'a, 'b> {
|
||||
fn invoke(self) {
|
||||
*self.p = self.y;
|
||||
}
|
||||
}
|
||||
|
||||
fn deref(_: &i32) { }
|
||||
|
||||
fn main() { }
|
13
src/test/ui/nll/capture-ref-in-struct.stderr
Normal file
13
src/test/ui/nll/capture-ref-in-struct.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/capture-ref-in-struct.rs:36:6
|
||||
|
|
||||
28 | let y = 22;
|
||||
| - temporary value created here
|
||||
...
|
||||
36 | }
|
||||
| ^ temporary value dropped here while still borrowed
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,48 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test closure that:
|
||||
//
|
||||
// - takes an argument `y`
|
||||
// - stores `y` into another, longer-lived spot
|
||||
//
|
||||
// *but* the signature of the closure doesn't indicate that `y` lives
|
||||
// long enough for that. The closure reports the error (and hence we
|
||||
// see it before the closure's "external requirements" report).
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_regions]
|
||||
fn test() {
|
||||
let x = 44;
|
||||
let mut p = &x;
|
||||
|
||||
{
|
||||
let y = 22;
|
||||
let mut closure = expect_sig(|p, y| *p = y);
|
||||
//~^ ERROR free region `'_#4r` does not outlive free region `'_#3r`
|
||||
//~| WARNING not reporting region error due to -Znll
|
||||
closure(&mut p, &y);
|
||||
}
|
||||
|
||||
deref(p);
|
||||
}
|
||||
|
||||
fn expect_sig<F>(f: F) -> F
|
||||
where F: FnMut(&mut &i32, &i32)
|
||||
{
|
||||
f
|
||||
}
|
||||
|
||||
fn deref(_p: &i32) { }
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,40 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/escape-argument-callee.rs:31:50
|
||||
|
|
||||
31 | let mut closure = expect_sig(|p, y| *p = y);
|
||||
| ^
|
||||
|
||||
error: free region `'_#4r` does not outlive free region `'_#3r`
|
||||
--> $DIR/escape-argument-callee.rs:31:45
|
||||
|
|
||||
31 | let mut closure = expect_sig(|p, y| *p = y);
|
||||
| ^^^^^^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/escape-argument-callee.rs:31:38
|
||||
|
|
||||
31 | let mut closure = expect_sig(|p, y| *p = y);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: defining type: DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7666))) mut &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7667))) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0(7668))) i32))
|
||||
]
|
||||
= note: number of external vids: 1
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/escape-argument-callee.rs:25:1
|
||||
|
|
||||
25 | / fn test() {
|
||||
26 | | let x = 44;
|
||||
27 | | let mut p = &x;
|
||||
28 | |
|
||||
... |
|
||||
37 | | deref(p);
|
||||
38 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:3 ~ escape_argument_callee[317d]::test[0]) with substs []
|
||||
|
||||
error: aborting due to previous error
|
||||
|
50
src/test/ui/nll/closure-requirements/escape-argument.rs
Normal file
50
src/test/ui/nll/closure-requirements/escape-argument.rs
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test closure that:
|
||||
//
|
||||
// - takes an argument `y`
|
||||
// - stores `y` into another, longer-lived spot
|
||||
//
|
||||
// but is invoked with a spot that doesn't live long
|
||||
// enough to store `y`.
|
||||
//
|
||||
// The error is reported in the caller: invoking the closure links the
|
||||
// lifetime of the borrow that is given as `y` and forces it to live
|
||||
// too long.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_regions]
|
||||
fn test() {
|
||||
let x = 44;
|
||||
let mut p = &x;
|
||||
|
||||
{
|
||||
let y = 22;
|
||||
let mut closure = expect_sig(|p, y| *p = y);
|
||||
closure(&mut p, &y);
|
||||
}
|
||||
//~^ ERROR borrowed value does not live long enough [E0597]
|
||||
|
||||
deref(p);
|
||||
}
|
||||
|
||||
fn expect_sig<F>(f: F) -> F
|
||||
where F: for<'a, 'b> FnMut(&'a mut &'b i32, &'b i32)
|
||||
{
|
||||
f
|
||||
}
|
||||
|
||||
fn deref(_p: &i32) { }
|
||||
|
||||
fn main() { }
|
39
src/test/ui/nll/closure-requirements/escape-argument.stderr
Normal file
39
src/test/ui/nll/closure-requirements/escape-argument.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
note: External requirements
|
||||
--> $DIR/escape-argument.rs:34:38
|
||||
|
|
||||
34 | let mut closure = expect_sig(|p, y| *p = y);
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: defining type: DefId(0/1:9 ~ escape_argument[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(8634))) mut &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(8635))) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(8635))) i32))
|
||||
]
|
||||
= note: number of external vids: 1
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/escape-argument.rs:28:1
|
||||
|
|
||||
28 | / fn test() {
|
||||
29 | | let x = 44;
|
||||
30 | | let mut p = &x;
|
||||
31 | |
|
||||
... |
|
||||
39 | | deref(p);
|
||||
40 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:3 ~ escape_argument[317d]::test[0]) with substs []
|
||||
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/escape-argument.rs:36:6
|
||||
|
|
||||
33 | let y = 22;
|
||||
| - temporary value created here
|
||||
...
|
||||
36 | }
|
||||
| ^ temporary value dropped here while still borrowed
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
43
src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
Normal file
43
src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// As in via-upvar, test closure that:
|
||||
//
|
||||
// - captures a variable `y`
|
||||
// - stores reference to `y` into another, longer-lived spot
|
||||
//
|
||||
// except that the closure does so via a second closure.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_regions]
|
||||
fn test() {
|
||||
let x = 44;
|
||||
let mut p = &x;
|
||||
|
||||
{
|
||||
let y = 22;
|
||||
|
||||
let mut closure = || {
|
||||
let mut closure1 = || p = &y;
|
||||
closure1();
|
||||
};
|
||||
|
||||
closure();
|
||||
} //~ ERROR borrowed value does not live long enough
|
||||
|
||||
deref(p);
|
||||
}
|
||||
|
||||
fn deref(_p: &i32) { }
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,61 @@
|
||||
note: External requirements
|
||||
--> $DIR/escape-upvar-nested.rs:31:32
|
||||
|
|
||||
31 | let mut closure1 = || p = &y;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: defining type: DefId(0/1:10 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
extern "rust-call" fn(()),
|
||||
&'_#1r mut &'_#2r i32,
|
||||
&'_#3r i32
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where '_#3r: '_#2r
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/escape-upvar-nested.rs:30:27
|
||||
|
|
||||
30 | let mut closure = || {
|
||||
| ___________________________^
|
||||
31 | | let mut closure1 = || p = &y;
|
||||
32 | | closure1();
|
||||
33 | | };
|
||||
| |_________^
|
||||
|
|
||||
= note: defining type: DefId(0/1:9 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
extern "rust-call" fn(()),
|
||||
&'_#1r mut &'_#2r i32,
|
||||
&'_#3r i32
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where '_#3r: '_#2r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/escape-upvar-nested.rs:23:1
|
||||
|
|
||||
23 | / fn test() {
|
||||
24 | | let x = 44;
|
||||
25 | | let mut p = &x;
|
||||
26 | |
|
||||
... |
|
||||
38 | | deref(p);
|
||||
39 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:3 ~ escape_upvar_nested[317d]::test[0]) with substs []
|
||||
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/escape-upvar-nested.rs:36:6
|
||||
|
|
||||
28 | let y = 22;
|
||||
| - temporary value created here
|
||||
...
|
||||
36 | } //~ ERROR borrowed value does not live long enough
|
||||
| ^ temporary value dropped here while still borrowed
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
35
src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
Normal file
35
src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test closure that:
|
||||
// - captures a variable `y`
|
||||
// - stores reference to `y` into another, longer-lived spot
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_regions]
|
||||
fn test() {
|
||||
let x = 44;
|
||||
let mut p = &x;
|
||||
|
||||
{
|
||||
let y = 22;
|
||||
let mut closure = || p = &y;
|
||||
closure();
|
||||
} //~ ERROR borrowed value does not live long enough
|
||||
|
||||
deref(p);
|
||||
}
|
||||
|
||||
fn deref(_p: &i32) { }
|
||||
|
||||
fn main() { }
|
42
src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
Normal file
42
src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
Normal file
@ -0,0 +1,42 @@
|
||||
note: External requirements
|
||||
--> $DIR/escape-upvar-ref.rs:26:27
|
||||
|
|
||||
26 | let mut closure = || p = &y;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: defining type: DefId(0/1:9 ~ escape_upvar_ref[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
extern "rust-call" fn(()),
|
||||
&'_#1r mut &'_#2r i32,
|
||||
&'_#3r i32
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
= note: where '_#3r: '_#2r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/escape-upvar-ref.rs:20:1
|
||||
|
|
||||
20 | / fn test() {
|
||||
21 | | let x = 44;
|
||||
22 | | let mut p = &x;
|
||||
23 | |
|
||||
... |
|
||||
30 | | deref(p);
|
||||
31 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:3 ~ escape_upvar_ref[317d]::test[0]) with substs []
|
||||
|
||||
error[E0597]: borrowed value does not live long enough
|
||||
--> $DIR/escape-upvar-ref.rs:28:6
|
||||
|
|
||||
25 | let y = 22;
|
||||
| - temporary value created here
|
||||
...
|
||||
28 | } //~ ERROR borrowed value does not live long enough
|
||||
| ^ temporary value dropped here while still borrowed
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,63 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test where we fail to approximate due to demanding a postdom
|
||||
// relationship between our upper bounds.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Callee knows that:
|
||||
//
|
||||
// 'x: 'a
|
||||
// 'x: 'b
|
||||
// 'c: 'y
|
||||
//
|
||||
// we have to prove that `'x: 'y`. We currently can only approximate
|
||||
// via a postdominator -- hence we fail to choose between `'a` and
|
||||
// `'b` here and report the error in the closure.
|
||||
fn establish_relationships<'a, 'b, 'c, F>(
|
||||
_cell_a: Cell<&'a u32>,
|
||||
_cell_b: Cell<&'b u32>,
|
||||
_cell_c: Cell<&'c u32>,
|
||||
_closure: F,
|
||||
) where
|
||||
F: for<'x, 'y> FnMut(
|
||||
Cell<&'a &'x u32>, // shows that 'x: 'a
|
||||
Cell<&'b &'x u32>, // shows that 'x: 'b
|
||||
Cell<&'y &'c u32>, // shows that 'c: 'y
|
||||
Cell<&'x u32>,
|
||||
Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) {
|
||||
establish_relationships(
|
||||
cell_a,
|
||||
cell_b,
|
||||
cell_c,
|
||||
|_outlives1, _outlives2, _outlives3, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
let p = x.get();
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
demand_y(x, y, p)
|
||||
//~^ ERROR free region `'_#5r` does not outlive free region `'_#6r`
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,46 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
|
||||
|
|
||||
55 | let p = x.get();
|
||||
| ^^^^^^^
|
||||
|
||||
error: free region `'_#5r` does not outlive free region `'_#6r`
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:57:25
|
||||
|
|
||||
57 | demand_y(x, y, p)
|
||||
| ^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
|
||||
|
|
||||
53 | / |_outlives1, _outlives2, _outlives3, x, y| {
|
||||
54 | | // Only works if 'x: 'y:
|
||||
55 | | let p = x.get();
|
||||
56 | | //~^ WARN not reporting region error due to -Znll
|
||||
57 | | demand_y(x, y, p)
|
||||
58 | | //~^ ERROR free region `'_#5r` does not outlive free region `'_#6r`
|
||||
59 | | },
|
||||
| |_________^
|
||||
|
|
||||
= note: defining type: DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9523))) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9523))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9524))) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9523))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9524))) u32>))
|
||||
]
|
||||
= note: number of external vids: 4
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:48:1
|
||||
|
|
||||
48 | / fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) {
|
||||
49 | | establish_relationships(
|
||||
50 | | cell_a,
|
||||
51 | | cell_b,
|
||||
... |
|
||||
60 | | );
|
||||
61 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]) with substs []
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,64 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Rather convoluted setup where we infer a relationship between two
|
||||
// free regions in the closure signature (`'a` and `'b`) on the basis
|
||||
// of a relationship between two bound regions (`'x` and `'y`).
|
||||
//
|
||||
// The idea is that, thanks to invoking `demand_y`, `'x: 'y` must
|
||||
// hold, where `'x` and `'y` are bound regions. The closure can't
|
||||
// prove that directly, and because `'x` and `'y` are bound it cannot
|
||||
// ask the caller to prove it either. But it has bounds on `'x` and
|
||||
// `'y` in terms of `'a` and `'b`, and it can propagate a relationship
|
||||
// between `'a` and `'b` to the caller.
|
||||
//
|
||||
// Note: the use of `Cell` here is to introduce invariance. One less
|
||||
// variable.
|
||||
//
|
||||
// FIXME: The `supply` function *ought* to generate an error, but it
|
||||
// currently does not. This is I believe a shortcoming of the MIR type
|
||||
// checker: the closure inference is expressing the correct
|
||||
// requirement, as you can see from the `#[rustc_regions]` output.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Callee knows that:
|
||||
//
|
||||
// 'x: 'a
|
||||
// 'b: 'y
|
||||
//
|
||||
// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must
|
||||
// hold.
|
||||
fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F)
|
||||
where
|
||||
F: for<'x, 'y> FnMut(
|
||||
&Cell<&'a &'x u32>, // shows that 'x: 'a
|
||||
&Cell<&'y &'b u32>, // shows that 'b: 'y
|
||||
&Cell<&'x u32>,
|
||||
&Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
demand_y(x, y, x.get())
|
||||
});
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,36 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-approximated-ref.rs:60:9
|
||||
|
|
||||
60 | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-approximated-ref.rs:58:47
|
||||
|
|
||||
58 | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
| _______________________________________________^
|
||||
59 | | // Only works if 'x: 'y:
|
||||
60 | | demand_y(x, y, x.get())
|
||||
61 | | });
|
||||
| |_____^
|
||||
|
|
||||
= note: defining type: DefId(0/1:18 ~ propagate_approximated_ref[317d]::supply[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7696))) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7697))) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0(7698))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1(7699))) &'_#2r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2(9524))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7697))) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't3(9525))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1(7699))) u32>))
|
||||
]
|
||||
= note: number of external vids: 3
|
||||
= note: where '_#1r: '_#2r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-ref.rs:57:1
|
||||
|
|
||||
57 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
58 | | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||
59 | | // Only works if 'x: 'y:
|
||||
60 | | demand_y(x, y, x.get())
|
||||
61 | | });
|
||||
62 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]) with substs []
|
||||
|
@ -0,0 +1,47 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test a case where we fail to approximate one of the regions and
|
||||
// hence report an error while checking the closure.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Callee knows that:
|
||||
//
|
||||
// 'b: 'y
|
||||
//
|
||||
// but this doesn't really help us in proving that `'x: 'y`, so closure gets an error.
|
||||
fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F)
|
||||
where
|
||||
F: for<'x, 'y> FnMut(
|
||||
&Cell<&'y &'b u32>, // shows that 'b: 'y
|
||||
&Cell<&'x u32>,
|
||||
&Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
demand_y(x, y, x.get())
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR free region `'_#6r` does not outlive free region `'_#4r`
|
||||
});
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,46 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-approximated-to-empty.rs:41:9
|
||||
|
|
||||
41 | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: free region `'_#6r` does not outlive free region `'_#4r`
|
||||
--> $DIR/propagate-approximated-to-empty.rs:41:21
|
||||
|
|
||||
41 | demand_y(x, y, x.get())
|
||||
| ^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-approximated-to-empty.rs:39:47
|
||||
|
|
||||
39 | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
| _______________________________________________^
|
||||
40 | | // Only works if 'x: 'y:
|
||||
41 | | demand_y(x, y, x.get())
|
||||
42 | | //~^ WARN not reporting region error due to -Znll
|
||||
43 | | //~| ERROR free region `'_#6r` does not outlive free region `'_#4r`
|
||||
44 | | });
|
||||
| |_____^
|
||||
|
|
||||
= note: defining type: DefId(0/1:18 ~ propagate_approximated_to_empty[317d]::supply[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7695))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7696))) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0(7697))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1(9522))) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2(9523))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7696))) u32>))
|
||||
]
|
||||
= note: number of external vids: 2
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-to-empty.rs:38:1
|
||||
|
|
||||
38 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
39 | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
40 | | // Only works if 'x: 'y:
|
||||
41 | | demand_y(x, y, x.get())
|
||||
... |
|
||||
44 | | });
|
||||
45 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_approximated_to_empty[317d]::supply[0]) with substs []
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,46 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test a case where we are forced to approximate one end-point with
|
||||
// `'static`. Note that `'static` shows up in the stderr output as `'0`.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Callee knows that:
|
||||
//
|
||||
// 'x: 'a
|
||||
//
|
||||
// so the only way we can ensure that `'x: 'y` is to show that
|
||||
// `'a: 'static`.
|
||||
fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F)
|
||||
where
|
||||
F: for<'x, 'y> FnMut(
|
||||
&Cell<&'a &'x u32>, // shows that 'x: 'a
|
||||
&Cell<&'x u32>,
|
||||
&Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
demand_y(x, y, x.get())
|
||||
});
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,36 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-approximated-to-static.rs:42:9
|
||||
|
|
||||
42 | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-approximated-to-static.rs:40:47
|
||||
|
|
||||
40 | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
| _______________________________________________^
|
||||
41 | | // Only works if 'x: 'y:
|
||||
42 | | demand_y(x, y, x.get())
|
||||
43 | | });
|
||||
| |_____^
|
||||
|
|
||||
= note: defining type: DefId(0/1:18 ~ propagate_approximated_to_static[317d]::supply[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7695))) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7696))) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0(7697))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(7696))) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1(9522))) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2(9523))) u32>))
|
||||
]
|
||||
= note: number of external vids: 2
|
||||
= note: where '_#1r: '_#0r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-to-static.rs:39:1
|
||||
|
|
||||
39 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
40 | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||
41 | | // Only works if 'x: 'y:
|
||||
42 | | demand_y(x, y, x.get())
|
||||
43 | | });
|
||||
44 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_approximated_to_static[317d]::supply[0]) with substs []
|
||||
|
@ -0,0 +1,52 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// A simpler variant of `outlives-from-argument` where cells are
|
||||
// passed by value.
|
||||
//
|
||||
// This is simpler because there are no "extraneous" region
|
||||
// relationships. In the 'main' variant, there are a number of
|
||||
// anonymous regions as well.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// Callee knows that:
|
||||
//
|
||||
// 'x: 'a
|
||||
// 'b: 'y
|
||||
//
|
||||
// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must
|
||||
// hold.
|
||||
fn establish_relationships<'a, 'b, F>(_cell_a: Cell<&'a u32>, _cell_b: Cell<&'b u32>, _closure: F)
|
||||
where
|
||||
F: for<'x, 'y> FnMut(
|
||||
Cell<&'a &'x u32>, // shows that 'x: 'a
|
||||
Cell<&'y &'b u32>, // shows that 'b: 'y
|
||||
Cell<&'x u32>,
|
||||
Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
demand_y(outlives1, outlives2, x.get())
|
||||
});
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,36 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-approximated-val.rs:48:9
|
||||
|
|
||||
48 | demand_y(outlives1, outlives2, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-approximated-val.rs:46:45
|
||||
|
|
||||
46 | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||
| _____________________________________________^
|
||||
47 | | // Only works if 'x: 'y:
|
||||
48 | | demand_y(outlives1, outlives2, x.get())
|
||||
49 | | });
|
||||
| |_____^
|
||||
|
|
||||
= note: defining type: DefId(0/1:18 ~ propagate_approximated_val[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9519))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9520))) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9519))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9520))) u32>))
|
||||
]
|
||||
= note: number of external vids: 3
|
||||
= note: where '_#1r: '_#2r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-approximated-val.rs:45:1
|
||||
|
|
||||
45 | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
46 | | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||
47 | | // Only works if 'x: 'y:
|
||||
48 | | demand_y(outlives1, outlives2, x.get())
|
||||
49 | | });
|
||||
50 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]) with substs []
|
||||
|
@ -0,0 +1,59 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test where we might in theory be able to see that the relationship
|
||||
// between two bound regions is true within closure and hence have no
|
||||
// need to propagate; but in fact we do because identity of free
|
||||
// regions is erased.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
// In theory, callee knows that:
|
||||
//
|
||||
// 'x: 'a
|
||||
// 'a: 'y
|
||||
//
|
||||
// and hence could satisfy that `'x: 'y` locally. However, in our
|
||||
// checking, we ignore the precise free regions that come into the
|
||||
// region and just assign each position a distinct universally bound
|
||||
// region. Hence, we propagate a constraint to our caller that will
|
||||
// wind up being solvable.
|
||||
fn establish_relationships<'a, F>(
|
||||
_cell_a: Cell<&'a u32>,
|
||||
_closure: F,
|
||||
) where
|
||||
F: for<'x, 'y> FnMut(
|
||||
Cell<&'a &'x u32>, // shows that 'x: 'a
|
||||
Cell<&'y &'a u32>, // shows that 'a: 'y
|
||||
Cell<&'x u32>,
|
||||
Cell<&'y u32>,
|
||||
),
|
||||
{
|
||||
}
|
||||
|
||||
fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {}
|
||||
|
||||
#[rustc_regions]
|
||||
fn supply<'a>(cell_a: Cell<&'a u32>) {
|
||||
establish_relationships(
|
||||
cell_a,
|
||||
|_outlives1, _outlives2, x, y| {
|
||||
// Only works if 'x: 'y:
|
||||
let p = x.get();
|
||||
demand_y(x, y, p)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,37 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/propagate-despite-same-free-region.rs:53:21
|
||||
|
|
||||
53 | let p = x.get();
|
||||
| ^^^^^^^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/propagate-despite-same-free-region.rs:51:9
|
||||
|
|
||||
51 | / |_outlives1, _outlives2, x, y| {
|
||||
52 | | // Only works if 'x: 'y:
|
||||
53 | | let p = x.get();
|
||||
54 | | demand_y(x, y, p)
|
||||
55 | | },
|
||||
| |_________^
|
||||
|
|
||||
= note: defining type: DefId(0/1:16 ~ propagate_despite_same_free_region[317d]::supply[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9518))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9519))) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(9518))) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(9519))) u32>))
|
||||
]
|
||||
= note: number of external vids: 3
|
||||
= note: where '_#1r: '_#2r
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/propagate-despite-same-free-region.rs:48:1
|
||||
|
|
||||
48 | / fn supply<'a>(cell_a: Cell<&'a u32>) {
|
||||
49 | | establish_relationships(
|
||||
50 | | cell_a,
|
||||
51 | | |_outlives1, _outlives2, x, y| {
|
||||
... |
|
||||
56 | | );
|
||||
57 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:6 ~ propagate_despite_same_free_region[317d]::supply[0]) with substs []
|
||||
|
@ -0,0 +1,26 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Basic test for free regions in the NLL code. This test ought to
|
||||
// report an error due to a reborrowing constraint. Right now, we get
|
||||
// a variety of errors from the older, AST-based machinery (notably
|
||||
// borrowck), and then we get the NLL error at the end.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir
|
||||
|
||||
fn foo<'a>(x: &'a u32) -> &'static u32
|
||||
where 'static: 'a
|
||||
{
|
||||
&*x
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR free region `'a` does not outlive free region `'static`
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,14 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/region-ebr-does-not-outlive-static.rs:21:5
|
||||
|
|
||||
21 | &*x
|
||||
| ^^^
|
||||
|
||||
error: free region `'a` does not outlive free region `'static`
|
||||
--> $DIR/region-ebr-does-not-outlive-static.rs:21:5
|
||||
|
|
||||
21 | &*x
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,25 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Basic test for free regions in the NLL code. This test ought to
|
||||
// report an error due to a reborrowing constraint. Right now, we get
|
||||
// a variety of errors from the older, AST-based machinery (notably
|
||||
// borrowck), and then we get the NLL error at the end.
|
||||
|
||||
// compile-flags:-Znll
|
||||
|
||||
fn foo(x: &u32) -> &'static u32 {
|
||||
&*x
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR `*x` does not live long enough
|
||||
//~| ERROR free region `'_#1r` does not outlive free region `'static`
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,32 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error[E0597]: `*x` does not live long enough
|
||||
--> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:6
|
||||
|
|
||||
19 | &*x
|
||||
| ^^ does not live long enough
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
note: ...but borrowed value is only valid for the anonymous lifetime #1 defined on the function body at 18:1
|
||||
--> $DIR/region-lbr-anon-does-not-outlive-static.rs:18:1
|
||||
|
|
||||
18 | / fn foo(x: &u32) -> &'static u32 {
|
||||
19 | | &*x
|
||||
20 | | //~^ WARN not reporting region error due to -Znll
|
||||
21 | | //~| ERROR `*x` does not live long enough
|
||||
22 | | //~| ERROR free region `'_#1r` does not outlive free region `'static`
|
||||
23 | | }
|
||||
| |_^
|
||||
|
||||
error: free region `'_#1r` does not outlive free region `'static`
|
||||
--> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -0,0 +1,24 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Basic test for free regions in the NLL code. This test ought to
|
||||
// report an error due to a reborrowing constraint. Right now, we get
|
||||
// a variety of errors from the older, AST-based machinery (notably
|
||||
// borrowck), and then we get the NLL error at the end.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir
|
||||
|
||||
fn foo<'a>(x: &'a u32) -> &'static u32 {
|
||||
&*x
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR free region `'_#1r` does not outlive free region `'static`
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,14 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error: free region `'_#1r` does not outlive free region `'static`
|
||||
--> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -13,12 +13,12 @@
|
||||
// a variety of errors from the older, AST-based machinery (notably
|
||||
// borrowck), and then we get the NLL error at the end.
|
||||
|
||||
// compile-flags:-Znll
|
||||
// compile-flags:-Znll -Zborrowck=mir
|
||||
|
||||
fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 {
|
||||
&*x //~ ERROR free region `'a` does not outlive `'b`
|
||||
//~^ ERROR `*x` does not live long enough
|
||||
//~| WARN not reporting region error due to -Znll
|
||||
&*x
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR free region `'_#1r` does not outlive free region `'_#2r`
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,14 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/region-lbr1-does-not-outlive-ebr2.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error: free region `'_#1r` does not outlive free region `'_#2r`
|
||||
--> $DIR/region-lbr1-does-not-outlive-ebr2.rs:19:5
|
||||
|
|
||||
19 | &*x
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -0,0 +1,23 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Basic test for free regions in the NLL code. This test does not
|
||||
// report an error because of the (implied) bound that `'b: 'a`.
|
||||
|
||||
// compile-flags:-Znll
|
||||
// must-compile-successfully
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
fn foo<'a, 'b>(x: &'a &'b u32) -> &'a u32 {
|
||||
&**x
|
||||
}
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,34 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// Test closure that takes two references and is supposed to return
|
||||
// the first, but actually returns the second. This should fail within
|
||||
// the closure.
|
||||
|
||||
// compile-flags:-Znll -Zborrowck=mir -Zverbose
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_regions]
|
||||
fn test() {
|
||||
expect_sig(|a, b| b); // ought to return `a`
|
||||
//~^ WARN not reporting region error due to -Znll
|
||||
//~| ERROR free region `'_#3r` does not outlive free region `'_#2r`
|
||||
}
|
||||
|
||||
fn expect_sig<F>(f: F) -> F
|
||||
where F: for<'a> FnMut(&'a i32, &i32) -> &'a i32
|
||||
{
|
||||
f
|
||||
}
|
||||
|
||||
fn deref(_p: &i32) { }
|
||||
|
||||
fn main() { }
|
@ -0,0 +1,38 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/return-wrong-bound-region.rs:21:23
|
||||
|
|
||||
21 | expect_sig(|a, b| b); // ought to return `a`
|
||||
| ^
|
||||
|
||||
error: free region `'_#3r` does not outlive free region `'_#2r`
|
||||
--> $DIR/return-wrong-bound-region.rs:21:23
|
||||
|
|
||||
21 | expect_sig(|a, b| b); // ought to return `a`
|
||||
| ^
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/return-wrong-bound-region.rs:21:16
|
||||
|
|
||||
21 | expect_sig(|a, b| b); // ought to return `a`
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: defining type: DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]) with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7661))) i32, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's(8630))) i32)) -> &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r(7661))) i32
|
||||
]
|
||||
= note: number of external vids: 1
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/return-wrong-bound-region.rs:20:1
|
||||
|
|
||||
20 | / fn test() {
|
||||
21 | | expect_sig(|a, b| b); // ought to return `a`
|
||||
22 | | //~^ WARN not reporting region error due to -Znll
|
||||
23 | | //~| ERROR free region `'_#3r` does not outlive free region `'_#2r`
|
||||
24 | | }
|
||||
| |_^
|
||||
|
|
||||
= note: defining type: DefId(0/0:3 ~ return_wrong_bound_region[317d]::test[0]) with substs []
|
||||
|
||||
error: aborting due to previous error
|
||||
|
87
src/test/ui/nll/closure-requirements/via-upvar-nested.stderr
Normal file
87
src/test/ui/nll/closure-requirements/via-upvar-nested.stderr
Normal file
@ -0,0 +1,87 @@
|
||||
note: External requirements
|
||||
--> $DIR/via-upvar-nested.rs:24:28
|
||||
|
|
||||
24 | let closure1 = || p = &y;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: _0: ()
|
||||
= note: _1: &mut [closure@$DIR/via-upvar-nested.rs:24:28: 24:37 p:&mut &i32, y:&i32]
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/via-upvar-nested.rs:23:27
|
||||
|
|
||||
23 | let mut closure = || {
|
||||
| ___________________________^
|
||||
24 | | let closure1 = || p = &y;
|
||||
25 | | closure1();
|
||||
26 | | };
|
||||
| |_________^
|
||||
|
|
||||
= note: _0: ()
|
||||
= note: _1: &mut [closure@$DIR/via-upvar-nested.rs:23:27: 26:10 p:&mut &i32, y:&i32]
|
||||
= note: where '_#1r: '_#2r
|
||||
|
||||
error[E0596]: cannot borrow immutable item `closure1` as mutable (Mir)
|
||||
--> $DIR/via-upvar-nested.rs:25:13
|
||||
|
|
||||
25 | closure1();
|
||||
| ^^^^^^^^ cannot borrow as mutable
|
||||
|
||||
error[E0597]: `**y` does not live long enough (Ast)
|
||||
--> $DIR/via-upvar-nested.rs:24:36
|
||||
|
|
||||
24 | let closure1 = || p = &y;
|
||||
| -- ^ does not live long enough
|
||||
| |
|
||||
| capture occurs here
|
||||
...
|
||||
29 | }
|
||||
| - borrowed value only lives until here
|
||||
...
|
||||
32 | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error[E0596]: cannot borrow immutable local variable `closure1` as mutable (Ast)
|
||||
--> $DIR/via-upvar-nested.rs:25:13
|
||||
|
|
||||
24 | let closure1 = || p = &y;
|
||||
| -------- consider changing this to `mut closure1`
|
||||
25 | closure1();
|
||||
| ^^^^^^^^ cannot borrow mutably
|
||||
|
||||
note: No external requirements
|
||||
--> $DIR/via-upvar-nested.rs:16:1
|
||||
|
|
||||
16 | / fn test() {
|
||||
17 | | let x = 44;
|
||||
18 | | let mut p = &x;
|
||||
19 | |
|
||||
... |
|
||||
31 | | deref(p);
|
||||
32 | | }
|
||||
| |_^
|
||||
|
||||
error[E0597]: borrowed value does not live long enough (Mir)
|
||||
--> $DIR/via-upvar-nested.rs:29:6
|
||||
|
|
||||
21 | let y = 22;
|
||||
| - temporary value created here
|
||||
...
|
||||
29 | }
|
||||
| ^ temporary value dropped here while still borrowed
|
||||
|
|
||||
= note: consider using a `let` binding to increase its lifetime
|
||||
|
||||
error[E0502]: cannot borrow `(*p)` as immutable because it is also borrowed as mutable (Mir)
|
||||
--> $DIR/via-upvar-nested.rs:31:11
|
||||
|
|
||||
23 | let mut closure = || {
|
||||
| -- mutable borrow occurs here
|
||||
24 | let closure1 = || p = &y;
|
||||
| - previous borrow occurs due to use of `(*p)` in closure
|
||||
...
|
||||
31 | deref(p);
|
||||
| ^ immutable borrow occurs here
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -1,31 +0,0 @@
|
||||
warning: not reporting region error due to -Znll
|
||||
--> $DIR/named-region-basic.rs:19:5
|
||||
|
|
||||
19 | &*x //~ ERROR free region `'a` does not outlive `'b`
|
||||
| ^^^
|
||||
|
||||
error[E0597]: `*x` does not live long enough
|
||||
--> $DIR/named-region-basic.rs:19:6
|
||||
|
|
||||
19 | &*x //~ ERROR free region `'a` does not outlive `'b`
|
||||
| ^^ does not live long enough
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
note: ...but borrowed value is only valid for the lifetime 'a as defined on the function body at 18:1
|
||||
--> $DIR/named-region-basic.rs:18:1
|
||||
|
|
||||
18 | / fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 {
|
||||
19 | | &*x //~ ERROR free region `'a` does not outlive `'b`
|
||||
20 | | //~^ ERROR `*x` does not live long enough
|
||||
21 | | //~| WARN not reporting region error due to -Znll
|
||||
22 | | }
|
||||
| |_^
|
||||
|
||||
error: free region `'a` does not outlive `'b`
|
||||
--> $DIR/named-region-basic.rs:19:5
|
||||
|
|
||||
19 | &*x //~ ERROR free region `'a` does not outlive `'b`
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user