diff --git a/src/doc/rust.css b/src/doc/rust.css index 932594b99126d..664bc0fdab002 100644 --- a/src/doc/rust.css +++ b/src/doc/rust.css @@ -44,7 +44,9 @@ font-family: 'Source Code Pro'; font-style: normal; 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) { diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index cb69de2cb3cac..b355c8f2c4c6f 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -26,7 +26,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { extent: cx.tcx.region_maps.node_extent(self.id), span: self.span, 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>, block_id: ast::NodeId, stmts: &'tcx [hir::Stmt]) - -> Vec> -{ + -> Vec> { let mut result = vec![]; for (index, stmt) in stmts.iter().enumerate() { 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 { span: stmt.span, kind: StmtKind::Expr { 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::StmtDecl(ref decl, id) => match decl.node { - hir::DeclItem(..) => { /* ignore for purposes of the MIR */ } - hir::DeclLocal(ref local) => { - let remainder_extent = CodeExtentData::Remainder(BlockRemainder { - block: block_id, - first_statement_index: index as u32, - }); - let remainder_extent = - cx.tcx.region_maps.lookup_code_extent(remainder_extent); + hir::DeclLocal(ref local) => { + let remainder_extent = CodeExtentData::Remainder(BlockRemainder { + block: block_id, + first_statement_index: index as u32, + }); + let remainder_extent = + cx.tcx.region_maps.lookup_code_extent(remainder_extent); - let pattern = Pattern::from_hir(cx.tcx, &local.pat); - result.push(StmtRef::Mirror(Box::new(Stmt { - span: stmt.span, - kind: StmtKind::Let { - remainder_scope: remainder_extent, - init_scope: cx.tcx.region_maps.node_extent(id), - pattern: pattern, - initializer: local.init.to_ref(), - }, - }))); + let pattern = Pattern::from_hir(cx.tcx, &local.pat); + result.push(StmtRef::Mirror(Box::new(Stmt { + span: stmt.span, + kind: StmtKind::Let { + remainder_scope: remainder_extent, + init_scope: cx.tcx.region_maps.node_extent(id), + pattern: pattern, + initializer: local.init.to_ref(), + }, + }))); + } } } } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index bd4724159b4cb..d579cdb042fb3 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -36,7 +36,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { let adj = cx.tcx.tables().adjustments.get(&self.id).cloned(); debug!("make_mirror: unadjusted-expr={:?} applying adjustments={:?}", - expr, adj); + expr, + adj); // Now apply adjustments, if any. 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 { let i = i as u32; let adjusted_ty = - expr.ty.adjust_for_autoderef( - cx.tcx, - self.id, - self.span, - i, - |mc| cx.tcx.tables().method_map.get(&mc).map(|m| m.ty)); - debug!("make_mirror: autoderef #{}, adjusted_ty={:?}", i, adjusted_ty); + expr.ty.adjust_for_autoderef(cx.tcx, self.id, self.span, i, |mc| { + cx.tcx.tables().method_map.get(&mc).map(|m| m.ty) + }); + debug!("make_mirror: autoderef #{}, adjusted_ty={:?}", + i, + adjusted_ty); let method_key = ty::MethodCall::autoderef(self.id, i); - let meth_ty = - cx.tcx.tables().method_map.get(&method_key).map(|m| m.ty); + let meth_ty = cx.tcx.tables().method_map.get(&method_key).map(|m| m.ty); let kind = if let Some(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 (region, mutbl) = match ref_ty { - Some(&ty::TyS { - sty: ty::TyRef(region, mt), .. - }) => (region, mt.mutbl), - _ => span_bug!(expr.span, "autoderef returned bad type") + Some(&ty::TyS { sty: ty::TyRef(region, mt), .. }) => (region, mt.mutbl), + _ => span_bug!(expr.span, "autoderef returned bad type"), }; expr = Expr { temp_lifetime: temp_lifetime, - ty: cx.tcx.mk_ref( - region, ty::TypeAndMut { ty: expr.ty, mutbl: mutbl }), + ty: cx.tcx.mk_ref(region, + ty::TypeAndMut { + ty: expr.ty, + mutbl: mutbl, + }), span: expr.span, kind: ExprKind::Borrow { region: region, borrow_kind: to_borrow_kind(mutbl), - arg: expr.to_ref() - } + arg: expr.to_ref(), + }, }; - overloaded_lvalue(cx, self, method_key, - PassArgs::ByRef, expr.to_ref(), vec![]) + overloaded_lvalue(cx, + self, + method_key, + PassArgs::ByRef, + expr.to_ref(), + vec![]) } else { debug!("make_mirror: built-in autoderef"); 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); expr = Expr { 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, kind: ExprKind::Borrow { 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 { 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(|| { - span_bug!(expr.span, "method call has late-bound regions") - }); + let sig = cx.tcx + .no_late_bound_regions(sig) + .unwrap_or_else(|| span_bug!(expr.span, "method call has late-bound regions")); 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], temp_lifetime: temp_lifetime, span: expr.span, - kind: ExprKind::Tuple { - fields: args.iter().map(ToRef::to_ref).collect() - } + kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() }, }; ExprKind::Call { ty: method.ty, fun: method.to_ref(), - args: vec![fun.to_ref(), tupled_args.to_ref()] + args: vec![fun.to_ref(), tupled_args.to_ref()], } } else { 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. - expr_ty.ty_adt_def().and_then(|adt_def|{ + expr_ty.ty_adt_def().and_then(|adt_def| { match path.def { Def::VariantCtor(variant_id, CtorKind::Fn) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) - }, - Def::StructCtor(_, CtorKind::Fn) => { - Some((adt_def, 0)) - }, - _ => None + } + Def::StructCtor(_, CtorKind::Fn) => Some((adt_def, 0)), + _ => None, } }) - } else { None }; + } else { + None + }; 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(&[])); - let field_refs = args.iter().enumerate().map(|(idx, e)| FieldExprRef { - name: Field::new(idx), - expr: e.to_ref() - }).collect(); + let field_refs = args.iter() + .enumerate() + .map(|(idx, e)| { + FieldExprRef { + name: Field::new(idx), + expr: e.to_ref(), + } + }) + .collect(); ExprKind::Adt { adt_def: adt_def, substs: substs, variant_index: index, fields: field_refs, - base: None + base: None, } } else { ExprKind::Call { @@ -314,9 +327,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - hir::ExprBlock(ref blk) => { - ExprKind::Block { body: &blk } - } + hir::ExprBlock(ref blk) => ExprKind::Block { body: &blk }, hir::ExprAssign(ref lhs, ref rhs) => { ExprKind::Assign { @@ -332,8 +343,12 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } else { PassArgs::ByRef }; - overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), - pass_args, lhs.to_ref(), vec![rhs]) + overloaded_operator(cx, + expr, + ty::MethodCall::expr(expr.id), + pass_args, + lhs.to_ref(), + vec![rhs]) } else { ExprKind::AssignOp { 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 { - literal: cx.const_eval_literal(expr) - }, + hir::ExprLit(..) => ExprKind::Literal { literal: cx.const_eval_literal(expr) }, hir::ExprBinary(op, ref lhs, ref rhs) => { 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 { PassArgs::ByRef }; - overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), - pass_args, lhs.to_ref(), vec![rhs]) + overloaded_operator(cx, + expr, + ty::MethodCall::expr(expr.id), + pass_args, + lhs.to_ref(), + vec![rhs]) } else { // FIXME overflow 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) => { if cx.tcx.tables().is_method_call(expr.id) { - overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id), - PassArgs::ByValue, lhs.to_ref(), vec![index]) + overloaded_lvalue(cx, + expr, + ty::MethodCall::expr(expr.id), + PassArgs::ByValue, + lhs.to_ref(), + vec![index]) } else { ExprKind::Index { 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) => { if cx.tcx.tables().is_method_call(expr.id) { - overloaded_lvalue(cx, expr, ty::MethodCall::expr(expr.id), - PassArgs::ByValue, arg.to_ref(), vec![]) + overloaded_lvalue(cx, + expr, + ty::MethodCall::expr(expr.id), + PassArgs::ByValue, + arg.to_ref(), + vec![]) } else { 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) => { if cx.tcx.tables().is_method_call(expr.id) { - overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), - PassArgs::ByValue, arg.to_ref(), vec![]) + overloaded_operator(cx, + expr, + ty::MethodCall::expr(expr.id), + PassArgs::ByValue, + arg.to_ref(), + vec![]) } else { ExprKind::Unary { 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) => { if cx.tcx.tables().is_method_call(expr.id) { - overloaded_operator(cx, expr, ty::MethodCall::expr(expr.id), - PassArgs::ByValue, arg.to_ref(), vec![]) + overloaded_operator(cx, + expr, + ty::MethodCall::expr(expr.id), + PassArgs::ByValue, + arg.to_ref(), + vec![]) } else { // FIXME runtime-overflow if let hir::ExprLit(_) = arg.node { - ExprKind::Literal { - literal: cx.const_eval_literal(expr), - } + ExprKind::Literal { literal: cx.const_eval_literal(expr) } } else { ExprKind::Unary { 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) => { match expr_ty.sty { - ty::TyAdt(adt, substs) => match adt.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - let field_refs = field_refs(&adt.variants[0], fields); - ExprKind::Adt { - adt_def: adt, - variant_index: 0, - substs: substs, - fields: field_refs, - base: base.as_ref().map(|base| { - FruInfo { - base: base.to_ref(), - field_types: - cx.tcx.tables().fru_field_types[&expr.id].clone() - } - }) + ty::TyAdt(adt, substs) => { + match adt.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + let field_refs = field_refs(&adt.variants[0], fields); + ExprKind::Adt { + adt_def: adt, + variant_index: 0, + substs: substs, + fields: field_refs, + base: base.as_ref().map(|base| { + FruInfo { + base: base.to_ref(), + field_types: cx.tcx.tables().fru_field_types[&expr.id] + .clone(), + } + }), + } } - } - AdtKind::Enum => { - let def = match *qpath { - hir::QPath::Resolved(_, ref path) => path.def, - hir::QPath::TypeRelative(..) => Def::Err - }; - match def { - Def::Variant(variant_id) => { - assert!(base.is_none()); - - let index = adt.variant_index_with_id(variant_id); - let field_refs = field_refs(&adt.variants[index], fields); - ExprKind::Adt { - adt_def: adt, - variant_index: index, - substs: substs, - fields: field_refs, - base: None + AdtKind::Enum => { + let def = match *qpath { + hir::QPath::Resolved(_, ref path) => path.def, + hir::QPath::TypeRelative(..) => Def::Err, + }; + match def { + Def::Variant(variant_id) => { + assert!(base.is_none()); + + let index = adt.variant_index_with_id(variant_id); + let field_refs = field_refs(&adt.variants[index], fields); + ExprKind::Adt { + adt_def: adt, + variant_index: index, + substs: substs, + fields: field_refs, + base: None, + } + } + _ => { + span_bug!(expr.span, "unexpected def: {:?}", def); } - } - _ => { - span_bug!( - expr.span, - "unexpected def: {:?}", - def); } } } - }, + } _ => { - span_bug!( - expr.span, - "unexpected type for struct literal: {:?}", - expr_ty); + span_bug!(expr.span, + "unexpected type for struct literal: {:?}", + 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 { ty::TyClosure(def_id, substs) => (def_id, substs), _ => { - span_bug!(expr.span, - "closure expr w/o closure type: {:?}", - closure_ty); + span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty); } }; 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 { asm: asm, outputs: outputs.to_ref(), - inputs: inputs.to_ref() + inputs: inputs.to_ref(), } } // Now comes the rote stuff: - - hir::ExprRepeat(ref v, ref c) => ExprKind::Repeat { - value: v.to_ref(), - count: TypedConstVal { - ty: cx.tcx.tables().expr_ty(c), - span: c.span, - value: match const_eval::eval_const_expr(cx.tcx.global_tcx(), c) { - ConstVal::Integral(ConstInt::Usize(u)) => u, - other => bug!("constant evaluation of repeat count yielded {:?}", other), + hir::ExprRepeat(ref v, ref c) => { + ExprKind::Repeat { + value: v.to_ref(), + count: TypedConstVal { + ty: cx.tcx.tables().expr_ty(c), + span: c.span, + value: match const_eval::eval_const_expr(cx.tcx.global_tcx(), c) { + ConstVal::Integral(ConstInt::Usize(u)) => u, + other => bug!("constant evaluation of repeat count yielded {:?}", other), + }, }, } - }, - hir::ExprRet(ref v) => - ExprKind::Return { value: v.to_ref() }, - hir::ExprBreak(label, ref value) => + } + hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() }, + hir::ExprBreak(label, ref value) => { ExprKind::Break { - label: label.map(|label| { - cx.tcx.region_maps.node_extent(label.loop_id) - }), - value: value.to_ref() - }, - hir::ExprAgain(label) => + label: label.map(|label| cx.tcx.region_maps.node_extent(label.loop_id)), + value: value.to_ref(), + } + } + hir::ExprAgain(label) => { ExprKind::Continue { - label: label.map(|label| { - cx.tcx.region_maps.node_extent(label.loop_id) - }) - }, - hir::ExprMatch(ref discr, ref arms, _) => - ExprKind::Match { discriminant: discr.to_ref(), - 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), - otherwise: otherwise.to_ref() }, - 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) }, + label: label.map(|label| cx.tcx.region_maps.node_extent(label.loop_id)), + } + } + hir::ExprMatch(ref discr, ref arms, _) => { + ExprKind::Match { + discriminant: discr.to_ref(), + 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), + otherwise: otherwise.to_ref(), + } + } + 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) => { let index = match cx.tcx.tables().expr_ty_adjusted(source).sty { - ty::TyAdt(adt_def, _) => - adt_def.variants[0].index_of_field_named(name.node), - ref ty => - span_bug!(expr.span, "field of non-ADT: {:?}", ty), + ty::TyAdt(adt_def, _) => adt_def.variants[0].index_of_field_named(name.node), + ref ty => span_bug!(expr.span, "field of non-ADT: {:?}", ty), }; - let index = index.unwrap_or_else(|| { - span_bug!( - expr.span, - "no index found for field `{}`", - name.node) - }); - ExprKind::Field { lhs: source.to_ref(), name: Field::new(index) } + let index = + index.unwrap_or_else(|| { + span_bug!(expr.span, "no index found for field `{}`", name.node) + }); + ExprKind::Field { + lhs: source.to_ref(), + 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, _) => { // Check to see if this cast is a "coercion cast", where the cast is actually done // 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() } } } - hir::ExprType(ref source, _) => - return source.make_mirror(cx), - hir::ExprBox(ref value) => + hir::ExprType(ref source, _) => return source.make_mirror(cx), + hir::ExprBox(ref value) => { ExprKind::Box { value: value.to_ref(), - value_extents: cx.tcx.region_maps.node_extent(value.id) - }, - hir::ExprArray(ref fields) => - ExprKind::Vec { fields: fields.to_ref() }, - hir::ExprTup(ref fields) => - ExprKind::Tuple { fields: fields.to_ref() }, + value_extents: cx.tcx.region_maps.node_extent(value.id), + } + } + hir::ExprArray(ref fields) => ExprKind::Vec { fields: fields.to_ref() }, + hir::ExprTup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() }, }; 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>, - arm: &'tcx hir::Arm) -> Arm<'tcx> { +fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { Arm { patterns: arm.pats.iter().map(|p| Pattern::from_hir(cx.tcx, p)).collect(), 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, def: Def) -> 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(&[])); let def_id = match def { // 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::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::VariantCtor(def_id, CtorKind::Const) => { match cx.tcx.tables().node_id_to_type(expr.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. - ty::TyAdt(adt_def, substs) => return ExprKind::Adt { - adt_def: adt_def, - variant_index: adt_def.variant_index_with_id(def_id), - substs: substs, - fields: vec![], - base: None, - }, - ref sty => bug!("unexpected sty: {:?}", sty) + ty::TyAdt(adt_def, substs) => { + return ExprKind::Adt { + adt_def: adt_def, + variant_index: adt_def.variant_index_with_id(def_id), + substs: substs, + fields: vec![], + base: None, + } + } + ref sty => bug!("unexpected sty: {:?}", sty), } } - Def::Static(node_id, _) => return ExprKind::StaticRef { - id: node_id, - }, + Def::Static(node_id, _) => return ExprKind::StaticRef { id: node_id }, Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def), _ => span_bug!(expr.span, "def `{:?}` not yet implemented", def), }; 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 { Def::Local(def_id) => { let node_id = cx.tcx.map.as_local_node_id(def_id).unwrap(); - ExprKind::VarRef { - id: node_id, - } + ExprKind::VarRef { id: node_id } } Def::Upvar(def_id, index, closure_expr_id) => { 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 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)) { ty::ClosureKind::Fn => { - let ref_closure_ty = - cx.tcx.mk_ref(region, - ty::TypeAndMut { ty: closure_ty, - mutbl: hir::MutImmutable }); + let ref_closure_ty = cx.tcx.mk_ref(region, + ty::TypeAndMut { + ty: closure_ty, + mutbl: hir::MutImmutable, + }); Expr { ty: closure_ty, temp_lifetime: temp_lifetime, span: expr.span, kind: ExprKind::Deref { arg: Expr { - ty: ref_closure_ty, - temp_lifetime: temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef - }.to_ref() - } + ty: ref_closure_ty, + temp_lifetime: temp_lifetime, + span: expr.span, + kind: ExprKind::SelfRef, + } + .to_ref(), + }, } } ty::ClosureKind::FnMut => { - let ref_closure_ty = - cx.tcx.mk_ref(region, - ty::TypeAndMut { ty: closure_ty, - mutbl: hir::MutMutable }); + let ref_closure_ty = cx.tcx.mk_ref(region, + ty::TypeAndMut { + ty: closure_ty, + mutbl: hir::MutMutable, + }); Expr { ty: closure_ty, temp_lifetime: temp_lifetime, span: expr.span, kind: ExprKind::Deref { arg: Expr { - ty: ref_closure_ty, - temp_lifetime: temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef - }.to_ref() - } + ty: ref_closure_ty, + temp_lifetime: temp_lifetime, + span: expr.span, + kind: ExprKind::SelfRef, + } + .to_ref(), + }, } } 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) { Some(c) => c, None => { - span_bug!( - expr.span, - "no upvar_capture for {:?}", - upvar_id); + span_bug!(expr.span, "no upvar_capture for {:?}", upvar_id); } }; match upvar_capture { @@ -834,15 +879,16 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty::UpvarCapture::ByRef(borrow) => { ExprKind::Deref { arg: Expr { - temp_lifetime: temp_lifetime, - ty: cx.tcx.mk_ref(borrow.region, - ty::TypeAndMut { - ty: var_ty, - mutbl: borrow.kind.to_mutbl_lossy() - }), - span: expr.span, - kind: field_kind, - }.to_ref() + temp_lifetime: temp_lifetime, + ty: cx.tcx.mk_ref(borrow.region, + ty::TypeAndMut { + ty: var_ty, + mutbl: borrow.kind.to_mutbl_lossy(), + }), + span: expr.span, + kind: field_kind, + } + .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 // operator, we have to gin up the autorefs (but by value is easy) match pass_args { - PassArgs::ByValue => { - argrefs.extend(args.iter().map(|arg| arg.to_ref())) - } + PassArgs::ByValue => argrefs.extend(args.iter().map(|arg| arg.to_ref())), PassArgs::ByRef => { let region = cx.tcx.node_scope_region(expr.id); let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id); - argrefs.extend( - args.iter() - .map(|arg| { - let arg_ty = cx.tcx.tables().expr_ty_adjusted(arg); - let adjusted_ty = - cx.tcx.mk_ref(region, - ty::TypeAndMut { ty: arg_ty, - mutbl: hir::MutImmutable }); - Expr { + argrefs.extend(args.iter() + .map(|arg| { + let arg_ty = cx.tcx.tables().expr_ty_adjusted(arg); + let adjusted_ty = cx.tcx.mk_ref(region, + ty::TypeAndMut { + ty: arg_ty, + mutbl: hir::MutImmutable, + }); + Expr { temp_lifetime: temp_lifetime, ty: adjusted_ty, span: expr.span, - kind: ExprKind::Borrow { region: region, - borrow_kind: BorrowKind::Shared, - arg: arg.to_ref() } - }.to_ref() - })) + kind: ExprKind::Borrow { + region: region, + borrow_kind: BorrowKind::Shared, + 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), }; match upvar_capture { - ty::UpvarCapture::ByValue => { - captured_var.to_ref() - } + ty::UpvarCapture::ByValue => captured_var.to_ref(), ty::UpvarCapture::ByRef(upvar_borrow) => { let borrow_kind = match upvar_borrow.kind { 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, }; Expr { - temp_lifetime: temp_lifetime, - ty: freevar_ty, - span: closure_expr.span, - kind: ExprKind::Borrow { region: upvar_borrow.region, - borrow_kind: borrow_kind, - arg: captured_var.to_ref() } - }.to_ref() + temp_lifetime: temp_lifetime, + ty: freevar_ty, + span: closure_expr.span, + kind: ExprKind::Borrow { + region: upvar_borrow.region, + borrow_kind: borrow_kind, + 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. fn field_refs<'tcx>(variant: &'tcx VariantDef, fields: &'tcx [hir::Field]) - -> Vec> -{ + -> Vec> { fields.iter() - .map(|field| FieldExprRef { - name: Field::new(variant.index_of_field_named(field.name.node).unwrap()), - expr: field.expr.to_ref(), - }) - .collect() + .map(|field| { + FieldExprRef { + name: Field::new(variant.index_of_field_named(field.name.node).unwrap()), + expr: field.expr.to_ref(), + } + }) + .collect() } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index e7a6b40c830bd..7d111fccd0056 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/*! - * This module contains the code to convert from the wacky tcx data - * structures into the hair. The `builder` is generally ignorant of - * the tcx etc, and instead goes through the `Cx` for most of its - * work. - */ +//! This module contains the code to convert from the wacky tcx data +//! structures into the hair. The `builder` is generally ignorant of +//! the tcx etc, and instead goes through the `Cx` for most of its +//! work. +//! use hair::*; use rustc::mir::transform::MirSource; @@ -32,19 +31,17 @@ use rustc::hir; use rustc_const_math::{ConstInt, ConstUsize}; #[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>, infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, constness: hir::Constness, /// True if this constant/function needs overflow checks. - check_overflow: bool + check_overflow: bool, } impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - src: MirSource) - -> Cx<'a, 'gcx, 'tcx> { + pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, src: MirSource) -> Cx<'a, 'gcx, 'tcx> { let constness = match src { MirSource::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)); fn_like.map_or(hir::Constness::NotConst, |f| f.constness()) } - MirSource::Promoted(..) => bug!() + MirSource::Promoted(..) => bug!(), }; 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, // however, they may not get codegen'd, depending on // the settings for the crate they are translated in. - let mut check_overflow = attrs.iter().any(|item| { - item.check_name("rustc_inherit_overflow_checks") - }); + let mut check_overflow = attrs.iter() + .any(|item| item.check_name("rustc_inherit_overflow_checks")); // Respect -Z force-overflow-checks=on and -C debug-assertions. - check_overflow |= infcx.tcx.sess.opts.debugging_opts.force_overflow_checks - .unwrap_or(infcx.tcx.sess.opts.debug_assertions); + check_overflow |= infcx.tcx + .sess + .opts + .debugging_opts + .force_overflow_checks + .unwrap_or(infcx.tcx.sess.opts.debug_assertions); // Constants and const fn's always need overflow checks. check_overflow |= constness == hir::Constness::Const; @@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { tcx: infcx.tcx, infcx: infcx, 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> { 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"), } } @@ -128,9 +128,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { } pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> { - Literal::Value { - value: const_eval::eval_const_expr(self.tcx.global_tcx(), e) - } + Literal::Value { value: const_eval::eval_const_expr(self.tcx.global_tcx(), e) } } 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 { let method_ty = self.tcx.item_type(item.def_id); let method_ty = method_ty.subst(self.tcx, substs); - return (method_ty, Literal::Item { - def_id: item.def_id, - substs: substs, - }); + return (method_ty, + Literal::Item { + 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 { let ty = self.tcx.lift_to_global(&ty).unwrap_or_else(|| { 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) } diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index 63dbde474380a..6930a959d6515 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -18,7 +18,7 @@ pub trait ToRef { 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>; 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 { +impl<'a, 'tcx: 'a> ToRef for &'tcx P { type Output = ExprRef<'tcx>; fn to_ref(self) -> ExprRef<'tcx> { @@ -34,7 +34,7 @@ impl<'a,'tcx:'a> ToRef for &'tcx P { } } -impl<'a,'tcx:'a> ToRef for Expr<'tcx> { +impl<'a, 'tcx: 'a> ToRef for Expr<'tcx> { type Output = 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 - where &'tcx T: ToRef +impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx Option + where &'tcx T: ToRef { type Output = Option; @@ -52,8 +52,8 @@ impl<'a,'tcx:'a,T,U> ToRef for &'tcx Option } } -impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec - where &'tcx T: ToRef +impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx Vec + where &'tcx T: ToRef { type Output = Vec; @@ -62,8 +62,8 @@ impl<'a,'tcx:'a,T,U> ToRef for &'tcx Vec } } -impl<'a,'tcx:'a,T,U> ToRef for &'tcx P<[T]> - where &'tcx T: ToRef +impl<'a, 'tcx: 'a, T, U> ToRef for &'tcx P<[T]> + where &'tcx T: ToRef { type Output = Vec; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index e721b66779fff..ac336fe45e54a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1468,6 +1468,13 @@ impl<'a> Item<'a> { return None; } } 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) { Some(&(ref name, ref src, Local)) => (name, src), Some(&(ref name, ref src, Remote(ref s))) => { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 7ee184c089ca4..15912b41d59c0 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -52,13 +52,15 @@ font-family: 'Source Code Pro'; font-style: normal; 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-family: 'Source Code Pro'; font-style: normal; font-weight: 600; - src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff'); + src: url("SourceCodePro-Semibold.woff") format('woff'); } * { diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index b280f466dd439..f8a5ec0b3791e 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -499,6 +499,19 @@ impl UdpSocket { /// This will retrieve the stored error in the underlying socket, clearing /// the field in the process. This can be useful for checking errors between /// 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")] pub fn take_error(&self) -> io::Result> { self.0.take_error() @@ -507,6 +520,15 @@ impl UdpSocket { /// 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 /// 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")] pub fn connect(&self, addr: A) -> io::Result<()> { 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. /// - /// 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. + /// + /// [`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")] pub fn send(&self, buf: &[u8]) -> io::Result { self.0.send(buf) @@ -526,6 +560,20 @@ impl UdpSocket { /// /// The `connect` method will connect this socket to a remote address. This /// 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")] pub fn recv(&self, buf: &mut [u8]) -> io::Result { self.0.recv(buf) @@ -535,6 +583,15 @@ impl UdpSocket { /// /// On Unix this corresponds to calling fcntl, and on Windows this /// 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")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { self.0.set_nonblocking(nonblocking) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index ca6e46eb15ac6..9f51d3e87f3f7 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -454,10 +454,16 @@ impl UnsafeFlavor for Receiver { } /// Creates a new asynchronous channel, returning the sender/receiver halves. -/// /// 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"). /// +/// 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 /// /// ``` @@ -487,18 +493,23 @@ pub fn channel() -> (Sender, Receiver) { /// 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 /// sender from asynchronous channels, however. /// -/// This channel has an internal buffer on which messages will be queued. `bound` -/// specifies the buffer size. When the internal buffer becomes full, future sends -/// will *block* waiting for the buffer to open up. Note that a buffer size of 0 -/// is valid, in which case this becomes "rendezvous channel" where each send will -/// not return until a recv is paired with it. +/// This channel has an internal buffer on which messages will be queued. +/// `bound` specifies the buffer size. When the internal buffer becomes full, +/// future sends will *block* waiting for the buffer to open up. Note that a +/// buffer size of 0 is valid, in which case this becomes "rendezvous channel" +/// where each [`send()`] will not return until a recv is paired with it. +/// +/// Like asynchronous channels, if the [`Receiver`] is disconnected while +/// trying to [`send()`] with the [`SyncSender`], the [`send()`] method will +/// return an error. /// -/// As with asynchronous channels, all senders will panic in `send` if the -/// `Receiver` has been destroyed. +/// [`send()`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send +/// [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html +/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html /// /// # Examples /// diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs new file mode 100644 index 0000000000000..38fe5cdffebd0 --- /dev/null +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/incremental/hashes/enum_constructors.rs b/src/test/incremental/hashes/enum_constructors.rs new file mode 100644 index 0000000000000..7f991b30fc492 --- /dev/null +++ b/src/test/incremental/hashes/enum_constructors.rs @@ -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 or the MIT license +// , 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 + } +} diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs new file mode 100644 index 0000000000000..082badacc6ccd --- /dev/null +++ b/src/test/incremental/hashes/exported_vs_not.rs @@ -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 or the MIT license +// , 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 +} + diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs new file mode 100644 index 0000000000000..bb31982d93f21 --- /dev/null +++ b/src/test/incremental/hashes/indexing_expressions.rs @@ -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 or the MIT license +// , 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] +} diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index 6a9f4698bf887..0e23d953baf2d 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -202,6 +202,12 @@ mod change_constructor_path_indirectly_regular_struct { #[cfg(not(cfail1))] 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 { Struct { x: 0, @@ -262,6 +268,12 @@ mod change_constructor_path_indirectly_tuple_struct { #[cfg(not(cfail1))] 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 { Struct(0, 1, 2) } diff --git a/x.py b/x.py index 54148b0d2b29d..d281a6abc93e3 100755 --- a/x.py +++ b/x.py @@ -16,4 +16,7 @@ import bootstrap -bootstrap.main() +try: + bootstrap.main() +except KeyboardInterrupt: + sys.exit()