Skip to content

Commit d322f99

Browse files
committed
Auto merge of #32496 - Manishearth:rollup, r=Manishearth
Rollup of 11 pull requests - Successful merges: #32131, #32199, #32257, #32325, #32435, #32447, #32448, #32456, #32469, #32476, #32482 - Failed merges: #32240
2 parents 8d2d2be + 6c10866 commit d322f99

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+825
-307
lines changed

src/libcore/str/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,10 @@ impl StrExt for str {
19531953

19541954
#[inline]
19551955
fn is_char_boundary(&self, index: usize) -> bool {
1956-
if index == self.len() { return true; }
1956+
// 0 and len are always ok.
1957+
// Test for 0 explicitly so that it can optimize out the check
1958+
// easily and skip reading string data for that case.
1959+
if index == 0 || index == self.len() { return true; }
19571960
match self.as_bytes().get(index) {
19581961
None => false,
19591962
Some(&b) => b < 128 || b >= 192,
@@ -2026,6 +2029,7 @@ impl StrExt for str {
20262029
self.find(pat)
20272030
}
20282031

2032+
#[inline]
20292033
fn split_at(&self, mid: usize) -> (&str, &str) {
20302034
// is_char_boundary checks that the index is in [0, .len()]
20312035
if self.is_char_boundary(mid) {

src/librustc/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ compiled:
12611261
fn foo<T: Index<u8>>(x: T){}
12621262
12631263
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
1264-
trait Index<Idx> { ... }
1264+
trait Index<Idx> { /* ... */ }
12651265
12661266
foo(true); // `bool` does not implement `Index<u8>`
12671267
```
@@ -1291,7 +1291,7 @@ compiled:
12911291
fn foo<T: Index<u8>>(x: T){}
12921292
12931293
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
1294-
trait Index<Idx> { ... }
1294+
trait Index<Idx> { /* ... */ }
12951295
12961296
foo(true); // `bool` does not implement `Index<u8>`
12971297
```
@@ -1319,7 +1319,7 @@ compiled:
13191319
fn foo<T: Index<u8>>(x: T){}
13201320
13211321
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
1322-
trait Index<Idx> { ... }
1322+
trait Index<Idx> { /* ... */ }
13231323
13241324
foo(true); // `bool` does not implement `Index<u8>`
13251325
```

src/librustc/lint/builtin.rs

+15
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,19 @@ declare_lint! {
136136
"type parameter default erroneously allowed in invalid location"
137137
}
138138

139+
declare_lint! {
140+
pub ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
141+
Warn,
142+
"floating-point constants cannot be used in patterns"
143+
}
144+
145+
declare_lint! {
146+
pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
147+
Deny,
148+
"constants of struct or enum type can only be used in a pattern if \
149+
the struct or enum has `#[derive(PartialEq, Eq)]`"
150+
}
151+
139152
declare_lint! {
140153
pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
141154
Deny,
@@ -193,6 +206,8 @@ impl LintPass for HardwiredLints {
193206
PRIVATE_IN_PUBLIC,
194207
INACCESSIBLE_EXTERN_CRATE,
195208
INVALID_TYPE_PARAM_DEFAULT,
209+
ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
210+
ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
196211
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
197212
CONST_ERR,
198213
RAW_POINTER_DERIVE,

src/librustc/middle/check_match.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -478,15 +478,24 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
478478
Some(Def::Const(did)) => {
479479
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
480480
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
481-
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
482-
483-
if let Some(ref mut renaming_map) = self.renaming_map {
484-
// Record any renamings we do here
485-
record_renamings(const_expr, &pat, renaming_map);
481+
match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
482+
Ok(new_pat) => {
483+
if let Some(ref mut map) = self.renaming_map {
484+
// Record any renamings we do here
485+
record_renamings(const_expr, &pat, map);
486+
}
487+
new_pat
486488
}
487-
488-
new_pat
489-
})
489+
Err(def_id) => {
490+
self.failed = true;
491+
self.tcx.sess.span_err(
492+
pat.span,
493+
&format!("constants of the type `{}` \
494+
cannot be used in patterns",
495+
self.tcx.item_path_str(def_id)));
496+
pat
497+
}
498+
}
490499
} else {
491500
self.failed = true;
492501
span_err!(self.tcx.sess, pat.span, E0158,

src/librustc/middle/const_eval.rs

+58-16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use self::EvalHint::*;
1616

1717
use front::map as ast_map;
1818
use front::map::blocks::FnLikeNode;
19+
use lint;
1920
use middle::cstore::{self, CrateStore, InlinedItem};
2021
use middle::{infer, subst, traits};
2122
use middle::def::Def;
@@ -323,10 +324,41 @@ impl ConstVal {
323324
}
324325
}
325326

326-
pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
327+
pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, pat_id: ast::NodeId, span: Span)
328+
-> Result<P<hir::Pat>, DefId> {
329+
let pat_ty = tcx.expr_ty(expr);
330+
debug!("expr={:?} pat_ty={:?} pat_id={}", expr, pat_ty, pat_id);
331+
match pat_ty.sty {
332+
ty::TyFloat(_) => {
333+
tcx.sess.add_lint(
334+
lint::builtin::ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
335+
pat_id,
336+
span,
337+
format!("floating point constants cannot be used in patterns"));
338+
}
339+
ty::TyEnum(adt_def, _) |
340+
ty::TyStruct(adt_def, _) => {
341+
if !tcx.has_attr(adt_def.did, "structural_match") {
342+
tcx.sess.add_lint(
343+
lint::builtin::ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
344+
pat_id,
345+
span,
346+
format!("to use a constant of type `{}` \
347+
in a pattern, \
348+
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
349+
tcx.item_path_str(adt_def.did),
350+
tcx.item_path_str(adt_def.did)));
351+
}
352+
}
353+
_ => { }
354+
}
355+
327356
let pat = match expr.node {
328357
hir::ExprTup(ref exprs) =>
329-
PatKind::Tup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect()),
358+
PatKind::Tup(try!(exprs.iter()
359+
.map(|expr| const_expr_to_pat(tcx, &expr,
360+
pat_id, span))
361+
.collect())),
330362

331363
hir::ExprCall(ref callee, ref args) => {
332364
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
@@ -336,31 +368,41 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
336368
let path = match def.full_def() {
337369
Def::Struct(def_id) => def_to_path(tcx, def_id),
338370
Def::Variant(_, variant_did) => def_to_path(tcx, variant_did),
339-
Def::Fn(..) => return P(hir::Pat {
371+
Def::Fn(..) => return Ok(P(hir::Pat {
340372
id: expr.id,
341373
node: PatKind::Lit(P(expr.clone())),
342374
span: span,
343-
}),
375+
})),
344376
_ => unreachable!()
345377
};
346-
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
378+
let pats = try!(args.iter()
379+
.map(|expr| const_expr_to_pat(tcx, &**expr,
380+
pat_id, span))
381+
.collect());
347382
PatKind::TupleStruct(path, Some(pats))
348383
}
349384

350385
hir::ExprStruct(ref path, ref fields, None) => {
351-
let field_pats = fields.iter().map(|field| codemap::Spanned {
352-
span: codemap::DUMMY_SP,
353-
node: hir::FieldPat {
354-
name: field.name.node,
355-
pat: const_expr_to_pat(tcx, &field.expr, span),
356-
is_shorthand: false,
357-
},
358-
}).collect();
386+
let field_pats =
387+
try!(fields.iter()
388+
.map(|field| Ok(codemap::Spanned {
389+
span: codemap::DUMMY_SP,
390+
node: hir::FieldPat {
391+
name: field.name.node,
392+
pat: try!(const_expr_to_pat(tcx, &field.expr,
393+
pat_id, span)),
394+
is_shorthand: false,
395+
},
396+
}))
397+
.collect());
359398
PatKind::Struct(path.clone(), field_pats, false)
360399
}
361400

362401
hir::ExprVec(ref exprs) => {
363-
let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &expr, span)).collect();
402+
let pats = try!(exprs.iter()
403+
.map(|expr| const_expr_to_pat(tcx, &expr,
404+
pat_id, span))
405+
.collect());
364406
PatKind::Vec(pats, None, hir::HirVec::new())
365407
}
366408

@@ -373,15 +415,15 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
373415
Some(Def::AssociatedConst(def_id)) => {
374416
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
375417
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
376-
return const_expr_to_pat(tcx, expr, span);
418+
return const_expr_to_pat(tcx, expr, pat_id, span);
377419
},
378420
_ => unreachable!(),
379421
}
380422
}
381423

382424
_ => PatKind::Lit(P(expr.clone()))
383425
};
384-
P(hir::Pat { id: expr.id, node: pat, span: span })
426+
Ok(P(hir::Pat { id: expr.id, node: pat, span: span }))
385427
}
386428

