提交 e87bf30f 编写于 作者: N Niko Matsakis

propagate user-ascribes types down onto resulting bindings

But only in very simple cases.
上级 a8710539
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
mutability, mutability,
ty, ty,
user_ty,
name, name,
source_info, source_info,
visibility_scope, visibility_scope,
......
...@@ -640,6 +640,12 @@ pub struct LocalDecl<'tcx> { ...@@ -640,6 +640,12 @@ pub struct LocalDecl<'tcx> {
/// Type of this local. /// Type of this local.
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
/// If the user manually ascribed a type to this variable,
/// e.g. via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: Option<CanonicalTy<'tcx>>,
/// Name of the local, used in debuginfo and pretty-printing. /// Name of the local, used in debuginfo and pretty-printing.
/// ///
/// Note that function arguments can also have this set to `Some(_)` /// Note that function arguments can also have this set to `Some(_)`
...@@ -802,6 +808,7 @@ fn new_local( ...@@ -802,6 +808,7 @@ fn new_local(
LocalDecl { LocalDecl {
mutability, mutability,
ty, ty,
user_ty: None,
name: None, name: None,
source_info: SourceInfo { source_info: SourceInfo {
span, span,
...@@ -821,6 +828,7 @@ pub fn new_return_place(return_ty: Ty, span: Span) -> LocalDecl { ...@@ -821,6 +828,7 @@ pub fn new_return_place(return_ty: Ty, span: Span) -> LocalDecl {
LocalDecl { LocalDecl {
mutability: Mutability::Mut, mutability: Mutability::Mut,
ty: return_ty, ty: return_ty,
user_ty: None,
source_info: SourceInfo { source_info: SourceInfo {
span, span,
scope: OUTERMOST_SOURCE_SCOPE, scope: OUTERMOST_SOURCE_SCOPE,
...@@ -2613,6 +2621,7 @@ impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> { ...@@ -2613,6 +2621,7 @@ impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> {
is_user_variable, is_user_variable,
internal, internal,
ty, ty,
user_ty,
name, name,
source_info, source_info,
visibility_scope, visibility_scope,
......
...@@ -721,6 +721,7 @@ fn super_local_decl(&mut self, ...@@ -721,6 +721,7 @@ fn super_local_decl(&mut self,
let LocalDecl { let LocalDecl {
mutability: _, mutability: _,
ref $($mutability)* ty, ref $($mutability)* ty,
ref $($mutability)* user_ty,
name: _, name: _,
ref $($mutability)* source_info, ref $($mutability)* source_info,
ref $($mutability)* visibility_scope, ref $($mutability)* visibility_scope,
...@@ -732,6 +733,9 @@ fn super_local_decl(&mut self, ...@@ -732,6 +733,9 @@ fn super_local_decl(&mut self,
local, local,
source_info: *source_info, source_info: *source_info,
}); });
if let Some(user_ty) = user_ty {
self.visit_canonical_ty(user_ty);
}
self.visit_source_info(source_info); self.visit_source_info(source_info);
self.visit_source_scope(visibility_scope); self.visit_source_scope(visibility_scope);
} }
......
...@@ -275,6 +275,25 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { ...@@ -275,6 +275,25 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
self.super_local_decl(local, local_decl); self.super_local_decl(local, local_decl);
self.sanitize_type(local_decl, local_decl.ty); self.sanitize_type(local_decl, local_decl.ty);
if let Some(user_ty) = local_decl.user_ty {
if let Err(terr) = self.cx.relate_type_and_user_type(
local_decl.ty,
ty::Variance::Invariant,
user_ty,
Locations::All,
) {
span_mirbug!(
self,
local,
"bad user type on variable {:?}: {:?} != {:?} ({:?})",
local,
local_decl.ty,
local_decl.user_ty,
terr,
);
}
}
} }
fn visit_mir(&mut self, mir: &Mir<'tcx>) { fn visit_mir(&mut self, mir: &Mir<'tcx>) {
......
...@@ -143,7 +143,7 @@ fn ast_block_stmts(&mut self, ...@@ -143,7 +143,7 @@ fn ast_block_stmts(&mut self,
None, remainder_span, lint_level, slice::from_ref(&pattern), None, remainder_span, lint_level, slice::from_ref(&pattern),
ArmHasGuard(false), None); ArmHasGuard(false), None);
this.visit_bindings(&pattern, &mut |this, _, _, _, node, span, _| { this.visit_bindings(&pattern, None, &mut |this, _, _, _, node, span, _, _| {
this.storage_live_binding(block, node, span, OutsideGuard); this.storage_live_binding(block, node, span, OutsideGuard);
this.schedule_drop_for_binding(node, span, OutsideGuard); this.schedule_drop_for_binding(node, span, OutsideGuard);
}) })
......
...@@ -296,6 +296,7 @@ pub fn into_expr( ...@@ -296,6 +296,7 @@ pub fn into_expr(
let ptr_temp = this.local_decls.push(LocalDecl { let ptr_temp = this.local_decls.push(LocalDecl {
mutability: Mutability::Mut, mutability: Mutability::Mut,
ty: ptr_ty, ty: ptr_ty,
user_ty: None,
name: None, name: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
......
...@@ -399,7 +399,8 @@ pub fn declare_bindings( ...@@ -399,7 +399,8 @@ pub fn declare_bindings(
let num_patterns = patterns.len(); let num_patterns = patterns.len();
self.visit_bindings( self.visit_bindings(
&patterns[0], &patterns[0],
&mut |this, mutability, name, mode, var, span, ty| { None,
&mut |this, mutability, name, mode, var, span, ty, user_ty| {
if visibility_scope.is_none() { if visibility_scope.is_none() {
visibility_scope = visibility_scope =
Some(this.new_source_scope(scope_span, LintLevel::Inherited, None)); Some(this.new_source_scope(scope_span, LintLevel::Inherited, None));
...@@ -421,6 +422,7 @@ pub fn declare_bindings( ...@@ -421,6 +422,7 @@ pub fn declare_bindings(
num_patterns, num_patterns,
var, var,
ty, ty,
user_ty,
has_guard, has_guard,
opt_match_place.map(|(x, y)| (x.cloned(), y)), opt_match_place.map(|(x, y)| (x.cloned(), y)),
patterns[0].span, patterns[0].span,
...@@ -470,10 +472,21 @@ pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard: ...@@ -470,10 +472,21 @@ pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard:
); );
} }
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F) pub fn visit_bindings(
where &mut self,
F: FnMut(&mut Self, Mutability, Name, BindingMode, NodeId, Span, Ty<'tcx>), pattern: &Pattern<'tcx>,
{ pattern_user_ty: Option<CanonicalTy<'tcx>>,
f: &mut impl FnMut(
&mut Self,
Mutability,
Name,
BindingMode,
NodeId,
Span,
Ty<'tcx>,
Option<CanonicalTy<'tcx>>,
),
) {
match *pattern.kind { match *pattern.kind {
PatternKind::Binding { PatternKind::Binding {
mutability, mutability,
...@@ -484,9 +497,9 @@ pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F) ...@@ -484,9 +497,9 @@ pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
ref subpattern, ref subpattern,
.. ..
} => { } => {
f(self, mutability, name, mode, var, pattern.span, ty); f(self, mutability, name, mode, var, pattern.span, ty, pattern_user_ty);
if let Some(subpattern) = subpattern.as_ref() { if let Some(subpattern) = subpattern.as_ref() {
self.visit_bindings(subpattern, f); self.visit_bindings(subpattern, pattern_user_ty, f);
} }
} }
PatternKind::Array { PatternKind::Array {
...@@ -499,21 +512,34 @@ pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F) ...@@ -499,21 +512,34 @@ pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
ref slice, ref slice,
ref suffix, ref suffix,
} => { } => {
// FIXME(#47184): extract or handle `pattern_user_ty` somehow
for subpattern in prefix.iter().chain(slice).chain(suffix) { for subpattern in prefix.iter().chain(slice).chain(suffix) {
self.visit_bindings(subpattern, f); self.visit_bindings(subpattern, None, f);
} }
} }
PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {} PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {}
PatternKind::AscribeUserType { ref subpattern, .. } PatternKind::Deref { ref subpattern } => {
| PatternKind::Deref { ref subpattern } => { // FIXME(#47184): extract or handle `pattern_user_ty` somehow
self.visit_bindings(subpattern, f); self.visit_bindings(subpattern, None, f);
}
PatternKind::AscribeUserType { ref subpattern, user_ty } => {
// This corresponds to something like
//
// ```
// let (p1: T1): T2 = ...;
// ```
//
// Not presently possible, though maybe someday.
assert!(pattern_user_ty.is_none());
self.visit_bindings(subpattern, Some(user_ty), f)
} }
PatternKind::Leaf { ref subpatterns } PatternKind::Leaf { ref subpatterns }
| PatternKind::Variant { | PatternKind::Variant {
ref subpatterns, .. ref subpatterns, ..
} => { } => {
// FIXME(#47184): extract or handle `pattern_user_ty` somehow
for subpattern in subpatterns { for subpattern in subpatterns {
self.visit_bindings(&subpattern.pattern, f); self.visit_bindings(&subpattern.pattern, None, f);
} }
} }
} }
...@@ -1375,6 +1401,7 @@ fn declare_binding( ...@@ -1375,6 +1401,7 @@ fn declare_binding(
num_patterns: usize, num_patterns: usize,
var_id: NodeId, var_id: NodeId,
var_ty: Ty<'tcx>, var_ty: Ty<'tcx>,
user_var_ty: Option<CanonicalTy<'tcx>>,
has_guard: ArmHasGuard, has_guard: ArmHasGuard,
opt_match_place: Option<(Option<Place<'tcx>>, Span)>, opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
pat_span: Span, pat_span: Span,
...@@ -1392,7 +1419,8 @@ fn declare_binding( ...@@ -1392,7 +1419,8 @@ fn declare_binding(
}; };
let local = LocalDecl::<'tcx> { let local = LocalDecl::<'tcx> {
mutability, mutability,
ty: var_ty.clone(), ty: var_ty,
user_ty: user_var_ty,
name: Some(name), name: Some(name),
source_info, source_info,
visibility_scope, visibility_scope,
...@@ -1424,6 +1452,7 @@ fn declare_binding( ...@@ -1424,6 +1452,7 @@ fn declare_binding(
// See previous comment. // See previous comment.
mutability: Mutability::Not, mutability: Mutability::Not,
ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty), ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty),
user_ty: None,
name: Some(name), name: Some(name),
source_info, source_info,
visibility_scope, visibility_scope,
......
...@@ -730,6 +730,7 @@ fn args_and_body(&mut self, ...@@ -730,6 +730,7 @@ fn args_and_body(&mut self,
self.local_decls.push(LocalDecl { self.local_decls.push(LocalDecl {
mutability: Mutability::Mut, mutability: Mutability::Mut,
ty, ty,
user_ty: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
name, name,
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#![feature(if_while_or_patterns)] #![feature(if_while_or_patterns)]
#![feature(try_from)] #![feature(try_from)]
#![feature(reverse_bits)] #![feature(reverse_bits)]
#![feature(underscore_imports)]
#![recursion_limit="256"] #![recursion_limit="256"]
......
...@@ -140,7 +140,9 @@ enum CallKind { ...@@ -140,7 +140,9 @@ enum CallKind {
fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl { fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl {
let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span }; let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span };
LocalDecl { LocalDecl {
mutability, ty, name: None, mutability, ty,
user_ty: None,
name: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
internal: false, internal: false,
......
...@@ -303,6 +303,7 @@ fn replace_result_variable<'tcx>( ...@@ -303,6 +303,7 @@ fn replace_result_variable<'tcx>(
let new_ret = LocalDecl { let new_ret = LocalDecl {
mutability: Mutability::Mut, mutability: Mutability::Mut,
ty: ret_ty, ty: ret_ty,
user_ty: None,
name: None, name: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
...@@ -656,6 +657,7 @@ fn create_generator_drop_shim<'a, 'tcx>( ...@@ -656,6 +657,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
mir.local_decls[RETURN_PLACE] = LocalDecl { mir.local_decls[RETURN_PLACE] = LocalDecl {
mutability: Mutability::Mut, mutability: Mutability::Mut,
ty: tcx.mk_nil(), ty: tcx.mk_nil(),
user_ty: None,
name: None, name: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
...@@ -672,6 +674,7 @@ fn create_generator_drop_shim<'a, 'tcx>( ...@@ -672,6 +674,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
ty: gen_ty, ty: gen_ty,
mutbl: hir::Mutability::MutMutable, mutbl: hir::Mutability::MutMutable,
}), }),
user_ty: None,
name: None, name: None,
source_info, source_info,
visibility_scope: source_info.scope, visibility_scope: source_info.scope,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use std::fmt::Display; use std::fmt::Display;
use std::fmt::Write as _;
use std::fs; use std::fs;
use std::io::{self, Write}; use std::io::{self, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
...@@ -493,14 +494,18 @@ fn write_scope_tree( ...@@ -493,14 +494,18 @@ fn write_scope_tree(
}; };
let indent = indent + INDENT.len(); let indent = indent + INDENT.len();
let indented_var = format!( let mut indented_var = format!(
"{0:1$}let {2}{3:?}: {4:?};", "{0:1$}let {2}{3:?}: {4:?}",
INDENT, INDENT,
indent, indent,
mut_str, mut_str,
local, local,
var.ty var.ty
); );
if let Some(user_ty) = var.user_ty {
write!(indented_var, " as {:?}", user_ty).unwrap();
}
indented_var.push_str(";");
writeln!( writeln!(
w, w,
"{0:1$} // \"{2}\" in {3}", "{0:1$} // \"{2}\" in {3}",
......
...@@ -3,10 +3,41 @@ ...@@ -3,10 +3,41 @@
#![feature(nll)] #![feature(nll)]
fn variable_no_initializer() { fn variable_no_initializer() {
// FIXME: It is unclear to me whether this should be an error or not.
let x = 22; let x = 22;
let y: &'static u32; let y: &'static u32;
y = &x; //~ ERROR
}
fn tuple_no_initializer() {
// FIXME(#47187): We are not propagating ascribed type through tuples.
let x = 22;
let (y, z): (&'static u32, &'static u32);
y = &x;
}
fn ref_with_ascribed_static_type() -> u32 {
// Check the behavior in some wacky cases.
let x = 22;
let y = &x; //~ ERROR
let ref z: &'static u32 = y; //~ ERROR
**z
}
fn ref_with_ascribed_any_type() -> u32 {
let x = 22;
let y = &x;
let ref z: &u32 = y;
**z
}
struct Single<T> { value: T }
fn struct_no_initializer() {
// FIXME(#47187): We are not propagating ascribed type through patterns.
let x = 22;
let Single { value: y }: Single<&'static u32>;
y = &x; y = &x;
} }
...@@ -39,8 +70,6 @@ fn pair_variable_with_initializer() { ...@@ -39,8 +70,6 @@ fn pair_variable_with_initializer() {
let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR
} }
struct Single<T> { value: T }
fn struct_single_field_variable_with_initializer() { fn struct_single_field_variable_with_initializer() {
let x = 22; let x = 22;
let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR
...@@ -73,7 +102,7 @@ fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { ...@@ -73,7 +102,7 @@ fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
} }
fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
// FIXME: The fact that this type-checks is perhaps surprising. // FIXME(#47187): The fact that this type-checks is perhaps surprising.
// What happens is that the right-hand side is constrained to have // What happens is that the right-hand side is constrained to have
// type `&'a u32`, which is possible, because it has type // type `&'a u32`, which is possible, because it has type
// `&'static u32`. The variable `y` is then forced to have type // `&'static u32`. The variable `y` is then forced to have type
......
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:15:27 --> $DIR/patterns.rs:8:9
|
LL | y = &x; //~ ERROR
| ^^ borrowed value does not live long enough
LL | }
| - `x` dropped here while still borrowed
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:22:13
|
LL | let y = &x; //~ ERROR
| ^^ borrowed value does not live long enough
...
LL | }
| - `x` dropped here while still borrowed
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: `y` does not live long enough
--> $DIR/patterns.rs:23:9
|
LL | let ref z: &'static u32 = y; //~ ERROR
| ^^^^^ borrowed value does not live long enough
LL | **z
LL | }
| - `y` dropped here while still borrowed
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:46:27
| |
LL | let y: &'static u32 = &x; //~ ERROR LL | let y: &'static u32 = &x; //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -9,7 +41,7 @@ LL | } ...@@ -9,7 +41,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:20:27 --> $DIR/patterns.rs:51:27
| |
LL | let _: &'static u32 = &x; //~ ERROR LL | let _: &'static u32 = &x; //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -20,7 +52,7 @@ LL | } ...@@ -20,7 +52,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough error[E0597]: borrowed value does not live long enough
--> $DIR/patterns.rs:22:41 --> $DIR/patterns.rs:53:41
| |
LL | let _: Vec<&'static String> = vec![&String::new()]; LL | let _: Vec<&'static String> = vec![&String::new()];
| ^^^^^^^^^^^^^ - temporary value only lives until here | ^^^^^^^^^^^^^ - temporary value only lives until here
...@@ -30,7 +62,7 @@ LL | let _: Vec<&'static String> = vec![&String::new()]; ...@@ -30,7 +62,7 @@ LL | let _: Vec<&'static String> = vec![&String::new()];
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough error[E0597]: borrowed value does not live long enough
--> $DIR/patterns.rs:25:52 --> $DIR/patterns.rs:56:52
| |
LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44);
| ^^^^^^^^^^^^^ - temporary value only lives until here | ^^^^^^^^^^^^^ - temporary value only lives until here
...@@ -40,7 +72,7 @@ LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); ...@@ -40,7 +72,7 @@ LL | let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44);
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough error[E0597]: borrowed value does not live long enough
--> $DIR/patterns.rs:28:53 --> $DIR/patterns.rs:59:53
| |
LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
| ^^^^^^^^^^^^^ - temporary value only lives until here | ^^^^^^^^^^^^^ - temporary value only lives until here
...@@ -50,7 +82,7 @@ LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); ...@@ -50,7 +82,7 @@ LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44);
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:34:40 --> $DIR/patterns.rs:65:40
| |
LL | let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR LL | let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -60,7 +92,7 @@ LL | } ...@@ -60,7 +92,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:39:40 --> $DIR/patterns.rs:70:40
| |
LL | let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR LL | let (y, _): (&'static u32, u32) = (&x, 44); //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -70,7 +102,7 @@ LL | } ...@@ -70,7 +102,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:46:69 --> $DIR/patterns.rs:75:69
| |
LL | let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR LL | let Single { value: y }: Single<&'static u32> = Single { value: &x }; //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -80,7 +112,7 @@ LL | } ...@@ -80,7 +112,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:51:69 --> $DIR/patterns.rs:80:69
| |
LL | let Single { value: _ }: Single<&'static u32> = Single { value: &x }; //~ ERROR LL | let Single { value: _ }: Single<&'static u32> = Single { value: &x }; //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -90,7 +122,7 @@ LL | } ...@@ -90,7 +122,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error[E0597]: `x` does not live long enough error[E0597]: `x` does not live long enough
--> $DIR/patterns.rs:59:17 --> $DIR/patterns.rs:88:17
| |
LL | value1: &x, //~ ERROR LL | value1: &x, //~ ERROR
| ^^ borrowed value does not live long enough | ^^ borrowed value does not live long enough
...@@ -101,7 +133,7 @@ LL | } ...@@ -101,7 +133,7 @@ LL | }
= note: borrowed value must be valid for the static lifetime... = note: borrowed value must be valid for the static lifetime...
error: unsatisfied lifetime constraints error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:72:5 --> $DIR/patterns.rs:101:5
| |
LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
...@@ -110,13 +142,13 @@ LL | y //~ ERROR ...@@ -110,13 +142,13 @@ LL | y //~ ERROR
| ^ returning this value requires that `'a` must outlive `'static` | ^ returning this value requires that `'a` must outlive `'static`
error: unsatisfied lifetime constraints error: unsatisfied lifetime constraints
--> $DIR/patterns.rs:88:40 --> $DIR/patterns.rs:117:40
| |
LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
| -- lifetime `'a` defined here | -- lifetime `'a` defined here
LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR LL | let (y, _z): (&'static u32, u32) = (x, 44); //~ ERROR
| ^^^^^^^ requires that `'a` must outlive `'static` | ^^^^^^^ requires that `'a` must outlive `'static`
error: aborting due to 12 previous errors error: aborting due to 15 previous errors
For more information about this error, try `rustc --explain E0597`. For more information about this error, try `rustc --explain E0597`.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册