) {
for ascription in ascriptions {
let source_info = self.source_info(ascription.span);
+
+ debug!(
+ "adding user ascription at span {:?} of place {:?} and {:?}",
+ source_info.span,
+ ascription.source,
+ ascription.user_ty,
+ );
+
self.cfg.push(
block,
Statement {
use const_eval::{const_field, const_variant_index};
+use hair::util::UserAnnotatedTyHelpers;
+
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
use rustc::ty::{self, CanonicalTy, TyCtxt, AdtDef, Ty, Region};
field: Field::new(i),
pattern: self.lower_pattern(field),
})
- .collect();
- self.lower_variant_or_leaf(def, pat.span, ty, subpatterns)
+ .collect();
+
+ self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
}
PatKind::Struct(ref qpath, ref fields, _) => {
})
.collect();
- self.lower_variant_or_leaf(def, pat.span, ty, subpatterns)
+ self.lower_variant_or_leaf(def, pat.hir_id, pat.span, ty, subpatterns)
}
};
fn lower_variant_or_leaf(
&mut self,
def: Def,
+ hir_id: hir::HirId,
span: Span,
ty: Ty<'tcx>,
- subpatterns: Vec<FieldPattern<'tcx>>)
- -> PatternKind<'tcx>
- {
- match def {
+ subpatterns: Vec<FieldPattern<'tcx>>,
+ ) -> PatternKind<'tcx> {
+ let mut kind = match def {
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
let enum_id = self.tcx.parent_def_id(variant_id).unwrap();
let adt_def = self.tcx.adt_def(enum_id);
self.errors.push(PatternError::NonConstPath(span));
PatternKind::Wild
}
+ };
+
+ if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) {
+ let subpattern = Pattern {
+ span,
+ ty,
+ kind: Box::new(kind),
+ };
+
+ debug!("pattern user_ty = {:?} for pattern at {:?}", user_ty, span);
+
+ kind = PatternKind::AscribeUserType {
+ subpattern,
+ user_ty,
+ };
}
+
+ kind
}
/// Takes a HIR Path. If the path is a constant, evaluates it and feeds
},
}
}
- _ => self.lower_variant_or_leaf(def, span, ty, vec![]),
+ _ => self.lower_variant_or_leaf(def, id, span, ty, vec![]),
};
Pattern {
}
}
+impl UserAnnotatedTyHelpers<'tcx, 'tcx> for PatternContext<'_, 'tcx> {
+ fn tcx(&self) -> TyCtxt<'_, 'tcx, 'tcx> {
+ self.tcx
+ }
+
+ fn tables(&self) -> &ty::TypeckTables<'tcx> {
+ self.tables
+ }
+}
+
+
pub trait PatternFoldable<'tcx> : Sized {
fn fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
self.super_fold_with(folder)
/// occurred**, so that annotations like `Vec<_>` are preserved
/// properly.
pub fn write_user_substs_from_substs(&self, hir_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
+ debug!(
+ "write_user_substs_from_substs({:?}, {:?}) in fcx {}",
+ hir_id,
+ substs,
+ self.tag(),
+ );
+
if !substs.is_noop() {
let user_substs = self.infcx.canonicalize_response(&substs);
debug!("instantiate_value_path: user_substs = {:?}", user_substs);
--- /dev/null
+#![feature(nll)]
+
+enum Foo<'a> {
+ Bar { field: &'a u32 }
+}
+
+fn in_let() {
+ let y = 22;
+ let foo = Foo::Bar { field: &y };
+ //~^ ERROR `y` does not live long enough
+ let Foo::Bar::<'static> { field: _z } = foo;
+}
+
+fn in_match() {
+ let y = 22;
+ let foo = Foo::Bar { field: &y };
+ //~^ ERROR `y` does not live long enough
+ match foo {
+ Foo::Bar::<'static> { field: _z } => {
+ }
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:33
+ |
+LL | let foo = Foo::Bar { field: &y };
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_brace_enum_variant.rs:16:33
+ |
+LL | let foo = Foo::Bar { field: &y };
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+#![feature(nll)]
+
+struct Foo<'a> { field: &'a u32 }
+
+fn in_let() {
+ let y = 22;
+ let foo = Foo { field: &y };
+ //~^ ERROR `y` does not live long enough
+ let Foo::<'static> { field: _z } = foo;
+}
+
+fn in_main() {
+ let y = 22;
+ let foo = Foo { field: &y };
+ //~^ ERROR `y` does not live long enough
+ match foo {
+ Foo::<'static> { field: _z } => {
+ }
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_brace_struct.rs:7:28
+ |
+LL | let foo = Foo { field: &y };
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_brace_struct.rs:14:28
+ |
+LL | let foo = Foo { field: &y };
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+#![feature(nll)]
+
+enum Foo<'a> {
+ Bar(&'a u32)
+}
+
+fn in_let() {
+ let y = 22;
+ let foo = Foo::Bar(&y);
+ //~^ ERROR `y` does not live long enough
+ let Foo::Bar::<'static>(_z) = foo;
+}
+
+fn in_match() {
+ let y = 22;
+ let foo = Foo::Bar(&y);
+ //~^ ERROR `y` does not live long enough
+ match foo {
+ Foo::Bar::<'static>(_z) => {
+ }
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:24
+ |
+LL | let foo = Foo::Bar(&y);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_tuple_enum_variant.rs:16:24
+ |
+LL | let foo = Foo::Bar(&y);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+#![feature(nll)]
+
+struct Foo<'a>(&'a u32);
+
+fn in_let() {
+ let y = 22;
+ let foo = Foo(&y);
+ //~^ ERROR `y` does not live long enough
+ let Foo::<'static>(_z) = foo;
+}
+
+fn in_match() {
+ let y = 22;
+ let foo = Foo(&y);
+ //~^ ERROR `y` does not live long enough
+ match foo {
+ Foo::<'static>(_z) => {
+ }
+ }
+}
+
+fn main() { }
--- /dev/null
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_tuple_struct.rs:7:19
+ |
+LL | let foo = Foo(&y);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/pattern_substs_on_tuple_struct.rs:14:19
+ |
+LL | let foo = Foo(&y);
+ | ^^ borrowed value does not live long enough
+...
+LL | }
+ | - `y` dropped here while still borrowed
+ |
+ = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.