387429
pub fn eval_const_expr(tcx: &TyCtxt, e: &Expr) -> ConstVal {

src/librustc/mir/visit.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,15 @@ macro_rules! make_mir_visitor {
614614

615615
fn super_constant(&mut self,
616616
constant: & $($mutability)* Constant<'tcx>) {
617-
self.visit_span(& $($mutability)* constant.span);
618-
self.visit_ty(& $($mutability)* constant.ty);
619-
self.visit_literal(& $($mutability)* constant.literal);
617+
let Constant {
618+
ref $($mutability)* span,
619+
ref $($mutability)* ty,
620+
ref $($mutability)* literal,
621+
} = *constant;
622+
623+
self.visit_span(span);
624+
self.visit_ty(ty);
625+
self.visit_literal(literal);
620626
}
621627

622628
fn super_typed_const_val(&mut self,
@@ -626,6 +632,7 @@ macro_rules! make_mir_visitor {
626632
ref $($mutability)* ty,
627633
ref $($mutability)* value,
628634
} = *constant;
635+
629636
self.visit_span(span);
630637
self.visit_ty(ty);
631638
self.visit_const_usize(value);

src/librustc/session/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,13 @@ impl Session {
252252
let lint_id = lint::LintId::of(lint);
253253
let mut lints = self.lints.borrow_mut();
254254
match lints.get_mut(&id) {
255-
Some(arr) => { arr.push((lint_id, sp, msg)); return; }
255+
Some(arr) => {
256+
let tuple = (lint_id, sp, msg);
257+
if !arr.contains(&tuple) {
258+
arr.push(tuple);
259+
}
260+
return;
261+
}
256262
None => {}
257263
}
258264
lints.insert(id, vec!((lint_id, sp, msg)));

src/librustc_lint/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
179179
id: LintId::of(OVERLAPPING_INHERENT_IMPLS),
180180
reference: "issue #22889 <https://github.com/rust-lang/rust/issues/22889>",
181181
},
182+
FutureIncompatibleInfo {
183+
id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN),
184+
reference: "RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>",
185+
},
186+
FutureIncompatibleInfo {
187+
id: LintId::of(ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN),
188+
reference: "RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>",
189+
},
182190
]);
183191

184192
// We have one lint pass defined specially

src/librustc_mir/hair/cx/pattern.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,16 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
9090
let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
9191
match const_eval::lookup_const_by_id(self.cx.tcx, def_id, substs) {
9292
Some((const_expr, _const_ty)) => {
93-
let pat = const_eval::const_expr_to_pat(self.cx.tcx, const_expr,
94-
pat.span);
95-
return self.to_pattern(&pat);
93+
match const_eval::const_expr_to_pat(self.cx.tcx,
94+
const_expr,
95+
pat.id,
96+
pat.span) {
97+
Ok(pat) =>
98+
return self.to_pattern(&pat),
99+
Err(_) =>
100+
self.cx.tcx.sess.span_bug(
101+
pat.span, "illegal constant"),
102+
}
96103
}
97104
None => {
98105
self.cx.tcx.sess.span_bug(

0 commit comments

Comments
 (0)