Auto merge of #38325 - frewsxcv:rollup, r=frewsxcv
Rollup of 7 pull requests - Successful merges: #37052, #37941, #38067, #38164, #38202, #38264, #38299 - Failed merges:
This commit is contained in:
commit
5a2b50b33d
15 changed files with 1254 additions and 332 deletions
|
@ -44,7 +44,9 @@
|
||||||
font-family: 'Source Code Pro';
|
font-family: 'Source Code Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
|
/* Avoid using locally installed font because bad versions are in circulation:
|
||||||
|
* see https://github.com/rust-lang/rust/issues/24355 */
|
||||||
|
src: url("SourceCodePro-Regular.woff") format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
*:not(body) {
|
*:not(body) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
|
||||||
extent: cx.tcx.region_maps.node_extent(self.id),
|
extent: cx.tcx.region_maps.node_extent(self.id),
|
||||||
span: self.span,
|
span: self.span,
|
||||||
stmts: stmts,
|
stmts: stmts,
|
||||||
expr: self.expr.to_ref()
|
expr: self.expr.to_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,39 +34,44 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
|
||||||
fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
block_id: ast::NodeId,
|
block_id: ast::NodeId,
|
||||||
stmts: &'tcx [hir::Stmt])
|
stmts: &'tcx [hir::Stmt])
|
||||||
-> Vec<StmtRef<'tcx>>
|
-> Vec<StmtRef<'tcx>> {
|
||||||
{
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
for (index, stmt) in stmts.iter().enumerate() {
|
for (index, stmt) in stmts.iter().enumerate() {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtExpr(ref expr, id) | hir::StmtSemi(ref expr, id) =>
|
hir::StmtExpr(ref expr, id) |
|
||||||
|
hir::StmtSemi(ref expr, id) => {
|
||||||
result.push(StmtRef::Mirror(Box::new(Stmt {
|
result.push(StmtRef::Mirror(Box::new(Stmt {
|
||||||
span: stmt.span,
|
span: stmt.span,
|
||||||
kind: StmtKind::Expr {
|
kind: StmtKind::Expr {
|
||||||
scope: cx.tcx.region_maps.node_extent(id),
|
scope: cx.tcx.region_maps.node_extent(id),
|
||||||
expr: expr.to_ref()
|
expr: expr.to_ref(),
|
||||||
|
},
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
hir::StmtDecl(ref decl, id) => {
|
||||||
|
match decl.node {
|
||||||
|
hir::DeclItem(..) => {
|
||||||
|
// ignore for purposes of the MIR
|
||||||
}
|
}
|
||||||
}))),
|
hir::DeclLocal(ref local) => {
|
||||||
hir::StmtDecl(ref decl, id) => match decl.node {
|
let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
|
||||||
hir::DeclItem(..) => { /* ignore for purposes of the MIR */ }
|
block: block_id,
|
||||||
hir::DeclLocal(ref local) => {
|
first_statement_index: index as u32,
|
||||||
let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
|
});
|
||||||
block: block_id,
|
let remainder_extent =
|
||||||
first_statement_index: index as u32,
|
cx.tcx.region_maps.lookup_code_extent(remainder_extent);
|
||||||
});
|
|
||||||
let remainder_extent =
|
|
||||||
cx.tcx.region_maps.lookup_code_extent(remainder_extent);
|
|
||||||
|
|
||||||
let pattern = Pattern::from_hir(cx.tcx, &local.pat);
|
let pattern = Pattern::from_hir(cx.tcx, &local.pat);
|
||||||
result.push(StmtRef::Mirror(Box::new(Stmt {
|
result.push(StmtRef::Mirror(Box::new(Stmt {
|
||||||
span: stmt.span,
|
span: stmt.span,
|
||||||
kind: StmtKind::Let {
|
kind: StmtKind::Let {
|
||||||
remainder_scope: remainder_extent,
|
remainder_scope: remainder_extent,
|
||||||
init_scope: cx.tcx.region_maps.node_extent(id),
|
init_scope: cx.tcx.region_maps.node_extent(id),
|
||||||
pattern: pattern,
|
pattern: pattern,
|
||||||
initializer: local.init.to_ref(),
|
initializer: local.init.to_ref(),
|
||||||
},
|
},
|
||||||
})));
|
})));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
let adj = cx.tcx.tables().adjustments.get(&self.id).cloned();
|
let adj = cx.tcx.tables().adjustments.get(&self.id).cloned();
|
||||||
|
|
||||||
debug!("make_mirror: unadjusted-expr={:?} applying adjustments={:?}",
|
debug!("make_mirror: unadjusted-expr={:?} applying adjustments={:?}",
|
||||||
expr, adj);
|
expr,
|
||||||
|
adj);
|
||||||
|
|
||||||
// Now apply adjustments, if any.
|
// Now apply adjustments, if any.
|
||||||
match adj.map(|adj| (adj.kind, adj.target)) {
|
match adj.map(|adj| (adj.kind, adj.target)) {
|
||||||
|
@ -78,41 +79,44 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
for i in 0..autoderefs {
|
for i in 0..autoderefs {
|
||||||
let i = i as u32;
|
let i = i as u32;
|
||||||
let adjusted_ty =
|
let adjusted_ty =
|
||||||
expr.ty.adjust_for_autoderef(
|
expr.ty.adjust_for_autoderef(cx.tcx, self.id, self.span, i, |mc| {
|
||||||
cx.tcx,
|
cx.tcx.tables().method_map.get(&mc).map(|m| m.ty)
|
||||||
self.id,
|
});
|
||||||
self.span,
|
debug!("make_mirror: autoderef #{}, adjusted_ty={:?}",
|
||||||
i,
|
i,
|
||||||
|mc| cx.tcx.tables().method_map.get(&mc).map(|m| m.ty));
|
adjusted_ty);
|
||||||
debug!("make_mirror: autoderef #{}, adjusted_ty={:?}", i, adjusted_ty);
|
|
||||||
let method_key = ty::MethodCall::autoderef(self.id, i);
|
let method_key = ty::MethodCall::autoderef(self.id, i);
|
||||||
let meth_ty =
|
let meth_ty = cx.tcx.tables().method_map.get(&method_key).map(|m| m.ty);
|
||||||
cx.tcx.tables().method_map.get(&method_key).map(|m| m.ty);
|
|
||||||
let kind = if let Some(meth_ty) = meth_ty {
|
let kind = if let Some(meth_ty) = meth_ty {
|
||||||
debug!("make_mirror: overloaded autoderef (meth_ty={:?})", meth_ty);
|
debug!("make_mirror: overloaded autoderef (meth_ty={:?})", meth_ty);
|
||||||
|
|
||||||
let ref_ty = cx.tcx.no_late_bound_regions(&meth_ty.fn_ret());
|
let ref_ty = cx.tcx.no_late_bound_regions(&meth_ty.fn_ret());
|
||||||
let (region, mutbl) = match ref_ty {
|
let (region, mutbl) = match ref_ty {
|
||||||
Some(&ty::TyS {
|
Some(&ty::TyS { sty: ty::TyRef(region, mt), .. }) => (region, mt.mutbl),
|
||||||
sty: ty::TyRef(region, mt), ..
|
_ => span_bug!(expr.span, "autoderef returned bad type"),
|
||||||
}) => (region, mt.mutbl),
|
|
||||||
_ => span_bug!(expr.span, "autoderef returned bad type")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
expr = Expr {
|
expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: cx.tcx.mk_ref(
|
ty: cx.tcx.mk_ref(region,
|
||||||
region, ty::TypeAndMut { ty: expr.ty, mutbl: mutbl }),
|
ty::TypeAndMut {
|
||||||
|
ty: expr.ty,
|
||||||
|
mutbl: mutbl,
|
||||||
|
}),
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Borrow {
|
kind: ExprKind::Borrow {
|
||||||
region: region,
|
region: region,
|
||||||
borrow_kind: to_borrow_kind(mutbl),
|
borrow_kind: to_borrow_kind(mutbl),
|
||||||
arg: expr.to_ref()
|
arg: expr.to_ref(),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
overloaded_lvalue(cx, self, method_key,
|
overloaded_lvalue(cx,
|
||||||
PassArgs::ByRef, expr.to_ref(), vec![])
|
self,
|
||||||
|
method_key,
|
||||||
|
PassArgs::ByRef,
|
||||||
|
expr.to_ref(),
|
||||||
|
vec![])
|
||||||
} else {
|
} else {
|
||||||
debug!("make_mirror: built-in autoderef");
|
debug!("make_mirror: built-in autoderef");
|
||||||
ExprKind::Deref { arg: expr.to_ref() }
|
ExprKind::Deref { arg: expr.to_ref() }
|
||||||
|
@ -148,7 +152,11 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
let region = cx.tcx.mk_region(region);
|
let region = cx.tcx.mk_region(region);
|
||||||
expr = Expr {
|
expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, mutbl: m }),
|
ty: cx.tcx.mk_ref(region,
|
||||||
|
ty::TypeAndMut {
|
||||||
|
ty: expr.ty,
|
||||||
|
mutbl: m,
|
||||||
|
}),
|
||||||
span: self.span,
|
span: self.span,
|
||||||
kind: ExprKind::Borrow {
|
kind: ExprKind::Borrow {
|
||||||
region: region,
|
region: region,
|
||||||
|
@ -240,12 +248,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
let sig = match method.ty.sty {
|
let sig = match method.ty.sty {
|
||||||
ty::TyFnDef(.., fn_ty) => &fn_ty.sig,
|
ty::TyFnDef(.., fn_ty) => &fn_ty.sig,
|
||||||
_ => span_bug!(expr.span, "type of method is not an fn")
|
_ => span_bug!(expr.span, "type of method is not an fn"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let sig = cx.tcx.no_late_bound_regions(sig).unwrap_or_else(|| {
|
let sig = cx.tcx
|
||||||
span_bug!(expr.span, "method call has late-bound regions")
|
.no_late_bound_regions(sig)
|
||||||
});
|
.unwrap_or_else(|| span_bug!(expr.span, "method call has late-bound regions"));
|
||||||
|
|
||||||
assert_eq!(sig.inputs().len(), 2);
|
assert_eq!(sig.inputs().len(), 2);
|
||||||
|
|
||||||
|
@ -253,44 +261,49 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
ty: sig.inputs()[1],
|
ty: sig.inputs()[1],
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Tuple {
|
kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() },
|
||||||
fields: args.iter().map(ToRef::to_ref).collect()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ExprKind::Call {
|
ExprKind::Call {
|
||||||
ty: method.ty,
|
ty: method.ty,
|
||||||
fun: method.to_ref(),
|
fun: method.to_ref(),
|
||||||
args: vec![fun.to_ref(), tupled_args.to_ref()]
|
args: vec![fun.to_ref(), tupled_args.to_ref()],
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let adt_data = if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = fun.node {
|
let adt_data = if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = fun.node {
|
||||||
// Tuple-like ADTs are represented as ExprCall. We convert them here.
|
// Tuple-like ADTs are represented as ExprCall. We convert them here.
|
||||||
expr_ty.ty_adt_def().and_then(|adt_def|{
|
expr_ty.ty_adt_def().and_then(|adt_def| {
|
||||||
match path.def {
|
match path.def {
|
||||||
Def::VariantCtor(variant_id, CtorKind::Fn) => {
|
Def::VariantCtor(variant_id, CtorKind::Fn) => {
|
||||||
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
|
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
|
||||||
},
|
}
|
||||||
Def::StructCtor(_, CtorKind::Fn) => {
|
Def::StructCtor(_, CtorKind::Fn) => Some((adt_def, 0)),
|
||||||
Some((adt_def, 0))
|
_ => None,
|
||||||
},
|
|
||||||
_ => None
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else { None };
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
if let Some((adt_def, index)) = adt_data {
|
if let Some((adt_def, index)) = adt_data {
|
||||||
let substs = cx.tcx.tables().node_id_item_substs(fun.id)
|
let substs = cx.tcx
|
||||||
|
.tables()
|
||||||
|
.node_id_item_substs(fun.id)
|
||||||
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
||||||
let field_refs = args.iter().enumerate().map(|(idx, e)| FieldExprRef {
|
let field_refs = args.iter()
|
||||||
name: Field::new(idx),
|
.enumerate()
|
||||||
expr: e.to_ref()
|
.map(|(idx, e)| {
|
||||||
}).collect();
|
FieldExprRef {
|
||||||
|
name: Field::new(idx),
|
||||||
|
expr: e.to_ref(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
ExprKind::Adt {
|
ExprKind::Adt {
|
||||||
adt_def: adt_def,
|
adt_def: adt_def,
|
||||||
substs: substs,
|
substs: substs,
|
||||||
variant_index: index,
|
variant_index: index,
|
||||||
fields: field_refs,
|
fields: field_refs,
|
||||||
base: None
|
base: None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Call {
|
ExprKind::Call {
|
||||||
|
@ -314,9 +327,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprBlock(ref blk) => {
|
hir::ExprBlock(ref blk) => ExprKind::Block { body: &blk },
|
||||||
ExprKind::Block { body: &blk }
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::ExprAssign(ref lhs, ref rhs) => {
|
hir::ExprAssign(ref lhs, ref rhs) => {
|
||||||
ExprKind::Assign {
|
ExprKind::Assign {
|
||||||
|
@ -332,8 +343,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
} else {
|
} else {
|
||||||
PassArgs::ByRef
|
PassArgs::ByRef
|
||||||
};
|
};
|
||||||
overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_operator(cx,
|
||||||
pass_args, lhs.to_ref(), vec![rhs])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
pass_args,
|
||||||
|
lhs.to_ref(),
|
||||||
|
vec![rhs])
|
||||||
} else {
|
} else {
|
||||||
ExprKind::AssignOp {
|
ExprKind::AssignOp {
|
||||||
op: bin_op(op.node),
|
op: bin_op(op.node),
|
||||||
|
@ -343,9 +358,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprLit(..) => ExprKind::Literal {
|
hir::ExprLit(..) => ExprKind::Literal { literal: cx.const_eval_literal(expr) },
|
||||||
literal: cx.const_eval_literal(expr)
|
|
||||||
},
|
|
||||||
|
|
||||||
hir::ExprBinary(op, ref lhs, ref rhs) => {
|
hir::ExprBinary(op, ref lhs, ref rhs) => {
|
||||||
if cx.tcx.tables().is_method_call(expr.id) {
|
if cx.tcx.tables().is_method_call(expr.id) {
|
||||||
|
@ -354,8 +367,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
} else {
|
} else {
|
||||||
PassArgs::ByRef
|
PassArgs::ByRef
|
||||||
};
|
};
|
||||||
overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_operator(cx,
|
||||||
pass_args, lhs.to_ref(), vec![rhs])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
pass_args,
|
||||||
|
lhs.to_ref(),
|
||||||
|
vec![rhs])
|
||||||
} else {
|
} else {
|
||||||
// FIXME overflow
|
// FIXME overflow
|
||||||
match (op.node, cx.constness) {
|
match (op.node, cx.constness) {
|
||||||
|
@ -405,8 +422,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
hir::ExprIndex(ref lhs, ref index) => {
|
hir::ExprIndex(ref lhs, ref index) => {
|
||||||
if cx.tcx.tables().is_method_call(expr.id) {
|
if cx.tcx.tables().is_method_call(expr.id) {
|
||||||
overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_lvalue(cx,
|
||||||
PassArgs::ByValue, lhs.to_ref(), vec![index])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
PassArgs::ByValue,
|
||||||
|
lhs.to_ref(),
|
||||||
|
vec![index])
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Index {
|
ExprKind::Index {
|
||||||
lhs: lhs.to_ref(),
|
lhs: lhs.to_ref(),
|
||||||
|
@ -417,8 +438,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
hir::ExprUnary(hir::UnOp::UnDeref, ref arg) => {
|
hir::ExprUnary(hir::UnOp::UnDeref, ref arg) => {
|
||||||
if cx.tcx.tables().is_method_call(expr.id) {
|
if cx.tcx.tables().is_method_call(expr.id) {
|
||||||
overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_lvalue(cx,
|
||||||
PassArgs::ByValue, arg.to_ref(), vec![])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
PassArgs::ByValue,
|
||||||
|
arg.to_ref(),
|
||||||
|
vec![])
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Deref { arg: arg.to_ref() }
|
ExprKind::Deref { arg: arg.to_ref() }
|
||||||
}
|
}
|
||||||
|
@ -426,8 +451,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
hir::ExprUnary(hir::UnOp::UnNot, ref arg) => {
|
hir::ExprUnary(hir::UnOp::UnNot, ref arg) => {
|
||||||
if cx.tcx.tables().is_method_call(expr.id) {
|
if cx.tcx.tables().is_method_call(expr.id) {
|
||||||
overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_operator(cx,
|
||||||
PassArgs::ByValue, arg.to_ref(), vec![])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
PassArgs::ByValue,
|
||||||
|
arg.to_ref(),
|
||||||
|
vec![])
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Unary {
|
ExprKind::Unary {
|
||||||
op: UnOp::Not,
|
op: UnOp::Not,
|
||||||
|
@ -438,14 +467,16 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
|
hir::ExprUnary(hir::UnOp::UnNeg, ref arg) => {
|
||||||
if cx.tcx.tables().is_method_call(expr.id) {
|
if cx.tcx.tables().is_method_call(expr.id) {
|
||||||
overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id),
|
overloaded_operator(cx,
|
||||||
PassArgs::ByValue, arg.to_ref(), vec![])
|
expr,
|
||||||
|
ty::MethodCall::expr(expr.id),
|
||||||
|
PassArgs::ByValue,
|
||||||
|
arg.to_ref(),
|
||||||
|
vec![])
|
||||||
} else {
|
} else {
|
||||||
// FIXME runtime-overflow
|
// FIXME runtime-overflow
|
||||||
if let hir::ExprLit(_) = arg.node {
|
if let hir::ExprLit(_) = arg.node {
|
||||||
ExprKind::Literal {
|
ExprKind::Literal { literal: cx.const_eval_literal(expr) }
|
||||||
literal: cx.const_eval_literal(expr),
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Unary {
|
ExprKind::Unary {
|
||||||
op: UnOp::Neg,
|
op: UnOp::Neg,
|
||||||
|
@ -457,56 +488,54 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
hir::ExprStruct(ref qpath, ref fields, ref base) => {
|
hir::ExprStruct(ref qpath, ref fields, ref base) => {
|
||||||
match expr_ty.sty {
|
match expr_ty.sty {
|
||||||
ty::TyAdt(adt, substs) => match adt.adt_kind() {
|
ty::TyAdt(adt, substs) => {
|
||||||
AdtKind::Struct | AdtKind::Union => {
|
match adt.adt_kind() {
|
||||||
let field_refs = field_refs(&adt.variants[0], fields);
|
AdtKind::Struct | AdtKind::Union => {
|
||||||
ExprKind::Adt {
|
let field_refs = field_refs(&adt.variants[0], fields);
|
||||||
adt_def: adt,
|
ExprKind::Adt {
|
||||||
variant_index: 0,
|
adt_def: adt,
|
||||||
substs: substs,
|
variant_index: 0,
|
||||||
fields: field_refs,
|
substs: substs,
|
||||||
base: base.as_ref().map(|base| {
|
fields: field_refs,
|
||||||
FruInfo {
|
base: base.as_ref().map(|base| {
|
||||||
base: base.to_ref(),
|
FruInfo {
|
||||||
field_types:
|
base: base.to_ref(),
|
||||||
cx.tcx.tables().fru_field_types[&expr.id].clone()
|
field_types: cx.tcx.tables().fru_field_types[&expr.id]
|
||||||
}
|
.clone(),
|
||||||
})
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
AdtKind::Enum => {
|
||||||
AdtKind::Enum => {
|
let def = match *qpath {
|
||||||
let def = match *qpath {
|
hir::QPath::Resolved(_, ref path) => path.def,
|
||||||
hir::QPath::Resolved(_, ref path) => path.def,
|
hir::QPath::TypeRelative(..) => Def::Err,
|
||||||
hir::QPath::TypeRelative(..) => Def::Err
|
};
|
||||||
};
|
match def {
|
||||||
match def {
|
Def::Variant(variant_id) => {
|
||||||
Def::Variant(variant_id) => {
|
assert!(base.is_none());
|
||||||
assert!(base.is_none());
|
|
||||||
|
|
||||||
let index = adt.variant_index_with_id(variant_id);
|
let index = adt.variant_index_with_id(variant_id);
|
||||||
let field_refs = field_refs(&adt.variants[index], fields);
|
let field_refs = field_refs(&adt.variants[index], fields);
|
||||||
ExprKind::Adt {
|
ExprKind::Adt {
|
||||||
adt_def: adt,
|
adt_def: adt,
|
||||||
variant_index: index,
|
variant_index: index,
|
||||||
substs: substs,
|
substs: substs,
|
||||||
fields: field_refs,
|
fields: field_refs,
|
||||||
base: None
|
base: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
span_bug!(expr.span, "unexpected def: {:?}", def);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
span_bug!(
|
|
||||||
expr.span,
|
|
||||||
"unexpected def: {:?}",
|
|
||||||
def);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(
|
span_bug!(expr.span,
|
||||||
expr.span,
|
"unexpected type for struct literal: {:?}",
|
||||||
"unexpected type for struct literal: {:?}",
|
expr_ty);
|
||||||
expr_ty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,9 +545,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
let (def_id, substs) = match closure_ty.sty {
|
let (def_id, substs) = match closure_ty.sty {
|
||||||
ty::TyClosure(def_id, substs) => (def_id, substs),
|
ty::TyClosure(def_id, substs) => (def_id, substs),
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(expr.span,
|
span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
|
||||||
"closure expr w/o closure type: {:?}",
|
|
||||||
closure_ty);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let upvars = cx.tcx.with_freevars(expr.id, |freevars| {
|
let upvars = cx.tcx.with_freevars(expr.id, |freevars| {
|
||||||
|
@ -543,69 +570,81 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
ExprKind::InlineAsm {
|
ExprKind::InlineAsm {
|
||||||
asm: asm,
|
asm: asm,
|
||||||
outputs: outputs.to_ref(),
|
outputs: outputs.to_ref(),
|
||||||
inputs: inputs.to_ref()
|
inputs: inputs.to_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now comes the rote stuff:
|
// Now comes the rote stuff:
|
||||||
|
hir::ExprRepeat(ref v, ref c) => {
|
||||||
hir::ExprRepeat(ref v, ref c) => ExprKind::Repeat {
|
ExprKind::Repeat {
|
||||||
value: v.to_ref(),
|
value: v.to_ref(),
|
||||||
count: TypedConstVal {
|
count: TypedConstVal {
|
||||||
ty: cx.tcx.tables().expr_ty(c),
|
ty: cx.tcx.tables().expr_ty(c),
|
||||||
span: c.span,
|
span: c.span,
|
||||||
value: match const_eval::eval_const_expr(cx.tcx.global_tcx(), c) {
|
value: match const_eval::eval_const_expr(cx.tcx.global_tcx(), c) {
|
||||||
ConstVal::Integral(ConstInt::Usize(u)) => u,
|
ConstVal::Integral(ConstInt::Usize(u)) => u,
|
||||||
other => bug!("constant evaluation of repeat count yielded {:?}", other),
|
other => bug!("constant evaluation of repeat count yielded {:?}", other),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
hir::ExprRet(ref v) =>
|
hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() },
|
||||||
ExprKind::Return { value: v.to_ref() },
|
hir::ExprBreak(label, ref value) => {
|
||||||
hir::ExprBreak(label, ref value) =>
|
|
||||||
ExprKind::Break {
|
ExprKind::Break {
|
||||||
label: label.map(|label| {
|
label: label.map(|label| cx.tcx.region_maps.node_extent(label.loop_id)),
|
||||||
cx.tcx.region_maps.node_extent(label.loop_id)
|
value: value.to_ref(),
|
||||||
}),
|
}
|
||||||
value: value.to_ref()
|
}
|
||||||
},
|
hir::ExprAgain(label) => {
|
||||||
hir::ExprAgain(label) =>
|
|
||||||
ExprKind::Continue {
|
ExprKind::Continue {
|
||||||
label: label.map(|label| {
|
label: label.map(|label| cx.tcx.region_maps.node_extent(label.loop_id)),
|
||||||
cx.tcx.region_maps.node_extent(label.loop_id)
|
}
|
||||||
})
|
}
|
||||||
},
|
hir::ExprMatch(ref discr, ref arms, _) => {
|
||||||
hir::ExprMatch(ref discr, ref arms, _) =>
|
ExprKind::Match {
|
||||||
ExprKind::Match { discriminant: discr.to_ref(),
|
discriminant: discr.to_ref(),
|
||||||
arms: arms.iter().map(|a| convert_arm(cx, a)).collect() },
|
arms: arms.iter().map(|a| convert_arm(cx, a)).collect(),
|
||||||
hir::ExprIf(ref cond, ref then, ref otherwise) =>
|
}
|
||||||
ExprKind::If { condition: cond.to_ref(),
|
}
|
||||||
then: block::to_expr_ref(cx, then),
|
hir::ExprIf(ref cond, ref then, ref otherwise) => {
|
||||||
otherwise: otherwise.to_ref() },
|
ExprKind::If {
|
||||||
hir::ExprWhile(ref cond, ref body, _) =>
|
condition: cond.to_ref(),
|
||||||
ExprKind::Loop { condition: Some(cond.to_ref()),
|
then: block::to_expr_ref(cx, then),
|
||||||
body: block::to_expr_ref(cx, body) },
|
otherwise: otherwise.to_ref(),
|
||||||
hir::ExprLoop(ref body, _, _) =>
|
}
|
||||||
ExprKind::Loop { condition: None,
|
}
|
||||||
body: block::to_expr_ref(cx, body) },
|
hir::ExprWhile(ref cond, ref body, _) => {
|
||||||
|
ExprKind::Loop {
|
||||||
|
condition: Some(cond.to_ref()),
|
||||||
|
body: block::to_expr_ref(cx, body),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::ExprLoop(ref body, _, _) => {
|
||||||
|
ExprKind::Loop {
|
||||||
|
condition: None,
|
||||||
|
body: block::to_expr_ref(cx, body),
|
||||||
|
}
|
||||||
|
}
|
||||||
hir::ExprField(ref source, name) => {
|
hir::ExprField(ref source, name) => {
|
||||||
let index = match cx.tcx.tables().expr_ty_adjusted(source).sty {
|
let index = match cx.tcx.tables().expr_ty_adjusted(source).sty {
|
||||||
ty::TyAdt(adt_def, _) =>
|
ty::TyAdt(adt_def, _) => adt_def.variants[0].index_of_field_named(name.node),
|
||||||
adt_def.variants[0].index_of_field_named(name.node),
|
ref ty => span_bug!(expr.span, "field of non-ADT: {:?}", ty),
|
||||||
ref ty =>
|
|
||||||
span_bug!(expr.span, "field of non-ADT: {:?}", ty),
|
|
||||||
};
|
};
|
||||||
let index = index.unwrap_or_else(|| {
|
let index =
|
||||||
span_bug!(
|
index.unwrap_or_else(|| {
|
||||||
expr.span,
|
span_bug!(expr.span, "no index found for field `{}`", name.node)
|
||||||
"no index found for field `{}`",
|
});
|
||||||
name.node)
|
ExprKind::Field {
|
||||||
});
|
lhs: source.to_ref(),
|
||||||
ExprKind::Field { lhs: source.to_ref(), name: Field::new(index) }
|
name: Field::new(index),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::ExprTupField(ref source, index) => {
|
||||||
|
ExprKind::Field {
|
||||||
|
lhs: source.to_ref(),
|
||||||
|
name: Field::new(index.node as usize),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hir::ExprTupField(ref source, index) =>
|
|
||||||
ExprKind::Field { lhs: source.to_ref(),
|
|
||||||
name: Field::new(index.node as usize) },
|
|
||||||
hir::ExprCast(ref source, _) => {
|
hir::ExprCast(ref source, _) => {
|
||||||
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
||||||
// using a coercion (or is a no-op).
|
// using a coercion (or is a no-op).
|
||||||
|
@ -616,17 +655,15 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
ExprKind::Cast { source: source.to_ref() }
|
ExprKind::Cast { source: source.to_ref() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ExprType(ref source, _) =>
|
hir::ExprType(ref source, _) => return source.make_mirror(cx),
|
||||||
return source.make_mirror(cx),
|
hir::ExprBox(ref value) => {
|
||||||
hir::ExprBox(ref value) =>
|
|
||||||
ExprKind::Box {
|
ExprKind::Box {
|
||||||
value: value.to_ref(),
|
value: value.to_ref(),
|
||||||
value_extents: cx.tcx.region_maps.node_extent(value.id)
|
value_extents: cx.tcx.region_maps.node_extent(value.id),
|
||||||
},
|
}
|
||||||
hir::ExprArray(ref fields) =>
|
}
|
||||||
ExprKind::Vec { fields: fields.to_ref() },
|
hir::ExprArray(ref fields) => ExprKind::Vec { fields: fields.to_ref() },
|
||||||
hir::ExprTup(ref fields) =>
|
hir::ExprTup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() },
|
||||||
ExprKind::Tuple { fields: fields.to_ref() },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Expr {
|
Expr {
|
||||||
|
@ -663,8 +700,7 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
|
||||||
arm: &'tcx hir::Arm) -> Arm<'tcx> {
|
|
||||||
Arm {
|
Arm {
|
||||||
patterns: arm.pats.iter().map(|p| Pattern::from_hir(cx.tcx, p)).collect(),
|
patterns: arm.pats.iter().map(|p| Pattern::from_hir(cx.tcx, p)).collect(),
|
||||||
guard: arm.guard.to_ref(),
|
guard: arm.guard.to_ref(),
|
||||||
|
@ -676,41 +712,48 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
expr: &'tcx hir::Expr,
|
expr: &'tcx hir::Expr,
|
||||||
def: Def)
|
def: Def)
|
||||||
-> ExprKind<'tcx> {
|
-> ExprKind<'tcx> {
|
||||||
let substs = cx.tcx.tables().node_id_item_substs(expr.id)
|
let substs = cx.tcx
|
||||||
|
.tables()
|
||||||
|
.node_id_item_substs(expr.id)
|
||||||
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
.unwrap_or_else(|| cx.tcx.intern_substs(&[]));
|
||||||
let def_id = match def {
|
let def_id = match def {
|
||||||
// A regular function, constructor function or a constant.
|
// A regular function, constructor function or a constant.
|
||||||
Def::Fn(def_id) | Def::Method(def_id) |
|
Def::Fn(def_id) |
|
||||||
|
Def::Method(def_id) |
|
||||||
Def::StructCtor(def_id, CtorKind::Fn) |
|
Def::StructCtor(def_id, CtorKind::Fn) |
|
||||||
Def::VariantCtor(def_id, CtorKind::Fn) |
|
Def::VariantCtor(def_id, CtorKind::Fn) |
|
||||||
Def::Const(def_id) | Def::AssociatedConst(def_id) => def_id,
|
Def::Const(def_id) |
|
||||||
|
Def::AssociatedConst(def_id) => def_id,
|
||||||
|
|
||||||
Def::StructCtor(def_id, CtorKind::Const) |
|
Def::StructCtor(def_id, CtorKind::Const) |
|
||||||
Def::VariantCtor(def_id, CtorKind::Const) => {
|
Def::VariantCtor(def_id, CtorKind::Const) => {
|
||||||
match cx.tcx.tables().node_id_to_type(expr.id).sty {
|
match cx.tcx.tables().node_id_to_type(expr.id).sty {
|
||||||
// A unit struct/variant which is used as a value.
|
// A unit struct/variant which is used as a value.
|
||||||
// We return a completely different ExprKind here to account for this special case.
|
// We return a completely different ExprKind here to account for this special case.
|
||||||
ty::TyAdt(adt_def, substs) => return ExprKind::Adt {
|
ty::TyAdt(adt_def, substs) => {
|
||||||
adt_def: adt_def,
|
return ExprKind::Adt {
|
||||||
variant_index: adt_def.variant_index_with_id(def_id),
|
adt_def: adt_def,
|
||||||
substs: substs,
|
variant_index: adt_def.variant_index_with_id(def_id),
|
||||||
fields: vec![],
|
substs: substs,
|
||||||
base: None,
|
fields: vec![],
|
||||||
},
|
base: None,
|
||||||
ref sty => bug!("unexpected sty: {:?}", sty)
|
}
|
||||||
|
}
|
||||||
|
ref sty => bug!("unexpected sty: {:?}", sty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Def::Static(node_id, _) => return ExprKind::StaticRef {
|
Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id },
|
||||||
id: node_id,
|
|
||||||
},
|
|
||||||
|
|
||||||
Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def),
|
Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def),
|
||||||
|
|
||||||
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
_ => span_bug!(expr.span, "def `{:?}` not yet implemented", def),
|
||||||
};
|
};
|
||||||
ExprKind::Literal {
|
ExprKind::Literal {
|
||||||
literal: Literal::Item { def_id: def_id, substs: substs }
|
literal: Literal::Item {
|
||||||
|
def_id: def_id,
|
||||||
|
substs: substs,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,14 +766,15 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
match def {
|
match def {
|
||||||
Def::Local(def_id) => {
|
Def::Local(def_id) => {
|
||||||
let node_id = cx.tcx.map.as_local_node_id(def_id).unwrap();
|
let node_id = cx.tcx.map.as_local_node_id(def_id).unwrap();
|
||||||
ExprKind::VarRef {
|
ExprKind::VarRef { id: node_id }
|
||||||
id: node_id,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Def::Upvar(def_id, index, closure_expr_id) => {
|
Def::Upvar(def_id, index, closure_expr_id) => {
|
||||||
let id_var = cx.tcx.map.as_local_node_id(def_id).unwrap();
|
let id_var = cx.tcx.map.as_local_node_id(def_id).unwrap();
|
||||||
debug!("convert_var(upvar({:?}, {:?}, {:?}))", id_var, index, closure_expr_id);
|
debug!("convert_var(upvar({:?}, {:?}, {:?}))",
|
||||||
|
id_var,
|
||||||
|
index,
|
||||||
|
closure_expr_id);
|
||||||
let var_ty = cx.tcx.tables().node_id_to_type(id_var);
|
let var_ty = cx.tcx.tables().node_id_to_type(id_var);
|
||||||
|
|
||||||
let body_id = match cx.tcx.map.find(closure_expr_id) {
|
let body_id = match cx.tcx.map.find(closure_expr_id) {
|
||||||
|
@ -761,41 +805,45 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
|
|
||||||
let self_expr = match cx.tcx.closure_kind(cx.tcx.map.local_def_id(closure_expr_id)) {
|
let self_expr = match cx.tcx.closure_kind(cx.tcx.map.local_def_id(closure_expr_id)) {
|
||||||
ty::ClosureKind::Fn => {
|
ty::ClosureKind::Fn => {
|
||||||
let ref_closure_ty =
|
let ref_closure_ty = cx.tcx.mk_ref(region,
|
||||||
cx.tcx.mk_ref(region,
|
ty::TypeAndMut {
|
||||||
ty::TypeAndMut { ty: closure_ty,
|
ty: closure_ty,
|
||||||
mutbl: hir::MutImmutable });
|
mutbl: hir::MutImmutable,
|
||||||
|
});
|
||||||
Expr {
|
Expr {
|
||||||
ty: closure_ty,
|
ty: closure_ty,
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Deref {
|
kind: ExprKind::Deref {
|
||||||
arg: Expr {
|
arg: Expr {
|
||||||
ty: ref_closure_ty,
|
ty: ref_closure_ty,
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::SelfRef
|
kind: ExprKind::SelfRef,
|
||||||
}.to_ref()
|
}
|
||||||
}
|
.to_ref(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ClosureKind::FnMut => {
|
ty::ClosureKind::FnMut => {
|
||||||
let ref_closure_ty =
|
let ref_closure_ty = cx.tcx.mk_ref(region,
|
||||||
cx.tcx.mk_ref(region,
|
ty::TypeAndMut {
|
||||||
ty::TypeAndMut { ty: closure_ty,
|
ty: closure_ty,
|
||||||
mutbl: hir::MutMutable });
|
mutbl: hir::MutMutable,
|
||||||
|
});
|
||||||
Expr {
|
Expr {
|
||||||
ty: closure_ty,
|
ty: closure_ty,
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Deref {
|
kind: ExprKind::Deref {
|
||||||
arg: Expr {
|
arg: Expr {
|
||||||
ty: ref_closure_ty,
|
ty: ref_closure_ty,
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::SelfRef
|
kind: ExprKind::SelfRef,
|
||||||
}.to_ref()
|
}
|
||||||
}
|
.to_ref(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ClosureKind::FnOnce => {
|
ty::ClosureKind::FnOnce => {
|
||||||
|
@ -823,10 +871,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
let upvar_capture = match cx.tcx.tables().upvar_capture(upvar_id) {
|
let upvar_capture = match cx.tcx.tables().upvar_capture(upvar_id) {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => {
|
None => {
|
||||||
span_bug!(
|
span_bug!(expr.span, "no upvar_capture for {:?}", upvar_id);
|
||||||
expr.span,
|
|
||||||
"no upvar_capture for {:?}",
|
|
||||||
upvar_id);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match upvar_capture {
|
match upvar_capture {
|
||||||
|
@ -834,15 +879,16 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
ty::UpvarCapture::ByRef(borrow) => {
|
ty::UpvarCapture::ByRef(borrow) => {
|
||||||
ExprKind::Deref {
|
ExprKind::Deref {
|
||||||
arg: Expr {
|
arg: Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: cx.tcx.mk_ref(borrow.region,
|
ty: cx.tcx.mk_ref(borrow.region,
|
||||||
ty::TypeAndMut {
|
ty::TypeAndMut {
|
||||||
ty: var_ty,
|
ty: var_ty,
|
||||||
mutbl: borrow.kind.to_mutbl_lossy()
|
mutbl: borrow.kind.to_mutbl_lossy(),
|
||||||
}),
|
}),
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: field_kind,
|
kind: field_kind,
|
||||||
}.to_ref()
|
}
|
||||||
|
.to_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -894,30 +940,31 @@ fn overloaded_operator<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
// the arguments, unfortunately, do not, so if this is a ByRef
|
// the arguments, unfortunately, do not, so if this is a ByRef
|
||||||
// operator, we have to gin up the autorefs (but by value is easy)
|
// operator, we have to gin up the autorefs (but by value is easy)
|
||||||
match pass_args {
|
match pass_args {
|
||||||
PassArgs::ByValue => {
|
PassArgs::ByValue => argrefs.extend(args.iter().map(|arg| arg.to_ref())),
|
||||||
argrefs.extend(args.iter().map(|arg| arg.to_ref()))
|
|
||||||
}
|
|
||||||
|
|
||||||
PassArgs::ByRef => {
|
PassArgs::ByRef => {
|
||||||
let region = cx.tcx.node_scope_region(expr.id);
|
let region = cx.tcx.node_scope_region(expr.id);
|
||||||
let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
|
let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
|
||||||
argrefs.extend(
|
argrefs.extend(args.iter()
|
||||||
args.iter()
|
.map(|arg| {
|
||||||
.map(|arg| {
|
let arg_ty = cx.tcx.tables().expr_ty_adjusted(arg);
|
||||||
let arg_ty = cx.tcx.tables().expr_ty_adjusted(arg);
|
let adjusted_ty = cx.tcx.mk_ref(region,
|
||||||
let adjusted_ty =
|
ty::TypeAndMut {
|
||||||
cx.tcx.mk_ref(region,
|
ty: arg_ty,
|
||||||
ty::TypeAndMut { ty: arg_ty,
|
mutbl: hir::MutImmutable,
|
||||||
mutbl: hir::MutImmutable });
|
});
|
||||||
Expr {
|
Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: adjusted_ty,
|
ty: adjusted_ty,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
kind: ExprKind::Borrow { region: region,
|
kind: ExprKind::Borrow {
|
||||||
borrow_kind: BorrowKind::Shared,
|
region: region,
|
||||||
arg: arg.to_ref() }
|
borrow_kind: BorrowKind::Shared,
|
||||||
}.to_ref()
|
arg: arg.to_ref(),
|
||||||
}))
|
},
|
||||||
|
}
|
||||||
|
.to_ref()
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,9 +1028,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
kind: convert_var(cx, closure_expr, freevar.def),
|
kind: convert_var(cx, closure_expr, freevar.def),
|
||||||
};
|
};
|
||||||
match upvar_capture {
|
match upvar_capture {
|
||||||
ty::UpvarCapture::ByValue => {
|
ty::UpvarCapture::ByValue => captured_var.to_ref(),
|
||||||
captured_var.to_ref()
|
|
||||||
}
|
|
||||||
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
||||||
let borrow_kind = match upvar_borrow.kind {
|
let borrow_kind = match upvar_borrow.kind {
|
||||||
ty::BorrowKind::ImmBorrow => BorrowKind::Shared,
|
ty::BorrowKind::ImmBorrow => BorrowKind::Shared,
|
||||||
|
@ -991,13 +1036,16 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
ty::BorrowKind::MutBorrow => BorrowKind::Mut,
|
ty::BorrowKind::MutBorrow => BorrowKind::Mut,
|
||||||
};
|
};
|
||||||
Expr {
|
Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: freevar_ty,
|
ty: freevar_ty,
|
||||||
span: closure_expr.span,
|
span: closure_expr.span,
|
||||||
kind: ExprKind::Borrow { region: upvar_borrow.region,
|
kind: ExprKind::Borrow {
|
||||||
borrow_kind: borrow_kind,
|
region: upvar_borrow.region,
|
||||||
arg: captured_var.to_ref() }
|
borrow_kind: borrow_kind,
|
||||||
}.to_ref()
|
arg: captured_var.to_ref(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.to_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1005,12 +1053,13 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
/// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
|
/// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
|
||||||
fn field_refs<'tcx>(variant: &'tcx VariantDef,
|
fn field_refs<'tcx>(variant: &'tcx VariantDef,
|
||||||
fields: &'tcx [hir::Field])
|
fields: &'tcx [hir::Field])
|
||||||
-> Vec<FieldExprRef<'tcx>>
|
-> Vec<FieldExprRef<'tcx>> {
|
||||||
{
|
|
||||||
fields.iter()
|
fields.iter()
|
||||||
.map(|field| FieldExprRef {
|
.map(|field| {
|
||||||
name: Field::new(variant.index_of_field_named(field.name.node).unwrap()),
|
FieldExprRef {
|
||||||
expr: field.expr.to_ref(),
|
name: Field::new(variant.index_of_field_named(field.name.node).unwrap()),
|
||||||
})
|
expr: field.expr.to_ref(),
|
||||||
.collect()
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
/*!
|
//! This module contains the code to convert from the wacky tcx data
|
||||||
* This module contains the code to convert from the wacky tcx data
|
//! structures into the hair. The `builder` is generally ignorant of
|
||||||
* structures into the hair. The `builder` is generally ignorant of
|
//! the tcx etc, and instead goes through the `Cx` for most of its
|
||||||
* the tcx etc, and instead goes through the `Cx` for most of its
|
//! work.
|
||||||
* work.
|
//!
|
||||||
*/
|
|
||||||
|
|
||||||
use hair::*;
|
use hair::*;
|
||||||
use rustc::mir::transform::MirSource;
|
use rustc::mir::transform::MirSource;
|
||||||
|
@ -32,19 +31,17 @@ use rustc::hir;
|
||||||
use rustc_const_math::{ConstInt, ConstUsize};
|
use rustc_const_math::{ConstInt, ConstUsize};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Cx<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
constness: hir::Constness,
|
constness: hir::Constness,
|
||||||
|
|
||||||
/// True if this constant/function needs overflow checks.
|
/// True if this constant/function needs overflow checks.
|
||||||
check_overflow: bool
|
check_overflow: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, src: MirSource) -> Cx<'a, 'gcx, 'tcx> {
|
||||||
src: MirSource)
|
|
||||||
-> Cx<'a, 'gcx, 'tcx> {
|
|
||||||
let constness = match src {
|
let constness = match src {
|
||||||
MirSource::Const(_) |
|
MirSource::Const(_) |
|
||||||
MirSource::Static(..) => hir::Constness::Const,
|
MirSource::Static(..) => hir::Constness::Const,
|
||||||
|
@ -52,7 +49,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
let fn_like = FnLikeNode::from_node(infcx.tcx.map.get(id));
|
let fn_like = FnLikeNode::from_node(infcx.tcx.map.get(id));
|
||||||
fn_like.map_or(hir::Constness::NotConst, |f| f.constness())
|
fn_like.map_or(hir::Constness::NotConst, |f| f.constness())
|
||||||
}
|
}
|
||||||
MirSource::Promoted(..) => bug!()
|
MirSource::Promoted(..) => bug!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let src_node_id = src.item_id();
|
let src_node_id = src.item_id();
|
||||||
|
@ -70,13 +67,16 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
// Some functions always have overflow checks enabled,
|
// Some functions always have overflow checks enabled,
|
||||||
// however, they may not get codegen'd, depending on
|
// however, they may not get codegen'd, depending on
|
||||||
// the settings for the crate they are translated in.
|
// the settings for the crate they are translated in.
|
||||||
let mut check_overflow = attrs.iter().any(|item| {
|
let mut check_overflow = attrs.iter()
|
||||||
item.check_name("rustc_inherit_overflow_checks")
|
.any(|item| item.check_name("rustc_inherit_overflow_checks"));
|
||||||
});
|
|
||||||
|
|
||||||
// Respect -Z force-overflow-checks=on and -C debug-assertions.
|
// Respect -Z force-overflow-checks=on and -C debug-assertions.
|
||||||
check_overflow |= infcx.tcx.sess.opts.debugging_opts.force_overflow_checks
|
check_overflow |= infcx.tcx
|
||||||
.unwrap_or(infcx.tcx.sess.opts.debug_assertions);
|
.sess
|
||||||
|
.opts
|
||||||
|
.debugging_opts
|
||||||
|
.force_overflow_checks
|
||||||
|
.unwrap_or(infcx.tcx.sess.opts.debug_assertions);
|
||||||
|
|
||||||
// Constants and const fn's always need overflow checks.
|
// Constants and const fn's always need overflow checks.
|
||||||
check_overflow |= constness == hir::Constness::Const;
|
check_overflow |= constness == hir::Constness::Const;
|
||||||
|
@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
tcx: infcx.tcx,
|
tcx: infcx.tcx,
|
||||||
infcx: infcx,
|
infcx: infcx,
|
||||||
constness: constness,
|
constness: constness,
|
||||||
check_overflow: check_overflow
|
check_overflow: check_overflow,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
pub fn usize_literal(&mut self, value: u64) -> Literal<'tcx> {
|
pub fn usize_literal(&mut self, value: u64) -> Literal<'tcx> {
|
||||||
match ConstUsize::new(value, self.tcx.sess.target.uint_type) {
|
match ConstUsize::new(value, self.tcx.sess.target.uint_type) {
|
||||||
Ok(val) => Literal::Value { value: ConstVal::Integral(ConstInt::Usize(val))},
|
Ok(val) => Literal::Value { value: ConstVal::Integral(ConstInt::Usize(val)) },
|
||||||
Err(_) => bug!("usize literal out of range for target"),
|
Err(_) => bug!("usize literal out of range for target"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,9 +128,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
|
pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
|
||||||
Literal::Value {
|
Literal::Value { value: const_eval::eval_const_expr(self.tcx.global_tcx(), e) }
|
||||||
value: const_eval::eval_const_expr(self.tcx.global_tcx(), e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_method(&mut self,
|
pub fn trait_method(&mut self,
|
||||||
|
@ -145,10 +143,11 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
if item.kind == ty::AssociatedKind::Method && item.name == method_name {
|
if item.kind == ty::AssociatedKind::Method && item.name == method_name {
|
||||||
let method_ty = self.tcx.item_type(item.def_id);
|
let method_ty = self.tcx.item_type(item.def_id);
|
||||||
let method_ty = method_ty.subst(self.tcx, substs);
|
let method_ty = method_ty.subst(self.tcx, substs);
|
||||||
return (method_ty, Literal::Item {
|
return (method_ty,
|
||||||
def_id: item.def_id,
|
Literal::Item {
|
||||||
substs: substs,
|
def_id: item.def_id,
|
||||||
});
|
substs: substs,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +167,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool {
|
pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool {
|
||||||
let ty = self.tcx.lift_to_global(&ty).unwrap_or_else(|| {
|
let ty = self.tcx.lift_to_global(&ty).unwrap_or_else(|| {
|
||||||
bug!("MIR: Cx::needs_drop({}) got \
|
bug!("MIR: Cx::needs_drop({}) got \
|
||||||
type with inference types/regions", ty);
|
type with inference types/regions",
|
||||||
|
ty);
|
||||||
});
|
});
|
||||||
self.tcx.type_needs_drop_given_env(ty, &self.infcx.parameter_environment)
|
self.tcx.type_needs_drop_given_env(ty, &self.infcx.parameter_environment)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub trait ToRef {
|
||||||
fn to_ref(self) -> Self::Output;
|
fn to_ref(self) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a> ToRef for &'tcx hir::Expr {
|
impl<'a, 'tcx: 'a> ToRef for &'tcx hir::Expr {
|
||||||
type Output = ExprRef<'tcx>;
|
type Output = ExprRef<'tcx>;
|
||||||
|
|
||||||
fn to_ref(self) -> ExprRef<'tcx> {
|
fn to_ref(self) -> ExprRef<'tcx> {
|
||||||
|
@ -26,7 +26,7 @@ impl<'a,'tcx:'a> ToRef for &'tcx hir::Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a> ToRef for &'tcx P<hir::Expr> {
|
impl<'a, 'tcx: 'a> ToRef for &'tcx P<hir::Expr> {
|
||||||
type Output = ExprRef<'tcx>;
|
type Output = ExprRef<'tcx>;
|
||||||
|
|
||||||
fn to_ref(self) -> ExprRef<'tcx> {
|
fn to_ref(self) -> ExprRef<'tcx> {
|
||||||
|
@ -34,7 +34,7 @@ impl<'a,'tcx:'a> ToRef for &'tcx P<hir::Expr> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a> ToRef for Expr<'tcx> {
|
impl<'a, 'tcx: 'a> ToRef for Expr<'tcx> {
|
||||||
type Output = ExprRef<'tcx>;
|
type Output = ExprRef<'tcx>;
|
||||||
|
|
||||||
fn to_ref(self) -> ExprRef<'tcx> {
|
fn to_ref(self) -> ExprRef<'tcx> {
|
||||||
|
@ -42,8 +42,8 @@ impl<'a,'tcx:'a> ToRef for Expr<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a,T,U> ToRef for &'tcx Option<T>
|
impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx Option<T>
|
||||||
where &'tcx T: ToRef<Output=U>
|
where &'tcx T: ToRef<Output = U>
|
||||||
{
|
{
|
||||||
type Output = Option<U>;
|
type Output = Option<U>;
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ impl<'a,'tcx:'a,T,U> ToRef for &'tcx Option<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec<T>
|
impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx Vec<T>
|
||||||
where &'tcx T: ToRef<Output=U>
|
where &'tcx T: ToRef<Output = U>
|
||||||
{
|
{
|
||||||
type Output = Vec<U>;
|
type Output = Vec<U>;
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a,T,U> ToRef for &'tcx P<[T]>
|
impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx P<[T]>
|
||||||
where &'tcx T: ToRef<Output=U>
|
where &'tcx T: ToRef<Output = U>
|
||||||
{
|
{
|
||||||
type Output = Vec<U>;
|
type Output = Vec<U>;
|
||||||
|
|
||||||
|
|
|
@ -1468,6 +1468,13 @@ impl<'a> Item<'a> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Macros from other libraries get special filenames which we can
|
||||||
|
// safely ignore.
|
||||||
|
if self.item.source.filename.starts_with("<") &&
|
||||||
|
self.item.source.filename.ends_with("macros>") {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let (krate, src_root) = match cache.extern_locations.get(&self.item.def_id.krate) {
|
let (krate, src_root) = match cache.extern_locations.get(&self.item.def_id.krate) {
|
||||||
Some(&(ref name, ref src, Local)) => (name, src),
|
Some(&(ref name, ref src, Local)) => (name, src),
|
||||||
Some(&(ref name, ref src, Remote(ref s))) => {
|
Some(&(ref name, ref src, Remote(ref s))) => {
|
||||||
|
|
|
@ -52,13 +52,15 @@
|
||||||
font-family: 'Source Code Pro';
|
font-family: 'Source Code Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
|
/* Avoid using locally installed font because bad versions are in circulation:
|
||||||
|
* see https://github.com/rust-lang/rust/issues/24355 */
|
||||||
|
src: url("SourceCodePro-Regular.woff") format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Code Pro';
|
font-family: 'Source Code Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff');
|
src: url("SourceCodePro-Semibold.woff") format('woff');
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
|
|
@ -499,6 +499,19 @@ impl UdpSocket {
|
||||||
/// This will retrieve the stored error in the underlying socket, clearing
|
/// This will retrieve the stored error in the underlying socket, clearing
|
||||||
/// the field in the process. This can be useful for checking errors between
|
/// the field in the process. This can be useful for checking errors between
|
||||||
/// calls.
|
/// calls.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||||
|
/// match socket.take_error() {
|
||||||
|
/// Ok(Some(error)) => println!("UdpSocket error: {:?}", error),
|
||||||
|
/// Ok(None) => println!("No error"),
|
||||||
|
/// Err(error) => println!("UdpSocket.take_error failed: {:?}", error),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||||
self.0.take_error()
|
self.0.take_error()
|
||||||
|
@ -507,6 +520,15 @@ impl UdpSocket {
|
||||||
/// Connects this UDP socket to a remote address, allowing the `send` and
|
/// Connects this UDP socket to a remote address, allowing the `send` and
|
||||||
/// `recv` syscalls to be used to send data and also applies filters to only
|
/// `recv` syscalls to be used to send data and also applies filters to only
|
||||||
/// receive data from the specified address.
|
/// receive data from the specified address.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||||
|
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
|
||||||
|
/// ```
|
||||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||||
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
|
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
|
||||||
super::each_addr(addr, |addr| self.0.connect(addr))
|
super::each_addr(addr, |addr| self.0.connect(addr))
|
||||||
|
@ -514,8 +536,20 @@ impl UdpSocket {
|
||||||
|
|
||||||
/// Sends data on the socket to the remote address to which it is connected.
|
/// Sends data on the socket to the remote address to which it is connected.
|
||||||
///
|
///
|
||||||
/// The `connect` method will connect this socket to a remote address. This
|
/// The [`connect()`] method will connect this socket to a remote address. This
|
||||||
/// method will fail if the socket is not connected.
|
/// method will fail if the socket is not connected.
|
||||||
|
///
|
||||||
|
/// [`connect()`]: #method.connect
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||||
|
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
|
||||||
|
/// socket.send(&[0, 1, 2]).expect("couldn't send message");
|
||||||
|
/// ```
|
||||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||||
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.send(buf)
|
self.0.send(buf)
|
||||||
|
@ -526,6 +560,20 @@ impl UdpSocket {
|
||||||
///
|
///
|
||||||
/// The `connect` method will connect this socket to a remote address. This
|
/// The `connect` method will connect this socket to a remote address. This
|
||||||
/// method will fail if the socket is not connected.
|
/// method will fail if the socket is not connected.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||||
|
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
|
||||||
|
/// let mut buf = [0; 10];
|
||||||
|
/// match socket.recv(&mut buf) {
|
||||||
|
/// Ok(received) => println!("received {} bytes", received),
|
||||||
|
/// Err(e) => println!("recv function failed: {:?}", e),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||||
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.recv(buf)
|
self.0.recv(buf)
|
||||||
|
@ -535,6 +583,15 @@ impl UdpSocket {
|
||||||
///
|
///
|
||||||
/// On Unix this corresponds to calling fcntl, and on Windows this
|
/// On Unix this corresponds to calling fcntl, and on Windows this
|
||||||
/// corresponds to calling ioctlsocket.
|
/// corresponds to calling ioctlsocket.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::net::UdpSocket;
|
||||||
|
///
|
||||||
|
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||||
|
/// socket.set_nonblocking(true).expect("set_nonblocking call failed");
|
||||||
|
/// ```
|
||||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||||
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
|
||||||
self.0.set_nonblocking(nonblocking)
|
self.0.set_nonblocking(nonblocking)
|
||||||
|
|
|
@ -454,10 +454,16 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new asynchronous channel, returning the sender/receiver halves.
|
/// Creates a new asynchronous channel, returning the sender/receiver halves.
|
||||||
///
|
|
||||||
/// All data sent on the sender will become available on the receiver, and no
|
/// All data sent on the sender will become available on the receiver, and no
|
||||||
/// send will block the calling thread (this channel has an "infinite buffer").
|
/// send will block the calling thread (this channel has an "infinite buffer").
|
||||||
///
|
///
|
||||||
|
/// If the [`Receiver`] is disconnected while trying to [`send()`] with the
|
||||||
|
/// [`Sender`], the [`send()`] method will return an error.
|
||||||
|
///
|
||||||
|
/// [`send()`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
|
||||||
|
/// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
|
||||||
|
/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -487,18 +493,23 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
||||||
|
|
||||||
/// Creates a new synchronous, bounded channel.
|
/// Creates a new synchronous, bounded channel.
|
||||||
///
|
///
|
||||||
/// Like asynchronous channels, the `Receiver` will block until a message
|
/// Like asynchronous channels, the [`Receiver`] will block until a message
|
||||||
/// becomes available. These channels differ greatly in the semantics of the
|
/// becomes available. These channels differ greatly in the semantics of the
|
||||||
/// sender from asynchronous channels, however.
|
/// sender from asynchronous channels, however.
|
||||||
///
|
///
|
||||||
/// This channel has an internal buffer on which messages will be queued. `bound`
|
/// This channel has an internal buffer on which messages will be queued.
|
||||||
/// specifies the buffer size. When the internal buffer becomes full, future sends
|
/// `bound` specifies the buffer size. When the internal buffer becomes full,
|
||||||
/// will *block* waiting for the buffer to open up. Note that a buffer size of 0
|
/// future sends will *block* waiting for the buffer to open up. Note that a
|
||||||
/// is valid, in which case this becomes "rendezvous channel" where each send will
|
/// buffer size of 0 is valid, in which case this becomes "rendezvous channel"
|
||||||
/// not return until a recv is paired with it.
|
/// where each [`send()`] will not return until a recv is paired with it.
|
||||||
///
|
///
|
||||||
/// As with asynchronous channels, all senders will panic in `send` if the
|
/// Like asynchronous channels, if the [`Receiver`] is disconnected while
|
||||||
/// `Receiver` has been destroyed.
|
/// trying to [`send()`] with the [`SyncSender`], the [`send()`] method will
|
||||||
|
/// return an error.
|
||||||
|
///
|
||||||
|
/// [`send()`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
|
||||||
|
/// [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html
|
||||||
|
/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
144
src/test/incremental/hashes/closure_expressions.rs
Normal file
144
src/test/incremental/hashes/closure_expressions.rs
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
// This test case tests the incremental compilation hash (ICH) implementation
|
||||||
|
// for closure expression.
|
||||||
|
|
||||||
|
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||||
|
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||||
|
// rev3 and make sure that the hash has not changed.
|
||||||
|
|
||||||
|
// must-compile-successfully
|
||||||
|
// revisions: cfail1 cfail2 cfail3
|
||||||
|
// compile-flags: -Z query-dep-graph
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
|
||||||
|
|
||||||
|
// Change closure body ---------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_closure_body() {
|
||||||
|
let _ = || 1u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_closure_body() {
|
||||||
|
let _ = || 3u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add parameter ---------------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn add_parameter() {
|
||||||
|
let x = 0u32;
|
||||||
|
let _ = || x + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn add_parameter() {
|
||||||
|
let x = 0u32;
|
||||||
|
let _ = |x: u32| x + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change parameter pattern ----------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_parameter_pattern() {
|
||||||
|
let _ = |x: &u32| x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_parameter_pattern() {
|
||||||
|
let _ = |&x: &u32| x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add `move` to closure -------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn add_move() {
|
||||||
|
let _ = || 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn add_move() {
|
||||||
|
let _ = move || 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add type ascription to parameter --------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn add_type_ascription_to_parameter() {
|
||||||
|
let closure = |x| x + 1u32;
|
||||||
|
let _: u32 = closure(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn add_type_ascription_to_parameter() {
|
||||||
|
let closure = |x: u32| x + 1u32;
|
||||||
|
let _: u32 = closure(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change parameter type -------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_parameter_type() {
|
||||||
|
let closure = |x: u32| (x as u64) + 1;
|
||||||
|
let _ = closure(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_parameter_type() {
|
||||||
|
let closure = |x: u16| (x as u64) + 1;
|
||||||
|
let _ = closure(1);
|
||||||
|
}
|
387
src/test/incremental/hashes/enum_constructors.rs
Normal file
387
src/test/incremental/hashes/enum_constructors.rs
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
// This test case tests the incremental compilation hash (ICH) implementation
|
||||||
|
// for struct constructor expressions.
|
||||||
|
|
||||||
|
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||||
|
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||||
|
// rev3 and make sure that the hash has not changed.
|
||||||
|
|
||||||
|
// must-compile-successfully
|
||||||
|
// revisions: cfail1 cfail2 cfail3
|
||||||
|
// compile-flags: -Z query-dep-graph
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
|
||||||
|
|
||||||
|
enum Enum {
|
||||||
|
Struct {
|
||||||
|
x: i32,
|
||||||
|
y: i64,
|
||||||
|
z: i16,
|
||||||
|
},
|
||||||
|
Tuple(i32, i64, i16)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change field value (struct-like) -----------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_field_value_struct_like() -> Enum {
|
||||||
|
Enum::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_field_value_struct_like() -> Enum {
|
||||||
|
Enum::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 2,
|
||||||
|
z: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change field order (struct-like) -----------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_field_order_struct_like() -> Enum {
|
||||||
|
Enum::Struct {
|
||||||
|
x: 3,
|
||||||
|
y: 4,
|
||||||
|
z: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_field_order_struct_like() -> Enum {
|
||||||
|
Enum::Struct {
|
||||||
|
y: 4,
|
||||||
|
x: 3,
|
||||||
|
z: 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Enum2 {
|
||||||
|
Struct {
|
||||||
|
x: i8,
|
||||||
|
y: i8,
|
||||||
|
z: i8,
|
||||||
|
},
|
||||||
|
Struct2 {
|
||||||
|
x: i8,
|
||||||
|
y: i8,
|
||||||
|
z: i8,
|
||||||
|
},
|
||||||
|
Tuple(u16, u16, u16),
|
||||||
|
Tuple2(u64, u64, u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change constructor path (struct-like) ------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_path_struct_like() {
|
||||||
|
let _ = Enum::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_path_struct_like() {
|
||||||
|
let _ = Enum2::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change variant (regular struct) ------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_variant_struct_like() {
|
||||||
|
let _ = Enum2::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_variant_struct_like() {
|
||||||
|
let _ = Enum2::Struct2 {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor path indirectly (struct-like) -------------------------
|
||||||
|
mod change_constructor_path_indirectly_struct_like {
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Enum as TheEnum;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Enum2 as TheEnum;
|
||||||
|
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> TheEnum {
|
||||||
|
TheEnum::Struct {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor variant indirectly (struct-like) ---------------------------
|
||||||
|
mod change_constructor_variant_indirectly_struct_like {
|
||||||
|
use super::Enum2;
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Enum2::Struct as Variant;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Enum2::Struct2 as Variant;
|
||||||
|
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> Enum2 {
|
||||||
|
Variant {
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
z: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Change field value (tuple-like) -------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_field_value_tuple_like() -> Enum {
|
||||||
|
Enum::Tuple(0, 1, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_field_value_tuple_like() -> Enum {
|
||||||
|
Enum::Tuple(0, 1, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor path (tuple-like) --------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_path_tuple_like() {
|
||||||
|
let _ = Enum::Tuple(0, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_path_tuple_like() {
|
||||||
|
let _ = Enum2::Tuple(0, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor variant (tuple-like) --------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_variant_tuple_like() {
|
||||||
|
let _ = Enum2::Tuple(0, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_variant_tuple_like() {
|
||||||
|
let _ = Enum2::Tuple2(0, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor path indirectly (tuple-like) ---------------------------
|
||||||
|
mod change_constructor_path_indirectly_tuple_like {
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Enum as TheEnum;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Enum2 as TheEnum;
|
||||||
|
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> TheEnum {
|
||||||
|
TheEnum::Tuple(0, 1, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor variant indirectly (tuple-like) ---------------------------
|
||||||
|
mod change_constructor_variant_indirectly_tuple_like {
|
||||||
|
use super::Enum2;
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Enum2::Tuple as Variant;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Enum2::Tuple2 as Variant;
|
||||||
|
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> Enum2 {
|
||||||
|
Variant(0, 1, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum Clike {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Clike2 {
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
D
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change constructor path (C-like) --------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_path_c_like() {
|
||||||
|
let _ = Clike::B;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_path_c_like() {
|
||||||
|
let _ = Clike2::B;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor variant (C-like) --------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_constructor_variant_c_like() {
|
||||||
|
let _ = Clike::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_constructor_variant_c_like() {
|
||||||
|
let _ = Clike::C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor path indirectly (C-like) ---------------------------
|
||||||
|
mod change_constructor_path_indirectly_c_like {
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Clike as TheEnum;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Clike2 as TheEnum;
|
||||||
|
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> TheEnum {
|
||||||
|
TheEnum::B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change constructor variant indirectly (C-like) ---------------------------
|
||||||
|
mod change_constructor_variant_indirectly_c_like {
|
||||||
|
use super::Clike;
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
use super::Clike::A as Variant;
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
use super::Clike::B as Variant;
|
||||||
|
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn function() -> Clike {
|
||||||
|
Variant
|
||||||
|
}
|
||||||
|
}
|
86
src/test/incremental/hashes/exported_vs_not.rs
Normal file
86
src/test/incremental/hashes/exported_vs_not.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// must-compile-successfully
|
||||||
|
// revisions: cfail1 cfail2 cfail3
|
||||||
|
// compile-flags: -Z query-dep-graph
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
|
||||||
|
// Case 1: The function body is not exported to metadata. If the body changes,
|
||||||
|
// the hash of the HirBody node should change, but not the hash of
|
||||||
|
// either the Hir or the Metadata node.
|
||||||
|
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
pub fn body_not_exported_to_metadata() -> u32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
pub fn body_not_exported_to_metadata() -> u32 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Case 2: The function body *is* exported to metadata because the function is
|
||||||
|
// marked as #[inline]. Only the hash of the Hir depnode should be
|
||||||
|
// unaffected by a change to the body.
|
||||||
|
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
#[inline]
|
||||||
|
pub fn body_exported_to_metadata_because_of_inline() -> u32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
#[inline]
|
||||||
|
pub fn body_exported_to_metadata_because_of_inline() -> u32 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Case 2: The function body *is* exported to metadata because the function is
|
||||||
|
// generic. Only the hash of the Hir depnode should be
|
||||||
|
// unaffected by a change to the body.
|
||||||
|
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
#[inline]
|
||||||
|
pub fn body_exported_to_metadata_because_of_generic() -> u32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
#[inline]
|
||||||
|
pub fn body_exported_to_metadata_because_of_generic() -> u32 {
|
||||||
|
2
|
||||||
|
}
|
||||||
|
|
157
src/test/incremental/hashes/indexing_expressions.rs
Normal file
157
src/test/incremental/hashes/indexing_expressions.rs
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
|
||||||
|
// This test case tests the incremental compilation hash (ICH) implementation
|
||||||
|
// for closure expression.
|
||||||
|
|
||||||
|
// The general pattern followed here is: Change one thing between rev1 and rev2
|
||||||
|
// and make sure that the hash has changed, then change nothing between rev2 and
|
||||||
|
// rev3 and make sure that the hash has not changed.
|
||||||
|
|
||||||
|
// must-compile-successfully
|
||||||
|
// revisions: cfail1 cfail2 cfail3
|
||||||
|
// compile-flags: -Z query-dep-graph
|
||||||
|
|
||||||
|
#![allow(warnings)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![crate_type="rlib"]
|
||||||
|
#![feature(inclusive_range_syntax)]
|
||||||
|
|
||||||
|
// Change simple index ---------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_simple_index(slice: &[u32]) -> u32 {
|
||||||
|
slice[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_simple_index(slice: &[u32]) -> u32 {
|
||||||
|
slice[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change lower bound ----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_lower_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..5]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_lower_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[2..5]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change upper bound ----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_upper_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..5]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_upper_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..7]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add lower bound -------------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn add_lower_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[..4]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn add_lower_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..4]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add upper bound -------------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn add_upper_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn add_upper_bound(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..7]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Change mutability -----------------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn change_mutability(slice: &mut [u32]) -> u32 {
|
||||||
|
(&mut slice[3..5])[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn change_mutability(slice: &mut [u32]) -> u32 {
|
||||||
|
(&slice[3..5])[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Exclusive to inclusive range ------------------------------------------------
|
||||||
|
#[cfg(cfail1)]
|
||||||
|
fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3..7]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(cfail1))]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
|
fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
|
||||||
|
&slice[3...7]
|
||||||
|
}
|
|
@ -202,6 +202,12 @@ mod change_constructor_path_indirectly_regular_struct {
|
||||||
#[cfg(not(cfail1))]
|
#[cfg(not(cfail1))]
|
||||||
use super::RegularStruct2 as Struct;
|
use super::RegularStruct2 as Struct;
|
||||||
|
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
fn function() -> Struct {
|
fn function() -> Struct {
|
||||||
Struct {
|
Struct {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -262,6 +268,12 @@ mod change_constructor_path_indirectly_tuple_struct {
|
||||||
#[cfg(not(cfail1))]
|
#[cfg(not(cfail1))]
|
||||||
use super::TupleStruct2 as Struct;
|
use super::TupleStruct2 as Struct;
|
||||||
|
|
||||||
|
#[rustc_dirty(label="Hir", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="Hir", cfg="cfail3")]
|
||||||
|
#[rustc_dirty(label="HirBody", cfg="cfail2")]
|
||||||
|
#[rustc_clean(label="HirBody", cfg="cfail3")]
|
||||||
|
#[rustc_metadata_dirty(cfg="cfail2")]
|
||||||
|
#[rustc_metadata_clean(cfg="cfail3")]
|
||||||
fn function() -> Struct {
|
fn function() -> Struct {
|
||||||
Struct(0, 1, 2)
|
Struct(0, 1, 2)
|
||||||
}
|
}
|
||||||
|
|
5
x.py
5
x.py
|
@ -16,4 +16,7 @@ sys.path.append(os.path.abspath(os.path.join(dir, "src", "bootstrap")))
|
||||||
|
|
||||||
import bootstrap
|
import bootstrap
|
||||||
|
|
||||||
bootstrap.main()
|
try:
|
||||||
|
bootstrap.main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue