support user-given types in adts
This commit is contained in:
parent
2d1d3fef62
commit
56506cfa25
@ -479,10 +479,11 @@ for mir::AggregateKind<'gcx> {
|
||||
mir::AggregateKind::Array(t) => {
|
||||
t.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
|
||||
mir::AggregateKind::Adt(adt_def, idx, substs, user_substs, active_field) => {
|
||||
adt_def.hash_stable(hcx, hasher);
|
||||
idx.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
user_substs.hash_stable(hcx, hasher);
|
||||
active_field.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::AggregateKind::Closure(def_id, ref substs) => {
|
||||
|
@ -2009,7 +2009,7 @@ pub enum AggregateKind<'tcx> {
|
||||
/// active field number and is present only for union expressions
|
||||
/// -- e.g. for a union expression `SomeUnion { c: .. }`, the
|
||||
/// active field index would identity the field `c`
|
||||
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>),
|
||||
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<CanonicalTy<'tcx>>, Option<usize>),
|
||||
|
||||
Closure(DefId, ClosureSubsts<'tcx>),
|
||||
Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
|
||||
@ -2135,7 +2135,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||
_ => fmt_tuple(fmt, places),
|
||||
},
|
||||
|
||||
AggregateKind::Adt(adt_def, variant, substs, _) => {
|
||||
AggregateKind::Adt(adt_def, variant, substs, _user_ty, _) => {
|
||||
let variant_def = &adt_def.variants[variant];
|
||||
|
||||
ppaux::parameterized(fmt, substs, variant_def.did, &[])?;
|
||||
@ -2813,8 +2813,14 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
let kind = box match **kind {
|
||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
|
||||
AggregateKind::Tuple => AggregateKind::Tuple,
|
||||
AggregateKind::Adt(def, v, substs, n) => {
|
||||
AggregateKind::Adt(def, v, substs.fold_with(folder), n)
|
||||
AggregateKind::Adt(def, v, substs, user_ty, n) => {
|
||||
AggregateKind::Adt(
|
||||
def,
|
||||
v,
|
||||
substs.fold_with(folder),
|
||||
user_ty.fold_with(folder),
|
||||
n,
|
||||
)
|
||||
}
|
||||
AggregateKind::Closure(id, substs) => {
|
||||
AggregateKind::Closure(id, substs.fold_with(folder))
|
||||
@ -2846,7 +2852,8 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
(match **kind {
|
||||
AggregateKind::Array(ty) => ty.visit_with(visitor),
|
||||
AggregateKind::Tuple => false,
|
||||
AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor),
|
||||
AggregateKind::Adt(_, _, substs, user_ty, _) =>
|
||||
substs.visit_with(visitor) || user_ty.visit_with(visitor),
|
||||
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
|
||||
}) || fields.visit_with(visitor)
|
||||
|
@ -216,7 +216,7 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
AggregateKind::Tuple => {
|
||||
tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx)))
|
||||
}
|
||||
AggregateKind::Adt(def, _, substs, _) => {
|
||||
AggregateKind::Adt(def, _, substs, _, _) => {
|
||||
tcx.type_of(def.did).subst(tcx, substs)
|
||||
}
|
||||
AggregateKind::Closure(did, substs) => {
|
||||
|
@ -589,6 +589,7 @@ macro_rules! make_mir_visitor {
|
||||
AggregateKind::Adt(_adt_def,
|
||||
_variant_index,
|
||||
ref $($mutability)* substs,
|
||||
_user_substs,
|
||||
_active_field_index) => {
|
||||
self.visit_substs(substs, location);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
|
||||
|
||||
mir::Rvalue::Aggregate(ref kind, ref operands) => {
|
||||
let (dest, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
|
||||
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
|
||||
dest.codegen_set_discr(&bx, variant_index);
|
||||
if adt_def.is_enum() {
|
||||
(dest.project_downcast(&bx, variant_index), active_field_index)
|
||||
|
@ -917,6 +917,20 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
terr
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(user_ty) = self.rvalue_user_ty(rv) {
|
||||
if let Err(terr) = self.eq_canonical_type_and_type(user_ty, rv_ty, location.boring()) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
stmt,
|
||||
"bad user type on rvalue ({:?} = {:?}): {:?}",
|
||||
user_ty,
|
||||
rv_ty,
|
||||
terr
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
self.check_rvalue(mir, rv, location);
|
||||
if !self.tcx().features().unsized_locals {
|
||||
let trait_ref = ty::TraitRef {
|
||||
@ -1391,7 +1405,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
match *ak {
|
||||
AggregateKind::Adt(def, variant_index, substs, active_field_index) => {
|
||||
AggregateKind::Adt(def, variant_index, substs, _, active_field_index) => {
|
||||
let variant = &def.variants[variant_index];
|
||||
let adj_field_index = active_field_index.unwrap_or(field_index);
|
||||
if let Some(field) = variant.fields.get(adj_field_index) {
|
||||
@ -1557,6 +1571,36 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// If this rvalue supports a user-given type annotation, then
|
||||
/// extract and return it. This represents the final type of the
|
||||
/// rvalue and will be unified with the inferred type.
|
||||
fn rvalue_user_ty(
|
||||
&self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
) -> Option<CanonicalTy<'tcx>> {
|
||||
match rvalue {
|
||||
Rvalue::Use(_) |
|
||||
Rvalue::Repeat(..) |
|
||||
Rvalue::Ref(..) |
|
||||
Rvalue::Len(..) |
|
||||
Rvalue::Cast(..) |
|
||||
Rvalue::BinaryOp(..) |
|
||||
Rvalue::CheckedBinaryOp(..) |
|
||||
Rvalue::NullaryOp(..) |
|
||||
Rvalue::UnaryOp(..) |
|
||||
Rvalue::Discriminant(..) =>
|
||||
None,
|
||||
|
||||
Rvalue::Aggregate(aggregate, _) => match **aggregate {
|
||||
AggregateKind::Adt(_, _, _, user_ty, _) => user_ty,
|
||||
AggregateKind::Array(_) => None,
|
||||
AggregateKind::Tuple => None,
|
||||
AggregateKind::Closure(_, _) => None,
|
||||
AggregateKind::Generator(_, _, _) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_aggregate_rvalue(
|
||||
&mut self,
|
||||
mir: &Mir<'tcx>,
|
||||
@ -1750,7 +1794,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
);
|
||||
|
||||
let instantiated_predicates = match aggregate_kind {
|
||||
AggregateKind::Adt(def, _, substs, _) => {
|
||||
AggregateKind::Adt(def, _, substs, _, _) => {
|
||||
tcx.predicates_of(def.did).instantiate(tcx, substs)
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
block.and(Rvalue::Aggregate(result, operands))
|
||||
}
|
||||
ExprKind::Adt {
|
||||
adt_def, variant_index, substs, fields, base
|
||||
adt_def, variant_index, substs, user_ty, fields, base
|
||||
} => { // see (*) above
|
||||
let is_union = adt_def.is_union();
|
||||
let active_field_index = if is_union { Some(fields[0].name.index()) } else { None };
|
||||
@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
let adt =
|
||||
box AggregateKind::Adt(adt_def, variant_index, substs, active_field_index);
|
||||
box AggregateKind::Adt(adt_def, variant_index, substs, user_ty, active_field_index);
|
||||
block.and(Rvalue::Aggregate(adt, fields))
|
||||
}
|
||||
ExprKind::Assign { .. } |
|
||||
|
@ -256,6 +256,16 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
};
|
||||
if let Some((adt_def, index)) = adt_data {
|
||||
let substs = cx.tables().node_substs(fun.hir_id);
|
||||
|
||||
let user_ty = cx.tables().user_substs(fun.hir_id)
|
||||
.map(|user_substs| {
|
||||
user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_adt(adt_def, user_substs)
|
||||
})
|
||||
});
|
||||
|
||||
let field_refs = args.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, e)| {
|
||||
@ -265,12 +275,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
// FIXME(#47184) -- user given type annot on ADTs
|
||||
ExprKind::Adt {
|
||||
adt_def,
|
||||
substs,
|
||||
variant_index: index,
|
||||
fields: field_refs,
|
||||
user_ty,
|
||||
base: None,
|
||||
}
|
||||
} else {
|
||||
@ -424,11 +434,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
ty::Adt(adt, substs) => {
|
||||
match adt.adt_kind() {
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
// FIXME(#47184) -- user given type annot on ADTs
|
||||
ExprKind::Adt {
|
||||
adt_def: adt,
|
||||
variant_index: 0,
|
||||
substs,
|
||||
user_ty: user_annotated_ty_for_adt(cx, expr.hir_id, adt),
|
||||
fields: field_refs(cx, fields),
|
||||
base: base.as_ref().map(|base| {
|
||||
FruInfo {
|
||||
@ -450,11 +460,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
assert!(base.is_none());
|
||||
|
||||
let index = adt.variant_index_with_id(variant_id);
|
||||
// FIXME(#47184) -- user given type annot on ADTs
|
||||
ExprKind::Adt {
|
||||
adt_def: adt,
|
||||
variant_index: index,
|
||||
substs,
|
||||
user_ty: user_annotated_ty_for_adt(cx, expr.hir_id, adt),
|
||||
fields: field_refs(cx, fields),
|
||||
base: None,
|
||||
}
|
||||
@ -694,8 +704,7 @@ fn user_annotated_ty_for_def(
|
||||
hir_id: hir::HirId,
|
||||
def: &Def,
|
||||
) -> Option<CanonicalTy<'tcx>> {
|
||||
let user_substs = cx.tables().user_substs(hir_id)?;
|
||||
Some(match def {
|
||||
match def {
|
||||
// A reference to something callable -- e.g., a fn, method, or
|
||||
// a tuple-struct or tuple-variant. This has the type of a
|
||||
// `Fn` but with the user-given substitutions.
|
||||
@ -703,11 +712,11 @@ fn user_annotated_ty_for_def(
|
||||
Def::Method(_) |
|
||||
Def::StructCtor(_, CtorKind::Fn) |
|
||||
Def::VariantCtor(_, CtorKind::Fn) =>
|
||||
user_substs.unchecked_map(|user_substs| {
|
||||
Some(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
|
||||
// Here, we just pair a `DefId` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_fn_def(def.def_id(), user_substs)
|
||||
}),
|
||||
})),
|
||||
|
||||
Def::Const(_def_id) |
|
||||
Def::AssociatedConst(_def_id) =>
|
||||
@ -720,18 +729,26 @@ fn user_annotated_ty_for_def(
|
||||
Def::StructCtor(_def_id, CtorKind::Const) |
|
||||
Def::VariantCtor(_def_id, CtorKind::Const) =>
|
||||
match &cx.tables().node_id_to_type(hir_id).sty {
|
||||
ty::TyAdt(adt_def, _) =>
|
||||
user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_adt(adt_def, user_substs)
|
||||
}),
|
||||
ty::Adt(adt_def, _) => user_annotated_ty_for_adt(cx, hir_id, adt_def),
|
||||
sty => bug!("unexpected sty: {:?}", sty),
|
||||
},
|
||||
|
||||
_ =>
|
||||
bug!("user_annotated_ty_for_def: unexpected def {:?} at {:?}", def, hir_id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn user_annotated_ty_for_adt(
|
||||
cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
adt_def: &'tcx AdtDef,
|
||||
) -> Option<CanonicalTy<'tcx>> {
|
||||
let user_substs = cx.tables().user_substs(hir_id)?;
|
||||
Some(user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_adt(adt_def, user_substs)
|
||||
}))
|
||||
}
|
||||
|
||||
fn method_callee<'a, 'gcx, 'tcx>(
|
||||
@ -835,7 +852,6 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
|
||||
Def::StructCtor(def_id, CtorKind::Const) |
|
||||
Def::VariantCtor(def_id, CtorKind::Const) => {
|
||||
// FIXME(#47184) -- user given type annot on ADTs
|
||||
match cx.tables().node_id_to_type(expr.hir_id).sty {
|
||||
// A unit struct/variant which is used as a value.
|
||||
// We return a completely different ExprKind here to account for this special case.
|
||||
@ -844,6 +860,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
adt_def,
|
||||
variant_index: adt_def.variant_index_with_id(def_id),
|
||||
substs,
|
||||
user_ty: user_annotated_ty_for_adt(cx, expr.hir_id, adt_def),
|
||||
fields: vec![],
|
||||
base: None,
|
||||
}
|
||||
|
@ -261,6 +261,11 @@ pub enum ExprKind<'tcx> {
|
||||
adt_def: &'tcx AdtDef,
|
||||
variant_index: usize,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
|
||||
/// Optional user-given substs: for something like `let x =
|
||||
/// Bar::<T> { ... }`.
|
||||
user_ty: Option<CanonicalTy<'tcx>>,
|
||||
|
||||
fields: Vec<FieldExprRef<'tcx>>,
|
||||
base: Option<FruInfo<'tcx>>
|
||||
},
|
||||
|
@ -208,7 +208,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
|
||||
Aggregate(ref kind, ref operands) => {
|
||||
let (dest, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
|
||||
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
|
||||
self.write_discriminant_value(variant_index, dest)?;
|
||||
if adt_def.is_enum() {
|
||||
(self.place_downcast(dest, variant_index)?, active_field_index)
|
||||
|
@ -850,7 +850,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
|
||||
kind: StatementKind::Assign(
|
||||
Place::Local(RETURN_PLACE),
|
||||
Rvalue::Aggregate(
|
||||
box AggregateKind::Adt(adt_def, variant_no, substs, None),
|
||||
box AggregateKind::Adt(adt_def, variant_no, substs, None, None),
|
||||
(1..sig.inputs().len()+1).map(|i| {
|
||||
Operand::Move(Place::Local(Local::new(i)))
|
||||
}).collect()
|
||||
|
@ -48,7 +48,7 @@ impl MirPass for Deaggregator {
|
||||
|
||||
let mut set_discriminant = None;
|
||||
let active_field_index = match *kind {
|
||||
AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
|
||||
AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
|
||||
if adt_def.is_enum() {
|
||||
set_discriminant = Some(Statement {
|
||||
kind: StatementKind::SetDiscriminant {
|
||||
|
@ -157,7 +157,7 @@ struct TransformVisitor<'a, 'tcx: 'a> {
|
||||
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||
// Make a GeneratorState rvalue
|
||||
fn make_state(&self, idx: usize, val: Operand<'tcx>) -> Rvalue<'tcx> {
|
||||
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None);
|
||||
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None, None);
|
||||
Rvalue::Aggregate(box adt, vec![val])
|
||||
}
|
||||
|
||||
|
@ -1367,7 +1367,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||
-> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
|
||||
debug!("def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})",
|
||||
path.def, opt_self_ty, path.segments);
|
||||
|
||||
let span = path.span;
|
||||
|
@ -2113,16 +2113,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_user_substs(&self, node_id: hir::HirId, substs: CanonicalSubsts<'tcx>) {
|
||||
/// Given the substs that we just converted from the HIR, try to
|
||||
/// canonicalize them and store them as user-given substitutions
|
||||
/// (i.e., substitutions that must be respected by the NLL check).
|
||||
///
|
||||
/// This should be invoked **before any unifications have
|
||||
/// 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>) {
|
||||
if !substs.is_noop() {
|
||||
let user_substs = self.infcx.canonicalize_response(&substs);
|
||||
debug!("instantiate_value_path: user_substs = {:?}", user_substs);
|
||||
self.write_user_substs(hir_id, user_substs);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_user_substs(&self, hir_id: hir::HirId, substs: CanonicalSubsts<'tcx>) {
|
||||
debug!(
|
||||
"write_user_substs({:?}, {:?}) in fcx {}",
|
||||
node_id,
|
||||
hir_id,
|
||||
substs,
|
||||
self.tag(),
|
||||
);
|
||||
|
||||
if !substs.is_identity() {
|
||||
self.tables.borrow_mut().user_substs_mut().insert(node_id, substs);
|
||||
self.tables.borrow_mut().user_substs_mut().insert(hir_id, substs);
|
||||
} else {
|
||||
debug!("write_user_substs: skipping identity substs");
|
||||
}
|
||||
@ -3596,6 +3611,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
if let Some((variant, did, substs)) = variant {
|
||||
debug!("check_struct_path: did={:?} substs={:?}", did, substs);
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
|
||||
self.write_user_substs_from_substs(hir_id, substs);
|
||||
|
||||
// Check bounds on type arguments used in the path.
|
||||
let bounds = self.instantiate_bounds(path_span, did, substs);
|
||||
let cause = traits::ObligationCause::new(path_span, self.body_id,
|
||||
@ -5138,11 +5157,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
|
||||
self.write_substs(hir_id, substs);
|
||||
|
||||
if !substs.is_noop() {
|
||||
let user_substs = self.infcx.canonicalize_response(&substs);
|
||||
debug!("instantiate_value_path: user_substs = {:?}", user_substs);
|
||||
self.write_user_substs(hir_id, user_substs);
|
||||
}
|
||||
self.write_user_substs_from_substs(hir_id, substs);
|
||||
|
||||
ty_substituted
|
||||
}
|
||||
|
62
src/test/ui/nll/user-annotations/adt-brace-enums.rs
Normal file
62
src/test/ui/nll/user-annotations/adt-brace-enums.rs
Normal file
@ -0,0 +1,62 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
enum SomeEnum<T> {
|
||||
SomeVariant { t: T }
|
||||
}
|
||||
|
||||
fn no_annot() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant { t: &c };
|
||||
}
|
||||
|
||||
fn annot_underscore() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<_> { t: &c };
|
||||
}
|
||||
|
||||
fn annot_reference_any_lifetime() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&u32> { t: &c };
|
||||
}
|
||||
|
||||
fn annot_reference_static_lifetime() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'static u32> { t: &c }; //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) {
|
||||
SomeEnum::SomeVariant::<&'a u32> { t: c };
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
let _closure = || {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) {
|
||||
let _closure = || {
|
||||
SomeEnum::SomeVariant::<&'a u32> { t: c };
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
41
src/test/ui/nll/user-annotations/adt-brace-enums.stderr
Normal file
41
src/test/ui/nll/user-annotations/adt-brace-enums.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-enums.rs:37:48
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-enums.rs:42:43
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 40:35...
|
||||
--> $DIR/adt-brace-enums.rs:40:35
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-enums.rs:52:47
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 49:46...
|
||||
--> $DIR/adt-brace-enums.rs:49:46
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
60
src/test/ui/nll/user-annotations/adt-brace-structs.rs
Normal file
60
src/test/ui/nll/user-annotations/adt-brace-structs.rs
Normal file
@ -0,0 +1,60 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
struct SomeStruct<T> { t: T }
|
||||
|
||||
fn no_annot() {
|
||||
let c = 66;
|
||||
SomeStruct { t: &c };
|
||||
}
|
||||
|
||||
fn annot_underscore() {
|
||||
let c = 66;
|
||||
SomeStruct::<_> { t: &c };
|
||||
}
|
||||
|
||||
fn annot_reference_any_lifetime() {
|
||||
let c = 66;
|
||||
SomeStruct::<&u32> { t: &c };
|
||||
}
|
||||
|
||||
fn annot_reference_static_lifetime() {
|
||||
let c = 66;
|
||||
SomeStruct::<&'static u32> { t: &c }; //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
let c = 66;
|
||||
SomeStruct::<&'a u32> { t: &c }; //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) {
|
||||
SomeStruct::<&'a u32> { t: c };
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
let _closure = || {
|
||||
let c = 66;
|
||||
SomeStruct::<&'a u32> { t: &c }; //~ ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) {
|
||||
let _closure = || {
|
||||
SomeStruct::<&'a u32> { t: c };
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
41
src/test/ui/nll/user-annotations/adt-brace-structs.stderr
Normal file
41
src/test/ui/nll/user-annotations/adt-brace-structs.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-structs.rs:35:37
|
||||
|
|
||||
LL | SomeStruct::<&'static u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-structs.rs:40:32
|
||||
|
|
||||
LL | SomeStruct::<&'a u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 38:35...
|
||||
--> $DIR/adt-brace-structs.rs:38:35
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-brace-structs.rs:50:36
|
||||
|
|
||||
LL | SomeStruct::<&'a u32> { t: &c }; //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 47:46...
|
||||
--> $DIR/adt-brace-structs.rs:47:46
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
68
src/test/ui/nll/user-annotations/adt-nullary-enums.rs
Normal file
68
src/test/ui/nll/user-annotations/adt-nullary-enums.rs
Normal file
@ -0,0 +1,68 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
#![feature(nll)]
|
||||
#![allow(warnings)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
enum SomeEnum<T> {
|
||||
SomeVariant(T),
|
||||
SomeOtherVariant,
|
||||
}
|
||||
|
||||
fn combine<T>(_: T, _: T) { }
|
||||
|
||||
fn no_annot() {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant);
|
||||
}
|
||||
|
||||
fn annot_underscore() {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<_>>);
|
||||
}
|
||||
|
||||
fn annot_reference_any_lifetime() {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&u32>>);
|
||||
}
|
||||
|
||||
fn annot_reference_static_lifetime() {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'static u32>>); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) {
|
||||
combine(SomeEnum::SomeVariant(Cell::new(c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>);
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
let _closure = || {
|
||||
let c = 66;
|
||||
combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>); //~ ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) {
|
||||
let _closure = || {
|
||||
combine(SomeEnum::SomeVariant(Cell::new(c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>);
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
41
src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
Normal file
41
src/test/ui/nll/user-annotations/adt-nullary-enums.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-nullary-enums.rs:43:45
|
||||
|
|
||||
LL | combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'static u32>>); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-nullary-enums.rs:48:45
|
||||
|
|
||||
LL | combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 46:35...
|
||||
--> $DIR/adt-nullary-enums.rs:46:35
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-nullary-enums.rs:58:49
|
||||
|
|
||||
LL | combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::<Cell<&'a u32>>); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 55:46...
|
||||
--> $DIR/adt-nullary-enums.rs:55:46
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
64
src/test/ui/nll/user-annotations/adt-tuple-enums.rs
Normal file
64
src/test/ui/nll/user-annotations/adt-tuple-enums.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
#![feature(nll)]
|
||||
#![allow(warnings)]
|
||||
|
||||
enum SomeEnum<T> {
|
||||
SomeVariant(T),
|
||||
SomeOtherVariant,
|
||||
}
|
||||
|
||||
fn no_annot() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant(&c);
|
||||
}
|
||||
|
||||
fn annot_underscore() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<_>(&c);
|
||||
}
|
||||
|
||||
fn annot_reference_any_lifetime() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&u32>(&c);
|
||||
}
|
||||
|
||||
fn annot_reference_static_lifetime() {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'static u32>(&c); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) {
|
||||
SomeEnum::SomeVariant::<&'a u32>(c);
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
let _closure = || {
|
||||
let c = 66;
|
||||
SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) {
|
||||
let _closure = || {
|
||||
SomeEnum::SomeVariant::<&'a u32>(c);
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
41
src/test/ui/nll/user-annotations/adt-tuple-enums.stderr
Normal file
41
src/test/ui/nll/user-annotations/adt-tuple-enums.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-enums.rs:39:43
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'static u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-enums.rs:44:38
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 42:35...
|
||||
--> $DIR/adt-tuple-enums.rs:42:35
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-enums.rs:54:42
|
||||
|
|
||||
LL | SomeEnum::SomeVariant::<&'a u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 51:46...
|
||||
--> $DIR/adt-tuple-enums.rs:51:46
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
60
src/test/ui/nll/user-annotations/adt-tuple-struct.rs
Normal file
60
src/test/ui/nll/user-annotations/adt-tuple-struct.rs
Normal file
@ -0,0 +1,60 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
struct SomeStruct<T>(T);
|
||||
|
||||
fn no_annot() {
|
||||
let c = 66;
|
||||
SomeStruct(&c);
|
||||
}
|
||||
|
||||
fn annot_underscore() {
|
||||
let c = 66;
|
||||
SomeStruct::<_>(&c);
|
||||
}
|
||||
|
||||
fn annot_reference_any_lifetime() {
|
||||
let c = 66;
|
||||
SomeStruct::<&u32>(&c);
|
||||
}
|
||||
|
||||
fn annot_reference_static_lifetime() {
|
||||
let c = 66;
|
||||
SomeStruct::<&'static u32>(&c); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
let c = 66;
|
||||
SomeStruct::<&'a u32>(&c); //~ ERROR
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) {
|
||||
SomeStruct::<&'a u32>(c);
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
let _closure = || {
|
||||
let c = 66;
|
||||
SomeStruct::<&'a u32>(&c); //~ ERROR
|
||||
};
|
||||
}
|
||||
|
||||
fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) {
|
||||
let _closure = || {
|
||||
SomeStruct::<&'a u32>(c);
|
||||
};
|
||||
}
|
||||
|
||||
fn main() { }
|
41
src/test/ui/nll/user-annotations/adt-tuple-struct.stderr
Normal file
41
src/test/ui/nll/user-annotations/adt-tuple-struct.stderr
Normal file
@ -0,0 +1,41 @@
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-struct.rs:35:32
|
||||
|
|
||||
LL | SomeStruct::<&'static u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
= note: borrowed value must be valid for the static lifetime...
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-struct.rs:40:27
|
||||
|
|
||||
LL | SomeStruct::<&'a u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | }
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 38:35...
|
||||
--> $DIR/adt-tuple-struct.rs:38:35
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error[E0597]: `c` does not live long enough
|
||||
--> $DIR/adt-tuple-struct.rs:50:31
|
||||
|
|
||||
LL | SomeStruct::<&'a u32>(&c); //~ ERROR
|
||||
| ^^ borrowed value does not live long enough
|
||||
LL | };
|
||||
| - `c` dropped here while still borrowed
|
||||
|
|
||||
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 47:46...
|
||||
--> $DIR/adt-tuple-struct.rs:47:46
|
||||
|
|
||||
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||
| ^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
29
src/test/ui/nll/user-annotations/dump-adt-brace-struct.rs
Normal file
29
src/test/ui/nll/user-annotations/dump-adt-brace-struct.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// 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.
|
||||
|
||||
// Unit test for the "user substitutions" that are annotated on each
|
||||
// node.
|
||||
|
||||
// compile-flags:-Zverbose
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(nll)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct SomeStruct<T> { t: T }
|
||||
|
||||
#[rustc_dump_user_substs]
|
||||
fn main() {
|
||||
SomeStruct { t: 22 }; // Nothing given, no annotation.
|
||||
|
||||
SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation.
|
||||
|
||||
SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
error: user substs: Canonical { variables: [], value: [u32] }
|
||||
--> $DIR/dump-adt-brace-struct.rs:28:5
|
||||
|
|
||||
LL | SomeStruct::<u32> { t: 22 }; //~ ERROR [u32]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user