Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4124466
std: Fix inheriting stdin on status()
alexcrichton Mar 15, 2016
bb43f58
Document heap allocation location guarantee
aidanhs Mar 20, 2016
bef69a1
std: Add regression test for #32074
alexcrichton Mar 21, 2016
3ee841c
Don't loop forever on error recovery with EOF
Mar 18, 2016
2731dc1
Error recovery in the tokeniser
Mar 22, 2016
0950dc3
Remove ungrammatical dots from the error index.
nodakai Mar 23, 2016
be87650
Add augmented assignment operator impls for time types
sfackler Mar 23, 2016
80e7a1b
Mark str::split_at inline
bluss Mar 23, 2016
f621193
Accept 0 as a valid str char boundary
bluss Mar 23, 2016
180d6b5
Tests
Mar 22, 2016
2c48214
doc: remove needless bindings
tshepang Mar 22, 2016
ed28247
configure: update required LLVM version
cardoe Mar 24, 2016
7124ea4
remove broken config
steveklabnik Mar 24, 2016
8d4b1d1
Introduce name resolution fallback for primitive types
petrochenkov Mar 8, 2016
77f033b
Lift the restriction on reusing names of primitive types
petrochenkov Mar 8, 2016
b418cd2
Cleanup
petrochenkov Mar 10, 2016
78495d5
Fix unsound behaviour with null characters in thread names (issue #32…
diwic Mar 25, 2016
5bc2868
make `const_expr_to_pat` fallible (but never have it actually fail)
nikomatsakis Feb 3, 2016
99c2a6b
modify #[deriving(Eq)] to emit #[structural_match]
nikomatsakis Mar 11, 2016
05baf64
do not overwrite spans as eagerly
nikomatsakis Mar 11, 2016
f69eb8e
issue a future-compat lint for constants of invalid type
nikomatsakis Mar 11, 2016
73b4f06
suppress duplicate lints
nikomatsakis Mar 11, 2016
56ebf2b
fallout in existing tests
nikomatsakis Mar 11, 2016
7f661ec
new tests for RFC #1445
nikomatsakis Mar 11, 2016
93e4443
check for both partialeq and eq
nikomatsakis Mar 25, 2016
6ce63fb
Add note on `str` being an unsized type in strings section of book.
xevix Mar 25, 2016
b9a2311
rustc: move middle::subst into middle::ty.
eddyb Mar 22, 2016
a6f69f1
rustc: move cfg, infer, traits and ty from middle to top-level.
eddyb Mar 22, 2016
00e77be
rustc_trans: move save to librustc_save_analysis.
eddyb Mar 22, 2016
7eb0547
rustc_trans: move the contents of the trans module to top-level.
eddyb Mar 22, 2016
c7049f6
Fix the name of the 'check-cargotest' step
brson Mar 25, 2016
944dc4a
fix cargo.toml for new dependency
nikomatsakis Mar 25, 2016
2536ae5
fix error message
nikomatsakis Mar 25, 2016
88ab938
Avoid page reload upon hitting "S" when browing in local mode
Mar 25, 2016
a755a67
std: Rewrite Once with poisoning
alexcrichton Mar 18, 2016
eac55c2
Rollup merge of #32131 - petrochenkov:prim, r=eddyb
Manishearth Mar 26, 2016
1bf8d69
Rollup merge of #32199 - nikomatsakis:limiting-constants-in-patterns-…
Manishearth Mar 26, 2016
0274432
Rollup merge of #32257 - alexcrichton:fix-status-stdin, r=aturon
Manishearth Mar 26, 2016
9f2e0a6
Rollup merge of #32325 - alexcrichton:panic-once, r=aturon
Manishearth Mar 26, 2016
b27d113
Rollup merge of #32383 - aidanhs:aphs-heap-move-guarantee, r=alexcric…
Manishearth Mar 26, 2016
276d658
Rollup merge of #32387 - alexcrichton:ascii-test, r=aturon
Manishearth Mar 26, 2016
7b76b22
Rollup merge of #32432 - eddyb:dock-service, r=nikomatsakis
Manishearth Mar 26, 2016
92929be
Rollup merge of #32435 - nrc:fix-err-recover, r=nikomatsakis
Manishearth Mar 26, 2016
b6b2dbd
Rollup merge of #32440 - tshepang:compact, r=steveklabnik
Manishearth Mar 26, 2016
c5e3577
Rollup merge of #32447 - nodakai:dots-in-err-idx, r=Manishearth
Manishearth Mar 26, 2016
f6001ce
Rollup merge of #32448 - sfackler:time-augmented-assignment, r=alexcr…
Manishearth Mar 26, 2016
2e0dad7
Rollup merge of #32456 - bluss:str-zero, r=alexcrichton
Manishearth Mar 26, 2016
af2f001
Rollup merge of #32468 - cardoe:llvm-check, r=alexcrichton
Manishearth Mar 26, 2016
ab0f652
Rollup merge of #32470 - rust-lang:steveklabnik-patch-1, r=alexcrichton
Manishearth Mar 26, 2016
71fa130
Rollup merge of #32476 - diwic:63-null-thread-name, r=alexcrichton
Manishearth Mar 26, 2016
707517e
Rollup merge of #32478 - xevix:docs/strings-str-unsized-types, r=stev…
Manishearth Mar 26, 2016
49a9137
Rollup merge of #32484 - brson:cargotest, r=alexcrichton
Manishearth Mar 26, 2016
17ea3e8
Rollup merge of #32492 - xitep:master, r=alexcrichton
Manishearth Mar 26, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
issue a future-compat lint for constants of invalid type
This is a [breaking-change]: according to RFC #1445, constants used as
patterns must be of a type that *derives* `Eq`. If you encounter a
problem, you are most likely using a constant in an expression where the
type of the constant is some struct that does not currently implement
`Eq`. Something like the following:

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

The easiest and most future compatible fix is to annotate the type in
question with `#[derive(Eq)]` (note that merely *implementing* `Eq` is
not enough, it must be *derived*):

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

Another good option is to rewrite the match arm to use an `if`
condition (this is also particularly good for floating point types,
which implement `PartialEq` but not `Eq`):

```rust
match foo {
    c if c == SOME_CONST => ...
}
```

Finally, a third alternative is to tag the type with
`#[structural_match]`; but this is not recommended, as the attribute is
never expected to be stabilized. Please see RFC #1445 for more details.
  • Loading branch information
nikomatsakis committed Mar 25, 2016
commit f69eb8efbe5dbc373426bf0ff021b49f37db41cb
15 changes: 15 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ declare_lint! {
"type parameter default erroneously allowed in invalid location"
}

declare_lint! {
pub ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
Warn,
"floating-point constants cannot be used in patterns"
}

declare_lint! {
pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
Deny,
"constants of struct or enum type can only be used in a pattern if \
the struct or enum has `#[derive(Eq)]`"
}

declare_lint! {
pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
Deny,
Expand Down Expand Up @@ -193,6 +206,8 @@ impl LintPass for HardwiredLints {
PRIVATE_IN_PUBLIC,
INACCESSIBLE_EXTERN_CRATE,
INVALID_TYPE_PARAM_DEFAULT,
ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
CONST_ERR,
RAW_POINTER_DERIVE,
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
Some(Def::Const(did)) => {
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
match const_expr_to_pat(self.tcx, const_expr, pat.span) {
match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
Ok(new_pat) => {
if let Some(ref mut map) = self.renaming_map {
// Record any renamings we do here
Expand All @@ -487,7 +487,6 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
new_pat
}
Err(def_id) => {
// TODO back-compat
self.failed = true;
self.tcx.sess.span_err(
pat.span,
Expand Down
46 changes: 39 additions & 7 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use self::EvalHint::*;

use front::map as ast_map;
use front::map::blocks::FnLikeNode;
use lint;
use middle::cstore::{self, CrateStore, InlinedItem};
use middle::{infer, subst, traits};
use middle::def::Def;
Expand Down Expand Up @@ -323,13 +324,41 @@ impl ConstVal {
}
}

pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, pat_id: ast::NodeId, span: Span)
-> Result<P<hir::Pat>, DefId> {
let pat_ty = tcx.expr_ty(expr);
debug!("expr={:?} pat_ty={:?} pat_id={}", expr, pat_ty, pat_id);
match pat_ty.sty {
ty::TyFloat(_) => {
tcx.sess.add_lint(
lint::builtin::ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
pat_id,
span,
format!("floating point constants cannot be used in patterns"));
}
ty::TyEnum(adt_def, _) |
ty::TyStruct(adt_def, _) => {
if !tcx.has_attr(adt_def.did, "structural_match") {
tcx.sess.add_lint(
lint::builtin::ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
pat_id,
span,
format!("to use a constant of type `{}` \
in a pattern, \
`{}` must be annotated with `#[derive(Eq)]`",
tcx.item_path_str(adt_def.did),
tcx.item_path_str(adt_def.did)));
}
}
_ => { }
}

let pat = match expr.node {
hir::ExprTup(ref exprs) =>
PatKind::Tup(try!(exprs.iter()
.map(|expr| const_expr_to_pat(tcx, &expr, span))
.collect())),
.map(|expr| const_expr_to_pat(tcx, &expr,
pat_id, span))
.collect())),

hir::ExprCall(ref callee, ref args) => {
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
Expand All @@ -347,7 +376,8 @@ pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
_ => unreachable!()
};
let pats = try!(args.iter()
.map(|expr| const_expr_to_pat(tcx, &**expr, span))
.map(|expr| const_expr_to_pat(tcx, &**expr,
pat_id, span))
.collect());
PatKind::TupleStruct(path, Some(pats))
}
Expand All @@ -359,7 +389,8 @@ pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
span: codemap::DUMMY_SP,
node: hir::FieldPat {
name: field.name.node,
pat: try!(const_expr_to_pat(tcx, &field.expr, span)),
pat: try!(const_expr_to_pat(tcx, &field.expr,
pat_id, span)),
is_shorthand: false,
},
}))
Expand All @@ -369,7 +400,8 @@ pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)

hir::ExprVec(ref exprs) => {
let pats = try!(exprs.iter()
.map(|expr| const_expr_to_pat(tcx, &expr, span))
.map(|expr| const_expr_to_pat(tcx, &expr,
pat_id, span))
.collect());
PatKind::Vec(pats, None, hir::HirVec::new())
}
Expand All @@ -383,7 +415,7 @@ pub fn const_expr_to_pat(tcx: &ty::TyCtxt, expr: &Expr, span: Span)
Some(Def::AssociatedConst(def_id)) => {
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
return const_expr_to_pat(tcx, expr, span);
return const_expr_to_pat(tcx, expr, pat_id, span);
},
_ => unreachable!(),
}
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
id: LintId::of(OVERLAPPING_INHERENT_IMPLS),
reference: "issue #22889 <https://github.com/rust-lang/rust/issues/22889>",
},
FutureIncompatibleInfo {
id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN),
reference: "RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>",
},
FutureIncompatibleInfo {
id: LintId::of(ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN),
reference: "RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>",
},
]);

// We have one lint pass defined specially
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/hair/cx/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
Some((const_expr, _const_ty)) => {
match const_eval::const_expr_to_pat(self.cx.tcx,
const_expr,
pat.id,
pat.span) {
Ok(pat) =>
return self.to_pattern(&pat),
Expand Down